cc-recommender 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +21 -0
  3. package/README.ja.md +201 -0
  4. package/README.md +201 -0
  5. package/data/mcp-servers.json +34777 -0
  6. package/data/plugins.json +1571 -0
  7. package/data/skills.json +3233 -0
  8. package/dist/config/constants.d.ts +18 -0
  9. package/dist/config/constants.d.ts.map +1 -0
  10. package/dist/config/constants.js +34 -0
  11. package/dist/config/constants.js.map +1 -0
  12. package/dist/config/file-mappings.d.ts +13 -0
  13. package/dist/config/file-mappings.d.ts.map +1 -0
  14. package/dist/config/file-mappings.js +70 -0
  15. package/dist/config/file-mappings.js.map +1 -0
  16. package/dist/config/index.d.ts +9 -0
  17. package/dist/config/index.d.ts.map +1 -0
  18. package/dist/config/index.js +9 -0
  19. package/dist/config/index.js.map +1 -0
  20. package/dist/config/scoring-config.d.ts +27 -0
  21. package/dist/config/scoring-config.d.ts.map +1 -0
  22. package/dist/config/scoring-config.js +27 -0
  23. package/dist/config/scoring-config.js.map +1 -0
  24. package/dist/index.d.ts +9 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +25 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/repositories/index.d.ts +7 -0
  29. package/dist/repositories/index.d.ts.map +1 -0
  30. package/dist/repositories/index.js +7 -0
  31. package/dist/repositories/index.js.map +1 -0
  32. package/dist/repositories/recommendation.repository.d.ts +56 -0
  33. package/dist/repositories/recommendation.repository.d.ts.map +1 -0
  34. package/dist/repositories/recommendation.repository.js +142 -0
  35. package/dist/repositories/recommendation.repository.js.map +1 -0
  36. package/dist/repositories/remote-data.repository.d.ts +20 -0
  37. package/dist/repositories/remote-data.repository.d.ts.map +1 -0
  38. package/dist/repositories/remote-data.repository.js +307 -0
  39. package/dist/repositories/remote-data.repository.js.map +1 -0
  40. package/dist/schemas/index.d.ts +7 -0
  41. package/dist/schemas/index.d.ts.map +1 -0
  42. package/dist/schemas/index.js +7 -0
  43. package/dist/schemas/index.js.map +1 -0
  44. package/dist/schemas/tool-schemas.d.ts +55 -0
  45. package/dist/schemas/tool-schemas.d.ts.map +1 -0
  46. package/dist/schemas/tool-schemas.js +36 -0
  47. package/dist/schemas/tool-schemas.js.map +1 -0
  48. package/dist/server/index.d.ts +8 -0
  49. package/dist/server/index.d.ts.map +1 -0
  50. package/dist/server/index.js +8 -0
  51. package/dist/server/index.js.map +1 -0
  52. package/dist/server/mcp-server.d.ts +11 -0
  53. package/dist/server/mcp-server.d.ts.map +1 -0
  54. package/dist/server/mcp-server.js +27 -0
  55. package/dist/server/mcp-server.js.map +1 -0
  56. package/dist/server/tool-registry.d.ts +12 -0
  57. package/dist/server/tool-registry.d.ts.map +1 -0
  58. package/dist/server/tool-registry.js +114 -0
  59. package/dist/server/tool-registry.js.map +1 -0
  60. package/dist/services/analyzer/index.d.ts +7 -0
  61. package/dist/services/analyzer/index.d.ts.map +1 -0
  62. package/dist/services/analyzer/index.js +7 -0
  63. package/dist/services/analyzer/index.js.map +1 -0
  64. package/dist/services/analyzer/parsers/go-mod.parser.d.ts +11 -0
  65. package/dist/services/analyzer/parsers/go-mod.parser.d.ts.map +1 -0
  66. package/dist/services/analyzer/parsers/go-mod.parser.js +34 -0
  67. package/dist/services/analyzer/parsers/go-mod.parser.js.map +1 -0
  68. package/dist/services/analyzer/parsers/index.d.ts +9 -0
  69. package/dist/services/analyzer/parsers/index.d.ts.map +1 -0
  70. package/dist/services/analyzer/parsers/index.js +9 -0
  71. package/dist/services/analyzer/parsers/index.js.map +1 -0
  72. package/dist/services/analyzer/parsers/package-json.parser.d.ts +11 -0
  73. package/dist/services/analyzer/parsers/package-json.parser.d.ts.map +1 -0
  74. package/dist/services/analyzer/parsers/package-json.parser.js +61 -0
  75. package/dist/services/analyzer/parsers/package-json.parser.js.map +1 -0
  76. package/dist/services/analyzer/parsers/requirements-txt.parser.d.ts +11 -0
  77. package/dist/services/analyzer/parsers/requirements-txt.parser.d.ts.map +1 -0
  78. package/dist/services/analyzer/parsers/requirements-txt.parser.js +49 -0
  79. package/dist/services/analyzer/parsers/requirements-txt.parser.js.map +1 -0
  80. package/dist/services/analyzer/project-analyzer.service.d.ts +11 -0
  81. package/dist/services/analyzer/project-analyzer.service.d.ts.map +1 -0
  82. package/dist/services/analyzer/project-analyzer.service.js +101 -0
  83. package/dist/services/analyzer/project-analyzer.service.js.map +1 -0
  84. package/dist/services/analyzer.d.ts +8 -0
  85. package/dist/services/analyzer.d.ts.map +1 -0
  86. package/dist/services/analyzer.js +8 -0
  87. package/dist/services/analyzer.js.map +1 -0
  88. package/dist/services/mcp-fetcher.d.ts +12 -0
  89. package/dist/services/mcp-fetcher.d.ts.map +1 -0
  90. package/dist/services/mcp-fetcher.js +262 -0
  91. package/dist/services/mcp-fetcher.js.map +1 -0
  92. package/dist/services/plugin-fetcher.d.ts +12 -0
  93. package/dist/services/plugin-fetcher.d.ts.map +1 -0
  94. package/dist/services/plugin-fetcher.js +149 -0
  95. package/dist/services/plugin-fetcher.js.map +1 -0
  96. package/dist/services/recommender/formatters.d.ts +22 -0
  97. package/dist/services/recommender/formatters.d.ts.map +1 -0
  98. package/dist/services/recommender/formatters.js +90 -0
  99. package/dist/services/recommender/formatters.js.map +1 -0
  100. package/dist/services/recommender/index.d.ts +10 -0
  101. package/dist/services/recommender/index.d.ts.map +1 -0
  102. package/dist/services/recommender/index.js +10 -0
  103. package/dist/services/recommender/index.js.map +1 -0
  104. package/dist/services/recommender/recommendation.service.d.ts +27 -0
  105. package/dist/services/recommender/recommendation.service.d.ts.map +1 -0
  106. package/dist/services/recommender/recommendation.service.js +34 -0
  107. package/dist/services/recommender/recommendation.service.js.map +1 -0
  108. package/dist/services/recommender/scoring/index.d.ts +7 -0
  109. package/dist/services/recommender/scoring/index.d.ts.map +1 -0
  110. package/dist/services/recommender/scoring/index.js +7 -0
  111. package/dist/services/recommender/scoring/index.js.map +1 -0
  112. package/dist/services/recommender/scoring/scorer.d.ts +27 -0
  113. package/dist/services/recommender/scoring/scorer.d.ts.map +1 -0
  114. package/dist/services/recommender/scoring/scorer.js +100 -0
  115. package/dist/services/recommender/scoring/scorer.js.map +1 -0
  116. package/dist/services/recommender/search.service.d.ts +24 -0
  117. package/dist/services/recommender/search.service.d.ts.map +1 -0
  118. package/dist/services/recommender/search.service.js +57 -0
  119. package/dist/services/recommender/search.service.js.map +1 -0
  120. package/dist/services/recommender.d.ts +11 -0
  121. package/dist/services/recommender.d.ts.map +1 -0
  122. package/dist/services/recommender.js +11 -0
  123. package/dist/services/recommender.js.map +1 -0
  124. package/dist/services/security-scanner.service.d.ts +48 -0
  125. package/dist/services/security-scanner.service.d.ts.map +1 -0
  126. package/dist/services/security-scanner.service.js +98 -0
  127. package/dist/services/security-scanner.service.js.map +1 -0
  128. package/dist/services/skill-fetcher.d.ts +12 -0
  129. package/dist/services/skill-fetcher.d.ts.map +1 -0
  130. package/dist/services/skill-fetcher.js +307 -0
  131. package/dist/services/skill-fetcher.js.map +1 -0
  132. package/dist/tools/handlers/get-skill-details.tool.d.ts +25 -0
  133. package/dist/tools/handlers/get-skill-details.tool.d.ts.map +1 -0
  134. package/dist/tools/handlers/get-skill-details.tool.js +29 -0
  135. package/dist/tools/handlers/get-skill-details.tool.js.map +1 -0
  136. package/dist/tools/handlers/get-stats.tool.d.ts +19 -0
  137. package/dist/tools/handlers/get-stats.tool.d.ts.map +1 -0
  138. package/dist/tools/handlers/get-stats.tool.js +32 -0
  139. package/dist/tools/handlers/get-stats.tool.js.map +1 -0
  140. package/dist/tools/handlers/index.d.ts +11 -0
  141. package/dist/tools/handlers/index.d.ts.map +1 -0
  142. package/dist/tools/handlers/index.js +11 -0
  143. package/dist/tools/handlers/index.js.map +1 -0
  144. package/dist/tools/handlers/list-categories.tool.d.ts +19 -0
  145. package/dist/tools/handlers/list-categories.tool.d.ts.map +1 -0
  146. package/dist/tools/handlers/list-categories.tool.js +33 -0
  147. package/dist/tools/handlers/list-categories.tool.js.map +1 -0
  148. package/dist/tools/handlers/recommend-skills.tool.d.ts +32 -0
  149. package/dist/tools/handlers/recommend-skills.tool.d.ts.map +1 -0
  150. package/dist/tools/handlers/recommend-skills.tool.js +43 -0
  151. package/dist/tools/handlers/recommend-skills.tool.js.map +1 -0
  152. package/dist/tools/handlers/search-skills.tool.d.ts +27 -0
  153. package/dist/tools/handlers/search-skills.tool.d.ts.map +1 -0
  154. package/dist/tools/handlers/search-skills.tool.js +31 -0
  155. package/dist/tools/handlers/search-skills.tool.js.map +1 -0
  156. package/dist/tools/index.d.ts +9 -0
  157. package/dist/tools/index.d.ts.map +1 -0
  158. package/dist/tools/index.js +11 -0
  159. package/dist/tools/index.js.map +1 -0
  160. package/dist/types/domain-types.d.ts +102 -0
  161. package/dist/types/domain-types.d.ts.map +1 -0
  162. package/dist/types/domain-types.js +7 -0
  163. package/dist/types/domain-types.js.map +1 -0
  164. package/dist/types/index.d.ts +9 -0
  165. package/dist/types/index.d.ts.map +1 -0
  166. package/dist/types/index.js +7 -0
  167. package/dist/types/index.js.map +1 -0
  168. package/dist/types/raw-types.d.ts +46 -0
  169. package/dist/types/raw-types.d.ts.map +1 -0
  170. package/dist/types/raw-types.js +7 -0
  171. package/dist/types/raw-types.js.map +1 -0
  172. package/dist/types/service-types.d.ts +28 -0
  173. package/dist/types/service-types.d.ts.map +1 -0
  174. package/dist/types/service-types.js +7 -0
  175. package/dist/types/service-types.js.map +1 -0
  176. package/dist/utils/glob-matcher.d.ts +24 -0
  177. package/dist/utils/glob-matcher.d.ts.map +1 -0
  178. package/dist/utils/glob-matcher.js +34 -0
  179. package/dist/utils/glob-matcher.js.map +1 -0
  180. package/dist/utils/index.d.ts +7 -0
  181. package/dist/utils/index.d.ts.map +1 -0
  182. package/dist/utils/index.js +7 -0
  183. package/dist/utils/index.js.map +1 -0
  184. package/package.json +82 -0
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Recommendation Service
3
+ *
4
+ * Main service for generating recommendations based on project analysis
5
+ */
6
+ import { calculateScore } from "./scoring/scorer.js";
7
+ /**
8
+ * Generate recommendations based on project analysis
9
+ *
10
+ * @param database - The recommendations database
11
+ * @param project - The project information
12
+ * @param userQuery - Optional user search query
13
+ * @param options - Recommendation options
14
+ * @returns List of scored recommendations
15
+ */
16
+ export function recommend(database, project, userQuery, options = {}) {
17
+ const { maxResults = 20, minScore = 1, types } = options;
18
+ const results = [];
19
+ for (const item of database.items) {
20
+ // Filter by type if specified
21
+ if (types && !types.includes(item.type)) {
22
+ continue;
23
+ }
24
+ const { score, reasons } = calculateScore(item, project, userQuery);
25
+ if (score >= minScore) {
26
+ results.push({ item, score, reasons });
27
+ }
28
+ }
29
+ // Sort by score descending
30
+ results.sort((a, b) => b.score - a.score);
31
+ // Return top results
32
+ return results.slice(0, maxResults);
33
+ }
34
+ //# sourceMappingURL=recommendation.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendation.service.js","sourceRoot":"","sources":["../../../src/services/recommender/recommendation.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAYrD;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CACvB,QAAgC,EAChC,OAAoB,EACpB,SAAkB,EAClB,UAA4B,EAAE;IAE9B,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEzD,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,8BAA8B;QAC9B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,SAAS;QACX,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAEpE,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAE1C,qBAAqB;IACrB,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Scoring Exports
3
+ *
4
+ * Central export point for scoring functionality
5
+ */
6
+ export { calculateScore, getScoreIndicator } from "./scorer.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Scoring Exports
3
+ *
4
+ * Central export point for scoring functionality
5
+ */
6
+ export { calculateScore, getScoreIndicator } from "./scorer.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Scorer
3
+ *
4
+ * Calculates match scores for recommendations based on project information
5
+ */
6
+ import type { Recommendation } from "../../../types/domain-types.js";
7
+ import type { ProjectInfo } from "../../../types/service-types.js";
8
+ /**
9
+ * Calculate match score for a recommendation item
10
+ *
11
+ * @param item - The recommendation item to score
12
+ * @param project - The project information to match against
13
+ * @param userQuery - Optional user search query
14
+ * @returns Score and reasons for the match
15
+ */
16
+ export declare function calculateScore(item: Recommendation, project: ProjectInfo, userQuery?: string): {
17
+ score: number;
18
+ reasons: string[];
19
+ };
20
+ /**
21
+ * Get score indicator emoji and text
22
+ *
23
+ * @param score - The calculated score
24
+ * @returns Indicator string with emoji
25
+ */
26
+ export declare function getScoreIndicator(score: number): string;
27
+ //# sourceMappingURL=scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/scorer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAuFtC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Scorer
3
+ *
4
+ * Calculates match scores for recommendations based on project information
5
+ */
6
+ import { SCORING_MULTIPLIERS, SCORING_THRESHOLDS, SCORING_WEIGHTS, } from "../../../config/scoring-config.js";
7
+ import { matchGlob } from "../../../utils/glob-matcher.js";
8
+ /**
9
+ * Calculate match score for a recommendation item
10
+ *
11
+ * @param item - The recommendation item to score
12
+ * @param project - The project information to match against
13
+ * @param userQuery - Optional user search query
14
+ * @returns Score and reasons for the match
15
+ */
16
+ export function calculateScore(item, project, userQuery) {
17
+ let score = 0;
18
+ const reasons = [];
19
+ const detection = item.detection;
20
+ // 1. Language match
21
+ if (detection.languages && detection.languages.length > 0) {
22
+ const matches = detection.languages.filter((lang) => project.languages.includes(lang.toLowerCase()));
23
+ if (matches.length > 0) {
24
+ score += matches.length * SCORING_WEIGHTS.language;
25
+ reasons.push(`言語: ${matches.join(", ")}`);
26
+ }
27
+ }
28
+ // 2. Framework match
29
+ if (detection.frameworks && detection.frameworks.length > 0) {
30
+ const matches = detection.frameworks.filter((fw) => project.frameworks.includes(fw.toLowerCase()));
31
+ if (matches.length > 0) {
32
+ score += matches.length * SCORING_WEIGHTS.framework;
33
+ reasons.push(`フレームワーク: ${matches.join(", ")}`);
34
+ }
35
+ }
36
+ // 3. Dependency match
37
+ if (detection.dependencies && detection.dependencies.length > 0) {
38
+ const projectDepsLower = project.dependencies.map((d) => d.toLowerCase());
39
+ const matches = detection.dependencies.filter((dep) => projectDepsLower.includes(dep.toLowerCase()));
40
+ if (matches.length > 0) {
41
+ score += matches.length * SCORING_WEIGHTS.dependency;
42
+ reasons.push(`依存関係: ${matches.join(", ")}`);
43
+ }
44
+ }
45
+ // 4. File pattern match
46
+ if (detection.files && detection.files.length > 0) {
47
+ const matches = detection.files.filter((pattern) => project.files.some((file) => matchGlob(file, pattern)));
48
+ if (matches.length > 0) {
49
+ score += matches.length * SCORING_WEIGHTS.file;
50
+ reasons.push(`ファイル: ${matches.join(", ")}`);
51
+ }
52
+ }
53
+ // 5. Keyword match (from user query)
54
+ if (userQuery) {
55
+ const queryLower = userQuery.toLowerCase();
56
+ const keywords = detection.keywords || [];
57
+ const tagMatches = [...keywords, ...item.tags].filter((kw) => queryLower.includes(kw.toLowerCase()));
58
+ if (tagMatches.length > 0) {
59
+ score += tagMatches.length * SCORING_WEIGHTS.keyword;
60
+ reasons.push(`キーワード: ${[...new Set(tagMatches)].join(", ")}`);
61
+ }
62
+ // Also check name and description
63
+ if (queryLower.includes(item.name.toLowerCase())) {
64
+ score += SCORING_WEIGHTS.keyword * 2;
65
+ reasons.push(`名前一致: ${item.name}`);
66
+ }
67
+ }
68
+ // 6. Apply multipliers
69
+ if (item.metrics.isOfficial) {
70
+ score *= SCORING_MULTIPLIERS.official;
71
+ if (reasons.length > 0) {
72
+ reasons.push("公式");
73
+ }
74
+ }
75
+ if (item.metrics.securityScore !== undefined) {
76
+ if (item.metrics.securityScore >= SCORING_THRESHOLDS.highSecurityThreshold) {
77
+ score *= SCORING_MULTIPLIERS.highSecurity;
78
+ }
79
+ else if (item.metrics.securityScore < SCORING_THRESHOLDS.lowSecurityThreshold) {
80
+ score *= SCORING_MULTIPLIERS.lowSecurity;
81
+ }
82
+ }
83
+ return { score: Math.round(score * 100) / 100, reasons };
84
+ }
85
+ /**
86
+ * Get score indicator emoji and text
87
+ *
88
+ * @param score - The calculated score
89
+ * @returns Indicator string with emoji
90
+ */
91
+ export function getScoreIndicator(score) {
92
+ if (score >= 10)
93
+ return " ✅ 高適合";
94
+ if (score >= 5)
95
+ return " 👍 適合";
96
+ if (score >= 2)
97
+ return " 📝 参考";
98
+ return "";
99
+ }
100
+ //# sourceMappingURL=scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../../../src/services/recommender/scoring/scorer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,GAChB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAoB,EACpB,OAAoB,EACpB,SAAkB;IAElB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAEjC,oBAAoB;IACpB,IAAI,SAAS,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAClD,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAC/C,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,qBAAqB;IACrB,IAAI,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CACjD,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAC9C,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC;YACpD,OAAO,CAAC,IAAI,CAAC,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,IAAI,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChE,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CACpD,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAC7C,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CACjD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CACvD,CAAC;QACF,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,IAAI,OAAO,CAAC,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAC3D,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CACtC,CAAC;QACF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,IAAI,UAAU,CAAC,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,kCAAkC;QAClC,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACjD,KAAK,IAAI,eAAe,CAAC,OAAO,GAAG,CAAC,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAC5B,KAAK,IAAI,mBAAmB,CAAC,QAAQ,CAAC;QACtC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,kBAAkB,CAAC,qBAAqB,EAAE,CAAC;YAC3E,KAAK,IAAI,mBAAmB,CAAC,YAAY,CAAC;QAC5C,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,GAAG,kBAAkB,CAAC,oBAAoB,EAAE,CAAC;YAChF,KAAK,IAAI,mBAAmB,CAAC,WAAW,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,QAAQ,CAAC;IACjC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChC,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Search Service
3
+ *
4
+ * Searches for recommendations based on user query
5
+ */
6
+ import type { Recommendation, RecommendationDatabase } from "../../types/domain-types.js";
7
+ import type { ScoredRecommendation } from "../../types/service-types.js";
8
+ /** Options for search function */
9
+ export type SearchOptions = {
10
+ /** Maximum number of results */
11
+ maxResults?: number;
12
+ /** Filter by types */
13
+ types?: Recommendation["type"][];
14
+ };
15
+ /**
16
+ * Search for recommendations by query
17
+ *
18
+ * @param database - The recommendations database
19
+ * @param query - The search query
20
+ * @param options - Search options
21
+ * @returns List of scored recommendations
22
+ */
23
+ export declare function search(database: RecommendationDatabase, query: string, options?: SearchOptions): ScoredRecommendation[];
24
+ //# sourceMappingURL=search.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.service.d.ts","sourceRoot":"","sources":["../../../src/services/recommender/search.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEzE,kCAAkC;AAClC,MAAM,MAAM,aAAa,GAAG;IAC1B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sBAAsB;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;CAClC,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,oBAAoB,EAAE,CAoDxB"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Search Service
3
+ *
4
+ * Searches for recommendations based on user query
5
+ */
6
+ /**
7
+ * Search for recommendations by query
8
+ *
9
+ * @param database - The recommendations database
10
+ * @param query - The search query
11
+ * @param options - Search options
12
+ * @returns List of scored recommendations
13
+ */
14
+ export function search(database, query, options = {}) {
15
+ const { maxResults = 20, types } = options;
16
+ const queryLower = query.toLowerCase();
17
+ const results = [];
18
+ for (const item of database.items) {
19
+ // Filter by type if specified
20
+ if (types && !types.includes(item.type)) {
21
+ continue;
22
+ }
23
+ let score = 0;
24
+ const reasons = [];
25
+ // Name match
26
+ if (item.name.toLowerCase().includes(queryLower)) {
27
+ score += 10;
28
+ reasons.push("名前一致");
29
+ }
30
+ // Description match
31
+ if (item.description.toLowerCase().includes(queryLower)) {
32
+ score += 5;
33
+ reasons.push("説明一致");
34
+ }
35
+ // Category match
36
+ if (item.category.toLowerCase().includes(queryLower)) {
37
+ score += 3;
38
+ reasons.push("カテゴリ一致");
39
+ }
40
+ // Tag match
41
+ const tagMatch = item.tags.find((t) => t.toLowerCase().includes(queryLower));
42
+ if (tagMatch) {
43
+ score += 2;
44
+ reasons.push(`タグ: ${tagMatch}`);
45
+ }
46
+ // Official boost
47
+ if (item.metrics.isOfficial) {
48
+ score *= 1.2;
49
+ }
50
+ if (score > 0) {
51
+ results.push({ item, score, reasons });
52
+ }
53
+ }
54
+ results.sort((a, b) => b.score - a.score);
55
+ return results.slice(0, maxResults);
56
+ }
57
+ //# sourceMappingURL=search.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.service.js","sourceRoot":"","sources":["../../../src/services/recommender/search.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAaH;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CACpB,QAAgC,EAChC,KAAa,EACb,UAAyB,EAAE;IAE3B,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAE3C,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QAClC,8BAA8B;QAC9B,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACxC,SAAS;QACX,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,aAAa;QACb,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACjD,KAAK,IAAI,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAED,oBAAoB;QACpB,IAAI,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACxD,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAED,iBAAiB;QACjB,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACrD,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QAED,YAAY;QACZ,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAC7E,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,IAAI,CAAC,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,iBAAiB;QACjB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC5B,KAAK,IAAI,GAAG,CAAC;QACf,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Recommender Service (Legacy Export)
3
+ *
4
+ * Re-exports from the new recommender directory structure
5
+ * This file maintains backwards compatibility
6
+ */
7
+ export { formatRecommendations, groupByType } from "./recommender/formatters.js";
8
+ export { type RecommendOptions, recommend } from "./recommender/recommendation.service.js";
9
+ export { calculateScore, getScoreIndicator } from "./recommender/scoring/scorer.js";
10
+ export { type SearchOptions, search } from "./recommender/search.service.js";
11
+ //# sourceMappingURL=recommender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommender.d.ts","sourceRoot":"","sources":["../../src/services/recommender.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Recommender Service (Legacy Export)
3
+ *
4
+ * Re-exports from the new recommender directory structure
5
+ * This file maintains backwards compatibility
6
+ */
7
+ export { formatRecommendations, groupByType } from "./recommender/formatters.js";
8
+ export { recommend } from "./recommender/recommendation.service.js";
9
+ export { calculateScore, getScoreIndicator } from "./recommender/scoring/scorer.js";
10
+ export { search } from "./recommender/search.service.js";
11
+ //# sourceMappingURL=recommender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommender.js","sourceRoot":"","sources":["../../src/services/recommender.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AACjF,OAAO,EAAyB,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,EAAsB,MAAM,EAAE,MAAM,iCAAiC,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Security Scanner Service
3
+ *
4
+ * Scans GitHub repositories using cc-audit for security vulnerabilities
5
+ */
6
+ /** cc-audit スキャン結果 */
7
+ export type SecurityScanResult = {
8
+ /** セキュリティスコア (0-100, 100が最も安全) */
9
+ score: number;
10
+ /** 検出された脆弱性の数 */
11
+ findings: {
12
+ critical: number;
13
+ high: number;
14
+ medium: number;
15
+ low: number;
16
+ };
17
+ /** スキャン成功フラグ */
18
+ success: boolean;
19
+ /** エラーメッセージ(スキャン失敗時) */
20
+ error?: string;
21
+ };
22
+ /**
23
+ * GitHubリポジトリをcc-auditでスキャン
24
+ *
25
+ * @param repoUrl - GitHubリポジトリURL
26
+ * @param scanType - スキャンタイプ (mcp, skill, plugin)
27
+ * @returns スキャン結果
28
+ */
29
+ export declare function scanRepository(repoUrl: string, scanType?: "mcp" | "skill" | "plugin"): Promise<SecurityScanResult>;
30
+ /**
31
+ * 複数のリポジトリを並列スキャン
32
+ *
33
+ * @param repos - スキャン対象のリポジトリ情報
34
+ * @param concurrency - 並列実行数(デフォルト: 10)
35
+ * @returns スキャン結果のマップ
36
+ */
37
+ export declare function scanRepositories(repos: Array<{
38
+ url: string;
39
+ type: "mcp" | "skill" | "plugin";
40
+ }>, concurrency?: number): Promise<Map<string, SecurityScanResult>>;
41
+ /**
42
+ * セキュリティスコアのバッジテキストを生成
43
+ *
44
+ * @param score - セキュリティスコア (0-100)
45
+ * @returns バッジテキスト
46
+ */
47
+ export declare function getSecurityBadge(score: number): string;
48
+ //# sourceMappingURL=security-scanner.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-scanner.service.d.ts","sourceRoot":"","sources":["../../src/services/security-scanner.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,sBAAsB;AACtB,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB;IACjB,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,gBAAgB;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,KAAK,GAAG,OAAO,GAAG,QAAgB,GAC3C,OAAO,CAAC,kBAAkB,CAAC,CAiD7B;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAA;CAAE,CAAC,EAC/D,WAAW,SAAK,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAyB1C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKtD"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Security Scanner Service
3
+ *
4
+ * Scans GitHub repositories using cc-audit for security vulnerabilities
5
+ */
6
+ import { exec } from "node:child_process";
7
+ import { promisify } from "node:util";
8
+ const execAsync = promisify(exec);
9
+ /**
10
+ * GitHubリポジトリをcc-auditでスキャン
11
+ *
12
+ * @param repoUrl - GitHubリポジトリURL
13
+ * @param scanType - スキャンタイプ (mcp, skill, plugin)
14
+ * @returns スキャン結果
15
+ */
16
+ export async function scanRepository(repoUrl, scanType = "mcp") {
17
+ try {
18
+ // cc-audit を --remote モードで実行
19
+ // --config で現在のプロジェクトの設定ファイルを使用
20
+ const configPath = `${process.cwd()}/.cc-audit.yaml`;
21
+ const command = `npx -y @cc-audit/cc-audit check --remote ${repoUrl} --type ${scanType} --config ${configPath} --format json --ci`;
22
+ const { stdout } = await execAsync(command, {
23
+ timeout: 30000, // 30秒タイムアウト
24
+ });
25
+ // JSON出力をパース
26
+ const result = JSON.parse(stdout);
27
+ // スコア計算: 100点満点から減点方式
28
+ // critical: -25点, high: -10点, medium: -5点, low: -2点
29
+ const findings = {
30
+ critical: result.summary?.critical || 0,
31
+ high: result.summary?.high || 0,
32
+ medium: result.summary?.medium || 0,
33
+ low: result.summary?.low || 0,
34
+ };
35
+ const deduction = findings.critical * 25 + findings.high * 10 + findings.medium * 5 + findings.low * 2;
36
+ const score = Math.max(0, 100 - deduction);
37
+ return {
38
+ score,
39
+ findings,
40
+ success: true,
41
+ };
42
+ }
43
+ catch (error) {
44
+ console.error(`Security scan failed for ${repoUrl}:`, error);
45
+ // スキャン失敗時は最低スコア
46
+ return {
47
+ score: 0,
48
+ findings: {
49
+ critical: 0,
50
+ high: 0,
51
+ medium: 0,
52
+ low: 0,
53
+ },
54
+ success: false,
55
+ error: error instanceof Error ? error.message : "Unknown error",
56
+ };
57
+ }
58
+ }
59
+ /**
60
+ * 複数のリポジトリを並列スキャン
61
+ *
62
+ * @param repos - スキャン対象のリポジトリ情報
63
+ * @param concurrency - 並列実行数(デフォルト: 10)
64
+ * @returns スキャン結果のマップ
65
+ */
66
+ export async function scanRepositories(repos, concurrency = 10) {
67
+ const results = new Map();
68
+ // 並列実行数を制限しながらスキャン
69
+ for (let i = 0; i < repos.length; i += concurrency) {
70
+ const batch = repos.slice(i, i + concurrency);
71
+ const batchResults = await Promise.all(batch.map(async (repo) => ({
72
+ url: repo.url,
73
+ result: await scanRepository(repo.url, repo.type),
74
+ })));
75
+ for (const { url, result } of batchResults) {
76
+ results.set(url, result);
77
+ }
78
+ // 進捗表示
79
+ console.error(`Scanned ${Math.min(i + concurrency, repos.length)}/${repos.length} repositories`);
80
+ }
81
+ return results;
82
+ }
83
+ /**
84
+ * セキュリティスコアのバッジテキストを生成
85
+ *
86
+ * @param score - セキュリティスコア (0-100)
87
+ * @returns バッジテキスト
88
+ */
89
+ export function getSecurityBadge(score) {
90
+ if (score >= 90)
91
+ return "🟢 Excellent";
92
+ if (score >= 70)
93
+ return "🟡 Good";
94
+ if (score >= 50)
95
+ return "🟠 Fair";
96
+ return "🔴 Poor";
97
+ }
98
+ //# sourceMappingURL=security-scanner.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-scanner.service.js","sourceRoot":"","sources":["../../src/services/security-scanner.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Skill Fetcher
3
+ *
4
+ * Fetches skills, workflows, hooks, commands from awesome-claude-code
5
+ * Source: https://github.com/hesreallyhim/awesome-claude-code
6
+ */
7
+ import type { Recommendation } from "../types/domain-types.js";
8
+ /**
9
+ * Fetch skills from awesome-claude-code CSV
10
+ */
11
+ export declare function fetchSkills(): Promise<Recommendation[]>;
12
+ //# sourceMappingURL=skill-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-fetcher.d.ts","sourceRoot":"","sources":["../../src/services/skill-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AA0B/D;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAqB7D"}