skillpkg-mcp-server 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 (58) hide show
  1. package/README.md +148 -0
  2. package/dist/cli.d.ts +10 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +40 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/index.d.ts +20 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +23 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/server.d.ts +55 -0
  11. package/dist/server.d.ts.map +1 -0
  12. package/dist/server.js +162 -0
  13. package/dist/server.js.map +1 -0
  14. package/dist/tools/index.d.ts +21 -0
  15. package/dist/tools/index.d.ts.map +1 -0
  16. package/dist/tools/index.js +35 -0
  17. package/dist/tools/index.js.map +1 -0
  18. package/dist/tools/install-skill.d.ts +8 -0
  19. package/dist/tools/install-skill.d.ts.map +1 -0
  20. package/dist/tools/install-skill.js +233 -0
  21. package/dist/tools/install-skill.js.map +1 -0
  22. package/dist/tools/list-skills.d.ts +8 -0
  23. package/dist/tools/list-skills.d.ts.map +1 -0
  24. package/dist/tools/list-skills.js +68 -0
  25. package/dist/tools/list-skills.js.map +1 -0
  26. package/dist/tools/load-skill.d.ts +8 -0
  27. package/dist/tools/load-skill.d.ts.map +1 -0
  28. package/dist/tools/load-skill.js +93 -0
  29. package/dist/tools/load-skill.js.map +1 -0
  30. package/dist/tools/recommend-skill.d.ts +8 -0
  31. package/dist/tools/recommend-skill.d.ts.map +1 -0
  32. package/dist/tools/recommend-skill.js +133 -0
  33. package/dist/tools/recommend-skill.js.map +1 -0
  34. package/dist/tools/search-registry.d.ts +8 -0
  35. package/dist/tools/search-registry.d.ts.map +1 -0
  36. package/dist/tools/search-registry.js +72 -0
  37. package/dist/tools/search-registry.js.map +1 -0
  38. package/dist/tools/search-skills.d.ts +8 -0
  39. package/dist/tools/search-skills.d.ts.map +1 -0
  40. package/dist/tools/search-skills.js +159 -0
  41. package/dist/tools/search-skills.js.map +1 -0
  42. package/dist/tools/skill-info.d.ts +8 -0
  43. package/dist/tools/skill-info.d.ts.map +1 -0
  44. package/dist/tools/skill-info.js +83 -0
  45. package/dist/tools/skill-info.js.map +1 -0
  46. package/dist/tools/uninstall-skill.d.ts +8 -0
  47. package/dist/tools/uninstall-skill.d.ts.map +1 -0
  48. package/dist/tools/uninstall-skill.js +60 -0
  49. package/dist/tools/uninstall-skill.js.map +1 -0
  50. package/dist/tools/utils.d.ts +57 -0
  51. package/dist/tools/utils.d.ts.map +1 -0
  52. package/dist/tools/utils.js +151 -0
  53. package/dist/tools/utils.js.map +1 -0
  54. package/dist/types.d.ts +182 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +33 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +63 -0
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Tool: install_skill
3
+ *
4
+ * Installs a skill from registry, GitHub, Gist, URL, or local path.
5
+ */
6
+ import { getStore, getRegistryClient, successResult, errorResult, validateString, validateScope } from './utils.js';
7
+ import { InvalidSourceError } from '../types.js';
8
+ import { parse as parseSkillYaml } from 'skillpkg-core';
9
+ /**
10
+ * Parse source string to determine source type
11
+ */
12
+ function parseSource(source) {
13
+ // GitHub: github:user/repo or user/repo
14
+ if (source.startsWith('github:')) {
15
+ return { type: 'github', value: source.slice(7) };
16
+ }
17
+ if (/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_.-]+$/.test(source)) {
18
+ return { type: 'github', value: source };
19
+ }
20
+ // Gist: gist:id
21
+ if (source.startsWith('gist:')) {
22
+ return { type: 'gist', value: source.slice(5) };
23
+ }
24
+ // URL: https:// or http://
25
+ if (source.startsWith('https://') || source.startsWith('http://')) {
26
+ return { type: 'url', value: source };
27
+ }
28
+ // Local path: starts with ./ or / or contains path separators
29
+ if (source.startsWith('./') || source.startsWith('/') || source.startsWith('../')) {
30
+ return { type: 'local', value: source };
31
+ }
32
+ // Registry: skill name (alphanumeric with hyphens)
33
+ if (/^[a-z][a-z0-9-]*$/.test(source)) {
34
+ return { type: 'registry', value: source };
35
+ }
36
+ throw new InvalidSourceError(source);
37
+ }
38
+ /**
39
+ * Fetch skill content from URL
40
+ */
41
+ async function fetchSkillFromUrl(url) {
42
+ const response = await fetch(url, { redirect: 'follow' });
43
+ if (!response.ok) {
44
+ throw new Error(`Failed to fetch from ${url}: ${response.status} ${response.statusText}`);
45
+ }
46
+ return response.text();
47
+ }
48
+ /**
49
+ * Fetch skill from GitHub repo (raw skill.yaml)
50
+ */
51
+ async function fetchSkillFromGitHub(repo) {
52
+ // Try common locations for skill.yaml
53
+ const paths = ['skill.yaml', 'skill.yml', '.claude/skill.yaml'];
54
+ const branches = ['main', 'master'];
55
+ for (const branch of branches) {
56
+ for (const path of paths) {
57
+ const url = `https://raw.githubusercontent.com/${repo}/${branch}/${path}`;
58
+ try {
59
+ const content = await fetchSkillFromUrl(url);
60
+ return content;
61
+ }
62
+ catch {
63
+ // Try next path/branch
64
+ }
65
+ }
66
+ }
67
+ throw new Error(`Could not find skill.yaml in repository ${repo}`);
68
+ }
69
+ /**
70
+ * Fetch skill from Gist
71
+ */
72
+ async function fetchSkillFromGist(gistId) {
73
+ const apiUrl = `https://api.github.com/gists/${gistId}`;
74
+ const response = await fetch(apiUrl);
75
+ if (!response.ok) {
76
+ throw new Error(`Failed to fetch gist ${gistId}: ${response.status}`);
77
+ }
78
+ const gist = (await response.json());
79
+ // Look for skill.yaml or skill.yml
80
+ for (const [filename, file] of Object.entries(gist.files)) {
81
+ if (filename === 'skill.yaml' || filename === 'skill.yml') {
82
+ return file.content;
83
+ }
84
+ }
85
+ throw new Error(`No skill.yaml found in gist ${gistId}`);
86
+ }
87
+ /**
88
+ * Fetch skill from local path
89
+ */
90
+ async function fetchSkillFromLocal(path) {
91
+ const fs = await import('fs/promises');
92
+ const nodePath = await import('path');
93
+ let skillPath = path;
94
+ const stat = await fs.stat(path);
95
+ if (stat.isDirectory()) {
96
+ // Look for skill.yaml in directory
97
+ const candidates = ['skill.yaml', 'skill.yml'];
98
+ for (const candidate of candidates) {
99
+ const fullPath = nodePath.join(path, candidate);
100
+ try {
101
+ await fs.access(fullPath);
102
+ skillPath = fullPath;
103
+ break;
104
+ }
105
+ catch {
106
+ // Try next
107
+ }
108
+ }
109
+ }
110
+ return fs.readFile(skillPath, 'utf-8');
111
+ }
112
+ export function createInstallSkillHandler() {
113
+ return {
114
+ name: 'install_skill',
115
+ description: `Install a skill from various sources.
116
+
117
+ Supported source formats:
118
+ • Registry: skill-name (e.g., "commit-helper")
119
+ • GitHub: github:user/repo or user/repo (e.g., "anthropics/claude-code-skills")
120
+ • Gist: gist:id (e.g., "gist:abc123")
121
+ • URL: https://... (direct link to skill.yaml)
122
+ • Local: ./path or /absolute/path (local file or directory)`,
123
+ inputSchema: {
124
+ type: 'object',
125
+ properties: {
126
+ source: {
127
+ type: 'string',
128
+ description: 'Source to install from: skill-name, github:user/repo, gist:id, URL, or local path',
129
+ },
130
+ scope: {
131
+ type: 'string',
132
+ enum: ['local', 'global'],
133
+ default: 'local',
134
+ description: 'Where to install: local (project) or global (~/.skillpkg)',
135
+ },
136
+ },
137
+ required: ['source'],
138
+ },
139
+ async execute(args) {
140
+ const input = args;
141
+ try {
142
+ const sourceStr = validateString(input.source, 'source');
143
+ const scope = validateScope(input.scope, 'local');
144
+ // Parse the source
145
+ const { type, value } = parseSource(sourceStr);
146
+ // Fetch skill content based on source type
147
+ let skillContent;
148
+ switch (type) {
149
+ case 'registry': {
150
+ // Download from registry
151
+ const client = getRegistryClient();
152
+ const info = await client.getSkillInfo(value);
153
+ // For now, fetch the skill.yaml URL if available
154
+ // In future, download tarball and extract
155
+ if (info.repository) {
156
+ skillContent = await fetchSkillFromGitHub(info.repository.replace('https://github.com/', ''));
157
+ }
158
+ else {
159
+ throw new Error(`Registry skill "${value}" does not have a repository URL`);
160
+ }
161
+ break;
162
+ }
163
+ case 'github':
164
+ skillContent = await fetchSkillFromGitHub(value);
165
+ break;
166
+ case 'gist':
167
+ skillContent = await fetchSkillFromGist(value);
168
+ break;
169
+ case 'url':
170
+ skillContent = await fetchSkillFromUrl(value);
171
+ break;
172
+ case 'local':
173
+ skillContent = await fetchSkillFromLocal(value);
174
+ break;
175
+ }
176
+ // Parse the skill content
177
+ const parseResult = parseSkillYaml(skillContent);
178
+ if (!parseResult.success || !parseResult.data) {
179
+ const errors = parseResult.errors?.map((e) => e.message).join(', ') || 'Unknown parse error';
180
+ return errorResult(`Invalid skill.yaml: ${errors}`);
181
+ }
182
+ const skill = parseResult.data;
183
+ // Get the store and initialize if needed
184
+ const store = getStore(scope);
185
+ if (!(await store.isInitialized())) {
186
+ await store.init();
187
+ }
188
+ // Check if already installed
189
+ if (await store.hasSkill(skill.name)) {
190
+ // Update instead of error
191
+ await store.updateSkill(skill.name, skill);
192
+ const output = {
193
+ success: true,
194
+ skill: {
195
+ id: `${scope}:${skill.name}`,
196
+ name: skill.name,
197
+ version: skill.version,
198
+ source: sourceStr,
199
+ installedAt: new Date().toISOString(),
200
+ },
201
+ message: `Updated "${skill.name}" to v${skill.version} in ${scope} scope.`,
202
+ };
203
+ return successResult(output.message);
204
+ }
205
+ // Add the skill
206
+ await store.addSkill(skill, {
207
+ source: type === 'local' ? 'local' : type === 'registry' ? 'registry' : 'import',
208
+ sourceUrl: sourceStr,
209
+ });
210
+ const output = {
211
+ success: true,
212
+ skill: {
213
+ id: `${scope}:${skill.name}`,
214
+ name: skill.name,
215
+ version: skill.version,
216
+ source: sourceStr,
217
+ installedAt: new Date().toISOString(),
218
+ },
219
+ message: `Successfully installed "${skill.name}" v${skill.version} to ${scope} scope.`,
220
+ };
221
+ return successResult(output.message);
222
+ }
223
+ catch (error) {
224
+ if (error instanceof InvalidSourceError) {
225
+ return errorResult(error.message);
226
+ }
227
+ const message = error instanceof Error ? error.message : String(error);
228
+ return errorResult(`Failed to install skill: ${message}`);
229
+ }
230
+ },
231
+ };
232
+ }
233
+ //# sourceMappingURL=install-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-skill.js","sourceRoot":"","sources":["../../src/tools/install-skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: list_skills
3
+ *
4
+ * Lists all installed skills in local or global scope.
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createListSkillsHandler(): ToolHandler;
8
+ //# sourceMappingURL=list-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-skills.d.ts","sourceRoot":"","sources":["../../src/tools/list-skills.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAwD,MAAM,aAAa,CAAC;AAGrG,wBAAgB,uBAAuB,IAAI,WAAW,CAwErD"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Tool: list_skills
3
+ *
4
+ * Lists all installed skills in local or global scope.
5
+ */
6
+ import { getStore, successResult, errorResult } from './utils.js';
7
+ export function createListSkillsHandler() {
8
+ return {
9
+ name: 'list_skills',
10
+ description: 'List all installed skills. Returns skill metadata including name, version, description, and installation date.',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ scope: {
15
+ type: 'string',
16
+ enum: ['local', 'global', 'all'],
17
+ default: 'all',
18
+ description: 'Scope to list skills from: local (project), global (~/.skillpkg), or all',
19
+ },
20
+ },
21
+ },
22
+ async execute(args) {
23
+ const input = args;
24
+ const scopeFilter = input.scope || 'all';
25
+ try {
26
+ const results = [];
27
+ // Get skills from requested scopes
28
+ const scopes = scopeFilter === 'all' ? ['local', 'global'] : [scopeFilter];
29
+ for (const scope of scopes) {
30
+ const store = getStore(scope);
31
+ // Initialize store if needed
32
+ if (!(await store.isInitialized())) {
33
+ continue;
34
+ }
35
+ const skills = await store.listSkills();
36
+ for (const skill of skills) {
37
+ results.push({
38
+ id: `${scope}:${skill.name}`,
39
+ name: skill.name,
40
+ description: skill.description,
41
+ version: skill.version,
42
+ scope,
43
+ installedAt: skill.installedAt,
44
+ });
45
+ }
46
+ }
47
+ // Sort by name
48
+ results.sort((a, b) => a.name.localeCompare(b.name));
49
+ // Format output
50
+ if (results.length === 0) {
51
+ return successResult('No skills installed. Use install_skill to add skills.');
52
+ }
53
+ let text = `Found ${results.length} installed skill(s):\n\n`;
54
+ for (const skill of results) {
55
+ text += `• ${skill.name} v${skill.version} [${skill.scope}]\n`;
56
+ text += ` ${skill.description}\n`;
57
+ text += ` Installed: ${new Date(skill.installedAt).toLocaleDateString()}\n\n`;
58
+ }
59
+ return successResult(text.trim());
60
+ }
61
+ catch (error) {
62
+ const message = error instanceof Error ? error.message : String(error);
63
+ return errorResult(`Failed to list skills: ${message}`);
64
+ }
65
+ },
66
+ };
67
+ }
68
+ //# sourceMappingURL=list-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-skills.js","sourceRoot":"","sources":["../../src/tools/list-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: load_skill
3
+ *
4
+ * Loads a skill's full content including instructions.
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createLoadSkillHandler(): ToolHandler;
8
+ //# sourceMappingURL=load-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-skill.d.ts","sourceRoot":"","sources":["../../src/tools/load-skill.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAsD,MAAM,aAAa,CAAC;AAInG,wBAAgB,sBAAsB,IAAI,WAAW,CAgGpD"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Tool: load_skill
3
+ *
4
+ * Loads a skill's full content including instructions.
5
+ */
6
+ import { getStore, successResult, errorResult, validateString } from './utils.js';
7
+ import { SkillNotInstalledError } from '../types.js';
8
+ export function createLoadSkillHandler() {
9
+ return {
10
+ name: 'load_skill',
11
+ description: 'Load a skill by ID and return its full content including instructions. The skill must be installed first.',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ id: {
16
+ type: 'string',
17
+ description: 'Skill ID in format "scope:name" (e.g., "local:commit-helper") or just "name" to search all scopes',
18
+ },
19
+ },
20
+ required: ['id'],
21
+ },
22
+ async execute(args) {
23
+ const input = args;
24
+ try {
25
+ const id = validateString(input.id, 'id');
26
+ // Parse scope from ID
27
+ let scope;
28
+ let skillName;
29
+ if (id.includes(':')) {
30
+ const [scopePart, namePart] = id.split(':', 2);
31
+ if (scopePart === 'local' || scopePart === 'global') {
32
+ scope = scopePart;
33
+ skillName = namePart;
34
+ }
35
+ else {
36
+ skillName = id;
37
+ }
38
+ }
39
+ else {
40
+ skillName = id;
41
+ }
42
+ // Search for the skill
43
+ const scopesToCheck = scope ? [scope] : ['local', 'global'];
44
+ let foundSkill = null;
45
+ let foundScope = null;
46
+ for (const s of scopesToCheck) {
47
+ const store = getStore(s);
48
+ if (!(await store.isInitialized())) {
49
+ continue;
50
+ }
51
+ const skill = await store.getSkill(skillName);
52
+ if (skill) {
53
+ foundSkill = skill;
54
+ foundScope = s;
55
+ break;
56
+ }
57
+ }
58
+ if (!foundSkill || !foundScope) {
59
+ throw new SkillNotInstalledError(skillName);
60
+ }
61
+ const output = {
62
+ id: `${foundScope}:${foundSkill.name}`,
63
+ name: foundSkill.name,
64
+ version: foundSkill.version,
65
+ description: foundSkill.description,
66
+ instructions: foundSkill.instructions,
67
+ author: typeof foundSkill.author === 'string'
68
+ ? { name: foundSkill.author }
69
+ : foundSkill.author,
70
+ };
71
+ // Format output with instructions
72
+ let text = `# ${output.name} v${output.version}\n\n`;
73
+ text += `${output.description}\n\n`;
74
+ if (output.author) {
75
+ text += `Author: ${output.author.name}`;
76
+ if (output.author.email)
77
+ text += ` <${output.author.email}>`;
78
+ text += '\n\n';
79
+ }
80
+ text += `---\n\n## Instructions\n\n${output.instructions}`;
81
+ return successResult(text);
82
+ }
83
+ catch (error) {
84
+ if (error instanceof SkillNotInstalledError) {
85
+ return errorResult(error.message, 'Use search_skills to find and install_skill to install it.');
86
+ }
87
+ const message = error instanceof Error ? error.message : String(error);
88
+ return errorResult(`Failed to load skill: ${message}`);
89
+ }
90
+ },
91
+ };
92
+ }
93
+ //# sourceMappingURL=load-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-skill.js","sourceRoot":"","sources":["../../src/tools/load-skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: recommend_skill
3
+ *
4
+ * Recommends the best skill for a given use case.
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createRecommendSkillHandler(): ToolHandler;
8
+ //# sourceMappingURL=recommend-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend-skill.d.ts","sourceRoot":"","sources":["../../src/tools/recommend-skill.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EAOZ,MAAM,aAAa,CAAC;AAGrB,wBAAgB,2BAA2B,IAAI,WAAW,CAuJzD"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Tool: recommend_skill
3
+ *
4
+ * Recommends the best skill for a given use case.
5
+ */
6
+ import { getRegistryClient, successResult, errorResult, validateString, calculateRelevanceScore } from './utils.js';
7
+ export function createRecommendSkillHandler() {
8
+ return {
9
+ name: 'recommend_skill',
10
+ description: 'Get a skill recommendation for a specific use case. Returns the best matching skill with reasoning and alternatives.',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ query: {
15
+ type: 'string',
16
+ description: 'Describe what you need (e.g., "help with git commits", "code review")',
17
+ },
18
+ criteria: {
19
+ type: 'string',
20
+ enum: ['auto', 'popular', 'highest_rated', 'newest'],
21
+ default: 'auto',
22
+ description: 'Recommendation criteria: auto (balanced), popular, highest_rated, or newest',
23
+ },
24
+ },
25
+ required: ['query'],
26
+ },
27
+ async execute(args) {
28
+ const input = args;
29
+ try {
30
+ const query = validateString(input.query, 'query');
31
+ const criteria = input.criteria || 'auto';
32
+ const client = getRegistryClient();
33
+ // Search for relevant skills
34
+ const searchResult = await client.search(query, { limit: 10 });
35
+ if (searchResult.results.length === 0) {
36
+ return successResult(`No skills found matching "${query}". Try a different search term or browse available skills with search_registry.`);
37
+ }
38
+ const scoredSkills = searchResult.results.map((skill) => {
39
+ let score = calculateRelevanceScore({
40
+ name: skill.name,
41
+ description: skill.description,
42
+ downloads: skill.downloads,
43
+ updatedAt: skill.updatedAt,
44
+ tags: skill.keywords,
45
+ }, query);
46
+ // Adjust score based on criteria
47
+ switch (criteria) {
48
+ case 'popular':
49
+ score = (skill.downloads || 0) / 1000 + score * 0.3;
50
+ break;
51
+ case 'highest_rated':
52
+ // Rating not available yet, use downloads as proxy
53
+ score = Math.log10((skill.downloads || 0) + 1) * 10 + score * 0.3;
54
+ break;
55
+ case 'newest':
56
+ if (skill.updatedAt) {
57
+ const daysSinceUpdate = Math.floor((Date.now() - new Date(skill.updatedAt).getTime()) / (1000 * 60 * 60 * 24));
58
+ score = Math.max(0, 100 - daysSinceUpdate) + score * 0.3;
59
+ }
60
+ break;
61
+ // 'auto' uses the default balanced scoring
62
+ }
63
+ return { skill, score };
64
+ });
65
+ scoredSkills.sort((a, b) => b.score - a.score);
66
+ // Get top recommendation
67
+ const topSkill = scoredSkills[0].skill;
68
+ const recommendation = {
69
+ id: topSkill.name,
70
+ name: topSkill.name,
71
+ description: topSkill.description,
72
+ version: topSkill.version,
73
+ rating: 0, // Not available yet
74
+ downloads: topSkill.downloads || 0,
75
+ updatedAt: topSkill.updatedAt || new Date().toISOString(),
76
+ author: topSkill.author || 'Unknown',
77
+ tags: topSkill.keywords || [],
78
+ };
79
+ // Get alternatives (next 3)
80
+ const alternatives = scoredSkills.slice(1, 4).map((item) => ({
81
+ name: item.skill.name,
82
+ description: item.skill.description,
83
+ rating: 0, // Not available yet
84
+ }));
85
+ // Generate reason based on criteria
86
+ let reason = `"${recommendation.name}" is recommended because `;
87
+ switch (criteria) {
88
+ case 'popular':
89
+ reason += `it's the most popular skill (${recommendation.downloads} downloads) that matches your needs.`;
90
+ break;
91
+ case 'highest_rated':
92
+ reason += `it has the highest rating (${recommendation.rating.toFixed(1)}⭐) among matching skills.`;
93
+ break;
94
+ case 'newest':
95
+ reason += `it was recently updated and matches your requirements.`;
96
+ break;
97
+ default:
98
+ reason += `it best matches "${query}" based on name, description, popularity, and rating.`;
99
+ }
100
+ const output = {
101
+ recommendation,
102
+ reason,
103
+ alternatives,
104
+ installCommand: `install_skill source: "${recommendation.name}"`,
105
+ };
106
+ // Format output
107
+ let text = `## Recommended Skill\n\n`;
108
+ text += `**${recommendation.name}** v${recommendation.version}\n`;
109
+ text += `${recommendation.description}\n\n`;
110
+ text += `⭐ ${recommendation.rating.toFixed(1)} | 📥 ${recommendation.downloads} downloads\n`;
111
+ text += `Author: ${recommendation.author}\n`;
112
+ if (recommendation.tags.length > 0) {
113
+ text += `Tags: ${recommendation.tags.join(', ')}\n`;
114
+ }
115
+ text += `\n**Why this skill?**\n${reason}\n`;
116
+ if (alternatives.length > 0) {
117
+ text += `\n## Alternatives\n\n`;
118
+ for (const alt of alternatives) {
119
+ text += `• **${alt.name}** (⭐${alt.rating.toFixed(1)})\n`;
120
+ text += ` ${alt.description}\n\n`;
121
+ }
122
+ }
123
+ text += `\n---\n\nTo install: ${output.installCommand}`;
124
+ return successResult(text);
125
+ }
126
+ catch (error) {
127
+ const message = error instanceof Error ? error.message : String(error);
128
+ return errorResult(`Recommendation failed: ${message}`);
129
+ }
130
+ },
131
+ };
132
+ }
133
+ //# sourceMappingURL=recommend-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend-skill.js","sourceRoot":"","sources":["../../src/tools/recommend-skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: search_registry
3
+ *
4
+ * Searches the skill registry only (no local search).
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createSearchRegistryHandler(): ToolHandler;
8
+ //# sourceMappingURL=search-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-registry.d.ts","sourceRoot":"","sources":["../../src/tools/search-registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAyD,MAAM,aAAa,CAAC;AAItG,wBAAgB,2BAA2B,IAAI,WAAW,CA6EzD"}