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,72 @@
1
+ /**
2
+ * Tool: search_registry
3
+ *
4
+ * Searches the skill registry only (no local search).
5
+ */
6
+ import { getRegistryClient, successResult, errorResult, validateString, validateLimit } from './utils.js';
7
+ import { RegistryUnavailableError } from '../types.js';
8
+ export function createSearchRegistryHandler() {
9
+ return {
10
+ name: 'search_registry',
11
+ description: 'Search the skill registry for available skills. Returns skills from the remote registry only.',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ query: {
16
+ type: 'string',
17
+ description: 'Search query to find skills',
18
+ },
19
+ limit: {
20
+ type: 'number',
21
+ default: 20,
22
+ description: 'Maximum number of results (1-100)',
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 limit = validateLimit(input.limit, 20, 100);
32
+ const client = getRegistryClient();
33
+ // Check if registry is reachable
34
+ const isReachable = await client.ping();
35
+ if (!isReachable) {
36
+ throw new RegistryUnavailableError();
37
+ }
38
+ const searchResult = await client.search(query, { limit });
39
+ const output = {
40
+ results: searchResult.results.map((skill) => ({
41
+ name: skill.name,
42
+ description: skill.description,
43
+ version: skill.version,
44
+ author: skill.author || 'Unknown',
45
+ downloads: skill.downloads || 0,
46
+ })),
47
+ total: searchResult.total,
48
+ };
49
+ // Format output
50
+ if (output.results.length === 0) {
51
+ return successResult(`No skills found in registry for "${query}".`);
52
+ }
53
+ let text = `Registry search for "${query}" (${output.total} results):\n\n`;
54
+ for (const skill of output.results) {
55
+ text += `• ${skill.name} v${skill.version}\n`;
56
+ text += ` ${skill.description}\n`;
57
+ text += ` Author: ${skill.author} | Downloads: ${skill.downloads}\n\n`;
58
+ }
59
+ text += `\nTo install: use install_skill with the skill name.`;
60
+ return successResult(text.trim());
61
+ }
62
+ catch (error) {
63
+ if (error instanceof RegistryUnavailableError) {
64
+ return errorResult('Registry is currently unavailable.', 'Try again later or use list_skills to see locally installed skills.');
65
+ }
66
+ const message = error instanceof Error ? error.message : String(error);
67
+ return errorResult(`Registry search failed: ${message}`);
68
+ }
69
+ },
70
+ };
71
+ }
72
+ //# sourceMappingURL=search-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-registry.js","sourceRoot":"","sources":["../../src/tools/search-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: search_skills
3
+ *
4
+ * Searches for skills in local store and/or registry.
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createSearchSkillsHandler(): ToolHandler;
8
+ //# sourceMappingURL=search-skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-skills.d.ts","sourceRoot":"","sources":["../../src/tools/search-skills.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,WAAW,EAKZ,MAAM,aAAa,CAAC;AAYrB,wBAAgB,yBAAyB,IAAI,WAAW,CAqLvD"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Tool: search_skills
3
+ *
4
+ * Searches for skills in local store and/or registry.
5
+ */
6
+ import { getStore, getRegistryClient, successResult, errorResult, validateString, validateLimit, calculateRelevanceScore, } from './utils.js';
7
+ export function createSearchSkillsHandler() {
8
+ return {
9
+ name: 'search_skills',
10
+ description: 'Search for skills by keyword. Searches both installed skills and the registry, returning results sorted by relevance.',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ query: {
15
+ type: 'string',
16
+ description: 'Search query (matches name, description, and tags)',
17
+ },
18
+ source: {
19
+ type: 'string',
20
+ enum: ['all', 'local', 'registry'],
21
+ default: 'all',
22
+ description: 'Where to search: all, local (installed only), or registry (remote only)',
23
+ },
24
+ limit: {
25
+ type: 'number',
26
+ default: 20,
27
+ description: 'Maximum number of results to return (1-100)',
28
+ },
29
+ },
30
+ required: ['query'],
31
+ },
32
+ async execute(args) {
33
+ const input = args;
34
+ try {
35
+ const query = validateString(input.query, 'query');
36
+ const source = input.source || 'all';
37
+ const limit = validateLimit(input.limit, 20, 100);
38
+ const results = [];
39
+ const installedNames = new Set();
40
+ // Search local stores
41
+ if (source === 'all' || source === 'local') {
42
+ const scopes = ['local', 'global'];
43
+ for (const scope of scopes) {
44
+ const store = getStore(scope);
45
+ if (!(await store.isInitialized())) {
46
+ continue;
47
+ }
48
+ const skills = await store.listSkills();
49
+ const queryLower = query.toLowerCase();
50
+ for (const skill of skills) {
51
+ // Simple text matching
52
+ const nameMatch = skill.name.toLowerCase().includes(queryLower);
53
+ const descMatch = skill.description.toLowerCase().includes(queryLower);
54
+ if (nameMatch || descMatch) {
55
+ installedNames.add(skill.name);
56
+ results.push({
57
+ id: `${scope}:${skill.name}`,
58
+ name: skill.name,
59
+ description: skill.description,
60
+ version: skill.version,
61
+ source: 'local',
62
+ installed: true,
63
+ rating: 0, // Local skills don't have ratings
64
+ downloads: 0,
65
+ updatedAt: skill.installedAt,
66
+ tags: [],
67
+ relevanceScore: calculateRelevanceScore({
68
+ name: skill.name,
69
+ description: skill.description,
70
+ updatedAt: skill.installedAt,
71
+ }, query),
72
+ });
73
+ }
74
+ }
75
+ }
76
+ }
77
+ // Search registry
78
+ if (source === 'all' || source === 'registry') {
79
+ try {
80
+ const client = getRegistryClient();
81
+ const searchResult = await client.search(query, { limit });
82
+ for (const skill of searchResult.results) {
83
+ const isInstalled = installedNames.has(skill.name);
84
+ // Skip if already in results from local
85
+ if (isInstalled && source === 'all') {
86
+ // Update existing entry with registry metadata
87
+ const existing = results.find((r) => r.name === skill.name);
88
+ if (existing) {
89
+ existing.downloads = skill.downloads || 0;
90
+ existing.tags = skill.keywords || [];
91
+ }
92
+ continue;
93
+ }
94
+ results.push({
95
+ id: `registry:${skill.name}`,
96
+ name: skill.name,
97
+ description: skill.description,
98
+ version: skill.version,
99
+ source: 'registry',
100
+ installed: isInstalled,
101
+ rating: 0, // Registry doesn't have ratings yet
102
+ downloads: skill.downloads || 0,
103
+ updatedAt: skill.updatedAt || new Date().toISOString(),
104
+ tags: skill.keywords || [],
105
+ relevanceScore: calculateRelevanceScore({
106
+ name: skill.name,
107
+ description: skill.description,
108
+ downloads: skill.downloads,
109
+ updatedAt: skill.updatedAt,
110
+ tags: skill.keywords,
111
+ }, query),
112
+ });
113
+ }
114
+ }
115
+ catch {
116
+ // Registry might be unavailable, continue with local results
117
+ if (source === 'registry') {
118
+ return errorResult('Registry is currently unavailable.', 'Try searching with source: "local" to see installed skills.');
119
+ }
120
+ }
121
+ }
122
+ // Sort by relevance score (descending)
123
+ results.sort((a, b) => b.relevanceScore - a.relevanceScore);
124
+ // Apply limit
125
+ const limitedResults = results.slice(0, limit);
126
+ const output = {
127
+ results: limitedResults,
128
+ total: results.length,
129
+ query,
130
+ };
131
+ // Format output
132
+ if (limitedResults.length === 0) {
133
+ return successResult(`No skills found for "${query}".`);
134
+ }
135
+ let text = `Found ${output.total} skill(s) for "${query}":\n\n`;
136
+ for (const skill of limitedResults) {
137
+ const installed = skill.installed ? ' [installed]' : '';
138
+ const rating = skill.rating > 0 ? ` ⭐${skill.rating.toFixed(1)}` : '';
139
+ const downloads = skill.downloads > 0 ? ` 📥${skill.downloads}` : '';
140
+ text += `• ${skill.name} v${skill.version}${installed}${rating}${downloads}\n`;
141
+ text += ` ${skill.description}\n`;
142
+ if (skill.tags.length > 0) {
143
+ text += ` Tags: ${skill.tags.join(', ')}\n`;
144
+ }
145
+ text += '\n';
146
+ }
147
+ if (output.total > limit) {
148
+ text += `Showing ${limit} of ${output.total} results.`;
149
+ }
150
+ return successResult(text.trim());
151
+ }
152
+ catch (error) {
153
+ const message = error instanceof Error ? error.message : String(error);
154
+ return errorResult(`Search failed: ${message}`);
155
+ }
156
+ },
157
+ };
158
+ }
159
+ //# sourceMappingURL=search-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-skills.js","sourceRoot":"","sources":["../../src/tools/search-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: skill_info
3
+ *
4
+ * Gets detailed information about a skill from the registry.
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createSkillInfoHandler(): ToolHandler;
8
+ //# sourceMappingURL=skill-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-info.d.ts","sourceRoot":"","sources":["../../src/tools/skill-info.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAuD,MAAM,aAAa,CAAC;AAIpG,wBAAgB,sBAAsB,IAAI,WAAW,CAwFpD"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Tool: skill_info
3
+ *
4
+ * Gets detailed information about a skill from the registry.
5
+ */
6
+ import { getRegistryClient, successResult, errorResult, validateString } from './utils.js';
7
+ import { SkillNotFoundError } from '../types.js';
8
+ export function createSkillInfoHandler() {
9
+ return {
10
+ name: 'skill_info',
11
+ description: 'Get detailed information about a skill from the registry, including versions, readme, and metadata.',
12
+ inputSchema: {
13
+ type: 'object',
14
+ properties: {
15
+ name: {
16
+ type: 'string',
17
+ description: 'Name of the skill to get information about',
18
+ },
19
+ },
20
+ required: ['name'],
21
+ },
22
+ async execute(args) {
23
+ const input = args;
24
+ try {
25
+ const skillName = validateString(input.name, 'name');
26
+ const client = getRegistryClient();
27
+ let skillInfo;
28
+ try {
29
+ skillInfo = await client.getSkillInfo(skillName);
30
+ }
31
+ catch (error) {
32
+ const message = error instanceof Error ? error.message : '';
33
+ if (message.includes('404') || message.includes('not found')) {
34
+ throw new SkillNotFoundError(skillName);
35
+ }
36
+ throw error;
37
+ }
38
+ const author = typeof skillInfo.author === 'string'
39
+ ? { name: skillInfo.author }
40
+ : skillInfo.author || { name: 'Unknown' };
41
+ const output = {
42
+ name: skillInfo.name,
43
+ description: skillInfo.description,
44
+ version: skillInfo.version,
45
+ author,
46
+ repository: skillInfo.repository,
47
+ license: skillInfo.license,
48
+ tags: skillInfo.keywords,
49
+ };
50
+ // Format detailed output
51
+ let text = `# ${output.name}\n\n`;
52
+ text += `**Version:** ${output.version}\n`;
53
+ text += `**Author:** ${output.author.name}`;
54
+ if (output.author.email)
55
+ text += ` <${output.author.email}>`;
56
+ if (output.author.url)
57
+ text += ` (${output.author.url})`;
58
+ text += '\n';
59
+ if (output.license) {
60
+ text += `**License:** ${output.license}\n`;
61
+ }
62
+ if (output.repository) {
63
+ text += `**Repository:** ${output.repository}\n`;
64
+ }
65
+ if (output.tags && output.tags.length > 0) {
66
+ text += `**Tags:** ${output.tags.join(', ')}\n`;
67
+ }
68
+ text += '\n---\n\n';
69
+ text += `${output.description}\n`;
70
+ text += `\n\n---\n\nTo install: install_skill source: "${skillName}"`;
71
+ return successResult(text);
72
+ }
73
+ catch (error) {
74
+ if (error instanceof SkillNotFoundError) {
75
+ return errorResult(`Skill "${input.name}" not found in registry.`, 'Use search_registry to find available skills.');
76
+ }
77
+ const message = error instanceof Error ? error.message : String(error);
78
+ return errorResult(`Failed to get skill info: ${message}`);
79
+ }
80
+ },
81
+ };
82
+ }
83
+ //# sourceMappingURL=skill-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-info.js","sourceRoot":"","sources":["../../src/tools/skill-info.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tool: uninstall_skill
3
+ *
4
+ * Removes an installed skill.
5
+ */
6
+ import type { ToolHandler } from '../types.js';
7
+ export declare function createUninstallSkillHandler(): ToolHandler;
8
+ //# sourceMappingURL=uninstall-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall-skill.d.ts","sourceRoot":"","sources":["../../src/tools/uninstall-skill.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAyD,MAAM,aAAa,CAAC;AAGtG,wBAAgB,2BAA2B,IAAI,WAAW,CAkEzD"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Tool: uninstall_skill
3
+ *
4
+ * Removes an installed skill.
5
+ */
6
+ import { getStore, successResult, errorResult, validateString, validateScope } from './utils.js';
7
+ export function createUninstallSkillHandler() {
8
+ return {
9
+ name: 'uninstall_skill',
10
+ description: 'Uninstall a skill by name. Removes it from the specified scope.',
11
+ inputSchema: {
12
+ type: 'object',
13
+ properties: {
14
+ id: {
15
+ type: 'string',
16
+ description: 'Name of the skill to uninstall',
17
+ },
18
+ scope: {
19
+ type: 'string',
20
+ enum: ['local', 'global'],
21
+ default: 'local',
22
+ description: 'Scope to uninstall from: local (project) or global (~/.skillpkg)',
23
+ },
24
+ },
25
+ required: ['id'],
26
+ },
27
+ async execute(args) {
28
+ const input = args;
29
+ try {
30
+ const skillName = validateString(input.id, 'id');
31
+ const scope = validateScope(input.scope, 'local');
32
+ const store = getStore(scope);
33
+ // Check if store is initialized
34
+ if (!(await store.isInitialized())) {
35
+ return errorResult(`No skills installed in ${scope} scope.`, 'Use list_skills to see installed skills.');
36
+ }
37
+ // Check if skill exists
38
+ const exists = await store.hasSkill(skillName);
39
+ if (!exists) {
40
+ return errorResult(`Skill "${skillName}" is not installed in ${scope} scope.`, 'Use list_skills to see installed skills.');
41
+ }
42
+ // Remove the skill
43
+ const removed = await store.removeSkill(skillName);
44
+ if (!removed) {
45
+ return errorResult(`Failed to uninstall skill "${skillName}".`);
46
+ }
47
+ const output = {
48
+ success: true,
49
+ message: `Successfully uninstalled "${skillName}" from ${scope} scope.`,
50
+ };
51
+ return successResult(output.message);
52
+ }
53
+ catch (error) {
54
+ const message = error instanceof Error ? error.message : String(error);
55
+ return errorResult(`Failed to uninstall skill: ${message}`);
56
+ }
57
+ },
58
+ };
59
+ }
60
+ //# sourceMappingURL=uninstall-skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall-skill.js","sourceRoot":"","sources":["../../src/tools/uninstall-skill.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjG,MAAM,UAAU,2BAA2B;IACzC,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,iEAAiE;QAC9E,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,EAAE,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gCAAgC;iBAC9C;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;oBACzB,OAAO,EAAE,OAAO;oBAChB,WAAW,EAAE,kEAAkE;iBAChF;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,CAAC;SACjB;QAED,KAAK,CAAC,OAAO,CAAC,IAAa;YACzB,MAAM,KAAK,GAAG,IAA2B,CAAC;YAE1C,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBACjD,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBAElD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAE9B,gCAAgC;gBAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC;oBACnC,OAAO,WAAW,CAChB,0BAA0B,KAAK,SAAS,EACxC,0CAA0C,CAC3C,CAAC;gBACJ,CAAC;gBAED,wBAAwB;gBACxB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,WAAW,CAChB,UAAU,SAAS,yBAAyB,KAAK,SAAS,EAC1D,0CAA0C,CAC3C,CAAC;gBACJ,CAAC;gBAED,mBAAmB;gBACnB,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;gBAEnD,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,WAAW,CAAC,8BAA8B,SAAS,IAAI,CAAC,CAAC;gBAClE,CAAC;gBAED,MAAM,MAAM,GAAyB;oBACnC,OAAO,EAAE,IAAI;oBACb,OAAO,EAAE,6BAA6B,SAAS,UAAU,KAAK,SAAS;iBACxE,CAAC;gBAEF,OAAO,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,OAAO,WAAW,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Tool utilities - shared helpers for tool handlers
3
+ */
4
+ import { type StoreManager, type RegistryClient } from 'skillpkg-core';
5
+ import type { ToolResult, Scope } from '../types.js';
6
+ /**
7
+ * Get the appropriate store based on scope
8
+ */
9
+ export declare function getStore(scope: Scope, projectPath?: string): StoreManager;
10
+ /**
11
+ * Get registry client
12
+ */
13
+ export declare function getRegistryClient(): RegistryClient;
14
+ /**
15
+ * Create a success result
16
+ */
17
+ export declare function successResult(data: unknown): ToolResult;
18
+ /**
19
+ * Create an error result
20
+ */
21
+ export declare function errorResult(message: string, suggestion?: string): ToolResult;
22
+ /**
23
+ * Validate required string parameter
24
+ */
25
+ export declare function validateString(value: unknown, name: string): string;
26
+ /**
27
+ * Validate optional string parameter
28
+ */
29
+ export declare function validateOptionalString(value: unknown): string | undefined;
30
+ /**
31
+ * Validate scope parameter
32
+ */
33
+ export declare function validateScope(value: unknown, defaultValue?: Scope): Scope;
34
+ /**
35
+ * Validate limit parameter
36
+ */
37
+ export declare function validateLimit(value: unknown, defaultValue?: number, max?: number): number;
38
+ /**
39
+ * Calculate text match score (0-1)
40
+ */
41
+ export declare function calculateTextMatch(_text: string, query: string, fields: {
42
+ name?: string;
43
+ description?: string;
44
+ tags?: string[];
45
+ }): number;
46
+ /**
47
+ * Calculate relevance score for a skill
48
+ */
49
+ export declare function calculateRelevanceScore(skill: {
50
+ name: string;
51
+ description: string;
52
+ tags?: string[];
53
+ rating?: number;
54
+ downloads?: number;
55
+ updatedAt?: string;
56
+ }, query: string): number;
57
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAGL,KAAK,YAAY,EAEjB,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAErD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAKzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAKvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,UAAU,CAS5E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAKnE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQzE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,GAAE,KAAe,GAAG,KAAK,CAKlF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,SAAK,EAAE,GAAG,SAAM,GAAG,MAAM,CAKlF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/D,MAAM,CAyCR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,KAAK,EAAE,MAAM,GACZ,MAAM,CA2BR"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Tool utilities - shared helpers for tool handlers
3
+ */
4
+ import { createGlobalStore, createLocalStore, createRegistryClient, } from 'skillpkg-core';
5
+ /**
6
+ * Get the appropriate store based on scope
7
+ */
8
+ export function getStore(scope, projectPath) {
9
+ if (scope === 'global') {
10
+ return createGlobalStore();
11
+ }
12
+ return createLocalStore(projectPath);
13
+ }
14
+ /**
15
+ * Get registry client
16
+ */
17
+ export function getRegistryClient() {
18
+ // Use GitHub-based registry
19
+ return createRegistryClient({
20
+ registryUrl: 'https://raw.githubusercontent.com/skillpkg/registry/main',
21
+ });
22
+ }
23
+ /**
24
+ * Create a success result
25
+ */
26
+ export function successResult(data) {
27
+ const text = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
28
+ return {
29
+ content: [{ type: 'text', text }],
30
+ };
31
+ }
32
+ /**
33
+ * Create an error result
34
+ */
35
+ export function errorResult(message, suggestion) {
36
+ let text = `Error: ${message}`;
37
+ if (suggestion) {
38
+ text += `\n\nSuggestion: ${suggestion}`;
39
+ }
40
+ return {
41
+ content: [{ type: 'text', text }],
42
+ isError: true,
43
+ };
44
+ }
45
+ /**
46
+ * Validate required string parameter
47
+ */
48
+ export function validateString(value, name) {
49
+ if (typeof value !== 'string' || value.trim() === '') {
50
+ throw new Error(`${name} is required and must be a non-empty string`);
51
+ }
52
+ return value.trim();
53
+ }
54
+ /**
55
+ * Validate optional string parameter
56
+ */
57
+ export function validateOptionalString(value) {
58
+ if (value === undefined || value === null) {
59
+ return undefined;
60
+ }
61
+ if (typeof value !== 'string') {
62
+ return undefined;
63
+ }
64
+ return value.trim() || undefined;
65
+ }
66
+ /**
67
+ * Validate scope parameter
68
+ */
69
+ export function validateScope(value, defaultValue = 'local') {
70
+ if (value === 'local' || value === 'global') {
71
+ return value;
72
+ }
73
+ return defaultValue;
74
+ }
75
+ /**
76
+ * Validate limit parameter
77
+ */
78
+ export function validateLimit(value, defaultValue = 20, max = 100) {
79
+ if (typeof value === 'number' && value > 0) {
80
+ return Math.min(value, max);
81
+ }
82
+ return defaultValue;
83
+ }
84
+ /**
85
+ * Calculate text match score (0-1)
86
+ */
87
+ export function calculateTextMatch(_text, query, fields) {
88
+ const queryLower = query.toLowerCase();
89
+ const words = queryLower.split(/\s+/);
90
+ let score = 0;
91
+ let maxScore = 0;
92
+ // Name match (highest weight)
93
+ if (fields.name) {
94
+ maxScore += 3;
95
+ const nameLower = fields.name.toLowerCase();
96
+ if (nameLower === queryLower) {
97
+ score += 3; // Exact match
98
+ }
99
+ else if (nameLower.includes(queryLower)) {
100
+ score += 2; // Contains query
101
+ }
102
+ else if (words.some((w) => nameLower.includes(w))) {
103
+ score += 1; // Contains word
104
+ }
105
+ }
106
+ // Description match
107
+ if (fields.description) {
108
+ maxScore += 2;
109
+ const descLower = fields.description.toLowerCase();
110
+ if (descLower.includes(queryLower)) {
111
+ score += 2;
112
+ }
113
+ else if (words.some((w) => descLower.includes(w))) {
114
+ score += 1;
115
+ }
116
+ }
117
+ // Tags match
118
+ if (fields.tags && fields.tags.length > 0) {
119
+ maxScore += 1;
120
+ const tagsLower = fields.tags.map((t) => t.toLowerCase());
121
+ if (tagsLower.some((t) => t === queryLower || words.includes(t))) {
122
+ score += 1;
123
+ }
124
+ }
125
+ return maxScore > 0 ? score / maxScore : 0;
126
+ }
127
+ /**
128
+ * Calculate relevance score for a skill
129
+ */
130
+ export function calculateRelevanceScore(skill, query) {
131
+ // Text relevance (0-40)
132
+ const textRelevance = calculateTextMatch(query, query, {
133
+ name: skill.name,
134
+ description: skill.description,
135
+ tags: skill.tags,
136
+ }) * 40;
137
+ // Rating score (0-25)
138
+ const rating = skill.rating ?? 3;
139
+ const ratingScore = (rating / 5) * 25;
140
+ // Popularity score (0-20) - log scale
141
+ const downloads = skill.downloads ?? 0;
142
+ const popularityScore = Math.min(Math.log10(downloads + 1) / 4, 1) * 20;
143
+ // Freshness score (0-15) - decay over 180 days
144
+ let freshnessScore = 15;
145
+ if (skill.updatedAt) {
146
+ const daysSinceUpdate = Math.floor((Date.now() - new Date(skill.updatedAt).getTime()) / (1000 * 60 * 60 * 24));
147
+ freshnessScore = Math.max(0, 1 - daysSinceUpdate / 180) * 15;
148
+ }
149
+ return textRelevance + ratingScore + popularityScore + freshnessScore;
150
+ }
151
+ //# sourceMappingURL=utils.js.map