@skillsmith/cli 0.2.0 → 0.2.2
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.
- package/README.md +9 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/commands/analyze.d.ts +13 -0
- package/dist/src/commands/analyze.d.ts.map +1 -0
- package/dist/src/commands/analyze.js +182 -0
- package/dist/src/commands/analyze.js.map +1 -0
- package/dist/src/commands/index.d.ts +2 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +4 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/recommend.d.ts +17 -0
- package/dist/src/commands/recommend.d.ts.map +1 -0
- package/dist/src/commands/recommend.js +510 -0
- package/dist/src/commands/recommend.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/utils/license.d.ts +43 -2
- package/dist/src/utils/license.d.ts.map +1 -1
- package/dist/src/utils/license.js +119 -4
- package/dist/src/utils/license.js.map +1 -1
- package/dist/tests/e2e/search.e2e.test.js +3 -2
- package/dist/tests/e2e/search.e2e.test.js.map +1 -1
- package/dist/tests/recommend.test.d.ts +10 -0
- package/dist/tests/recommend.test.d.ts.map +1 -0
- package/dist/tests/recommend.test.js +658 -0
- package/dist/tests/recommend.test.js.map +1 -0
- package/package.json +5 -5
- package/dist/src/cli.d.ts +0 -8
- package/dist/src/cli.d.ts.map +0 -1
- package/dist/src/cli.js +0 -38
- package/dist/src/cli.js.map +0 -1
- package/dist/src/cli.test.d.ts +0 -2
- package/dist/src/cli.test.d.ts.map +0 -1
- package/dist/src/cli.test.js +0 -33
- package/dist/src/cli.test.js.map +0 -1
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1299: CLI Recommend Command
|
|
3
|
+
*
|
|
4
|
+
* Analyzes a codebase and recommends relevant skills based on detected
|
|
5
|
+
* frameworks, dependencies, and patterns.
|
|
6
|
+
*
|
|
7
|
+
* References:
|
|
8
|
+
* - SMI-1283 (analyze command pattern)
|
|
9
|
+
* - packages/mcp-server/src/tools/recommend.ts (recommendation logic)
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import ora from 'ora';
|
|
14
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
15
|
+
import { homedir } from 'node:os';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { CodebaseAnalyzer, createApiClient, } from '@skillsmith/core';
|
|
18
|
+
import { sanitizeError } from '../utils/sanitize.js';
|
|
19
|
+
/**
|
|
20
|
+
* Valid trust tier values
|
|
21
|
+
*/
|
|
22
|
+
const VALID_TRUST_TIERS = [
|
|
23
|
+
'verified',
|
|
24
|
+
'community',
|
|
25
|
+
'experimental',
|
|
26
|
+
'unknown',
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
29
|
+
* Validate and normalize trust tier from API response (SMI-1354)
|
|
30
|
+
* Returns 'unknown' for invalid values
|
|
31
|
+
*/
|
|
32
|
+
function validateTrustTier(tier) {
|
|
33
|
+
if (typeof tier === 'string' && VALID_TRUST_TIERS.includes(tier)) {
|
|
34
|
+
return tier;
|
|
35
|
+
}
|
|
36
|
+
return 'unknown';
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get trust badge for display (SMI-1357: Use TrustTier type)
|
|
40
|
+
*/
|
|
41
|
+
function getTrustBadge(tier) {
|
|
42
|
+
switch (tier) {
|
|
43
|
+
case 'verified':
|
|
44
|
+
return chalk.green('[VERIFIED]');
|
|
45
|
+
case 'community':
|
|
46
|
+
return chalk.blue('[COMMUNITY]');
|
|
47
|
+
case 'experimental':
|
|
48
|
+
return chalk.yellow('[EXPERIMENTAL]');
|
|
49
|
+
case 'unknown':
|
|
50
|
+
return chalk.gray('[UNKNOWN]');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Format recommendations for terminal display
|
|
55
|
+
*/
|
|
56
|
+
function formatRecommendations(response, context) {
|
|
57
|
+
const lines = [];
|
|
58
|
+
lines.push('');
|
|
59
|
+
lines.push(chalk.bold.blue('=== Skill Recommendations ==='));
|
|
60
|
+
lines.push('');
|
|
61
|
+
if (context) {
|
|
62
|
+
// Show detected frameworks
|
|
63
|
+
if (context.frameworks.length > 0) {
|
|
64
|
+
const frameworks = context.frameworks
|
|
65
|
+
.slice(0, 3)
|
|
66
|
+
.map((f) => f.name)
|
|
67
|
+
.join(', ');
|
|
68
|
+
lines.push(chalk.dim(`Detected: ${frameworks}`));
|
|
69
|
+
lines.push('');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (response.recommendations.length === 0) {
|
|
73
|
+
lines.push(chalk.yellow('No recommendations found.'));
|
|
74
|
+
lines.push('');
|
|
75
|
+
lines.push('Suggestions:');
|
|
76
|
+
lines.push(' - Ensure the project has a package.json');
|
|
77
|
+
lines.push(' - Try a project with more dependencies');
|
|
78
|
+
lines.push(' - Use --context to provide additional context');
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
lines.push(`Found ${chalk.bold(response.recommendations.length)} recommendation(s):`);
|
|
82
|
+
lines.push('');
|
|
83
|
+
response.recommendations.forEach((rec, index) => {
|
|
84
|
+
const trustBadge = getTrustBadge(rec.trust_tier);
|
|
85
|
+
const qualityColor = rec.quality_score >= 80 ? chalk.green : rec.quality_score >= 50 ? chalk.yellow : chalk.red;
|
|
86
|
+
// Format relevance - show N/A if not available from API (-1)
|
|
87
|
+
let relevanceDisplay;
|
|
88
|
+
if (rec.similarity_score < 0) {
|
|
89
|
+
relevanceDisplay = chalk.gray('N/A');
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const relevanceColor = rec.similarity_score >= 0.7
|
|
93
|
+
? chalk.green
|
|
94
|
+
: rec.similarity_score >= 0.4
|
|
95
|
+
? chalk.yellow
|
|
96
|
+
: chalk.gray;
|
|
97
|
+
relevanceDisplay = relevanceColor(`${Math.round(rec.similarity_score * 100)}%`);
|
|
98
|
+
}
|
|
99
|
+
lines.push(`${chalk.bold(`${index + 1}.`)} ${chalk.bold(rec.name)} ${trustBadge}`);
|
|
100
|
+
lines.push(` Score: ${qualityColor(`${rec.quality_score}/100`)} | Relevance: ${relevanceDisplay}`);
|
|
101
|
+
lines.push(` ${chalk.dim(rec.reason)}`);
|
|
102
|
+
lines.push(` ${chalk.dim(`ID: ${rec.skill_id}`)}`);
|
|
103
|
+
lines.push('');
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
lines.push(chalk.dim('---'));
|
|
107
|
+
lines.push(chalk.dim(`Candidates considered: ${response.candidates_considered}`));
|
|
108
|
+
if (response.overlap_filtered > 0) {
|
|
109
|
+
lines.push(chalk.dim(`Filtered for overlap: ${response.overlap_filtered}`));
|
|
110
|
+
}
|
|
111
|
+
if (response.context.auto_detected) {
|
|
112
|
+
lines.push(chalk.dim(`Installed skills: ${response.context.installed_count} (auto-detected from ~/.claude/skills/)`));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
lines.push(chalk.dim(`Installed skills: ${response.context.installed_count}`));
|
|
116
|
+
}
|
|
117
|
+
lines.push(chalk.dim(`Completed in ${response.timing.totalMs}ms`));
|
|
118
|
+
return lines.join('\n');
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Format recommendations as JSON
|
|
122
|
+
*/
|
|
123
|
+
function formatAsJson(response, context) {
|
|
124
|
+
const output = {
|
|
125
|
+
recommendations: response.recommendations,
|
|
126
|
+
analysis: context
|
|
127
|
+
? {
|
|
128
|
+
frameworks: context.frameworks.slice(0, 10).map((f) => ({
|
|
129
|
+
name: f.name,
|
|
130
|
+
confidence: Math.round(f.confidence * 100),
|
|
131
|
+
})),
|
|
132
|
+
dependencies: context.dependencies.slice(0, 20).map((d) => ({
|
|
133
|
+
name: d.name,
|
|
134
|
+
is_dev: d.isDev,
|
|
135
|
+
})),
|
|
136
|
+
stats: {
|
|
137
|
+
total_files: context.stats.totalFiles,
|
|
138
|
+
total_lines: context.stats.totalLines,
|
|
139
|
+
},
|
|
140
|
+
}
|
|
141
|
+
: null,
|
|
142
|
+
meta: {
|
|
143
|
+
candidates_considered: response.candidates_considered,
|
|
144
|
+
overlap_filtered: response.overlap_filtered,
|
|
145
|
+
installed_count: response.context.installed_count,
|
|
146
|
+
auto_detected: response.context.auto_detected,
|
|
147
|
+
timing_ms: response.timing.totalMs,
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
return JSON.stringify(output, null, 2);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Build stack from codebase analysis
|
|
154
|
+
*/
|
|
155
|
+
function buildStackFromAnalysis(context) {
|
|
156
|
+
const stack = [];
|
|
157
|
+
// Add detected frameworks
|
|
158
|
+
for (const fw of context.frameworks.slice(0, 5)) {
|
|
159
|
+
stack.push(fw.name.toLowerCase());
|
|
160
|
+
}
|
|
161
|
+
// Add key dependencies
|
|
162
|
+
for (const dep of context.dependencies.slice(0, 10)) {
|
|
163
|
+
if (!dep.isDev) {
|
|
164
|
+
stack.push(dep.name.toLowerCase());
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return [...new Set(stack)].slice(0, 10);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if error is a network-related error (SMI-1355)
|
|
171
|
+
*/
|
|
172
|
+
function isNetworkError(error) {
|
|
173
|
+
if (error instanceof Error) {
|
|
174
|
+
const message = error.message.toLowerCase();
|
|
175
|
+
return (message.includes('fetch failed') ||
|
|
176
|
+
message.includes('network') ||
|
|
177
|
+
message.includes('enotfound') ||
|
|
178
|
+
message.includes('econnrefused') ||
|
|
179
|
+
message.includes('timeout') ||
|
|
180
|
+
message.includes('socket') ||
|
|
181
|
+
error.name === 'AbortError');
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Format offline analysis results (SMI-1355)
|
|
187
|
+
*/
|
|
188
|
+
function formatOfflineResults(context, json) {
|
|
189
|
+
if (json) {
|
|
190
|
+
return JSON.stringify({
|
|
191
|
+
offline: true,
|
|
192
|
+
analysis: {
|
|
193
|
+
frameworks: context.frameworks.slice(0, 10).map((f) => ({
|
|
194
|
+
name: f.name,
|
|
195
|
+
confidence: Math.round(f.confidence * 100),
|
|
196
|
+
})),
|
|
197
|
+
dependencies: context.dependencies.slice(0, 20).map((d) => ({
|
|
198
|
+
name: d.name,
|
|
199
|
+
is_dev: d.isDev,
|
|
200
|
+
})),
|
|
201
|
+
stats: {
|
|
202
|
+
total_files: context.stats.totalFiles,
|
|
203
|
+
total_lines: context.stats.totalLines,
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
message: 'Unable to reach Skillsmith API. Showing analysis-only results.',
|
|
207
|
+
}, null, 2);
|
|
208
|
+
}
|
|
209
|
+
const lines = [];
|
|
210
|
+
lines.push('');
|
|
211
|
+
lines.push(chalk.yellow('⚠ Unable to reach Skillsmith API. Showing analysis-only results.'));
|
|
212
|
+
lines.push('');
|
|
213
|
+
lines.push(chalk.bold.blue('=== Codebase Analysis ==='));
|
|
214
|
+
lines.push('');
|
|
215
|
+
if (context.frameworks.length > 0) {
|
|
216
|
+
lines.push(chalk.bold('Detected Frameworks:'));
|
|
217
|
+
context.frameworks.slice(0, 5).forEach((f) => {
|
|
218
|
+
const confidence = Math.round(f.confidence * 100);
|
|
219
|
+
lines.push(` - ${f.name} (${confidence}% confidence)`);
|
|
220
|
+
});
|
|
221
|
+
lines.push('');
|
|
222
|
+
}
|
|
223
|
+
if (context.dependencies.length > 0) {
|
|
224
|
+
const prodDeps = context.dependencies.filter((d) => !d.isDev).slice(0, 10);
|
|
225
|
+
if (prodDeps.length > 0) {
|
|
226
|
+
lines.push(chalk.bold('Key Dependencies:'));
|
|
227
|
+
prodDeps.forEach((d) => lines.push(` - ${d.name}`));
|
|
228
|
+
lines.push('');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
lines.push(chalk.dim('---'));
|
|
232
|
+
lines.push(chalk.dim(`Files analyzed: ${context.stats.totalFiles}`));
|
|
233
|
+
lines.push(chalk.dim(`Total lines: ${context.stats.totalLines.toLocaleString()}`));
|
|
234
|
+
lines.push('');
|
|
235
|
+
lines.push(chalk.cyan('To get skill recommendations, ensure network connectivity and retry.'));
|
|
236
|
+
return lines.join('\n');
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Read installed skills from ~/.claude/skills/ directory (SMI-1358)
|
|
240
|
+
* Returns array of installed skill metadata
|
|
241
|
+
*/
|
|
242
|
+
function getInstalledSkills() {
|
|
243
|
+
const skillsDir = join(homedir(), '.claude', 'skills');
|
|
244
|
+
if (!existsSync(skillsDir)) {
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
const installedSkills = [];
|
|
248
|
+
try {
|
|
249
|
+
const entries = readdirSync(skillsDir);
|
|
250
|
+
for (const entry of entries) {
|
|
251
|
+
const skillPath = join(skillsDir, entry);
|
|
252
|
+
const stat = statSync(skillPath);
|
|
253
|
+
if (!stat.isDirectory()) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
// Try to read SKILL.md or skill.yaml for metadata
|
|
257
|
+
const skill = {
|
|
258
|
+
name: entry.toLowerCase(),
|
|
259
|
+
directory: entry,
|
|
260
|
+
tags: [],
|
|
261
|
+
category: null,
|
|
262
|
+
};
|
|
263
|
+
// Try to extract tags from SKILL.md frontmatter
|
|
264
|
+
const skillMdPath = join(skillPath, 'SKILL.md');
|
|
265
|
+
if (existsSync(skillMdPath)) {
|
|
266
|
+
try {
|
|
267
|
+
const content = readFileSync(skillMdPath, 'utf-8');
|
|
268
|
+
// Extract tags from YAML frontmatter
|
|
269
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
270
|
+
const frontmatter = frontmatterMatch?.[1];
|
|
271
|
+
if (frontmatter) {
|
|
272
|
+
// Extract tags
|
|
273
|
+
const tagsMatch = frontmatter.match(/tags:\s*\[(.*?)\]/);
|
|
274
|
+
const tagsContent = tagsMatch?.[1];
|
|
275
|
+
if (tagsContent) {
|
|
276
|
+
skill.tags = tagsContent
|
|
277
|
+
.split(',')
|
|
278
|
+
.map((t) => t.trim().replace(/['"]/g, '').toLowerCase())
|
|
279
|
+
.filter(Boolean);
|
|
280
|
+
}
|
|
281
|
+
// Extract category
|
|
282
|
+
const categoryMatch = frontmatter.match(/category:\s*["']?([^"'\n]+)["']?/);
|
|
283
|
+
const categoryContent = categoryMatch?.[1];
|
|
284
|
+
if (categoryContent) {
|
|
285
|
+
skill.category = categoryContent.trim().toLowerCase();
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
// Ignore read errors
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
installedSkills.push(skill);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
// Return empty array if directory cannot be read
|
|
298
|
+
return [];
|
|
299
|
+
}
|
|
300
|
+
return installedSkills;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Normalize a skill name for comparison (SMI-1358)
|
|
304
|
+
* Removes common prefixes/suffixes and normalizes case
|
|
305
|
+
*/
|
|
306
|
+
function normalizeSkillName(name) {
|
|
307
|
+
return name
|
|
308
|
+
.toLowerCase()
|
|
309
|
+
.replace(/[-_]/g, '')
|
|
310
|
+
.replace(/^skill/, '')
|
|
311
|
+
.replace(/skill$/, '')
|
|
312
|
+
.replace(/^helper/, '')
|
|
313
|
+
.replace(/helper$/, '')
|
|
314
|
+
.trim();
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Check if two skills overlap in functionality (SMI-1358)
|
|
318
|
+
* Uses name similarity, tag matching, and category comparison
|
|
319
|
+
*/
|
|
320
|
+
function skillsOverlap(installed, recommended) {
|
|
321
|
+
const installedName = normalizeSkillName(installed.name);
|
|
322
|
+
const recommendedName = normalizeSkillName(recommended.name);
|
|
323
|
+
const recommendedId = recommended.skill_id.toLowerCase();
|
|
324
|
+
// Direct name match (exact or normalized)
|
|
325
|
+
if (installedName === recommendedName) {
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
// Check if installed name is contained in recommended ID
|
|
329
|
+
// e.g., installed "jest" overlaps with "community/jest-helper"
|
|
330
|
+
if (recommendedId.includes(installed.name)) {
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
// Check if normalized names contain each other
|
|
334
|
+
if (installedName.includes(recommendedName) || recommendedName.includes(installedName)) {
|
|
335
|
+
// Only match if substantial overlap (at least 4 chars)
|
|
336
|
+
if (installedName.length >= 4 && recommendedName.length >= 4) {
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
// Tag-based overlap detection
|
|
341
|
+
if (installed.tags.length > 0) {
|
|
342
|
+
const recommendedNameParts = recommended.name.toLowerCase().split(/[-_\s]+/);
|
|
343
|
+
const hasTagOverlap = installed.tags.some((tag) => recommendedNameParts.includes(tag) || recommendedName.includes(tag));
|
|
344
|
+
if (hasTagOverlap) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Filter recommendations to remove overlaps with installed skills (SMI-1358)
|
|
352
|
+
*/
|
|
353
|
+
function filterOverlappingSkills(recommendations, installedSkills) {
|
|
354
|
+
if (installedSkills.length === 0) {
|
|
355
|
+
return { filtered: recommendations, overlapCount: 0 };
|
|
356
|
+
}
|
|
357
|
+
const filtered = [];
|
|
358
|
+
let overlapCount = 0;
|
|
359
|
+
for (const rec of recommendations) {
|
|
360
|
+
const hasOverlap = installedSkills.some((installed) => skillsOverlap(installed, rec));
|
|
361
|
+
if (hasOverlap) {
|
|
362
|
+
overlapCount++;
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
filtered.push(rec);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return { filtered, overlapCount };
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Run recommendation workflow
|
|
372
|
+
*/
|
|
373
|
+
async function runRecommend(targetPath, options) {
|
|
374
|
+
const spinner = ora();
|
|
375
|
+
let codebaseContext = null;
|
|
376
|
+
try {
|
|
377
|
+
// Step 1: Analyze codebase
|
|
378
|
+
spinner.start('Analyzing codebase...');
|
|
379
|
+
const analyzer = new CodebaseAnalyzer();
|
|
380
|
+
codebaseContext = await analyzer.analyze(targetPath, {
|
|
381
|
+
maxFiles: options.maxFiles,
|
|
382
|
+
includeDevDeps: true,
|
|
383
|
+
});
|
|
384
|
+
spinner.succeed(`Analyzed ${codebaseContext.stats.totalFiles} files (${codebaseContext.frameworks.length} frameworks detected)`);
|
|
385
|
+
// Step 2: Build recommendation request
|
|
386
|
+
spinner.start('Finding skill recommendations...');
|
|
387
|
+
const stack = buildStackFromAnalysis(codebaseContext);
|
|
388
|
+
// Add user-provided context
|
|
389
|
+
if (options.context) {
|
|
390
|
+
const contextWords = options.context
|
|
391
|
+
.toLowerCase()
|
|
392
|
+
.split(/\s+/)
|
|
393
|
+
.filter((w) => w.length > 3)
|
|
394
|
+
.slice(0, 5);
|
|
395
|
+
stack.push(...contextWords);
|
|
396
|
+
}
|
|
397
|
+
// Step 3: Call recommendation API
|
|
398
|
+
const apiClient = createApiClient();
|
|
399
|
+
const apiResponse = await apiClient.getRecommendations({
|
|
400
|
+
stack: stack.slice(0, 10),
|
|
401
|
+
limit: options.limit,
|
|
402
|
+
});
|
|
403
|
+
// Transform API response to expected format
|
|
404
|
+
let recommendations = apiResponse.data.map((skill) => ({
|
|
405
|
+
skill_id: skill.id,
|
|
406
|
+
name: skill.name,
|
|
407
|
+
reason: `Matches your stack: ${stack.slice(0, 3).join(', ')}`,
|
|
408
|
+
similarity_score: -1, // API doesn't return this; -1 indicates not available
|
|
409
|
+
trust_tier: validateTrustTier(skill.trust_tier),
|
|
410
|
+
quality_score: Math.round((skill.quality_score ?? 0.5) * 100),
|
|
411
|
+
}));
|
|
412
|
+
// SMI-1358: Apply overlap filtering if enabled (default behavior)
|
|
413
|
+
// noOverlap = true means user passed --no-overlap, so we should NOT filter
|
|
414
|
+
let overlapFiltered = 0;
|
|
415
|
+
let installedSkills = [];
|
|
416
|
+
const autoDetected = !options.installed || options.installed.length === 0;
|
|
417
|
+
if (!options.noOverlap) {
|
|
418
|
+
// Get installed skills (auto-detect from ~/.claude/skills/ if not provided)
|
|
419
|
+
if (options.installed && options.installed.length > 0) {
|
|
420
|
+
// Convert provided skill IDs to InstalledSkill format
|
|
421
|
+
installedSkills = options.installed.map((id) => ({
|
|
422
|
+
name: id.toLowerCase().split('/').pop() ?? id.toLowerCase(),
|
|
423
|
+
directory: id,
|
|
424
|
+
tags: [],
|
|
425
|
+
category: null,
|
|
426
|
+
}));
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
// Auto-detect installed skills
|
|
430
|
+
installedSkills = getInstalledSkills();
|
|
431
|
+
}
|
|
432
|
+
if (installedSkills.length > 0) {
|
|
433
|
+
const filterResult = filterOverlappingSkills(recommendations, installedSkills);
|
|
434
|
+
recommendations = filterResult.filtered;
|
|
435
|
+
overlapFiltered = filterResult.overlapCount;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
const response = {
|
|
439
|
+
recommendations,
|
|
440
|
+
candidates_considered: apiResponse.data.length,
|
|
441
|
+
overlap_filtered: overlapFiltered,
|
|
442
|
+
context: {
|
|
443
|
+
installed_count: installedSkills.length,
|
|
444
|
+
has_project_context: !!options.context,
|
|
445
|
+
using_semantic_matching: true,
|
|
446
|
+
auto_detected: autoDetected,
|
|
447
|
+
},
|
|
448
|
+
timing: {
|
|
449
|
+
totalMs: codebaseContext.metadata.durationMs,
|
|
450
|
+
},
|
|
451
|
+
};
|
|
452
|
+
spinner.succeed(`Found ${response.recommendations.length} recommendations${overlapFiltered > 0 ? ` (${overlapFiltered} filtered for overlap)` : ''}`);
|
|
453
|
+
// Step 4: Output results
|
|
454
|
+
if (options.json) {
|
|
455
|
+
console.log(formatAsJson(response, codebaseContext));
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
console.log(formatRecommendations(response, codebaseContext));
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
catch (error) {
|
|
462
|
+
// SMI-1355: Check if this is a network error and we have codebase context
|
|
463
|
+
if (isNetworkError(error) && codebaseContext) {
|
|
464
|
+
spinner.warn('Unable to reach API, showing analysis-only results');
|
|
465
|
+
console.log(formatOfflineResults(codebaseContext, options.json));
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
spinner.fail('Recommendation failed');
|
|
469
|
+
if (options.json) {
|
|
470
|
+
console.error(JSON.stringify({ error: sanitizeError(error) }));
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
console.error(chalk.red('Error:'), sanitizeError(error));
|
|
474
|
+
}
|
|
475
|
+
process.exit(1);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Create recommend command
|
|
480
|
+
*/
|
|
481
|
+
export function createRecommendCommand() {
|
|
482
|
+
const cmd = new Command('recommend')
|
|
483
|
+
.description('Analyze a codebase and recommend relevant skills based on detected patterns')
|
|
484
|
+
.argument('[path]', 'Path to the codebase to analyze', '.')
|
|
485
|
+
.option('-l, --limit <number>', 'Maximum recommendations to return', '5')
|
|
486
|
+
.option('-j, --json', 'Output results as JSON')
|
|
487
|
+
.option('-c, --context <text>', 'Additional context for recommendations')
|
|
488
|
+
.option('-i, --installed <skills...>', 'Currently installed skill IDs')
|
|
489
|
+
.option('--no-overlap', 'Disable overlap detection')
|
|
490
|
+
.option('-m, --max-files <number>', 'Maximum files to analyze', '1000')
|
|
491
|
+
.action(async (targetPath, opts) => {
|
|
492
|
+
const limit = parseInt(opts['limit'], 10);
|
|
493
|
+
const maxFiles = parseInt(opts['max-files'], 10);
|
|
494
|
+
const json = opts['json'] === true;
|
|
495
|
+
const context = opts['context'];
|
|
496
|
+
const installed = opts['installed'];
|
|
497
|
+
const noOverlap = opts['overlap'] === false;
|
|
498
|
+
await runRecommend(targetPath, {
|
|
499
|
+
limit: isNaN(limit) ? 5 : Math.min(Math.max(limit, 1), 50),
|
|
500
|
+
maxFiles: isNaN(maxFiles) ? 1000 : maxFiles,
|
|
501
|
+
json,
|
|
502
|
+
context,
|
|
503
|
+
installed,
|
|
504
|
+
noOverlap,
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
return cmd;
|
|
508
|
+
}
|
|
509
|
+
export default createRecommendCommand;
|
|
510
|
+
//# sourceMappingURL=recommend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../../src/commands/recommend.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* - init: Initialize new skill project (SMI-746)
|
|
12
12
|
* - validate: Validate local SKILL.md (SMI-746)
|
|
13
13
|
* - publish: Prepare skill for sharing (SMI-746)
|
|
14
|
+
* - analyze: Analyze codebase for skill recommendations (SMI-1283)
|
|
14
15
|
*/
|
|
15
16
|
export {};
|
|
16
17
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
|
package/dist/src/index.js
CHANGED
|
@@ -11,14 +11,15 @@
|
|
|
11
11
|
* - init: Initialize new skill project (SMI-746)
|
|
12
12
|
* - validate: Validate local SKILL.md (SMI-746)
|
|
13
13
|
* - publish: Prepare skill for sharing (SMI-746)
|
|
14
|
+
* - analyze: Analyze codebase for skill recommendations (SMI-1283)
|
|
14
15
|
*/
|
|
15
16
|
import { Command } from 'commander';
|
|
16
17
|
import { importSkills } from './import.js';
|
|
17
|
-
import { createSearchCommand, createListCommand, createUpdateCommand, createRemoveCommand, createInitCommand, createValidateCommand, createPublishCommand, } from './commands/index.js';
|
|
18
|
+
import { createSearchCommand, createListCommand, createUpdateCommand, createRemoveCommand, createInitCommand, createValidateCommand, createPublishCommand, createAnalyzeCommand, createRecommendCommand, } from './commands/index.js';
|
|
18
19
|
import { DEFAULT_DB_PATH } from './config.js';
|
|
19
20
|
import { sanitizeError } from './utils/sanitize.js';
|
|
20
21
|
import { displayStartupHeader } from './utils/license.js';
|
|
21
|
-
const CLI_VERSION = '0.
|
|
22
|
+
const CLI_VERSION = '0.2.0';
|
|
22
23
|
const program = new Command();
|
|
23
24
|
// Detect which command name was used (skillsmith or sklx)
|
|
24
25
|
const commandName = process.argv[1]?.endsWith('sklx') ? 'sklx' : 'skillsmith';
|
|
@@ -63,5 +64,9 @@ program.addCommand(createRemoveCommand());
|
|
|
63
64
|
program.addCommand(createInitCommand());
|
|
64
65
|
program.addCommand(createValidateCommand());
|
|
65
66
|
program.addCommand(createPublishCommand());
|
|
67
|
+
// SMI-1283: Codebase analysis
|
|
68
|
+
program.addCommand(createAnalyzeCommand());
|
|
69
|
+
// SMI-1299: Recommendations
|
|
70
|
+
program.addCommand(createRecommendCommand());
|
|
66
71
|
program.parse();
|
|
67
72
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,8 +13,25 @@
|
|
|
13
13
|
*/
|
|
14
14
|
/**
|
|
15
15
|
* Available license tiers
|
|
16
|
+
* - community: Free tier (1,000 API calls/month)
|
|
17
|
+
* - individual: Solo developers ($9.99/mo, 10,000 API calls/month)
|
|
18
|
+
* - team: Teams ($25/user/mo, 100,000 API calls/month)
|
|
19
|
+
* - enterprise: Full enterprise ($55/user/mo, unlimited)
|
|
16
20
|
*/
|
|
17
|
-
export type LicenseTier = 'community' | 'team' | 'enterprise';
|
|
21
|
+
export type LicenseTier = 'community' | 'individual' | 'team' | 'enterprise';
|
|
22
|
+
/**
|
|
23
|
+
* Quota information for display
|
|
24
|
+
*/
|
|
25
|
+
export interface QuotaInfo {
|
|
26
|
+
/** API calls used this period */
|
|
27
|
+
used: number;
|
|
28
|
+
/** API call limit (-1 for unlimited) */
|
|
29
|
+
limit: number;
|
|
30
|
+
/** Percentage used */
|
|
31
|
+
percentUsed: number;
|
|
32
|
+
/** When the quota resets */
|
|
33
|
+
resetAt: Date;
|
|
34
|
+
}
|
|
18
35
|
/**
|
|
19
36
|
* License status information returned by license check
|
|
20
37
|
*/
|
|
@@ -29,12 +46,20 @@ export interface LicenseStatus {
|
|
|
29
46
|
features: string[];
|
|
30
47
|
/** Error message if license validation failed */
|
|
31
48
|
error?: string;
|
|
49
|
+
/** Optional quota information */
|
|
50
|
+
quota?: QuotaInfo;
|
|
32
51
|
}
|
|
33
52
|
/**
|
|
34
53
|
* Reset the enterprise validator cache (for testing purposes)
|
|
35
54
|
* @internal
|
|
36
55
|
*/
|
|
37
56
|
export declare function _resetEnterpriseValidatorCache(): void;
|
|
57
|
+
/**
|
|
58
|
+
* API call limits per tier (per month)
|
|
59
|
+
* Note: These are reference values matching the enterprise package quotas.
|
|
60
|
+
* Actual quota enforcement happens in the MCP server via QuotaEnforcementService.
|
|
61
|
+
*/
|
|
62
|
+
export declare const TIER_QUOTAS: Record<LicenseTier, number>;
|
|
38
63
|
/**
|
|
39
64
|
* Get the current license status
|
|
40
65
|
*
|
|
@@ -64,10 +89,26 @@ export declare function getLicenseStatusLegacy(): Promise<LicenseStatus>;
|
|
|
64
89
|
* @returns Formatted tier badge string
|
|
65
90
|
*/
|
|
66
91
|
export declare function formatTierBadge(tier: LicenseTier): string;
|
|
92
|
+
/**
|
|
93
|
+
* Display a progress bar for quota usage
|
|
94
|
+
*
|
|
95
|
+
* @param used - API calls used
|
|
96
|
+
* @param limit - API call limit
|
|
97
|
+
* @returns Formatted progress bar string
|
|
98
|
+
*/
|
|
99
|
+
export declare function displayQuotaProgressBar(used: number, limit: number): string;
|
|
100
|
+
/**
|
|
101
|
+
* Display a quota warning box
|
|
102
|
+
*
|
|
103
|
+
* @param quota - Quota information
|
|
104
|
+
* @param tier - Current tier for upgrade suggestions
|
|
105
|
+
*/
|
|
106
|
+
export declare function displayQuotaWarning(quota: QuotaInfo, tier: LicenseTier): void;
|
|
67
107
|
/**
|
|
68
108
|
* Display license status on CLI startup
|
|
69
109
|
*
|
|
70
|
-
* Shows license tier, expiration (if applicable),
|
|
110
|
+
* Shows license tier, expiration (if applicable), features for paid tiers,
|
|
111
|
+
* and quota usage information.
|
|
71
112
|
* Uses colored output: green for valid, yellow for community, red for expired/invalid.
|
|
72
113
|
*
|
|
73
114
|
* @param status - License status to display
|