@skillsmith/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.
- package/dist/.tsbuildinfo +1 -0
- package/dist/src/__tests__/get-skill.test.d.ts +6 -0
- package/dist/src/__tests__/get-skill.test.d.ts.map +1 -0
- package/dist/src/__tests__/get-skill.test.js +88 -0
- package/dist/src/__tests__/get-skill.test.js.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts +7 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.js +304 -0
- package/dist/src/__tests__/middleware/errorFormatter.test.js.map +1 -0
- package/dist/src/__tests__/middleware/license.test.d.ts +7 -0
- package/dist/src/__tests__/middleware/license.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/license.test.js +500 -0
- package/dist/src/__tests__/middleware/license.test.js.map +1 -0
- package/dist/src/__tests__/search.test.d.ts +6 -0
- package/dist/src/__tests__/search.test.d.ts.map +1 -0
- package/dist/src/__tests__/search.test.js +86 -0
- package/dist/src/__tests__/search.test.js.map +1 -0
- package/dist/src/__tests__/test-utils.d.ts +19 -0
- package/dist/src/__tests__/test-utils.d.ts.map +1 -0
- package/dist/src/__tests__/test-utils.js +87 -0
- package/dist/src/__tests__/test-utils.js.map +1 -0
- package/dist/src/context/index.d.ts +19 -0
- package/dist/src/context/index.d.ts.map +1 -0
- package/dist/src/context/index.js +25 -0
- package/dist/src/context/index.js.map +1 -0
- package/dist/src/context/project-detector.d.ts +145 -0
- package/dist/src/context/project-detector.d.ts.map +1 -0
- package/dist/src/context/project-detector.js +321 -0
- package/dist/src/context/project-detector.js.map +1 -0
- package/dist/src/context.d.ts +100 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +157 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/core-shim.d.ts +7 -0
- package/dist/src/core-shim.d.ts.map +1 -0
- package/dist/src/core-shim.js +9 -0
- package/dist/src/core-shim.js.map +1 -0
- package/dist/src/health/healthCheck.d.ts +88 -0
- package/dist/src/health/healthCheck.d.ts.map +1 -0
- package/dist/src/health/healthCheck.js +117 -0
- package/dist/src/health/healthCheck.js.map +1 -0
- package/dist/src/health/index.d.ts +21 -0
- package/dist/src/health/index.d.ts.map +1 -0
- package/dist/src/health/index.js +21 -0
- package/dist/src/health/index.js.map +1 -0
- package/dist/src/health/readinessCheck.d.ts +139 -0
- package/dist/src/health/readinessCheck.d.ts.map +1 -0
- package/dist/src/health/readinessCheck.js +266 -0
- package/dist/src/health/readinessCheck.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +178 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/index.test.d.ts +2 -0
- package/dist/src/index.test.d.ts.map +1 -0
- package/dist/src/index.test.js +43 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/logger.d.ts +26 -0
- package/dist/src/logger.d.ts.map +1 -0
- package/dist/src/logger.js +179 -0
- package/dist/src/logger.js.map +1 -0
- package/dist/src/middleware/__tests__/csp.test.d.ts +2 -0
- package/dist/src/middleware/__tests__/csp.test.d.ts.map +1 -0
- package/dist/src/middleware/__tests__/csp.test.js +389 -0
- package/dist/src/middleware/__tests__/csp.test.js.map +1 -0
- package/dist/src/middleware/csp.d.ts +87 -0
- package/dist/src/middleware/csp.d.ts.map +1 -0
- package/dist/src/middleware/csp.js +273 -0
- package/dist/src/middleware/csp.js.map +1 -0
- package/dist/src/middleware/degradation.d.ts +99 -0
- package/dist/src/middleware/degradation.d.ts.map +1 -0
- package/dist/src/middleware/degradation.js +315 -0
- package/dist/src/middleware/degradation.js.map +1 -0
- package/dist/src/middleware/errorFormatter.d.ts +119 -0
- package/dist/src/middleware/errorFormatter.d.ts.map +1 -0
- package/dist/src/middleware/errorFormatter.js +294 -0
- package/dist/src/middleware/errorFormatter.js.map +1 -0
- package/dist/src/middleware/index.d.ts +10 -0
- package/dist/src/middleware/index.d.ts.map +1 -0
- package/dist/src/middleware/index.js +14 -0
- package/dist/src/middleware/index.js.map +1 -0
- package/dist/src/middleware/license.d.ts +161 -0
- package/dist/src/middleware/license.d.ts.map +1 -0
- package/dist/src/middleware/license.js +281 -0
- package/dist/src/middleware/license.js.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts +36 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.js +90 -0
- package/dist/src/middleware/toolFeatureMapping.js.map +1 -0
- package/dist/src/onboarding/first-run.d.ts +64 -0
- package/dist/src/onboarding/first-run.d.ts.map +1 -0
- package/dist/src/onboarding/first-run.js +77 -0
- package/dist/src/onboarding/first-run.js.map +1 -0
- package/dist/src/onboarding/index.d.ts +7 -0
- package/dist/src/onboarding/index.d.ts.map +1 -0
- package/dist/src/onboarding/index.js +7 -0
- package/dist/src/onboarding/index.js.map +1 -0
- package/dist/src/suggestions/index.d.ts +21 -0
- package/dist/src/suggestions/index.d.ts.map +1 -0
- package/dist/src/suggestions/index.js +20 -0
- package/dist/src/suggestions/index.js.map +1 -0
- package/dist/src/suggestions/suggestion-engine.d.ts +185 -0
- package/dist/src/suggestions/suggestion-engine.d.ts.map +1 -0
- package/dist/src/suggestions/suggestion-engine.js +352 -0
- package/dist/src/suggestions/suggestion-engine.js.map +1 -0
- package/dist/src/suggestions/types.d.ts +88 -0
- package/dist/src/suggestions/types.d.ts.map +1 -0
- package/dist/src/suggestions/types.js +21 -0
- package/dist/src/suggestions/types.js.map +1 -0
- package/dist/src/tools/analyze.d.ts +151 -0
- package/dist/src/tools/analyze.d.ts.map +1 -0
- package/dist/src/tools/analyze.js +205 -0
- package/dist/src/tools/analyze.js.map +1 -0
- package/dist/src/tools/compare.d.ts +149 -0
- package/dist/src/tools/compare.d.ts.map +1 -0
- package/dist/src/tools/compare.js +464 -0
- package/dist/src/tools/compare.js.map +1 -0
- package/dist/src/tools/get-skill.d.ts +116 -0
- package/dist/src/tools/get-skill.d.ts.map +1 -0
- package/dist/src/tools/get-skill.js +224 -0
- package/dist/src/tools/get-skill.js.map +1 -0
- package/dist/src/tools/index.d.ts +20 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +20 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/install.d.ts +122 -0
- package/dist/src/tools/install.d.ts.map +1 -0
- package/dist/src/tools/install.js +314 -0
- package/dist/src/tools/install.js.map +1 -0
- package/dist/src/tools/recommend.d.ts +171 -0
- package/dist/src/tools/recommend.d.ts.map +1 -0
- package/dist/src/tools/recommend.js +325 -0
- package/dist/src/tools/recommend.js.map +1 -0
- package/dist/src/tools/search.d.ts +121 -0
- package/dist/src/tools/search.d.ts.map +1 -0
- package/dist/src/tools/search.js +249 -0
- package/dist/src/tools/search.js.map +1 -0
- package/dist/src/tools/suggest.d.ts +181 -0
- package/dist/src/tools/suggest.d.ts.map +1 -0
- package/dist/src/tools/suggest.js +342 -0
- package/dist/src/tools/suggest.js.map +1 -0
- package/dist/src/tools/uninstall.d.ts +123 -0
- package/dist/src/tools/uninstall.d.ts.map +1 -0
- package/dist/src/tools/uninstall.js +250 -0
- package/dist/src/tools/uninstall.js.map +1 -0
- package/dist/src/tools/validate.d.ts +122 -0
- package/dist/src/tools/validate.d.ts.map +1 -0
- package/dist/src/tools/validate.js +497 -0
- package/dist/src/tools/validate.js.map +1 -0
- package/dist/src/utils/installed-skills.d.ts +101 -0
- package/dist/src/utils/installed-skills.d.ts.map +1 -0
- package/dist/src/utils/installed-skills.js +220 -0
- package/dist/src/utils/installed-skills.js.map +1 -0
- package/dist/src/utils/validation.d.ts +76 -0
- package/dist/src/utils/validation.d.ts.map +1 -0
- package/dist/src/utils/validation.js +153 -0
- package/dist/src/utils/validation.js.map +1 -0
- package/dist/src/webhooks/index.d.ts +8 -0
- package/dist/src/webhooks/index.d.ts.map +1 -0
- package/dist/src/webhooks/index.js +9 -0
- package/dist/src/webhooks/index.js.map +1 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts +149 -0
- package/dist/src/webhooks/webhook-endpoint.d.ts.map +1 -0
- package/dist/src/webhooks/webhook-endpoint.js +339 -0
- package/dist/src/webhooks/webhook-endpoint.js.map +1 -0
- package/dist/tests/compare.test.d.ts +6 -0
- package/dist/tests/compare.test.d.ts.map +1 -0
- package/dist/tests/compare.test.js +225 -0
- package/dist/tests/compare.test.js.map +1 -0
- package/dist/tests/context/project-detector.test.d.ts +6 -0
- package/dist/tests/context/project-detector.test.d.ts.map +1 -0
- package/dist/tests/context/project-detector.test.js +719 -0
- package/dist/tests/context/project-detector.test.js.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/compare.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/compare.e2e.test.js +286 -0
- package/dist/tests/e2e/compare.e2e.test.js.map +1 -0
- package/dist/tests/e2e/install-flow.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/install-flow.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/install-flow.e2e.test.js +209 -0
- package/dist/tests/e2e/install-flow.e2e.test.js.map +1 -0
- package/dist/tests/e2e/recommend.e2e.test.d.ts +12 -0
- package/dist/tests/e2e/recommend.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/recommend.e2e.test.js +347 -0
- package/dist/tests/e2e/recommend.e2e.test.js.map +1 -0
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts +10 -0
- package/dist/tests/e2e/skill-flow.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js +280 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -0
- package/dist/tests/e2e/suggest.e2e.test.d.ts +13 -0
- package/dist/tests/e2e/suggest.e2e.test.d.ts.map +1 -0
- package/dist/tests/e2e/suggest.e2e.test.js +347 -0
- package/dist/tests/e2e/suggest.e2e.test.js.map +1 -0
- package/dist/tests/e2e/utils/baseline-collector.d.ts +107 -0
- package/dist/tests/e2e/utils/baseline-collector.d.ts.map +1 -0
- package/dist/tests/e2e/utils/baseline-collector.js +211 -0
- package/dist/tests/e2e/utils/baseline-collector.js.map +1 -0
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts +46 -0
- package/dist/tests/e2e/utils/hardcoded-detector.d.ts.map +1 -0
- package/dist/tests/e2e/utils/hardcoded-detector.js +255 -0
- package/dist/tests/e2e/utils/hardcoded-detector.js.map +1 -0
- package/dist/tests/e2e/utils/index.d.ts +7 -0
- package/dist/tests/e2e/utils/index.d.ts.map +1 -0
- package/dist/tests/e2e/utils/index.js +7 -0
- package/dist/tests/e2e/utils/index.js.map +1 -0
- package/dist/tests/e2e/utils/linear-reporter.d.ts +60 -0
- package/dist/tests/e2e/utils/linear-reporter.d.ts.map +1 -0
- package/dist/tests/e2e/utils/linear-reporter.js +232 -0
- package/dist/tests/e2e/utils/linear-reporter.js.map +1 -0
- package/dist/tests/health.test.d.ts +9 -0
- package/dist/tests/health.test.d.ts.map +1 -0
- package/dist/tests/health.test.js +308 -0
- package/dist/tests/health.test.js.map +1 -0
- package/dist/tests/integration/analyze.integration.test.d.ts +2 -0
- package/dist/tests/integration/analyze.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/analyze.integration.test.js +244 -0
- package/dist/tests/integration/analyze.integration.test.js.map +1 -0
- package/dist/tests/integration/compare.integration.test.d.ts +2 -0
- package/dist/tests/integration/compare.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/compare.integration.test.js +120 -0
- package/dist/tests/integration/compare.integration.test.js.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts +62 -0
- package/dist/tests/integration/fixtures/test-skills.d.ts.map +1 -0
- package/dist/tests/integration/fixtures/test-skills.js +644 -0
- package/dist/tests/integration/fixtures/test-skills.js.map +1 -0
- package/dist/tests/integration/get-skill.integration.test.d.ts +6 -0
- package/dist/tests/integration/get-skill.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/get-skill.integration.test.js +203 -0
- package/dist/tests/integration/get-skill.integration.test.js.map +1 -0
- package/dist/tests/integration/github-api.integration.test.d.ts +14 -0
- package/dist/tests/integration/github-api.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/github-api.integration.test.js +190 -0
- package/dist/tests/integration/github-api.integration.test.js.map +1 -0
- package/dist/tests/integration/install.integration.test.d.ts +6 -0
- package/dist/tests/integration/install.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/install.integration.test.js +282 -0
- package/dist/tests/integration/install.integration.test.js.map +1 -0
- package/dist/tests/integration/recommend.integration.test.d.ts +2 -0
- package/dist/tests/integration/recommend.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/recommend.integration.test.js +215 -0
- package/dist/tests/integration/recommend.integration.test.js.map +1 -0
- package/dist/tests/integration/search.integration.test.d.ts +6 -0
- package/dist/tests/integration/search.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/search.integration.test.js +229 -0
- package/dist/tests/integration/search.integration.test.js.map +1 -0
- package/dist/tests/integration/setup.d.ts +71 -0
- package/dist/tests/integration/setup.d.ts.map +1 -0
- package/dist/tests/integration/setup.js +124 -0
- package/dist/tests/integration/setup.js.map +1 -0
- package/dist/tests/integration/uninstall.integration.test.d.ts +6 -0
- package/dist/tests/integration/uninstall.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/uninstall.integration.test.js +296 -0
- package/dist/tests/integration/uninstall.integration.test.js.map +1 -0
- package/dist/tests/integration/validate.integration.test.d.ts +2 -0
- package/dist/tests/integration/validate.integration.test.d.ts.map +1 -0
- package/dist/tests/integration/validate.integration.test.js +181 -0
- package/dist/tests/integration/validate.integration.test.js.map +1 -0
- package/dist/tests/onboarding/first-run.test.d.ts +7 -0
- package/dist/tests/onboarding/first-run.test.d.ts.map +1 -0
- package/dist/tests/onboarding/first-run.test.js +258 -0
- package/dist/tests/onboarding/first-run.test.js.map +1 -0
- package/dist/tests/performance/search-performance.test.d.ts +10 -0
- package/dist/tests/performance/search-performance.test.d.ts.map +1 -0
- package/dist/tests/performance/search-performance.test.js +218 -0
- package/dist/tests/performance/search-performance.test.js.map +1 -0
- package/dist/tests/recommend.test.d.ts +6 -0
- package/dist/tests/recommend.test.d.ts.map +1 -0
- package/dist/tests/recommend.test.js +208 -0
- package/dist/tests/recommend.test.js.map +1 -0
- package/dist/tests/suggestions/suggestion-engine.test.d.ts +6 -0
- package/dist/tests/suggestions/suggestion-engine.test.d.ts.map +1 -0
- package/dist/tests/suggestions/suggestion-engine.test.js +448 -0
- package/dist/tests/suggestions/suggestion-engine.test.js.map +1 -0
- package/dist/tests/test-utils.d.ts +74 -0
- package/dist/tests/test-utils.d.ts.map +1 -0
- package/dist/tests/test-utils.js +98 -0
- package/dist/tests/test-utils.js.map +1 -0
- package/dist/tests/tools.test.d.ts +5 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +138 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/tests/unit/installed-skills.test.d.ts +6 -0
- package/dist/tests/unit/installed-skills.test.d.ts.map +1 -0
- package/dist/tests/unit/installed-skills.test.js +285 -0
- package/dist/tests/unit/installed-skills.test.js.map +1 -0
- package/dist/tests/unit/logger.test.d.ts +6 -0
- package/dist/tests/unit/logger.test.d.ts.map +1 -0
- package/dist/tests/unit/logger.test.js +281 -0
- package/dist/tests/unit/logger.test.js.map +1 -0
- package/dist/tests/validate.test.d.ts +5 -0
- package/dist/tests/validate.test.d.ts.map +1 -0
- package/dist/tests/validate.test.js +303 -0
- package/dist/tests/validate.test.js.map +1 -0
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts +8 -0
- package/dist/tests/webhooks/proxy-trust.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/proxy-trust.security.test.js +145 -0
- package/dist/tests/webhooks/proxy-trust.security.test.js.map +1 -0
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts +8 -0
- package/dist/tests/webhooks/rate-limiter.security.test.d.ts.map +1 -0
- package/dist/tests/webhooks/rate-limiter.security.test.js +122 -0
- package/dist/tests/webhooks/rate-limiter.security.test.js.map +1 -0
- package/dist/vitest.config.d.ts +6 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +13 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP Skill Compare Tool for comparing two skills
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/compare
|
|
4
|
+
* @see SMI-743: Add MCP Tool skill_compare
|
|
5
|
+
* @see SMI-791: Wire compare tool to SkillRepository
|
|
6
|
+
*
|
|
7
|
+
* Compares two skills across multiple dimensions:
|
|
8
|
+
* - Quality scores
|
|
9
|
+
* - Trust tiers
|
|
10
|
+
* - Features and capabilities
|
|
11
|
+
* - Dependencies
|
|
12
|
+
* - Size and complexity
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Compare two skills with context
|
|
16
|
+
* const result = await executeCompare({
|
|
17
|
+
* skill_a: 'community/jest-helper',
|
|
18
|
+
* skill_b: 'community/vitest-helper'
|
|
19
|
+
* }, context);
|
|
20
|
+
* console.log(result.recommendation);
|
|
21
|
+
*/
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
import { SkillsmithError, ErrorCodes, } from '@skillsmith/core';
|
|
24
|
+
import { isValidSkillId, mapTrustTierFromDb, extractCategoryFromTags } from '../utils/validation.js';
|
|
25
|
+
/**
|
|
26
|
+
* Zod schema for compare tool input validation
|
|
27
|
+
*/
|
|
28
|
+
export const compareInputSchema = z.object({
|
|
29
|
+
/** First skill ID to compare */
|
|
30
|
+
skill_a: z.string().min(1, 'skill_a is required'),
|
|
31
|
+
/** Second skill ID to compare */
|
|
32
|
+
skill_b: z.string().min(1, 'skill_b is required'),
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* MCP tool schema definition for skill_compare
|
|
36
|
+
*/
|
|
37
|
+
export const compareToolSchema = {
|
|
38
|
+
name: 'skill_compare',
|
|
39
|
+
description: 'Compare two skills side-by-side. Analyzes quality scores, trust tiers, features, and dependencies to provide a recommendation.',
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
skill_a: {
|
|
44
|
+
type: 'string',
|
|
45
|
+
description: 'First skill ID to compare (e.g., "community/jest-helper")',
|
|
46
|
+
},
|
|
47
|
+
skill_b: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: 'Second skill ID to compare (e.g., "community/vitest-helper")',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
required: ['skill_a', 'skill_b'],
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
// isValidSkillId imported from ../utils/validation.js
|
|
56
|
+
/**
|
|
57
|
+
* Trust tier ranking for comparison
|
|
58
|
+
*/
|
|
59
|
+
const TRUST_TIER_RANK = {
|
|
60
|
+
verified: 4,
|
|
61
|
+
community: 3,
|
|
62
|
+
standard: 2,
|
|
63
|
+
unverified: 1,
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Convert skill to summary
|
|
67
|
+
*/
|
|
68
|
+
function toSummary(skill) {
|
|
69
|
+
return {
|
|
70
|
+
id: skill.id,
|
|
71
|
+
name: skill.name,
|
|
72
|
+
description: skill.description,
|
|
73
|
+
author: skill.author,
|
|
74
|
+
quality_score: skill.score,
|
|
75
|
+
score_breakdown: skill.scoreBreakdown ?? null,
|
|
76
|
+
trust_tier: skill.trustTier,
|
|
77
|
+
category: skill.category,
|
|
78
|
+
tags: skill.tags,
|
|
79
|
+
version: skill.version ?? null,
|
|
80
|
+
dependencies: skill.dependencies,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Generate comparison differences
|
|
85
|
+
*/
|
|
86
|
+
function generateDifferences(skillA, skillB) {
|
|
87
|
+
const differences = [];
|
|
88
|
+
// Quality score comparison
|
|
89
|
+
differences.push({
|
|
90
|
+
field: 'quality_score',
|
|
91
|
+
a_value: skillA.score,
|
|
92
|
+
b_value: skillB.score,
|
|
93
|
+
winner: skillA.score > skillB.score ? 'a' : skillA.score < skillB.score ? 'b' : 'tie',
|
|
94
|
+
});
|
|
95
|
+
// Trust tier comparison
|
|
96
|
+
const trustRankA = TRUST_TIER_RANK[skillA.trustTier];
|
|
97
|
+
const trustRankB = TRUST_TIER_RANK[skillB.trustTier];
|
|
98
|
+
differences.push({
|
|
99
|
+
field: 'trust_tier',
|
|
100
|
+
a_value: skillA.trustTier,
|
|
101
|
+
b_value: skillB.trustTier,
|
|
102
|
+
winner: trustRankA > trustRankB ? 'a' : trustRankA < trustRankB ? 'b' : 'tie',
|
|
103
|
+
});
|
|
104
|
+
// Dependencies (fewer is usually better)
|
|
105
|
+
differences.push({
|
|
106
|
+
field: 'dependencies_count',
|
|
107
|
+
a_value: skillA.dependencies.length,
|
|
108
|
+
b_value: skillB.dependencies.length,
|
|
109
|
+
winner: skillA.dependencies.length < skillB.dependencies.length
|
|
110
|
+
? 'a'
|
|
111
|
+
: skillA.dependencies.length > skillB.dependencies.length
|
|
112
|
+
? 'b'
|
|
113
|
+
: 'tie',
|
|
114
|
+
});
|
|
115
|
+
// Features (more is usually better)
|
|
116
|
+
differences.push({
|
|
117
|
+
field: 'features_count',
|
|
118
|
+
a_value: skillA.features.length,
|
|
119
|
+
b_value: skillB.features.length,
|
|
120
|
+
winner: skillA.features.length > skillB.features.length
|
|
121
|
+
? 'a'
|
|
122
|
+
: skillA.features.length < skillB.features.length
|
|
123
|
+
? 'b'
|
|
124
|
+
: 'tie',
|
|
125
|
+
});
|
|
126
|
+
// Score breakdown comparison
|
|
127
|
+
if (skillA.scoreBreakdown && skillB.scoreBreakdown) {
|
|
128
|
+
for (const key of [
|
|
129
|
+
'quality',
|
|
130
|
+
'popularity',
|
|
131
|
+
'maintenance',
|
|
132
|
+
'security',
|
|
133
|
+
'documentation',
|
|
134
|
+
]) {
|
|
135
|
+
const aVal = skillA.scoreBreakdown[key];
|
|
136
|
+
const bVal = skillB.scoreBreakdown[key];
|
|
137
|
+
differences.push({
|
|
138
|
+
field: `score_${key}`,
|
|
139
|
+
a_value: aVal,
|
|
140
|
+
b_value: bVal,
|
|
141
|
+
winner: aVal > bVal ? 'a' : aVal < bVal ? 'b' : 'tie',
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Category
|
|
146
|
+
if (skillA.category !== skillB.category) {
|
|
147
|
+
differences.push({
|
|
148
|
+
field: 'category',
|
|
149
|
+
a_value: skillA.category,
|
|
150
|
+
b_value: skillB.category,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Author
|
|
154
|
+
if (skillA.author !== skillB.author) {
|
|
155
|
+
differences.push({
|
|
156
|
+
field: 'author',
|
|
157
|
+
a_value: skillA.author,
|
|
158
|
+
b_value: skillB.author,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Tags difference
|
|
162
|
+
const tagsOnlyInA = skillA.tags.filter((t) => !skillB.tags.includes(t));
|
|
163
|
+
const tagsOnlyInB = skillB.tags.filter((t) => !skillA.tags.includes(t));
|
|
164
|
+
if (tagsOnlyInA.length > 0 || tagsOnlyInB.length > 0) {
|
|
165
|
+
differences.push({
|
|
166
|
+
field: 'unique_tags',
|
|
167
|
+
a_value: tagsOnlyInA,
|
|
168
|
+
b_value: tagsOnlyInB,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return differences;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Generate recommendation based on comparison
|
|
175
|
+
*/
|
|
176
|
+
function generateRecommendation(skillA, skillB, differences) {
|
|
177
|
+
// Count wins
|
|
178
|
+
let aWins = 0;
|
|
179
|
+
let bWins = 0;
|
|
180
|
+
for (const diff of differences) {
|
|
181
|
+
if (diff.winner === 'a')
|
|
182
|
+
aWins++;
|
|
183
|
+
else if (diff.winner === 'b')
|
|
184
|
+
bWins++;
|
|
185
|
+
}
|
|
186
|
+
// Weight certain factors more heavily
|
|
187
|
+
const trustRankA = TRUST_TIER_RANK[skillA.trustTier];
|
|
188
|
+
const trustRankB = TRUST_TIER_RANK[skillB.trustTier];
|
|
189
|
+
// Verified trust tier gets big bonus
|
|
190
|
+
if (trustRankA === 4)
|
|
191
|
+
aWins += 2;
|
|
192
|
+
if (trustRankB === 4)
|
|
193
|
+
bWins += 2;
|
|
194
|
+
// Higher quality score gets bonus
|
|
195
|
+
if (skillA.score > skillB.score + 5)
|
|
196
|
+
aWins += 1;
|
|
197
|
+
if (skillB.score > skillA.score + 5)
|
|
198
|
+
bWins += 1;
|
|
199
|
+
let winner;
|
|
200
|
+
let recommendation;
|
|
201
|
+
if (aWins > bWins + 1) {
|
|
202
|
+
winner = 'a';
|
|
203
|
+
recommendation = `${skillA.name} is recommended. It has `;
|
|
204
|
+
const reasons = [];
|
|
205
|
+
if (skillA.score > skillB.score) {
|
|
206
|
+
reasons.push(`higher quality score (${skillA.score} vs ${skillB.score})`);
|
|
207
|
+
}
|
|
208
|
+
if (trustRankA > trustRankB) {
|
|
209
|
+
reasons.push(`better trust tier (${skillA.trustTier})`);
|
|
210
|
+
}
|
|
211
|
+
if (skillA.dependencies.length < skillB.dependencies.length) {
|
|
212
|
+
reasons.push('fewer dependencies');
|
|
213
|
+
}
|
|
214
|
+
recommendation += reasons.length > 0 ? reasons.join(', ') + '.' : 'better overall metrics.';
|
|
215
|
+
if (skillB.features.length > skillA.features.length) {
|
|
216
|
+
recommendation += ` However, ${skillB.name} offers more features.`;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else if (bWins > aWins + 1) {
|
|
220
|
+
winner = 'b';
|
|
221
|
+
recommendation = `${skillB.name} is recommended. It has `;
|
|
222
|
+
const reasons = [];
|
|
223
|
+
if (skillB.score > skillA.score) {
|
|
224
|
+
reasons.push(`higher quality score (${skillB.score} vs ${skillA.score})`);
|
|
225
|
+
}
|
|
226
|
+
if (trustRankB > trustRankA) {
|
|
227
|
+
reasons.push(`better trust tier (${skillB.trustTier})`);
|
|
228
|
+
}
|
|
229
|
+
if (skillB.dependencies.length < skillA.dependencies.length) {
|
|
230
|
+
reasons.push('fewer dependencies');
|
|
231
|
+
}
|
|
232
|
+
recommendation += reasons.length > 0 ? reasons.join(', ') + '.' : 'better overall metrics.';
|
|
233
|
+
if (skillA.features.length > skillB.features.length) {
|
|
234
|
+
recommendation += ` However, ${skillA.name} offers more features.`;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
winner = 'tie';
|
|
239
|
+
recommendation = `Both skills are comparable. `;
|
|
240
|
+
if (skillA.category === skillB.category) {
|
|
241
|
+
recommendation += `Choose ${skillA.name} for ${skillA.tags
|
|
242
|
+
.filter((t) => !skillB.tags.includes(t))
|
|
243
|
+
.slice(0, 2)
|
|
244
|
+
.join('/')} workflows, `;
|
|
245
|
+
recommendation += `or ${skillB.name} for ${skillB.tags
|
|
246
|
+
.filter((t) => !skillA.tags.includes(t))
|
|
247
|
+
.slice(0, 2)
|
|
248
|
+
.join('/')} workflows.`;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
recommendation += `${skillA.name} is better for ${skillA.category}, while ${skillB.name} excels at ${skillB.category}.`;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return { recommendation, winner };
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Convert database skill to extended skill format
|
|
258
|
+
*
|
|
259
|
+
* Note: Dependencies are not currently stored in the database schema.
|
|
260
|
+
* Features are inferred from tags for now.
|
|
261
|
+
*/
|
|
262
|
+
function dbSkillToExtended(dbSkill) {
|
|
263
|
+
const tags = dbSkill.tags || [];
|
|
264
|
+
return {
|
|
265
|
+
id: dbSkill.id,
|
|
266
|
+
name: dbSkill.name,
|
|
267
|
+
description: dbSkill.description || '',
|
|
268
|
+
author: dbSkill.author || 'unknown',
|
|
269
|
+
repository: dbSkill.repoUrl || undefined,
|
|
270
|
+
version: undefined,
|
|
271
|
+
category: extractCategoryFromTags(tags),
|
|
272
|
+
trustTier: mapTrustTierFromDb(dbSkill.trustTier),
|
|
273
|
+
score: Math.round((dbSkill.qualityScore ?? 0) * 100),
|
|
274
|
+
scoreBreakdown: undefined,
|
|
275
|
+
tags,
|
|
276
|
+
installCommand: 'claude skill add ' + dbSkill.id,
|
|
277
|
+
createdAt: dbSkill.createdAt,
|
|
278
|
+
updatedAt: dbSkill.updatedAt,
|
|
279
|
+
// Note: Dependencies not yet stored in database - field reserved for future use
|
|
280
|
+
dependencies: [],
|
|
281
|
+
// Use non-category tags as feature indicators
|
|
282
|
+
features: tags.filter((t) => ![
|
|
283
|
+
'development',
|
|
284
|
+
'testing',
|
|
285
|
+
'documentation',
|
|
286
|
+
'devops',
|
|
287
|
+
'database',
|
|
288
|
+
'security',
|
|
289
|
+
'productivity',
|
|
290
|
+
'integration',
|
|
291
|
+
'ai-ml',
|
|
292
|
+
'other',
|
|
293
|
+
].includes(t.toLowerCase())),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Execute skill comparison.
|
|
298
|
+
*
|
|
299
|
+
* Uses SkillRepository to fetch skills from the database and compares them
|
|
300
|
+
* across multiple dimensions including quality scores, trust tiers, features,
|
|
301
|
+
* and dependencies.
|
|
302
|
+
*
|
|
303
|
+
* @param input - Comparison parameters with two skill IDs
|
|
304
|
+
* @param context - Tool context with database and services
|
|
305
|
+
* @returns Promise resolving to comparison response
|
|
306
|
+
* @throws {SkillsmithError} When skill IDs are invalid or not found
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* const response = await executeCompare({
|
|
310
|
+
* skill_a: 'community/jest-helper',
|
|
311
|
+
* skill_b: 'community/vitest-helper'
|
|
312
|
+
* }, context);
|
|
313
|
+
* console.log(response.recommendation);
|
|
314
|
+
*/
|
|
315
|
+
export async function executeCompare(input, context) {
|
|
316
|
+
const startTime = performance.now();
|
|
317
|
+
// Validate input with Zod
|
|
318
|
+
const validated = compareInputSchema.parse(input);
|
|
319
|
+
const { skill_a, skill_b } = validated;
|
|
320
|
+
// Validate skill ID formats
|
|
321
|
+
if (!isValidSkillId(skill_a)) {
|
|
322
|
+
throw new SkillsmithError(ErrorCodes.SKILL_INVALID_ID, `Invalid skill ID format: "${skill_a}"`, {
|
|
323
|
+
details: { id: skill_a },
|
|
324
|
+
suggestion: 'Skill IDs should be in format "author/skill-name" or a valid UUID',
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (!isValidSkillId(skill_b)) {
|
|
328
|
+
throw new SkillsmithError(ErrorCodes.SKILL_INVALID_ID, `Invalid skill ID format: "${skill_b}"`, {
|
|
329
|
+
details: { id: skill_b },
|
|
330
|
+
suggestion: 'Skill IDs should be in format "author/skill-name" or a valid UUID',
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
// Check for same skill comparison
|
|
334
|
+
if (skill_a.toLowerCase() === skill_b.toLowerCase()) {
|
|
335
|
+
throw new SkillsmithError(ErrorCodes.VALIDATION_INVALID_TYPE, 'Cannot compare a skill with itself', { details: { skill_a, skill_b } });
|
|
336
|
+
}
|
|
337
|
+
// Look up skills from database
|
|
338
|
+
const dbSkillA = context.skillRepository.findById(skill_a);
|
|
339
|
+
const dbSkillB = context.skillRepository.findById(skill_b);
|
|
340
|
+
if (!dbSkillA) {
|
|
341
|
+
throw new SkillsmithError(ErrorCodes.SKILL_NOT_FOUND, `Skill "${skill_a}" not found`, {
|
|
342
|
+
details: { id: skill_a },
|
|
343
|
+
suggestion: 'Try searching for similar skills with the search tool',
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
if (!dbSkillB) {
|
|
347
|
+
throw new SkillsmithError(ErrorCodes.SKILL_NOT_FOUND, `Skill "${skill_b}" not found`, {
|
|
348
|
+
details: { id: skill_b },
|
|
349
|
+
suggestion: 'Try searching for similar skills with the search tool',
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
// Convert to extended format
|
|
353
|
+
const skillA = dbSkillToExtended(dbSkillA);
|
|
354
|
+
const skillB = dbSkillToExtended(dbSkillB);
|
|
355
|
+
// Generate differences
|
|
356
|
+
const differences = generateDifferences(skillA, skillB);
|
|
357
|
+
// Generate recommendation
|
|
358
|
+
const { recommendation, winner } = generateRecommendation(skillA, skillB, differences);
|
|
359
|
+
const endTime = performance.now();
|
|
360
|
+
return {
|
|
361
|
+
comparison: {
|
|
362
|
+
a: toSummary(skillA),
|
|
363
|
+
b: toSummary(skillB),
|
|
364
|
+
},
|
|
365
|
+
differences,
|
|
366
|
+
recommendation,
|
|
367
|
+
winner,
|
|
368
|
+
timing: {
|
|
369
|
+
totalMs: Math.round(endTime - startTime),
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Format comparison results for terminal display
|
|
375
|
+
*/
|
|
376
|
+
export function formatComparisonResults(response) {
|
|
377
|
+
const lines = [];
|
|
378
|
+
const { a, b } = response.comparison;
|
|
379
|
+
lines.push('\n=== Skill Comparison ===\n');
|
|
380
|
+
lines.push(`${a.name} vs ${b.name}`);
|
|
381
|
+
lines.push('');
|
|
382
|
+
// Side by side comparison
|
|
383
|
+
lines.push(' | ' + padEnd(a.name, 20) + ' | ' + padEnd(b.name, 20));
|
|
384
|
+
lines.push('-'.repeat(70));
|
|
385
|
+
lines.push(' Quality Score | ' +
|
|
386
|
+
padEnd(String(a.quality_score) + '/100', 20) +
|
|
387
|
+
' | ' +
|
|
388
|
+
padEnd(String(b.quality_score) + '/100', 20));
|
|
389
|
+
lines.push(' Trust Tier | ' +
|
|
390
|
+
padEnd(a.trust_tier.toUpperCase(), 20) +
|
|
391
|
+
' | ' +
|
|
392
|
+
padEnd(b.trust_tier.toUpperCase(), 20));
|
|
393
|
+
lines.push(' Category | ' + padEnd(a.category, 20) + ' | ' + padEnd(b.category, 20));
|
|
394
|
+
lines.push(' Dependencies | ' +
|
|
395
|
+
padEnd(String(a.dependencies.length), 20) +
|
|
396
|
+
' | ' +
|
|
397
|
+
padEnd(String(b.dependencies.length), 20));
|
|
398
|
+
if (a.version || b.version) {
|
|
399
|
+
lines.push(' Version | ' +
|
|
400
|
+
padEnd(a.version ?? 'N/A', 20) +
|
|
401
|
+
' | ' +
|
|
402
|
+
padEnd(b.version ?? 'N/A', 20));
|
|
403
|
+
}
|
|
404
|
+
lines.push('');
|
|
405
|
+
// Score breakdown if available
|
|
406
|
+
if (a.score_breakdown && b.score_breakdown) {
|
|
407
|
+
lines.push('Score Breakdown:');
|
|
408
|
+
lines.push(' Quality | ' +
|
|
409
|
+
formatScoreBar(a.score_breakdown.quality, 14) +
|
|
410
|
+
' | ' +
|
|
411
|
+
formatScoreBar(b.score_breakdown.quality, 14));
|
|
412
|
+
lines.push(' Popularity | ' +
|
|
413
|
+
formatScoreBar(a.score_breakdown.popularity, 14) +
|
|
414
|
+
' | ' +
|
|
415
|
+
formatScoreBar(b.score_breakdown.popularity, 14));
|
|
416
|
+
lines.push(' Maintenance | ' +
|
|
417
|
+
formatScoreBar(a.score_breakdown.maintenance, 14) +
|
|
418
|
+
' | ' +
|
|
419
|
+
formatScoreBar(b.score_breakdown.maintenance, 14));
|
|
420
|
+
lines.push(' Security | ' +
|
|
421
|
+
formatScoreBar(a.score_breakdown.security, 14) +
|
|
422
|
+
' | ' +
|
|
423
|
+
formatScoreBar(b.score_breakdown.security, 14));
|
|
424
|
+
lines.push(' Documentation | ' +
|
|
425
|
+
formatScoreBar(a.score_breakdown.documentation, 14) +
|
|
426
|
+
' | ' +
|
|
427
|
+
formatScoreBar(b.score_breakdown.documentation, 14));
|
|
428
|
+
lines.push('');
|
|
429
|
+
}
|
|
430
|
+
// Winner indicator
|
|
431
|
+
lines.push('---');
|
|
432
|
+
if (response.winner === 'a') {
|
|
433
|
+
lines.push(`Winner: ${a.name}`);
|
|
434
|
+
}
|
|
435
|
+
else if (response.winner === 'b') {
|
|
436
|
+
lines.push(`Winner: ${b.name}`);
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
lines.push('Winner: TIE');
|
|
440
|
+
}
|
|
441
|
+
lines.push('');
|
|
442
|
+
// Recommendation
|
|
443
|
+
lines.push('Recommendation:');
|
|
444
|
+
lines.push(' ' + response.recommendation);
|
|
445
|
+
lines.push('');
|
|
446
|
+
lines.push('---');
|
|
447
|
+
lines.push(`Completed in ${response.timing.totalMs}ms`);
|
|
448
|
+
return lines.join('\n');
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Pad string to specified length
|
|
452
|
+
*/
|
|
453
|
+
function padEnd(str, length) {
|
|
454
|
+
return str.padEnd(length);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Format score as visual bar
|
|
458
|
+
*/
|
|
459
|
+
function formatScoreBar(score, width) {
|
|
460
|
+
const filled = Math.round((score / 100) * 10);
|
|
461
|
+
const bar = '='.repeat(filled) + '-'.repeat(10 - filled);
|
|
462
|
+
return `[${bar}] ${score}`.padEnd(width);
|
|
463
|
+
}
|
|
464
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../src/tools/compare.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP Get Skill Tool for retrieving detailed skill information
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/get-skill
|
|
4
|
+
* @see {@link https://github.com/wrsmith108/skillsmith|Skillsmith Repository}
|
|
5
|
+
* @see SMI-790: Wire get-skill tool to SkillRepository
|
|
6
|
+
*
|
|
7
|
+
* Retrieves comprehensive details for a specific skill including:
|
|
8
|
+
* - Basic metadata (name, author, version, category)
|
|
9
|
+
* - Quality scores with breakdown (quality, popularity, maintenance, security, documentation)
|
|
10
|
+
* - Trust tier with explanation
|
|
11
|
+
* - Repository link and tags
|
|
12
|
+
* - Installation command
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Get skill by ID with context
|
|
16
|
+
* const response = await executeGetSkill({ id: 'anthropic/commit' }, context);
|
|
17
|
+
* console.log(response.skill.description);
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Format for terminal display
|
|
21
|
+
* const response = await executeGetSkill({ id: 'community/jest-helper' }, context);
|
|
22
|
+
* console.log(formatSkillDetails(response));
|
|
23
|
+
*/
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
import { type GetSkillResponse } from '@skillsmith/core';
|
|
26
|
+
import type { ToolContext } from '../context.js';
|
|
27
|
+
/**
|
|
28
|
+
* Zod schema for get-skill input validation
|
|
29
|
+
*/
|
|
30
|
+
export declare const getSkillInputSchema: z.ZodObject<{
|
|
31
|
+
id: z.ZodString;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
id: string;
|
|
34
|
+
}, {
|
|
35
|
+
id: string;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Get skill tool schema for MCP
|
|
39
|
+
*/
|
|
40
|
+
export declare const getSkillToolSchema: {
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
inputSchema: {
|
|
44
|
+
type: "object";
|
|
45
|
+
properties: {
|
|
46
|
+
id: {
|
|
47
|
+
type: string;
|
|
48
|
+
description: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
required: string[];
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Input parameters for the get skill operation
|
|
56
|
+
* @interface GetSkillInput
|
|
57
|
+
*/
|
|
58
|
+
export interface GetSkillInput {
|
|
59
|
+
/** Skill ID in format "author/skill-name" or UUID */
|
|
60
|
+
id: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Retrieve full details for a specific skill by ID.
|
|
64
|
+
*
|
|
65
|
+
* Uses SkillRepository to fetch skill from the SQLite database.
|
|
66
|
+
*
|
|
67
|
+
* @param input - Input containing the skill ID to retrieve
|
|
68
|
+
* @param context - Tool context with database and services
|
|
69
|
+
* @returns Promise resolving to skill details and install command
|
|
70
|
+
* @throws {SkillsmithError} VALIDATION_REQUIRED_FIELD - When ID is empty
|
|
71
|
+
* @throws {SkillsmithError} SKILL_INVALID_ID - When ID format is invalid
|
|
72
|
+
* @throws {SkillsmithError} SKILL_NOT_FOUND - When skill doesn't exist
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* // Get a verified skill
|
|
76
|
+
* const response = await executeGetSkill({ id: 'anthropic/commit' }, context);
|
|
77
|
+
* console.log(response.skill.score); // 95
|
|
78
|
+
* console.log(response.installCommand); // 'claude skill add anthropic/commit'
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* // Handle not found
|
|
82
|
+
* try {
|
|
83
|
+
* await executeGetSkill({ id: 'unknown/skill' }, context);
|
|
84
|
+
* } catch (error) {
|
|
85
|
+
* if (error.code === 'SKILL_NOT_FOUND') {
|
|
86
|
+
* console.log(error.suggestion); // 'Try searching for similar skills...'
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
*/
|
|
90
|
+
export declare function executeGetSkill(input: GetSkillInput, context: ToolContext): Promise<GetSkillResponse>;
|
|
91
|
+
/**
|
|
92
|
+
* Format skill details for terminal/CLI display.
|
|
93
|
+
*
|
|
94
|
+
* Produces a comprehensive human-readable string including:
|
|
95
|
+
* - Basic info (ID, author, version, category)
|
|
96
|
+
* - Full description
|
|
97
|
+
* - Trust tier with explanation
|
|
98
|
+
* - Visual score breakdown bars
|
|
99
|
+
* - Repository and tags
|
|
100
|
+
* - Installation command
|
|
101
|
+
*
|
|
102
|
+
* @param response - Get skill response from executeGetSkill
|
|
103
|
+
* @returns Formatted string suitable for terminal output
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* const response = await executeGetSkill({ id: 'anthropic/commit' });
|
|
107
|
+
* console.log(formatSkillDetails(response));
|
|
108
|
+
* // Output:
|
|
109
|
+
* // === commit ===
|
|
110
|
+
* // ID: anthropic/commit
|
|
111
|
+
* // Author: anthropic
|
|
112
|
+
* // Version: 1.2.0
|
|
113
|
+
* // ...
|
|
114
|
+
*/
|
|
115
|
+
export declare function formatSkillDetails(response: GetSkillResponse): string;
|
|
116
|
+
//# sourceMappingURL=get-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-skill.d.ts","sourceRoot":"","sources":["../../../src/tools/get-skill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAEL,KAAK,gBAAgB,EAKtB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAGhD;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;EAE9B,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;CAa9B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,EAAE,EAAE,MAAM,CAAA;CACX;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,gBAAgB,CAAC,CA8D3B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAwDrE"}
|