@skillsmith/mcp-server 0.3.2 → 0.3.4

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 (130) hide show
  1. package/README.md +5 -3
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/__tests__/context.test.d.ts +10 -0
  4. package/dist/src/__tests__/context.test.d.ts.map +1 -0
  5. package/dist/src/__tests__/context.test.js +345 -0
  6. package/dist/src/__tests__/context.test.js.map +1 -0
  7. package/dist/src/__tests__/get-skill.test.d.ts +1 -0
  8. package/dist/src/__tests__/get-skill.test.d.ts.map +1 -1
  9. package/dist/src/__tests__/get-skill.test.js +84 -0
  10. package/dist/src/__tests__/get-skill.test.js.map +1 -1
  11. package/dist/src/__tests__/middleware/license.test.js +180 -78
  12. package/dist/src/__tests__/middleware/license.test.js.map +1 -1
  13. package/dist/src/__tests__/search.test.js +2 -1
  14. package/dist/src/__tests__/search.test.js.map +1 -1
  15. package/dist/src/__tests__/utils/validation.test.d.ts +7 -0
  16. package/dist/src/__tests__/utils/validation.test.d.ts.map +1 -0
  17. package/dist/src/__tests__/utils/validation.test.js +82 -0
  18. package/dist/src/__tests__/utils/validation.test.js.map +1 -0
  19. package/dist/src/context.d.ts +16 -0
  20. package/dist/src/context.d.ts.map +1 -1
  21. package/dist/src/context.js +57 -9
  22. package/dist/src/context.js.map +1 -1
  23. package/dist/src/index.js +1 -1
  24. package/dist/src/index.js.map +1 -1
  25. package/dist/src/llm/failover.d.ts +200 -0
  26. package/dist/src/llm/failover.d.ts.map +1 -0
  27. package/dist/src/llm/failover.js +329 -0
  28. package/dist/src/llm/failover.js.map +1 -0
  29. package/dist/src/middleware/license.d.ts +5 -0
  30. package/dist/src/middleware/license.d.ts.map +1 -1
  31. package/dist/src/middleware/license.js +2 -1
  32. package/dist/src/middleware/license.js.map +1 -1
  33. package/dist/src/tools/compare.d.ts +3 -102
  34. package/dist/src/tools/compare.d.ts.map +1 -1
  35. package/dist/src/tools/compare.helpers.d.ts +36 -0
  36. package/dist/src/tools/compare.helpers.d.ts.map +1 -0
  37. package/dist/src/tools/compare.helpers.js +252 -0
  38. package/dist/src/tools/compare.helpers.js.map +1 -0
  39. package/dist/src/tools/compare.js +6 -288
  40. package/dist/src/tools/compare.js.map +1 -1
  41. package/dist/src/tools/compare.types.d.ts +133 -0
  42. package/dist/src/tools/compare.types.d.ts.map +1 -0
  43. package/dist/src/tools/compare.types.js +45 -0
  44. package/dist/src/tools/compare.types.js.map +1 -0
  45. package/dist/src/tools/get-skill.d.ts.map +1 -1
  46. package/dist/src/tools/get-skill.js +35 -2
  47. package/dist/src/tools/get-skill.js.map +1 -1
  48. package/dist/src/tools/install.d.ts +6 -60
  49. package/dist/src/tools/install.d.ts.map +1 -1
  50. package/dist/src/tools/install.helpers.d.ts +82 -0
  51. package/dist/src/tools/install.helpers.d.ts.map +1 -0
  52. package/dist/src/tools/install.helpers.js +324 -0
  53. package/dist/src/tools/install.helpers.js.map +1 -0
  54. package/dist/src/tools/install.js +176 -168
  55. package/dist/src/tools/install.js.map +1 -1
  56. package/dist/src/tools/install.types.d.ts +114 -0
  57. package/dist/src/tools/install.types.d.ts.map +1 -0
  58. package/dist/src/tools/install.types.js +91 -0
  59. package/dist/src/tools/install.types.js.map +1 -0
  60. package/dist/src/tools/recommend.d.ts +2 -148
  61. package/dist/src/tools/recommend.d.ts.map +1 -1
  62. package/dist/src/tools/recommend.helpers.d.ts +42 -0
  63. package/dist/src/tools/recommend.helpers.d.ts.map +1 -0
  64. package/dist/src/tools/recommend.helpers.js +155 -0
  65. package/dist/src/tools/recommend.helpers.js.map +1 -0
  66. package/dist/src/tools/recommend.js +75 -140
  67. package/dist/src/tools/recommend.js.map +1 -1
  68. package/dist/src/tools/recommend.types.d.ts +164 -0
  69. package/dist/src/tools/recommend.types.d.ts.map +1 -0
  70. package/dist/src/tools/recommend.types.js +87 -0
  71. package/dist/src/tools/recommend.types.js.map +1 -0
  72. package/dist/src/tools/search.d.ts +18 -4
  73. package/dist/src/tools/search.d.ts.map +1 -1
  74. package/dist/src/tools/search.js +64 -12
  75. package/dist/src/tools/search.js.map +1 -1
  76. package/dist/src/tools/validate.d.ts +3 -70
  77. package/dist/src/tools/validate.d.ts.map +1 -1
  78. package/dist/src/tools/validate.helpers.d.ts +22 -0
  79. package/dist/src/tools/validate.helpers.d.ts.map +1 -0
  80. package/dist/src/tools/validate.helpers.js +276 -0
  81. package/dist/src/tools/validate.helpers.js.map +1 -0
  82. package/dist/src/tools/validate.js +4 -337
  83. package/dist/src/tools/validate.js.map +1 -1
  84. package/dist/src/tools/validate.types.d.ts +96 -0
  85. package/dist/src/tools/validate.types.d.ts.map +1 -0
  86. package/dist/src/tools/validate.types.js +71 -0
  87. package/dist/src/tools/validate.types.js.map +1 -0
  88. package/dist/src/webhooks/index.d.ts +1 -0
  89. package/dist/src/webhooks/index.d.ts.map +1 -1
  90. package/dist/src/webhooks/index.js +2 -0
  91. package/dist/src/webhooks/index.js.map +1 -1
  92. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +68 -0
  93. package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -0
  94. package/dist/src/webhooks/stripe-webhook-endpoint.js +213 -0
  95. package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -0
  96. package/dist/tests/integration/install.integration.test.js +273 -1
  97. package/dist/tests/integration/install.integration.test.js.map +1 -1
  98. package/dist/tests/integration/recommend.integration.test.js +2 -1
  99. package/dist/tests/integration/recommend.integration.test.js.map +1 -1
  100. package/dist/tests/llm/failover.test.d.ts +13 -0
  101. package/dist/tests/llm/failover.test.d.ts.map +1 -0
  102. package/dist/tests/llm/failover.test.js +250 -0
  103. package/dist/tests/llm/failover.test.js.map +1 -0
  104. package/dist/tests/recommend.test.js +133 -1
  105. package/dist/tests/recommend.test.js.map +1 -1
  106. package/dist/tests/tools.test.d.ts +1 -0
  107. package/dist/tests/tools.test.d.ts.map +1 -1
  108. package/dist/tests/tools.test.js +59 -1
  109. package/dist/tests/tools.test.js.map +1 -1
  110. package/dist/tests/unit/compare-helpers.test.d.ts +8 -0
  111. package/dist/tests/unit/compare-helpers.test.d.ts.map +1 -0
  112. package/dist/tests/unit/compare-helpers.test.js +224 -0
  113. package/dist/tests/unit/compare-helpers.test.js.map +1 -0
  114. package/dist/tests/unit/install-helpers.test.d.ts +8 -0
  115. package/dist/tests/unit/install-helpers.test.d.ts.map +1 -0
  116. package/dist/tests/unit/install-helpers.test.js +460 -0
  117. package/dist/tests/unit/install-helpers.test.js.map +1 -0
  118. package/dist/tests/unit/recommend-helpers.test.d.ts +8 -0
  119. package/dist/tests/unit/recommend-helpers.test.d.ts.map +1 -0
  120. package/dist/tests/unit/recommend-helpers.test.js +117 -0
  121. package/dist/tests/unit/recommend-helpers.test.js.map +1 -0
  122. package/dist/tests/unit/validate-helpers.test.d.ts +8 -0
  123. package/dist/tests/unit/validate-helpers.test.d.ts.map +1 -0
  124. package/dist/tests/unit/validate-helpers.test.js +243 -0
  125. package/dist/tests/unit/validate-helpers.test.js.map +1 -0
  126. package/package.json +1 -1
  127. package/src/assets/docs/USER_GUIDE.md +0 -192
  128. package/src/assets/skills/skillsmith/docs/QUOTAS.md +0 -182
  129. package/src/assets/skills/skillsmith/docs/SECURITY.md +0 -174
  130. package/src/assets/skills/skillsmith/docs/TRUST_TIERS.md +0 -142
@@ -54,8 +54,18 @@ export declare const searchToolSchema: {
54
54
  minimum: number;
55
55
  maximum: number;
56
56
  };
57
+ safe_only: {
58
+ type: string;
59
+ description: string;
60
+ };
61
+ max_risk: {
62
+ type: string;
63
+ description: string;
64
+ minimum: number;
65
+ maximum: number;
66
+ };
57
67
  };
58
- required: string[];
68
+ required: never[];
59
69
  };
60
70
  };
61
71
  /**
@@ -63,14 +73,18 @@ export declare const searchToolSchema: {
63
73
  * @interface SearchInput
64
74
  */
65
75
  export interface SearchInput {
66
- /** Search query string (minimum 2 characters) */
67
- query: string;
76
+ /** Search query string (optional if filters provided) */
77
+ query?: string;
68
78
  /** Filter by skill category */
69
79
  category?: string;
70
80
  /** Filter by trust tier level */
71
81
  trust_tier?: string;
72
82
  /** Minimum quality score (0-100) */
73
83
  min_score?: number;
84
+ /** SMI-825: Only show skills that passed security scan */
85
+ safe_only?: boolean;
86
+ /** SMI-825: Maximum risk score (0-100, lower is safer) */
87
+ max_risk?: number;
74
88
  }
75
89
  /**
76
90
  * Execute a search for Claude Code skills with optional filters.
@@ -82,7 +96,7 @@ export interface SearchInput {
82
96
  * @param input - Search parameters including query and optional filters
83
97
  * @param context - Tool context with API client and local services
84
98
  * @returns Promise resolving to search response with results and timing
85
- * @throws {SkillsmithError} When query is empty or less than 2 characters
99
+ * @throws {SkillsmithError} When no query and no filters are provided
86
100
  * @throws {SkillsmithError} When min_score is outside 0-100 range
87
101
  *
88
102
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAGL,KAAK,iBAAiB,IAAI,cAAc,EAMzC,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAQhD;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwC5B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CA4IzB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAgCpE"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAGL,KAAK,iBAAiB,IAAI,cAAc,EAMzC,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAQhD;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmD5B,CAAA;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iCAAiC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAkNzB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAgCpE"}
@@ -65,8 +65,19 @@ export const searchToolSchema = {
65
65
  minimum: 0,
66
66
  maximum: 100,
67
67
  },
68
+ // SMI-825: Security filters
69
+ safe_only: {
70
+ type: 'boolean',
71
+ description: 'Only show skills that passed security scan',
72
+ },
73
+ max_risk: {
74
+ type: 'number',
75
+ description: 'Maximum risk score (0-100, lower is safer)',
76
+ minimum: 0,
77
+ maximum: 100,
78
+ },
68
79
  },
69
- required: ['query'],
80
+ required: [], // Query is optional if filters are provided
70
81
  },
71
82
  };
72
83
  /**
@@ -79,7 +90,7 @@ export const searchToolSchema = {
79
90
  * @param input - Search parameters including query and optional filters
80
91
  * @param context - Tool context with API client and local services
81
92
  * @returns Promise resolving to search response with results and timing
82
- * @throws {SkillsmithError} When query is empty or less than 2 characters
93
+ * @throws {SkillsmithError} When no query and no filters are provided
83
94
  * @throws {SkillsmithError} When min_score is outside 0-100 range
84
95
  *
85
96
  * @example
@@ -89,17 +100,31 @@ export const searchToolSchema = {
89
100
  */
90
101
  export async function executeSearch(input, context) {
91
102
  const startTime = performance.now();
92
- // Validate query
93
- if (!input.query || input.query.trim().length < 2) {
94
- throw new SkillsmithError(ErrorCodes.SEARCH_QUERY_EMPTY, 'Search query must be at least 2 characters');
103
+ // Validate: require query OR at least one filter
104
+ const hasQuery = input.query && input.query.trim().length > 0;
105
+ const hasFilters = input.category ||
106
+ input.trust_tier ||
107
+ input.min_score !== undefined ||
108
+ input.safe_only !== undefined ||
109
+ input.max_risk !== undefined;
110
+ if (!hasQuery && !hasFilters) {
111
+ throw new SkillsmithError(ErrorCodes.SEARCH_QUERY_EMPTY, 'Provide a search query or at least one filter (category, trust_tier, min_score, safe_only, max_risk)');
112
+ }
113
+ // SMI-1613: Anti-scraping - require minimum 3 chars when query IS provided
114
+ if (hasQuery && input.query.trim().length < 3) {
115
+ throw new SkillsmithError(ErrorCodes.SEARCH_QUERY_EMPTY, 'Query must be at least 3 characters. Use specific search terms like "testing", "git", or "docker".');
95
116
  }
96
117
  const filters = {};
97
118
  // Apply category filter
98
119
  if (input.category) {
99
120
  filters.category = input.category;
100
121
  }
101
- // Apply trust tier filter
122
+ // Apply trust tier filter with runtime validation
123
+ const VALID_TRUST_TIERS = ['verified', 'community', 'experimental', 'unknown'];
102
124
  if (input.trust_tier) {
125
+ if (!VALID_TRUST_TIERS.includes(input.trust_tier)) {
126
+ throw new SkillsmithError(ErrorCodes.VALIDATION_INVALID_TYPE, `Invalid trust_tier: ${input.trust_tier}. Must be one of: ${VALID_TRUST_TIERS.join(', ')}`, { details: { trust_tier: input.trust_tier, allowed: VALID_TRUST_TIERS } });
127
+ }
103
128
  filters.trustTier = input.trust_tier;
104
129
  }
105
130
  // Apply minimum score filter (convert 0-100 to 0-1 for database)
@@ -109,12 +134,22 @@ export async function executeSearch(input, context) {
109
134
  }
110
135
  filters.minScore = input.min_score / 100; // Convert to 0-1 scale for DB
111
136
  }
137
+ // SMI-825: Apply security filters
138
+ if (input.safe_only !== undefined) {
139
+ filters.safeOnly = input.safe_only;
140
+ }
141
+ if (input.max_risk !== undefined) {
142
+ if (input.max_risk < 0 || input.max_risk > 100) {
143
+ throw new SkillsmithError(ErrorCodes.VALIDATION_OUT_OF_RANGE, 'max_risk must be between 0 and 100', { details: { max_risk: input.max_risk } });
144
+ }
145
+ filters.maxRiskScore = input.max_risk;
146
+ }
112
147
  const searchStart = performance.now();
113
148
  // SMI-1183: Try API first, fall back to local DB
114
149
  if (!context.apiClient.isOffline()) {
115
150
  try {
116
151
  const apiResponse = await context.apiClient.search({
117
- query: input.query.trim(),
152
+ query: hasQuery ? input.query.trim() : '',
118
153
  limit: 10,
119
154
  offset: 0,
120
155
  trustTier: filters.trustTier ? mapTrustTierToDb(filters.trustTier) : undefined,
@@ -123,6 +158,7 @@ export async function executeSearch(input, context) {
123
158
  });
124
159
  const searchEnd = performance.now();
125
160
  // Convert API results to SkillSearchResult format
161
+ // SMI-1491: Added repository field for transparency
126
162
  const results = apiResponse.data.map((item) => ({
127
163
  id: item.id,
128
164
  name: item.name,
@@ -131,12 +167,13 @@ export async function executeSearch(input, context) {
131
167
  category: extractCategoryFromTags(item.tags),
132
168
  trustTier: mapTrustTierFromDb(item.trust_tier),
133
169
  score: Math.round((item.quality_score ?? 0) * 100),
170
+ repository: item.repo_url || undefined,
134
171
  }));
135
172
  const endTime = performance.now();
136
173
  const response = {
137
174
  results,
138
175
  total: apiResponse.meta?.total ?? results.length,
139
- query: input.query,
176
+ query: input.query || '', // May be empty for filter-only searches
140
177
  filters,
141
178
  timing: {
142
179
  searchMs: Math.round(searchEnd - searchStart),
@@ -145,7 +182,7 @@ export async function executeSearch(input, context) {
145
182
  };
146
183
  // SMI-1184: Track search event (silent on failure)
147
184
  if (context.distinctId) {
148
- trackSkillSearch(context.distinctId, input.query, response.total, response.timing.totalMs, {
185
+ trackSkillSearch(context.distinctId, input.query || '', response.total, response.timing.totalMs, {
149
186
  trustTier: filters.trustTier,
150
187
  category: filters.category,
151
188
  });
@@ -159,16 +196,23 @@ export async function executeSearch(input, context) {
159
196
  }
160
197
  // Fallback: Use local SearchService for FTS5 search with BM25 ranking
161
198
  const dbTrustTier = filters.trustTier ? mapTrustTierToDb(filters.trustTier) : undefined;
199
+ // Local search fallback - pass empty string if no query
200
+ const searchQuery = hasQuery ? input.query.trim() : '';
162
201
  const searchResults = context.searchService.search({
163
- query: input.query.trim(),
202
+ query: searchQuery,
164
203
  limit: 10,
165
204
  offset: 0,
166
205
  trustTier: dbTrustTier,
167
206
  minQualityScore: filters.minScore,
168
207
  category: filters.category,
208
+ // SMI-825: Security filters
209
+ safeOnly: filters.safeOnly,
210
+ maxRiskScore: filters.maxRiskScore,
169
211
  });
170
212
  const searchEnd = performance.now();
171
213
  // Convert SearchResult to SkillSearchResult format
214
+ // SMI-1491: Added repository field for transparency
215
+ // SMI-825: Added security summary
172
216
  const results = searchResults.items.map((item) => ({
173
217
  id: item.skill.id,
174
218
  name: item.skill.name,
@@ -177,12 +221,20 @@ export async function executeSearch(input, context) {
177
221
  category: extractCategoryFromTags(item.skill.tags),
178
222
  trustTier: mapTrustTierFromDb(item.skill.trustTier),
179
223
  score: Math.round((item.skill.qualityScore ?? 0) * 100), // Convert 0-1 to 0-100
224
+ repository: item.skill.repoUrl || undefined,
225
+ // SMI-825: Security summary
226
+ security: {
227
+ passed: item.skill.securityPassed,
228
+ riskScore: item.skill.riskScore,
229
+ findingsCount: item.skill.securityFindingsCount,
230
+ scannedAt: item.skill.securityScannedAt,
231
+ },
180
232
  }));
181
233
  const endTime = performance.now();
182
234
  const response = {
183
235
  results,
184
236
  total: searchResults.total,
185
- query: input.query,
237
+ query: input.query || '', // May be empty for filter-only searches
186
238
  filters,
187
239
  timing: {
188
240
  searchMs: Math.round(searchEnd - searchStart),
@@ -191,7 +243,7 @@ export async function executeSearch(input, context) {
191
243
  };
192
244
  // SMI-1184: Track search event (silent on failure)
193
245
  if (context.distinctId) {
194
- trackSkillSearch(context.distinctId, input.query, response.total, response.timing.totalMs, {
246
+ trackSkillSearch(context.distinctId, input.query || '', response.total, response.timing.totalMs, {
195
247
  trustTier: filters.trustTier,
196
248
  category: filters.category,
197
249
  });
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/tools/search.ts"],"names":[],"mappings":"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"}
@@ -22,77 +22,10 @@
22
22
  * strict: true
23
23
  * });
24
24
  */
25
- import { z } from 'zod';
26
25
  import type { ToolContext } from '../context.js';
27
- /**
28
- * Zod schema for validate tool input
29
- */
30
- export declare const validateInputSchema: z.ZodObject<{
31
- /** Path to SKILL.md file or skill directory */
32
- skill_path: z.ZodString;
33
- /** Enable strict validation (default false) */
34
- strict: z.ZodDefault<z.ZodBoolean>;
35
- }, "strip", z.ZodTypeAny, {
36
- skill_path: string;
37
- strict: boolean;
38
- }, {
39
- skill_path: string;
40
- strict?: boolean | undefined;
41
- }>;
42
- /**
43
- * Input type (before parsing, allows optional fields)
44
- */
45
- export type ValidateInput = z.input<typeof validateInputSchema>;
46
- /**
47
- * Validation error with severity
48
- */
49
- export interface ValidationError {
50
- /** Field that has the error */
51
- field: string;
52
- /** Error message */
53
- message: string;
54
- /** Severity level */
55
- severity: 'error' | 'warning';
56
- }
57
- /**
58
- * Validation response
59
- */
60
- export interface ValidateResponse {
61
- /** Whether the skill is valid */
62
- valid: boolean;
63
- /** List of validation errors/warnings */
64
- errors: ValidationError[];
65
- /** Parsed metadata if valid */
66
- metadata: Record<string, unknown> | null;
67
- /** File path validated */
68
- path: string;
69
- /** Performance timing */
70
- timing: {
71
- totalMs: number;
72
- };
73
- }
74
- /**
75
- * MCP tool schema definition for skill_validate
76
- */
77
- export declare const validateToolSchema: {
78
- name: string;
79
- description: string;
80
- inputSchema: {
81
- type: "object";
82
- properties: {
83
- skill_path: {
84
- type: string;
85
- description: string;
86
- };
87
- strict: {
88
- type: string;
89
- description: string;
90
- default: boolean;
91
- };
92
- };
93
- required: string[];
94
- };
95
- };
26
+ import type { ValidateInput, ValidateResponse } from './validate.types.js';
27
+ export type { ValidateInput, ValidateResponse, ValidationError } from './validate.types.js';
28
+ export { validateInputSchema, validateToolSchema } from './validate.types.js';
96
29
  /**
97
30
  * Execute skill validation.
98
31
  *
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD;;GAEG;AACH,eAAO,MAAM,mBAAmB;IAC9B,+CAA+C;;IAE/C,+CAA+C;;;;;;;;EAE/C,CAAA;AAEF;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,qBAAqB;IACrB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,KAAK,EAAE,OAAO,CAAA;IACd,yCAAyC;IACzC,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACxC,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;CAoB9B,CAAA;AA+TD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,gBAAgB,CAAC,CA2E3B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAqD1E"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/tools/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAmB,MAAM,qBAAqB,CAAA;AAO3F,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAC3F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE7E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,aAAa,EACpB,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAyE3B;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAqD1E"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Validate Tool Helper Functions
3
+ * @module @skillsmith/mcp-server/tools/validate.helpers
4
+ */
5
+ import type { ValidationError } from './validate.types.js';
6
+ /**
7
+ * Parse YAML frontmatter from markdown content
8
+ */
9
+ export declare function parseYamlFrontmatter(content: string): Record<string, unknown> | null;
10
+ /**
11
+ * Check for SSRF patterns in a URL
12
+ */
13
+ export declare function hasSsrfPattern(url: string): boolean;
14
+ /**
15
+ * Check for path traversal patterns
16
+ */
17
+ export declare function hasPathTraversal(path: string): boolean;
18
+ /**
19
+ * Validate skill metadata
20
+ */
21
+ export declare function validateMetadata(metadata: Record<string, unknown>, strict: boolean): ValidationError[];
22
+ //# sourceMappingURL=validate.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/validate.helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAG1D;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAqFpF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,MAAM,EAAE,OAAO,GACd,eAAe,EAAE,CA4KnB"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Validate Tool Helper Functions
3
+ * @module @skillsmith/mcp-server/tools/validate.helpers
4
+ */
5
+ import { FIELD_LIMITS, SSRF_PATTERNS, PATH_TRAVERSAL_PATTERNS } from './validate.types.js';
6
+ /**
7
+ * Parse YAML frontmatter from markdown content
8
+ */
9
+ export function parseYamlFrontmatter(content) {
10
+ const trimmed = content.trim();
11
+ if (!trimmed.startsWith('---')) {
12
+ return null;
13
+ }
14
+ const endIndex = trimmed.indexOf('---', 3);
15
+ if (endIndex === -1) {
16
+ return null;
17
+ }
18
+ const yamlContent = trimmed.slice(3, endIndex).trim();
19
+ const result = {};
20
+ const lines = yamlContent.split('\n');
21
+ let currentKey = null;
22
+ let arrayBuffer = [];
23
+ let inArray = false;
24
+ for (const line of lines) {
25
+ const trimmedLine = line.trim();
26
+ if (!trimmedLine || trimmedLine.startsWith('#')) {
27
+ continue;
28
+ }
29
+ if (trimmedLine.startsWith('- ')) {
30
+ if (currentKey && inArray) {
31
+ const value = trimmedLine
32
+ .slice(2)
33
+ .trim()
34
+ .replace(/^["']|["']$/g, '');
35
+ arrayBuffer.push(value);
36
+ }
37
+ continue;
38
+ }
39
+ const colonIndex = trimmedLine.indexOf(':');
40
+ if (colonIndex > 0) {
41
+ if (currentKey && inArray && arrayBuffer.length > 0) {
42
+ result[currentKey] = arrayBuffer;
43
+ arrayBuffer = [];
44
+ }
45
+ const key = trimmedLine.slice(0, colonIndex).trim();
46
+ const value = trimmedLine.slice(colonIndex + 1).trim();
47
+ if (value === '' || value === '|' || value === '>') {
48
+ currentKey = key;
49
+ inArray = true;
50
+ arrayBuffer = [];
51
+ }
52
+ else {
53
+ currentKey = null;
54
+ inArray = false;
55
+ let parsedValue = value;
56
+ if ((value.startsWith('"') && value.endsWith('"')) ||
57
+ (value.startsWith("'") && value.endsWith("'"))) {
58
+ parsedValue = value.slice(1, -1);
59
+ }
60
+ else if (value === 'true') {
61
+ parsedValue = true;
62
+ }
63
+ else if (value === 'false') {
64
+ parsedValue = false;
65
+ }
66
+ else if (/^-?\d+(\.\d+)?$/.test(value)) {
67
+ parsedValue = parseFloat(value);
68
+ }
69
+ else if (value.startsWith('[') && value.endsWith(']')) {
70
+ parsedValue = value
71
+ .slice(1, -1)
72
+ .split(',')
73
+ .map((item) => item.trim().replace(/^["']|["']$/g, ''))
74
+ .filter((item) => item.length > 0);
75
+ }
76
+ result[key] = parsedValue;
77
+ }
78
+ }
79
+ }
80
+ if (currentKey && inArray && arrayBuffer.length > 0) {
81
+ result[currentKey] = arrayBuffer;
82
+ }
83
+ return result;
84
+ }
85
+ /**
86
+ * Check for SSRF patterns in a URL
87
+ */
88
+ export function hasSsrfPattern(url) {
89
+ return SSRF_PATTERNS.some((pattern) => pattern.test(url));
90
+ }
91
+ /**
92
+ * Check for path traversal patterns
93
+ */
94
+ export function hasPathTraversal(path) {
95
+ return PATH_TRAVERSAL_PATTERNS.some((pattern) => pattern.test(path));
96
+ }
97
+ /**
98
+ * Validate skill metadata
99
+ */
100
+ export function validateMetadata(metadata, strict) {
101
+ const errors = [];
102
+ // Required fields - name
103
+ if (!metadata.name) {
104
+ errors.push({
105
+ field: 'name',
106
+ message: 'Required field "name" is missing',
107
+ severity: 'error',
108
+ });
109
+ }
110
+ else if (typeof metadata.name !== 'string') {
111
+ errors.push({
112
+ field: 'name',
113
+ message: 'Field "name" must be a string',
114
+ severity: 'error',
115
+ });
116
+ }
117
+ else if (metadata.name.length > FIELD_LIMITS.name) {
118
+ errors.push({
119
+ field: 'name',
120
+ message: `Field "name" exceeds maximum length of ${FIELD_LIMITS.name} characters`,
121
+ severity: 'error',
122
+ });
123
+ }
124
+ // Description validation
125
+ if (!metadata.description) {
126
+ errors.push({
127
+ field: 'description',
128
+ message: 'Required field "description" is missing',
129
+ severity: strict ? 'error' : 'warning',
130
+ });
131
+ }
132
+ else if (typeof metadata.description !== 'string') {
133
+ errors.push({
134
+ field: 'description',
135
+ message: 'Field "description" must be a string',
136
+ severity: 'error',
137
+ });
138
+ }
139
+ else if (metadata.description.length > FIELD_LIMITS.description) {
140
+ errors.push({
141
+ field: 'description',
142
+ message: `Field "description" exceeds maximum length of ${FIELD_LIMITS.description} characters`,
143
+ severity: 'error',
144
+ });
145
+ }
146
+ // Author validation
147
+ if (metadata.author !== undefined) {
148
+ if (typeof metadata.author !== 'string') {
149
+ errors.push({
150
+ field: 'author',
151
+ message: 'Field "author" must be a string',
152
+ severity: 'error',
153
+ });
154
+ }
155
+ else if (metadata.author.length > FIELD_LIMITS.author) {
156
+ errors.push({
157
+ field: 'author',
158
+ message: `Field "author" exceeds maximum length of ${FIELD_LIMITS.author} characters`,
159
+ severity: 'error',
160
+ });
161
+ }
162
+ }
163
+ // Version validation
164
+ if (metadata.version !== undefined) {
165
+ if (typeof metadata.version !== 'string') {
166
+ errors.push({
167
+ field: 'version',
168
+ message: 'Field "version" must be a string',
169
+ severity: 'error',
170
+ });
171
+ }
172
+ else if (metadata.version.length > FIELD_LIMITS.version) {
173
+ errors.push({
174
+ field: 'version',
175
+ message: `Field "version" exceeds maximum length of ${FIELD_LIMITS.version} characters`,
176
+ severity: 'error',
177
+ });
178
+ }
179
+ }
180
+ else if (strict) {
181
+ errors.push({
182
+ field: 'version',
183
+ message: 'Field "version" is recommended',
184
+ severity: 'warning',
185
+ });
186
+ }
187
+ // Tags validation
188
+ if (metadata.tags !== undefined) {
189
+ if (!Array.isArray(metadata.tags)) {
190
+ errors.push({
191
+ field: 'tags',
192
+ message: 'Field "tags" must be an array',
193
+ severity: 'error',
194
+ });
195
+ }
196
+ else {
197
+ if (metadata.tags.length > FIELD_LIMITS.maxTags) {
198
+ errors.push({
199
+ field: 'tags',
200
+ message: `Field "tags" exceeds maximum count of ${FIELD_LIMITS.maxTags}`,
201
+ severity: 'error',
202
+ });
203
+ }
204
+ for (let i = 0; i < metadata.tags.length; i++) {
205
+ const tag = metadata.tags[i];
206
+ if (typeof tag !== 'string') {
207
+ errors.push({
208
+ field: `tags[${i}]`,
209
+ message: 'Tag must be a string',
210
+ severity: 'error',
211
+ });
212
+ }
213
+ else if (tag.length > FIELD_LIMITS.tagLength) {
214
+ errors.push({
215
+ field: `tags[${i}]`,
216
+ message: `Tag exceeds maximum length of ${FIELD_LIMITS.tagLength} characters`,
217
+ severity: 'error',
218
+ });
219
+ }
220
+ }
221
+ }
222
+ }
223
+ else if (strict) {
224
+ errors.push({
225
+ field: 'tags',
226
+ message: 'Field "tags" is recommended for discoverability',
227
+ severity: 'warning',
228
+ });
229
+ }
230
+ // Security: Check repository URL for SSRF
231
+ if (metadata.repository !== undefined) {
232
+ if (typeof metadata.repository !== 'string') {
233
+ errors.push({
234
+ field: 'repository',
235
+ message: 'Field "repository" must be a string',
236
+ severity: 'error',
237
+ });
238
+ }
239
+ else if (hasSsrfPattern(metadata.repository)) {
240
+ errors.push({
241
+ field: 'repository',
242
+ message: 'Field "repository" contains potentially dangerous URL pattern',
243
+ severity: 'error',
244
+ });
245
+ }
246
+ }
247
+ // Security: Check homepage URL for SSRF
248
+ if (metadata.homepage !== undefined) {
249
+ if (typeof metadata.homepage !== 'string') {
250
+ errors.push({
251
+ field: 'homepage',
252
+ message: 'Field "homepage" must be a string',
253
+ severity: 'error',
254
+ });
255
+ }
256
+ else if (hasSsrfPattern(metadata.homepage)) {
257
+ errors.push({
258
+ field: 'homepage',
259
+ message: 'Field "homepage" contains potentially dangerous URL pattern',
260
+ severity: 'error',
261
+ });
262
+ }
263
+ }
264
+ // Security: Check for path traversal in any string fields
265
+ for (const [key, value] of Object.entries(metadata)) {
266
+ if (typeof value === 'string' && hasPathTraversal(value)) {
267
+ errors.push({
268
+ field: key,
269
+ message: `Field "${key}" contains path traversal pattern`,
270
+ severity: 'error',
271
+ });
272
+ }
273
+ }
274
+ return errors;
275
+ }
276
+ //# sourceMappingURL=validate.helpers.js.map