@skillsmith/cli 0.3.1 → 0.3.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 +57 -0
- package/assets/skillsmith-skill/SKILL.md +235 -0
- package/dist/.tsbuildinfo +1 -1
- 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/install-skill.d.ts +13 -0
- package/dist/src/commands/install-skill.d.ts.map +1 -0
- package/dist/src/commands/install-skill.js +137 -0
- package/dist/src/commands/install-skill.js.map +1 -0
- package/dist/src/commands/manage.d.ts +4 -1
- package/dist/src/commands/manage.d.ts.map +1 -1
- package/dist/src/commands/manage.js +56 -10
- package/dist/src/commands/manage.js.map +1 -1
- package/dist/src/commands/merge.d.ts +17 -0
- package/dist/src/commands/merge.d.ts.map +1 -0
- package/dist/src/commands/merge.js +160 -0
- package/dist/src/commands/merge.js.map +1 -0
- package/dist/src/commands/recommend.d.ts +1 -4
- package/dist/src/commands/recommend.d.ts.map +1 -1
- package/dist/src/commands/recommend.helpers.d.ts +58 -0
- package/dist/src/commands/recommend.helpers.d.ts.map +1 -0
- package/dist/src/commands/recommend.helpers.js +428 -0
- package/dist/src/commands/recommend.helpers.js.map +1 -0
- package/dist/src/commands/recommend.js +50 -372
- package/dist/src/commands/recommend.js.map +1 -1
- package/dist/src/commands/recommend.types.d.ts +66 -0
- package/dist/src/commands/recommend.types.d.ts.map +1 -0
- package/dist/src/commands/recommend.types.js +14 -0
- package/dist/src/commands/recommend.types.js.map +1 -0
- package/dist/src/commands/search.d.ts.map +1 -1
- package/dist/src/commands/search.js +133 -18
- package/dist/src/commands/search.js.map +1 -1
- package/dist/src/config.d.ts +5 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +7 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/utils/license.test.js +6 -1
- package/dist/src/utils/license.test.js.map +1 -1
- package/dist/src/utils/node-version.d.ts +41 -0
- package/dist/src/utils/node-version.d.ts.map +1 -0
- package/dist/src/utils/node-version.js +123 -0
- package/dist/src/utils/node-version.js.map +1 -0
- package/dist/tests/e2e/search.e2e.test.js +62 -6
- package/dist/tests/e2e/search.e2e.test.js.map +1 -1
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -1
- package/dist/tests/e2e/utils/hardcoded-detector.js +44 -3
- package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -1
- package/dist/tests/install-skill.test.d.ts +8 -0
- package/dist/tests/install-skill.test.d.ts.map +1 -0
- package/dist/tests/install-skill.test.js +409 -0
- package/dist/tests/install-skill.test.js.map +1 -0
- package/dist/tests/manage.test.js +284 -8
- package/dist/tests/manage.test.js.map +1 -1
- package/dist/tests/node-version.test.d.ts +8 -0
- package/dist/tests/node-version.test.d.ts.map +1 -0
- package/dist/tests/node-version.test.js +200 -0
- package/dist/tests/node-version.test.js.map +1 -0
- package/dist/tests/recommend.test.js +94 -0
- package/dist/tests/recommend.test.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1299: CLI Recommend Command Helpers
|
|
3
|
+
* @module @skillsmith/cli/commands/recommend.helpers
|
|
4
|
+
*/
|
|
5
|
+
import type { TrustTier, CodebaseContext, SkillRole } from '@skillsmith/core';
|
|
6
|
+
import type { SkillRecommendation, RecommendResponse, InstalledSkill } from './recommend.types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Validate and normalize trust tier from API response (SMI-1354)
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateTrustTier(tier: unknown): TrustTier;
|
|
11
|
+
/**
|
|
12
|
+
* Check if error is a network-related error (SMI-1355)
|
|
13
|
+
*/
|
|
14
|
+
export declare function isNetworkError(error: unknown): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Get trust badge for display (SMI-1357)
|
|
17
|
+
*/
|
|
18
|
+
export declare function getTrustBadge(tier: TrustTier): string;
|
|
19
|
+
/**
|
|
20
|
+
* Format recommendations for terminal display
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatRecommendations(response: RecommendResponse, context: CodebaseContext | null): string;
|
|
23
|
+
/**
|
|
24
|
+
* Format recommendations as JSON
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatAsJson(response: RecommendResponse, context: CodebaseContext | null): string;
|
|
27
|
+
/**
|
|
28
|
+
* Format offline analysis results (SMI-1355)
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatOfflineResults(context: CodebaseContext, json: boolean): string;
|
|
31
|
+
/**
|
|
32
|
+
* Build stack from codebase analysis
|
|
33
|
+
*/
|
|
34
|
+
export declare function buildStackFromAnalysis(context: CodebaseContext): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Read installed skills from ~/.claude/skills/ directory (SMI-1358)
|
|
37
|
+
*/
|
|
38
|
+
export declare function getInstalledSkills(): InstalledSkill[];
|
|
39
|
+
/**
|
|
40
|
+
* SMI-1631: Infer skill roles from tags when not explicitly set
|
|
41
|
+
*/
|
|
42
|
+
export declare function inferRolesFromTags(tags: string[]): SkillRole[];
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a skill name for comparison (SMI-1358)
|
|
45
|
+
*/
|
|
46
|
+
export declare function normalizeSkillName(name: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Check if two skills overlap in functionality (SMI-1358)
|
|
49
|
+
*/
|
|
50
|
+
export declare function skillsOverlap(installed: InstalledSkill, recommended: SkillRecommendation): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Filter recommendations to remove overlaps with installed skills (SMI-1358)
|
|
53
|
+
*/
|
|
54
|
+
export declare function filterOverlappingSkills(recommendations: SkillRecommendation[], installedSkills: InstalledSkill[]): {
|
|
55
|
+
filtered: SkillRecommendation[];
|
|
56
|
+
overlapCount: number;
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=recommend.helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend.helpers.d.ts","sourceRoot":"","sources":["../../../src/commands/recommend.helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,SAAS,EAGV,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAOlG;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,CAK1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CActD;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAYrD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,eAAe,GAAG,IAAI,GAC9B,MAAM,CAsFR;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,iBAAiB,EAAE,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,MAAM,CA+BjG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAyDpF;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAczE;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,EAAE,CA0DrD;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAqE9D;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASvD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,cAAc,EACzB,WAAW,EAAE,mBAAmB,GAC/B,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,eAAe,EAAE,mBAAmB,EAAE,EACtC,eAAe,EAAE,cAAc,EAAE,GAChC;IAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAkB3D"}
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-1299: CLI Recommend Command Helpers
|
|
3
|
+
* @module @skillsmith/cli/commands/recommend.helpers
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { VALID_TRUST_TIERS } from './recommend.types.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Validation Helpers
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Validate and normalize trust tier from API response (SMI-1354)
|
|
15
|
+
*/
|
|
16
|
+
export function validateTrustTier(tier) {
|
|
17
|
+
if (typeof tier === 'string' && VALID_TRUST_TIERS.includes(tier)) {
|
|
18
|
+
return tier;
|
|
19
|
+
}
|
|
20
|
+
return 'unknown';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if error is a network-related error (SMI-1355)
|
|
24
|
+
*/
|
|
25
|
+
export function isNetworkError(error) {
|
|
26
|
+
if (error instanceof Error) {
|
|
27
|
+
const message = error.message.toLowerCase();
|
|
28
|
+
return (message.includes('fetch failed') ||
|
|
29
|
+
message.includes('network') ||
|
|
30
|
+
message.includes('enotfound') ||
|
|
31
|
+
message.includes('econnrefused') ||
|
|
32
|
+
message.includes('timeout') ||
|
|
33
|
+
message.includes('socket') ||
|
|
34
|
+
error.name === 'AbortError');
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
// ============================================================================
|
|
39
|
+
// Display Helpers
|
|
40
|
+
// ============================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Get trust badge for display (SMI-1357)
|
|
43
|
+
*/
|
|
44
|
+
export function getTrustBadge(tier) {
|
|
45
|
+
switch (tier) {
|
|
46
|
+
case 'verified':
|
|
47
|
+
return chalk.green('[VERIFIED]');
|
|
48
|
+
case 'community':
|
|
49
|
+
return chalk.blue('[COMMUNITY]');
|
|
50
|
+
case 'experimental':
|
|
51
|
+
return chalk.yellow('[EXPERIMENTAL]');
|
|
52
|
+
case 'unknown':
|
|
53
|
+
default:
|
|
54
|
+
return chalk.gray('[UNKNOWN]');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Format recommendations for terminal display
|
|
59
|
+
*/
|
|
60
|
+
export function formatRecommendations(response, context) {
|
|
61
|
+
const lines = [];
|
|
62
|
+
lines.push('');
|
|
63
|
+
lines.push(chalk.bold.blue('=== Skill Recommendations ==='));
|
|
64
|
+
lines.push('');
|
|
65
|
+
if (context) {
|
|
66
|
+
if (context.frameworks.length > 0) {
|
|
67
|
+
const frameworks = context.frameworks
|
|
68
|
+
.slice(0, 3)
|
|
69
|
+
.map((f) => f.name)
|
|
70
|
+
.join(', ');
|
|
71
|
+
lines.push(chalk.dim(`Detected: ${frameworks}`));
|
|
72
|
+
lines.push('');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
if (response.recommendations.length === 0) {
|
|
76
|
+
lines.push(chalk.yellow('No recommendations found.'));
|
|
77
|
+
lines.push('');
|
|
78
|
+
lines.push('Suggestions:');
|
|
79
|
+
lines.push(' - Ensure the project has a package.json');
|
|
80
|
+
lines.push(' - Try a project with more dependencies');
|
|
81
|
+
lines.push(' - Use --context to provide additional context');
|
|
82
|
+
if (response.context.role_filter) {
|
|
83
|
+
lines.push(` - Try removing the --role filter (currently: ${response.context.role_filter})`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
lines.push(`Found ${chalk.bold(response.recommendations.length)} recommendation(s):`);
|
|
88
|
+
lines.push('');
|
|
89
|
+
response.recommendations.forEach((rec, index) => {
|
|
90
|
+
const trustBadge = getTrustBadge(rec.trust_tier);
|
|
91
|
+
const qualityColor = rec.quality_score >= 80 ? chalk.green : rec.quality_score >= 50 ? chalk.yellow : chalk.red;
|
|
92
|
+
let relevanceDisplay;
|
|
93
|
+
if (rec.similarity_score < 0) {
|
|
94
|
+
relevanceDisplay = chalk.gray('N/A');
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const relevanceColor = rec.similarity_score >= 0.7
|
|
98
|
+
? chalk.green
|
|
99
|
+
: rec.similarity_score >= 0.4
|
|
100
|
+
? chalk.yellow
|
|
101
|
+
: chalk.gray;
|
|
102
|
+
relevanceDisplay = relevanceColor(`${Math.round(rec.similarity_score * 100)}%`);
|
|
103
|
+
}
|
|
104
|
+
const rolesDisplay = rec.roles?.length ? chalk.cyan(` [${rec.roles.join(', ')}]`) : '';
|
|
105
|
+
lines.push(`${chalk.bold(`${index + 1}.`)} ${chalk.bold(rec.name)} ${trustBadge}${rolesDisplay}`);
|
|
106
|
+
lines.push(` Score: ${qualityColor(`${rec.quality_score}/100`)} | Relevance: ${relevanceDisplay}`);
|
|
107
|
+
lines.push(` ${chalk.dim(rec.reason)}`);
|
|
108
|
+
lines.push(` ${chalk.dim(`ID: ${rec.skill_id}`)}`);
|
|
109
|
+
lines.push('');
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
lines.push(chalk.dim('---'));
|
|
113
|
+
lines.push(chalk.dim(`Candidates considered: ${response.candidates_considered}`));
|
|
114
|
+
if (response.overlap_filtered > 0) {
|
|
115
|
+
lines.push(chalk.dim(`Filtered for overlap: ${response.overlap_filtered}`));
|
|
116
|
+
}
|
|
117
|
+
if (response.role_filtered > 0) {
|
|
118
|
+
lines.push(chalk.dim(`Filtered for role: ${response.role_filtered}`));
|
|
119
|
+
}
|
|
120
|
+
if (response.context.role_filter) {
|
|
121
|
+
lines.push(chalk.dim(`Role filter: ${response.context.role_filter}`));
|
|
122
|
+
}
|
|
123
|
+
if (response.context.auto_detected) {
|
|
124
|
+
lines.push(chalk.dim(`Installed skills: ${response.context.installed_count} (auto-detected from ~/.claude/skills/)`));
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
lines.push(chalk.dim(`Installed skills: ${response.context.installed_count}`));
|
|
128
|
+
}
|
|
129
|
+
lines.push(chalk.dim(`Completed in ${response.timing.totalMs}ms`));
|
|
130
|
+
return lines.join('\n');
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Format recommendations as JSON
|
|
134
|
+
*/
|
|
135
|
+
export function formatAsJson(response, context) {
|
|
136
|
+
const output = {
|
|
137
|
+
recommendations: response.recommendations,
|
|
138
|
+
analysis: context
|
|
139
|
+
? {
|
|
140
|
+
frameworks: context.frameworks.slice(0, 10).map((f) => ({
|
|
141
|
+
name: f.name,
|
|
142
|
+
confidence: Math.round(f.confidence * 100),
|
|
143
|
+
})),
|
|
144
|
+
dependencies: context.dependencies.slice(0, 20).map((d) => ({
|
|
145
|
+
name: d.name,
|
|
146
|
+
is_dev: d.isDev,
|
|
147
|
+
})),
|
|
148
|
+
stats: {
|
|
149
|
+
total_files: context.stats.totalFiles,
|
|
150
|
+
total_lines: context.stats.totalLines,
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
: null,
|
|
154
|
+
meta: {
|
|
155
|
+
candidates_considered: response.candidates_considered,
|
|
156
|
+
overlap_filtered: response.overlap_filtered,
|
|
157
|
+
role_filtered: response.role_filtered,
|
|
158
|
+
role_filter: response.context.role_filter ?? null,
|
|
159
|
+
installed_count: response.context.installed_count,
|
|
160
|
+
auto_detected: response.context.auto_detected,
|
|
161
|
+
timing_ms: response.timing.totalMs,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
return JSON.stringify(output, null, 2);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Format offline analysis results (SMI-1355)
|
|
168
|
+
*/
|
|
169
|
+
export function formatOfflineResults(context, json) {
|
|
170
|
+
if (json) {
|
|
171
|
+
return JSON.stringify({
|
|
172
|
+
offline: true,
|
|
173
|
+
analysis: {
|
|
174
|
+
frameworks: context.frameworks.slice(0, 10).map((f) => ({
|
|
175
|
+
name: f.name,
|
|
176
|
+
confidence: Math.round(f.confidence * 100),
|
|
177
|
+
})),
|
|
178
|
+
dependencies: context.dependencies.slice(0, 20).map((d) => ({
|
|
179
|
+
name: d.name,
|
|
180
|
+
is_dev: d.isDev,
|
|
181
|
+
})),
|
|
182
|
+
stats: {
|
|
183
|
+
total_files: context.stats.totalFiles,
|
|
184
|
+
total_lines: context.stats.totalLines,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
message: 'Unable to reach Skillsmith API. Showing analysis-only results.',
|
|
188
|
+
}, null, 2);
|
|
189
|
+
}
|
|
190
|
+
const lines = [];
|
|
191
|
+
lines.push('');
|
|
192
|
+
lines.push(chalk.yellow('⚠ Unable to reach Skillsmith API. Showing analysis-only results.'));
|
|
193
|
+
lines.push('');
|
|
194
|
+
lines.push(chalk.bold.blue('=== Codebase Analysis ==='));
|
|
195
|
+
lines.push('');
|
|
196
|
+
if (context.frameworks.length > 0) {
|
|
197
|
+
lines.push(chalk.bold('Detected Frameworks:'));
|
|
198
|
+
context.frameworks.slice(0, 5).forEach((f) => {
|
|
199
|
+
lines.push(` - ${f.name} (${Math.round(f.confidence * 100)}% confidence)`);
|
|
200
|
+
});
|
|
201
|
+
lines.push('');
|
|
202
|
+
}
|
|
203
|
+
if (context.dependencies.length > 0) {
|
|
204
|
+
const prodDeps = context.dependencies.filter((d) => !d.isDev).slice(0, 10);
|
|
205
|
+
if (prodDeps.length > 0) {
|
|
206
|
+
lines.push(chalk.bold('Key Dependencies:'));
|
|
207
|
+
prodDeps.forEach((d) => lines.push(` - ${d.name}`));
|
|
208
|
+
lines.push('');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
lines.push(chalk.dim('---'));
|
|
212
|
+
lines.push(chalk.dim(`Files analyzed: ${context.stats.totalFiles}`));
|
|
213
|
+
lines.push(chalk.dim(`Total lines: ${context.stats.totalLines.toLocaleString()}`));
|
|
214
|
+
lines.push('');
|
|
215
|
+
lines.push(chalk.cyan('To get skill recommendations, ensure network connectivity and retry.'));
|
|
216
|
+
return lines.join('\n');
|
|
217
|
+
}
|
|
218
|
+
// ============================================================================
|
|
219
|
+
// Stack Building
|
|
220
|
+
// ============================================================================
|
|
221
|
+
/**
|
|
222
|
+
* Build stack from codebase analysis
|
|
223
|
+
*/
|
|
224
|
+
export function buildStackFromAnalysis(context) {
|
|
225
|
+
const stack = [];
|
|
226
|
+
for (const fw of context.frameworks.slice(0, 5)) {
|
|
227
|
+
stack.push(fw.name.toLowerCase());
|
|
228
|
+
}
|
|
229
|
+
for (const dep of context.dependencies.slice(0, 10)) {
|
|
230
|
+
if (!dep.isDev) {
|
|
231
|
+
stack.push(dep.name.toLowerCase());
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return [...new Set(stack)].slice(0, 10);
|
|
235
|
+
}
|
|
236
|
+
// ============================================================================
|
|
237
|
+
// Installed Skills Detection
|
|
238
|
+
// ============================================================================
|
|
239
|
+
/**
|
|
240
|
+
* Read installed skills from ~/.claude/skills/ directory (SMI-1358)
|
|
241
|
+
*/
|
|
242
|
+
export 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
|
+
const skill = {
|
|
256
|
+
name: entry.toLowerCase(),
|
|
257
|
+
directory: entry,
|
|
258
|
+
tags: [],
|
|
259
|
+
category: null,
|
|
260
|
+
};
|
|
261
|
+
const skillMdPath = join(skillPath, 'SKILL.md');
|
|
262
|
+
if (existsSync(skillMdPath)) {
|
|
263
|
+
try {
|
|
264
|
+
const content = readFileSync(skillMdPath, 'utf-8');
|
|
265
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
266
|
+
const frontmatter = frontmatterMatch?.[1];
|
|
267
|
+
if (frontmatter) {
|
|
268
|
+
const tagsMatch = frontmatter.match(/tags:\s*\[(.*?)\]/);
|
|
269
|
+
const tagsContent = tagsMatch?.[1];
|
|
270
|
+
if (tagsContent) {
|
|
271
|
+
skill.tags = tagsContent
|
|
272
|
+
.split(',')
|
|
273
|
+
.map((t) => t.trim().replace(/['"]/g, '').toLowerCase())
|
|
274
|
+
.filter(Boolean);
|
|
275
|
+
}
|
|
276
|
+
const categoryMatch = frontmatter.match(/category:\s*["']?([^"'\n]+)["']?/);
|
|
277
|
+
const categoryContent = categoryMatch?.[1];
|
|
278
|
+
if (categoryContent) {
|
|
279
|
+
skill.category = categoryContent.trim().toLowerCase();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
catch {
|
|
284
|
+
// Ignore read errors
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
installedSkills.push(skill);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
return [];
|
|
292
|
+
}
|
|
293
|
+
return installedSkills;
|
|
294
|
+
}
|
|
295
|
+
// ============================================================================
|
|
296
|
+
// Role Inference
|
|
297
|
+
// ============================================================================
|
|
298
|
+
/**
|
|
299
|
+
* SMI-1631: Infer skill roles from tags when not explicitly set
|
|
300
|
+
*/
|
|
301
|
+
export function inferRolesFromTags(tags) {
|
|
302
|
+
const roleMapping = {
|
|
303
|
+
lint: 'code-quality',
|
|
304
|
+
linting: 'code-quality',
|
|
305
|
+
format: 'code-quality',
|
|
306
|
+
formatting: 'code-quality',
|
|
307
|
+
prettier: 'code-quality',
|
|
308
|
+
eslint: 'code-quality',
|
|
309
|
+
'code-review': 'code-quality',
|
|
310
|
+
review: 'code-quality',
|
|
311
|
+
refactor: 'code-quality',
|
|
312
|
+
refactoring: 'code-quality',
|
|
313
|
+
'code-style': 'code-quality',
|
|
314
|
+
test: 'testing',
|
|
315
|
+
testing: 'testing',
|
|
316
|
+
jest: 'testing',
|
|
317
|
+
vitest: 'testing',
|
|
318
|
+
mocha: 'testing',
|
|
319
|
+
playwright: 'testing',
|
|
320
|
+
cypress: 'testing',
|
|
321
|
+
e2e: 'testing',
|
|
322
|
+
unit: 'testing',
|
|
323
|
+
integration: 'testing',
|
|
324
|
+
tdd: 'testing',
|
|
325
|
+
docs: 'documentation',
|
|
326
|
+
documentation: 'documentation',
|
|
327
|
+
readme: 'documentation',
|
|
328
|
+
jsdoc: 'documentation',
|
|
329
|
+
typedoc: 'documentation',
|
|
330
|
+
changelog: 'documentation',
|
|
331
|
+
api: 'documentation',
|
|
332
|
+
git: 'workflow',
|
|
333
|
+
commit: 'workflow',
|
|
334
|
+
pr: 'workflow',
|
|
335
|
+
'pull-request': 'workflow',
|
|
336
|
+
ci: 'workflow',
|
|
337
|
+
cd: 'workflow',
|
|
338
|
+
'ci-cd': 'workflow',
|
|
339
|
+
deploy: 'workflow',
|
|
340
|
+
deployment: 'workflow',
|
|
341
|
+
automation: 'workflow',
|
|
342
|
+
workflow: 'workflow',
|
|
343
|
+
security: 'security',
|
|
344
|
+
audit: 'security',
|
|
345
|
+
vulnerability: 'security',
|
|
346
|
+
cve: 'security',
|
|
347
|
+
secrets: 'security',
|
|
348
|
+
authentication: 'security',
|
|
349
|
+
auth: 'security',
|
|
350
|
+
ai: 'development-partner',
|
|
351
|
+
assistant: 'development-partner',
|
|
352
|
+
helper: 'development-partner',
|
|
353
|
+
copilot: 'development-partner',
|
|
354
|
+
productivity: 'development-partner',
|
|
355
|
+
scaffold: 'development-partner',
|
|
356
|
+
generator: 'development-partner',
|
|
357
|
+
};
|
|
358
|
+
const inferredRoles = new Set();
|
|
359
|
+
for (const tag of tags) {
|
|
360
|
+
const normalizedTag = tag.toLowerCase().replace(/[-_]/g, '');
|
|
361
|
+
for (const [keyword, role] of Object.entries(roleMapping)) {
|
|
362
|
+
if (normalizedTag.includes(keyword.replace(/[-_]/g, ''))) {
|
|
363
|
+
inferredRoles.add(role);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return [...inferredRoles];
|
|
368
|
+
}
|
|
369
|
+
// ============================================================================
|
|
370
|
+
// Overlap Detection
|
|
371
|
+
// ============================================================================
|
|
372
|
+
/**
|
|
373
|
+
* Normalize a skill name for comparison (SMI-1358)
|
|
374
|
+
*/
|
|
375
|
+
export function normalizeSkillName(name) {
|
|
376
|
+
return name
|
|
377
|
+
.toLowerCase()
|
|
378
|
+
.replace(/[-_]/g, '')
|
|
379
|
+
.replace(/^skill/, '')
|
|
380
|
+
.replace(/skill$/, '')
|
|
381
|
+
.replace(/^helper/, '')
|
|
382
|
+
.replace(/helper$/, '')
|
|
383
|
+
.trim();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Check if two skills overlap in functionality (SMI-1358)
|
|
387
|
+
*/
|
|
388
|
+
export function skillsOverlap(installed, recommended) {
|
|
389
|
+
const installedName = normalizeSkillName(installed.name);
|
|
390
|
+
const recommendedName = normalizeSkillName(recommended.name);
|
|
391
|
+
const recommendedId = recommended.skill_id.toLowerCase();
|
|
392
|
+
if (installedName === recommendedName)
|
|
393
|
+
return true;
|
|
394
|
+
if (recommendedId.includes(installed.name))
|
|
395
|
+
return true;
|
|
396
|
+
if (installedName.includes(recommendedName) || recommendedName.includes(installedName)) {
|
|
397
|
+
if (installedName.length >= 4 && recommendedName.length >= 4)
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
if (installed.tags.length > 0) {
|
|
401
|
+
const recommendedNameParts = recommended.name.toLowerCase().split(/[-_\s]+/);
|
|
402
|
+
const hasTagOverlap = installed.tags.some((tag) => recommendedNameParts.includes(tag) || recommendedName.includes(tag));
|
|
403
|
+
if (hasTagOverlap)
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Filter recommendations to remove overlaps with installed skills (SMI-1358)
|
|
410
|
+
*/
|
|
411
|
+
export function filterOverlappingSkills(recommendations, installedSkills) {
|
|
412
|
+
if (installedSkills.length === 0) {
|
|
413
|
+
return { filtered: recommendations, overlapCount: 0 };
|
|
414
|
+
}
|
|
415
|
+
const filtered = [];
|
|
416
|
+
let overlapCount = 0;
|
|
417
|
+
for (const rec of recommendations) {
|
|
418
|
+
const hasOverlap = installedSkills.some((installed) => skillsOverlap(installed, rec));
|
|
419
|
+
if (hasOverlap) {
|
|
420
|
+
overlapCount++;
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
filtered.push(rec);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return { filtered, overlapCount };
|
|
427
|
+
}
|
|
428
|
+
//# sourceMappingURL=recommend.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommend.helpers.js","sourceRoot":"","sources":["../../../src/commands/recommend.helpers.ts"],"names":[],"mappings":"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"}
|