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,262 @@
1
+ /**
2
+ * MCP Server Fetcher
3
+ *
4
+ * Fetches MCP servers from awesome-mcp-servers repository
5
+ * Source: https://github.com/punkpeye/awesome-mcp-servers
6
+ */
7
+ const README_URL = "https://raw.githubusercontent.com/punkpeye/awesome-mcp-servers/main/README.md";
8
+ /** Emoji to metadata mappings */
9
+ const EMOJI_MAPPINGS = {
10
+ // Languages
11
+ "🐍": { language: "python" },
12
+ "📇": { language: "typescript" },
13
+ "🏎️": { language: "go" },
14
+ "🦀": { language: "rust" },
15
+ "#️⃣": { language: "csharp" },
16
+ "☕": { language: "java" },
17
+ "🌊": { language: "cpp" },
18
+ "💎": { language: "ruby" },
19
+ // Scope
20
+ "☁️": { scope: "cloud" },
21
+ "🏠": { scope: "local" },
22
+ // Platform
23
+ "🍎": { platform: "macos" },
24
+ "🪟": { platform: "windows" },
25
+ "🐧": { platform: "linux" },
26
+ "📟": { platform: "embedded" },
27
+ // Official
28
+ "🎖️": { isOfficial: true },
29
+ };
30
+ /** Category section headers */
31
+ const CATEGORY_HEADERS = [
32
+ "Aggregators",
33
+ "Art & Culture",
34
+ "Architecture & Design",
35
+ "Browser Automation",
36
+ "Biology Medicine and Bioinformatics",
37
+ "Cloud Platforms",
38
+ "Code Execution",
39
+ "Coding Agents",
40
+ "Command Line",
41
+ "Communication",
42
+ "Customer Data Platforms",
43
+ "Databases",
44
+ "Data Platforms",
45
+ "Developer Tools",
46
+ "Data Science Tools",
47
+ "File Systems",
48
+ "Finance & Fintech",
49
+ "Gaming",
50
+ "Knowledge & Memory",
51
+ "Location Services",
52
+ "Marketing",
53
+ "Monitoring",
54
+ "Search",
55
+ "Security",
56
+ "Social Media",
57
+ "Sports",
58
+ "Text-to-Speech",
59
+ "Travel & Transportation",
60
+ "Version Control",
61
+ "Workplace & Productivity",
62
+ "Other Tools and Integrations",
63
+ ];
64
+ /**
65
+ * Fetch MCP servers from awesome-mcp-servers
66
+ */
67
+ export async function fetchMCPServers() {
68
+ console.log("🔌 Fetching MCP servers from awesome-mcp-servers...");
69
+ try {
70
+ const response = await fetch(README_URL);
71
+ if (!response.ok) {
72
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
73
+ }
74
+ const markdown = await response.text();
75
+ const entries = parseMarkdown(markdown);
76
+ const recommendations = entries
77
+ .map(transformMCPEntry)
78
+ .filter((r) => r !== null);
79
+ console.log(` ✓ Fetched ${recommendations.length} MCP servers`);
80
+ return recommendations;
81
+ }
82
+ catch (error) {
83
+ console.error(" ✗ Failed to fetch MCP servers:", error);
84
+ return [];
85
+ }
86
+ }
87
+ /**
88
+ * Parse markdown to extract MCP server entries
89
+ */
90
+ function parseMarkdown(markdown) {
91
+ const entries = [];
92
+ let currentCategory = "Uncategorized";
93
+ const lines = markdown.split("\n");
94
+ for (const line of lines) {
95
+ // Check for category headers: ### 🔗 <a name="aggregators"></a>Aggregators
96
+ const headerMatch = line.match(/^###?\s+(?:🔗|🎨|📐|📂|🧬|☁️|👨‍💻|🤖|🖥️|💬|👤|🗄️|📊|🚚|🛠️|🧮|📟|💰|🎮|🧠|🗺️|🎯|🔎|🔒|🌐|🏃|🎧|🌎|🚆|🔄|🏢|🚀)?\s*(?:<a[^>]*>)?(.+?)(?:<\/a>)?$/i);
97
+ if (headerMatch) {
98
+ const potentialCategory = headerMatch[1].trim();
99
+ if (CATEGORY_HEADERS.some((c) => potentialCategory.toLowerCase().includes(c.toLowerCase()))) {
100
+ currentCategory = potentialCategory;
101
+ }
102
+ continue;
103
+ }
104
+ // Parse entry lines: - [owner/repo](url) emojis - description
105
+ const entryMatch = line.match(/^[-*]\s+\[([^\]]+)\]\(([^)]+)\)\s*(.+)?$/);
106
+ if (entryMatch) {
107
+ const [, _nameOrPath, url, rest] = entryMatch;
108
+ // Skip if not a GitHub URL
109
+ if (!url.includes("github.com"))
110
+ continue;
111
+ // Parse owner/repo from URL or name
112
+ const repoMatch = url.match(/github\.com\/([^/]+)\/([^/\s#]+)/);
113
+ if (!repoMatch)
114
+ continue;
115
+ const [, owner, repo] = repoMatch;
116
+ // Parse emojis and description
117
+ const { metadata, description } = parseEmojisAndDescription(rest || "");
118
+ entries.push({
119
+ owner,
120
+ repo: repo.replace(/\.git$/, ""),
121
+ url,
122
+ description,
123
+ category: currentCategory,
124
+ ...metadata,
125
+ });
126
+ }
127
+ }
128
+ return entries;
129
+ }
130
+ /**
131
+ * Parse emojis and description from the rest of the line
132
+ */
133
+ function parseEmojisAndDescription(text) {
134
+ const metadata = {
135
+ platforms: [],
136
+ };
137
+ let remaining = text.trim();
138
+ // Extract emojis from the beginning
139
+ for (const [emoji, props] of Object.entries(EMOJI_MAPPINGS)) {
140
+ if (remaining.includes(emoji)) {
141
+ if ("language" in props) {
142
+ metadata.language = props.language;
143
+ }
144
+ if ("scope" in props) {
145
+ metadata.scope = props.scope;
146
+ }
147
+ if ("platform" in props) {
148
+ metadata.platforms?.push(props.platform);
149
+ }
150
+ if ("isOfficial" in props) {
151
+ metadata.isOfficial = props.isOfficial;
152
+ }
153
+ remaining = remaining.replace(emoji, "").trim();
154
+ }
155
+ }
156
+ // Clean up platforms
157
+ if (metadata.platforms?.length === 0) {
158
+ delete metadata.platforms;
159
+ }
160
+ // Extract description (after " - ")
161
+ const descMatch = remaining.match(/^-\s*(.+)$/);
162
+ const description = descMatch ? descMatch[1].trim() : remaining;
163
+ return { metadata, description };
164
+ }
165
+ /**
166
+ * Transform raw MCP entry to unified Recommendation
167
+ */
168
+ function transformMCPEntry(raw) {
169
+ try {
170
+ // Build detection rules
171
+ const detection = {
172
+ keywords: [raw.category.toLowerCase()],
173
+ };
174
+ // Add language-specific detection
175
+ if (raw.language) {
176
+ detection.languages = [raw.language];
177
+ }
178
+ // Category-based detection enhancement
179
+ const categoryKeywords = getCategoryKeywords(raw.category);
180
+ if (categoryKeywords.length > 0) {
181
+ detection.keywords = [...(detection.keywords ?? []), ...categoryKeywords];
182
+ }
183
+ const categoryDeps = getCategoryDependencies(raw.category);
184
+ if (categoryDeps.length > 0) {
185
+ detection.dependencies = categoryDeps;
186
+ }
187
+ // Build tags
188
+ const tags = [raw.category.toLowerCase()];
189
+ if (raw.language)
190
+ tags.push(raw.language);
191
+ if (raw.scope)
192
+ tags.push(raw.scope);
193
+ if (raw.platforms)
194
+ tags.push(...raw.platforms);
195
+ if (raw.isOfficial)
196
+ tags.push("official");
197
+ return {
198
+ id: `mcp-${raw.owner}-${raw.repo}`,
199
+ name: raw.repo,
200
+ type: "mcp",
201
+ url: raw.url,
202
+ description: raw.description,
203
+ author: {
204
+ name: raw.owner,
205
+ url: `https://github.com/${raw.owner}`,
206
+ },
207
+ category: raw.category,
208
+ tags,
209
+ detection,
210
+ metrics: {
211
+ source: raw.isOfficial ? "official" : "awesome-list",
212
+ isOfficial: raw.isOfficial || false,
213
+ },
214
+ install: {
215
+ method: "mcp-add",
216
+ command: `claude mcp add ${raw.repo}`,
217
+ },
218
+ };
219
+ }
220
+ catch {
221
+ console.warn(` ⚠ Failed to transform MCP: ${raw.owner}/${raw.repo}`);
222
+ return null;
223
+ }
224
+ }
225
+ /**
226
+ * Get keywords based on category
227
+ */
228
+ function getCategoryKeywords(category) {
229
+ const mappings = {
230
+ Databases: ["database", "sql", "nosql", "db", "query"],
231
+ "Browser Automation": ["browser", "selenium", "playwright", "puppeteer", "scraping"],
232
+ "Cloud Platforms": ["aws", "gcp", "azure", "cloud", "kubernetes", "docker"],
233
+ Communication: ["slack", "discord", "email", "chat", "messaging"],
234
+ "Developer Tools": ["git", "github", "ci", "cd", "devops"],
235
+ "File Systems": ["file", "storage", "filesystem", "s3"],
236
+ Security: ["security", "auth", "encryption", "vulnerability"],
237
+ "Version Control": ["git", "github", "gitlab", "bitbucket"],
238
+ };
239
+ for (const [cat, keywords] of Object.entries(mappings)) {
240
+ if (category.toLowerCase().includes(cat.toLowerCase())) {
241
+ return keywords;
242
+ }
243
+ }
244
+ return [];
245
+ }
246
+ /**
247
+ * Get dependency hints based on category
248
+ */
249
+ function getCategoryDependencies(category) {
250
+ const mappings = {
251
+ Databases: ["prisma", "@prisma/client", "mongoose", "typeorm", "pg", "mysql2", "sqlite3"],
252
+ "Browser Automation": ["playwright", "puppeteer", "selenium-webdriver"],
253
+ Communication: ["@slack/web-api", "discord.js", "nodemailer"],
254
+ };
255
+ for (const [cat, deps] of Object.entries(mappings)) {
256
+ if (category.toLowerCase().includes(cat.toLowerCase())) {
257
+ return deps;
258
+ }
259
+ }
260
+ return [];
261
+ }
262
+ //# sourceMappingURL=mcp-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-fetcher.js","sourceRoot":"","sources":["../../src/services/mcp-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Plugin Fetcher
3
+ *
4
+ * Fetches plugins from official Claude Code marketplace
5
+ * Source: https://github.com/anthropics/claude-plugins-official
6
+ */
7
+ import type { Recommendation } from "../types/domain-types.js";
8
+ /**
9
+ * Fetch plugins from the official Anthropic marketplace
10
+ */
11
+ export declare function fetchPlugins(): Promise<Recommendation[]>;
12
+ //# sourceMappingURL=plugin-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-fetcher.d.ts","sourceRoot":"","sources":["../../src/services/plugin-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAa/D;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAyB9D"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Plugin Fetcher
3
+ *
4
+ * Fetches plugins from official Claude Code marketplace
5
+ * Source: https://github.com/anthropics/claude-plugins-official
6
+ */
7
+ const MARKETPLACE_URL = "https://raw.githubusercontent.com/anthropics/claude-plugins-official/main/.claude-plugin/marketplace.json";
8
+ /**
9
+ * Fetch plugins from the official Anthropic marketplace
10
+ */
11
+ export async function fetchPlugins() {
12
+ console.log("📦 Fetching plugins from official marketplace...");
13
+ try {
14
+ const response = await fetch(MARKETPLACE_URL);
15
+ if (!response.ok) {
16
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
17
+ }
18
+ const data = (await response.json());
19
+ const recommendations = [];
20
+ for (const plugin of data.plugins) {
21
+ const rec = transformPlugin(plugin, data.owner);
22
+ if (rec) {
23
+ recommendations.push(rec);
24
+ }
25
+ }
26
+ console.log(` ✓ Fetched ${recommendations.length} plugins`);
27
+ return recommendations;
28
+ }
29
+ catch (error) {
30
+ console.error(" ✗ Failed to fetch plugins:", error);
31
+ return [];
32
+ }
33
+ }
34
+ /**
35
+ * Transform raw plugin entry to unified Recommendation
36
+ */
37
+ function transformPlugin(raw, fallbackAuthor) {
38
+ try {
39
+ // Validate required fields
40
+ if (!raw.name || !raw.description) {
41
+ console.warn(` ⚠ Failed to transform plugin: ${raw.name || "unknown"} - missing required fields`);
42
+ return null;
43
+ }
44
+ // Use plugin author or fallback to marketplace owner
45
+ const author = raw.author || fallbackAuthor;
46
+ // Determine source URL
47
+ const sourceUrl = typeof raw.source === "string"
48
+ ? `https://github.com/anthropics/claude-plugins-official/tree/main/${raw.source}`
49
+ : raw.source?.url || `https://github.com/anthropics/claude-plugins-official`;
50
+ // Determine type based on category and features
51
+ let type = "plugin";
52
+ if (raw.lspServers) {
53
+ type = "plugin"; // LSP plugins
54
+ }
55
+ // Extract detection rules
56
+ const detection = extractDetectionRules(raw);
57
+ // Determine if official
58
+ const isOfficial = author.name.toLowerCase().includes("anthropic");
59
+ return {
60
+ id: `plugin-${raw.name}`,
61
+ name: raw.name,
62
+ type,
63
+ url: raw.homepage || sourceUrl,
64
+ description: raw.description,
65
+ author: {
66
+ name: author.name,
67
+ email: author.email,
68
+ },
69
+ category: raw.category || "other",
70
+ tags: raw.tags || [raw.category || "plugin"],
71
+ detection,
72
+ metrics: {
73
+ source: isOfficial ? "official" : "community",
74
+ isOfficial,
75
+ },
76
+ install: {
77
+ method: "plugin",
78
+ command: `/plugin install ${raw.name}`,
79
+ marketplace: "claude-plugins-official",
80
+ },
81
+ };
82
+ }
83
+ catch (error) {
84
+ console.warn(` ⚠ Failed to transform plugin: ${raw.name || "unknown"} -`, error instanceof Error ? error.message : String(error));
85
+ return null;
86
+ }
87
+ }
88
+ /**
89
+ * Extract detection rules from plugin entry
90
+ */
91
+ function extractDetectionRules(raw) {
92
+ const rules = {
93
+ keywords: [raw.category, ...(raw.tags || [])],
94
+ };
95
+ // LSP plugins - extract language info
96
+ if (raw.lspServers) {
97
+ const languages = [];
98
+ const files = [];
99
+ for (const [_serverName, config] of Object.entries(raw.lspServers)) {
100
+ const serverConfig = config;
101
+ if (serverConfig.extensionToLanguage) {
102
+ for (const [ext, lang] of Object.entries(serverConfig.extensionToLanguage)) {
103
+ languages.push(lang);
104
+ files.push(`*.${ext}`);
105
+ }
106
+ }
107
+ }
108
+ if (languages.length > 0) {
109
+ rules.languages = [...new Set(languages)];
110
+ }
111
+ if (files.length > 0) {
112
+ rules.files = [...new Set(files)];
113
+ }
114
+ }
115
+ // Category-based detection
116
+ const categoryMappings = {
117
+ development: {
118
+ keywords: ["development", "coding", "ide"],
119
+ },
120
+ productivity: {
121
+ keywords: ["productivity", "workflow", "automation"],
122
+ },
123
+ database: {
124
+ keywords: ["database", "sql", "nosql"],
125
+ dependencies: ["prisma", "@prisma/client", "mongoose", "typeorm"],
126
+ },
127
+ security: {
128
+ keywords: ["security", "audit", "vulnerability"],
129
+ },
130
+ testing: {
131
+ keywords: ["testing", "test", "e2e"],
132
+ dependencies: ["jest", "vitest", "playwright", "cypress"],
133
+ },
134
+ deployment: {
135
+ keywords: ["deploy", "ci", "cd"],
136
+ },
137
+ };
138
+ const mapping = categoryMappings[raw.category];
139
+ if (mapping) {
140
+ if (mapping.keywords) {
141
+ rules.keywords = [...(rules.keywords || []), ...mapping.keywords];
142
+ }
143
+ if (mapping.dependencies) {
144
+ rules.dependencies = mapping.dependencies;
145
+ }
146
+ }
147
+ return rules;
148
+ }
149
+ //# sourceMappingURL=plugin-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-fetcher.js","sourceRoot":"","sources":["../../src/services/plugin-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Recommendation Formatters
3
+ *
4
+ * Formats recommendation results for display
5
+ */
6
+ import type { Recommendation } from "../../types/domain-types.js";
7
+ import type { ScoredRecommendation } from "../../types/service-types.js";
8
+ /**
9
+ * Group recommendations by type
10
+ *
11
+ * @param recommendations - List of scored recommendations
12
+ * @returns Map of type to recommendations
13
+ */
14
+ export declare function groupByType(recommendations: ScoredRecommendation[]): Map<Recommendation["type"], ScoredRecommendation[]>;
15
+ /**
16
+ * Format recommendations for display
17
+ *
18
+ * @param recommendations - List of scored recommendations
19
+ * @returns Formatted string for display
20
+ */
21
+ export declare function formatRecommendations(recommendations: ScoredRecommendation[]): string;
22
+ //# sourceMappingURL=formatters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../../src/services/recommender/formatters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAIzE;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,eAAe,EAAE,oBAAoB,EAAE,GACtC,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,oBAAoB,EAAE,CAAC,CAYrD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAuErF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Recommendation Formatters
3
+ *
4
+ * Formats recommendation results for display
5
+ */
6
+ import { getSecurityBadge } from "../security-scanner.service.js";
7
+ import { getScoreIndicator } from "./scoring/scorer.js";
8
+ /**
9
+ * Group recommendations by type
10
+ *
11
+ * @param recommendations - List of scored recommendations
12
+ * @returns Map of type to recommendations
13
+ */
14
+ export function groupByType(recommendations) {
15
+ const groups = new Map();
16
+ for (const rec of recommendations) {
17
+ const type = rec.item.type;
18
+ if (!groups.has(type)) {
19
+ groups.set(type, []);
20
+ }
21
+ groups.get(type)?.push(rec);
22
+ }
23
+ return groups;
24
+ }
25
+ /**
26
+ * Format recommendations for display
27
+ *
28
+ * @param recommendations - List of scored recommendations
29
+ * @returns Formatted string for display
30
+ */
31
+ export function formatRecommendations(recommendations) {
32
+ if (recommendations.length === 0) {
33
+ return "プロジェクトに適した推薦が見つかりませんでした。";
34
+ }
35
+ const grouped = groupByType(recommendations);
36
+ const lines = [];
37
+ // Type labels
38
+ const typeLabels = {
39
+ plugin: "📦 プラグイン",
40
+ mcp: "🔌 MCPサーバー",
41
+ skill: "🎯 スキル",
42
+ workflow: "🔄 ワークフロー",
43
+ hook: "🪝 フック",
44
+ command: "⚡ コマンド",
45
+ agent: "🤖 エージェント",
46
+ };
47
+ // Order of types to display
48
+ const typeOrder = [
49
+ "plugin",
50
+ "mcp",
51
+ "skill",
52
+ "workflow",
53
+ "hook",
54
+ "command",
55
+ "agent",
56
+ ];
57
+ for (const type of typeOrder) {
58
+ const items = grouped.get(type);
59
+ if (!items || items.length === 0)
60
+ continue;
61
+ lines.push(`\n${typeLabels[type]}`);
62
+ lines.push("━".repeat(40));
63
+ for (let i = 0; i < Math.min(items.length, 5); i++) {
64
+ const { item, score, reasons } = items[i];
65
+ lines.push(`${i + 1}. ${item.name}${item.metrics.isOfficial ? " (公式)" : ""}`);
66
+ lines.push(` ├─ 用途: ${item.description.slice(0, 60)}${item.description.length > 60 ? "..." : ""}`);
67
+ lines.push(` ├─ スコア: ${score}${getScoreIndicator(score)}`);
68
+ // セキュリティスコア表示
69
+ if (item.metrics.securityScore !== undefined) {
70
+ const securityBadge = getSecurityBadge(item.metrics.securityScore);
71
+ lines.push(` ├─ セキュリティ: ${securityBadge} (${item.metrics.securityScore}/100)`);
72
+ }
73
+ if (reasons.length > 0) {
74
+ lines.push(` ├─ 推薦理由: ${reasons.join(", ")}`);
75
+ }
76
+ if (item.install.command) {
77
+ lines.push(` └─ インストール: ${item.install.command}`);
78
+ }
79
+ else {
80
+ lines.push(` └─ URL: ${item.url}`);
81
+ }
82
+ lines.push("");
83
+ }
84
+ if (items.length > 5) {
85
+ lines.push(` ... 他 ${items.length - 5} 件`);
86
+ }
87
+ }
88
+ return lines.join("\n");
89
+ }
90
+ //# sourceMappingURL=formatters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../../src/services/recommender/formatters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Recommender Service Exports
3
+ *
4
+ * Central export point for recommendation functionality
5
+ */
6
+ export { formatRecommendations, groupByType } from "./formatters.js";
7
+ export { type RecommendOptions, recommend } from "./recommendation.service.js";
8
+ export { calculateScore, getScoreIndicator } from "./scoring/index.js";
9
+ export { type SearchOptions, search } from "./search.service.js";
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/recommender/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Recommender Service Exports
3
+ *
4
+ * Central export point for recommendation functionality
5
+ */
6
+ export { formatRecommendations, groupByType } from "./formatters.js";
7
+ export { recommend } from "./recommendation.service.js";
8
+ export { calculateScore, getScoreIndicator } from "./scoring/index.js";
9
+ export { search } from "./search.service.js";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/recommender/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAyB,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAsB,MAAM,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Recommendation Service
3
+ *
4
+ * Main service for generating recommendations based on project analysis
5
+ */
6
+ import type { Recommendation, RecommendationDatabase } from "../../types/domain-types.js";
7
+ import type { ProjectInfo, ScoredRecommendation } from "../../types/service-types.js";
8
+ /** Options for recommend function */
9
+ export type RecommendOptions = {
10
+ /** Maximum number of results */
11
+ maxResults?: number;
12
+ /** Minimum score threshold */
13
+ minScore?: number;
14
+ /** Filter by types */
15
+ types?: Recommendation["type"][];
16
+ };
17
+ /**
18
+ * Generate recommendations based on project analysis
19
+ *
20
+ * @param database - The recommendations database
21
+ * @param project - The project information
22
+ * @param userQuery - Optional user search query
23
+ * @param options - Recommendation options
24
+ * @returns List of scored recommendations
25
+ */
26
+ export declare function recommend(database: RecommendationDatabase, project: ProjectInfo, userQuery?: string, options?: RecommendOptions): ScoredRecommendation[];
27
+ //# sourceMappingURL=recommendation.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommendation.service.d.ts","sourceRoot":"","sources":["../../../src/services/recommender/recommendation.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGtF,qCAAqC;AACrC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gCAAgC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,KAAK,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;CAClC,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,sBAAsB,EAChC,OAAO,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,oBAAoB,EAAE,CAuBxB"}