@skillsmith/mcp-server 0.4.2 → 0.4.3

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 (178) hide show
  1. package/README.md +11 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/__tests__/LocalIndexer.test.js +158 -0
  4. package/dist/src/__tests__/LocalIndexer.test.js.map +1 -1
  5. package/dist/src/__tests__/compare.test.d.ts +8 -0
  6. package/dist/src/__tests__/compare.test.d.ts.map +1 -0
  7. package/dist/src/__tests__/compare.test.js +162 -0
  8. package/dist/src/__tests__/compare.test.js.map +1 -0
  9. package/dist/src/__tests__/context.async.test.d.ts +8 -0
  10. package/dist/src/__tests__/context.async.test.d.ts.map +1 -0
  11. package/dist/src/__tests__/context.async.test.js +223 -0
  12. package/dist/src/__tests__/context.async.test.js.map +1 -0
  13. package/dist/src/__tests__/middleware/errorFormatter.builders.test.d.ts +10 -0
  14. package/dist/src/__tests__/middleware/errorFormatter.builders.test.d.ts.map +1 -0
  15. package/dist/src/__tests__/middleware/errorFormatter.builders.test.js +93 -0
  16. package/dist/src/__tests__/middleware/errorFormatter.builders.test.js.map +1 -0
  17. package/dist/src/__tests__/middleware/license-renewal.test.d.ts +10 -0
  18. package/dist/src/__tests__/middleware/license-renewal.test.d.ts.map +1 -0
  19. package/dist/src/__tests__/middleware/license-renewal.test.js +152 -0
  20. package/dist/src/__tests__/middleware/license-renewal.test.js.map +1 -0
  21. package/dist/src/__tests__/middleware/quota-helpers.test.d.ts +9 -0
  22. package/dist/src/__tests__/middleware/quota-helpers.test.d.ts.map +1 -0
  23. package/dist/src/__tests__/middleware/quota-helpers.test.js +105 -0
  24. package/dist/src/__tests__/middleware/quota-helpers.test.js.map +1 -0
  25. package/dist/src/__tests__/middleware/quota.test.d.ts +12 -0
  26. package/dist/src/__tests__/middleware/quota.test.d.ts.map +1 -0
  27. package/dist/src/__tests__/middleware/quota.test.js +189 -0
  28. package/dist/src/__tests__/middleware/quota.test.js.map +1 -0
  29. package/dist/src/__tests__/recommend-online-path.test.d.ts +10 -0
  30. package/dist/src/__tests__/recommend-online-path.test.d.ts.map +1 -0
  31. package/dist/src/__tests__/recommend-online-path.test.js +225 -0
  32. package/dist/src/__tests__/recommend-online-path.test.js.map +1 -0
  33. package/dist/src/__tests__/recommend.test.d.ts +2 -0
  34. package/dist/src/__tests__/recommend.test.d.ts.map +1 -1
  35. package/dist/src/__tests__/recommend.test.js +14 -2
  36. package/dist/src/__tests__/recommend.test.js.map +1 -1
  37. package/dist/src/__tests__/search-online-path.test.d.ts +10 -0
  38. package/dist/src/__tests__/search-online-path.test.d.ts.map +1 -0
  39. package/dist/src/__tests__/search-online-path.test.js +140 -0
  40. package/dist/src/__tests__/search-online-path.test.js.map +1 -0
  41. package/dist/src/__tests__/search.test.js +153 -5
  42. package/dist/src/__tests__/search.test.js.map +1 -1
  43. package/dist/src/context/project-detector.d.ts.map +1 -1
  44. package/dist/src/context/project-detector.js +1 -0
  45. package/dist/src/context/project-detector.js.map +1 -1
  46. package/dist/src/context.async.d.ts +48 -0
  47. package/dist/src/context.async.d.ts.map +1 -0
  48. package/dist/src/context.async.js +215 -0
  49. package/dist/src/context.async.js.map +1 -0
  50. package/dist/src/context.d.ts +5 -145
  51. package/dist/src/context.d.ts.map +1 -1
  52. package/dist/src/context.helpers.d.ts +25 -0
  53. package/dist/src/context.helpers.d.ts.map +1 -0
  54. package/dist/src/context.helpers.js +49 -0
  55. package/dist/src/context.helpers.js.map +1 -0
  56. package/dist/src/context.js +11 -228
  57. package/dist/src/context.js.map +1 -1
  58. package/dist/src/context.types.d.ts +110 -0
  59. package/dist/src/context.types.d.ts.map +1 -0
  60. package/dist/src/context.types.js +10 -0
  61. package/dist/src/context.types.js.map +1 -0
  62. package/dist/src/health/readinessCheck.d.ts +1 -1
  63. package/dist/src/health/readinessCheck.d.ts.map +1 -1
  64. package/dist/src/index.js +21 -152
  65. package/dist/src/index.js.map +1 -1
  66. package/dist/src/indexer/FrontmatterParser.d.ts +6 -0
  67. package/dist/src/indexer/FrontmatterParser.d.ts.map +1 -1
  68. package/dist/src/indexer/FrontmatterParser.js +15 -0
  69. package/dist/src/indexer/FrontmatterParser.js.map +1 -1
  70. package/dist/src/indexer/LocalIndexer.d.ts +4 -0
  71. package/dist/src/indexer/LocalIndexer.d.ts.map +1 -1
  72. package/dist/src/indexer/LocalIndexer.js +3 -0
  73. package/dist/src/indexer/LocalIndexer.js.map +1 -1
  74. package/dist/src/middleware/degradation.d.ts.map +1 -1
  75. package/dist/src/middleware/degradation.js +8 -0
  76. package/dist/src/middleware/degradation.js.map +1 -1
  77. package/dist/src/middleware/errorFormatter.builders.d.ts +49 -0
  78. package/dist/src/middleware/errorFormatter.builders.d.ts.map +1 -0
  79. package/dist/src/middleware/errorFormatter.builders.js +237 -0
  80. package/dist/src/middleware/errorFormatter.builders.js.map +1 -0
  81. package/dist/src/middleware/errorFormatter.d.ts +5 -100
  82. package/dist/src/middleware/errorFormatter.d.ts.map +1 -1
  83. package/dist/src/middleware/errorFormatter.js +16 -238
  84. package/dist/src/middleware/errorFormatter.js.map +1 -1
  85. package/dist/src/middleware/errorFormatter.types.d.ts +81 -0
  86. package/dist/src/middleware/errorFormatter.types.d.ts.map +1 -0
  87. package/dist/src/middleware/errorFormatter.types.js +34 -0
  88. package/dist/src/middleware/errorFormatter.types.js.map +1 -0
  89. package/dist/src/middleware/toolFeatureMapping.d.ts +1 -1
  90. package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -1
  91. package/dist/src/middleware/toolFeatureMapping.js +8 -0
  92. package/dist/src/middleware/toolFeatureMapping.js.map +1 -1
  93. package/dist/src/tool-dispatch.d.ts +27 -0
  94. package/dist/src/tool-dispatch.d.ts.map +1 -0
  95. package/dist/src/tool-dispatch.js +127 -0
  96. package/dist/src/tool-dispatch.js.map +1 -0
  97. package/dist/src/tools/LocalSkillSearch.d.ts.map +1 -1
  98. package/dist/src/tools/LocalSkillSearch.js +4 -0
  99. package/dist/src/tools/LocalSkillSearch.js.map +1 -1
  100. package/dist/src/tools/get-skill.d.ts.map +1 -1
  101. package/dist/src/tools/get-skill.js +14 -0
  102. package/dist/src/tools/get-skill.js.map +1 -1
  103. package/dist/src/tools/index.d.ts +6 -0
  104. package/dist/src/tools/index.d.ts.map +1 -1
  105. package/dist/src/tools/index.js +6 -0
  106. package/dist/src/tools/index.js.map +1 -1
  107. package/dist/src/tools/install.d.ts +3 -35
  108. package/dist/src/tools/install.d.ts.map +1 -1
  109. package/dist/src/tools/install.js +22 -74
  110. package/dist/src/tools/install.js.map +1 -1
  111. package/dist/src/tools/install.optimize.d.ts +46 -0
  112. package/dist/src/tools/install.optimize.d.ts.map +1 -0
  113. package/dist/src/tools/install.optimize.js +67 -0
  114. package/dist/src/tools/install.optimize.js.map +1 -0
  115. package/dist/src/tools/install.tool.d.ts +44 -0
  116. package/dist/src/tools/install.tool.d.ts.map +1 -0
  117. package/dist/src/tools/install.tool.js +44 -0
  118. package/dist/src/tools/install.tool.js.map +1 -0
  119. package/dist/src/tools/install.types.d.ts +7 -1
  120. package/dist/src/tools/install.types.d.ts.map +1 -1
  121. package/dist/src/tools/recommend.d.ts +2 -4
  122. package/dist/src/tools/recommend.d.ts.map +1 -1
  123. package/dist/src/tools/recommend.format.d.ts +28 -0
  124. package/dist/src/tools/recommend.format.d.ts.map +1 -0
  125. package/dist/src/tools/recommend.format.js +111 -0
  126. package/dist/src/tools/recommend.format.js.map +1 -0
  127. package/dist/src/tools/recommend.js +6 -97
  128. package/dist/src/tools/recommend.js.map +1 -1
  129. package/dist/src/tools/recommend.types.d.ts +1 -1
  130. package/dist/src/tools/search.d.ts +24 -21
  131. package/dist/src/tools/search.d.ts.map +1 -1
  132. package/dist/src/tools/search.formatter.d.ts +30 -0
  133. package/dist/src/tools/search.formatter.d.ts.map +1 -0
  134. package/dist/src/tools/search.formatter.js +64 -0
  135. package/dist/src/tools/search.formatter.js.map +1 -0
  136. package/dist/src/tools/search.js +55 -54
  137. package/dist/src/tools/search.js.map +1 -1
  138. package/dist/src/tools/skill-audit.d.ts +98 -0
  139. package/dist/src/tools/skill-audit.d.ts.map +1 -0
  140. package/dist/src/tools/skill-audit.js +105 -0
  141. package/dist/src/tools/skill-audit.js.map +1 -0
  142. package/dist/src/tools/skill-audit.test.d.ts +6 -0
  143. package/dist/src/tools/skill-audit.test.d.ts.map +1 -0
  144. package/dist/src/tools/skill-audit.test.js +121 -0
  145. package/dist/src/tools/skill-audit.test.js.map +1 -0
  146. package/dist/src/tools/skill-diff.d.ts +107 -0
  147. package/dist/src/tools/skill-diff.d.ts.map +1 -0
  148. package/dist/src/tools/skill-diff.js +268 -0
  149. package/dist/src/tools/skill-diff.js.map +1 -0
  150. package/dist/src/tools/skill-diff.test.d.ts +6 -0
  151. package/dist/src/tools/skill-diff.test.d.ts.map +1 -0
  152. package/dist/src/tools/skill-diff.test.js +260 -0
  153. package/dist/src/tools/skill-diff.test.js.map +1 -0
  154. package/dist/src/tools/skill-updates.d.ts +1 -1
  155. package/dist/src/tools/skill-updates.d.ts.map +1 -1
  156. package/dist/src/tools/suggest.d.ts +4 -4
  157. package/dist/src/tools/uninstall.d.ts +1 -1
  158. package/dist/src/tools/validate.helpers.d.ts.map +1 -1
  159. package/dist/src/tools/validate.helpers.js +31 -0
  160. package/dist/src/tools/validate.helpers.js.map +1 -1
  161. package/dist/src/utils/validation.d.ts +13 -0
  162. package/dist/src/utils/validation.d.ts.map +1 -1
  163. package/dist/src/utils/validation.js +27 -0
  164. package/dist/src/utils/validation.js.map +1 -1
  165. package/dist/tests/health.test.js +4 -4
  166. package/dist/tests/health.test.js.map +1 -1
  167. package/dist/tests/integration/recommend.integration.test.js +2 -0
  168. package/dist/tests/integration/recommend.integration.test.js.map +1 -1
  169. package/dist/tests/integration/setup.d.ts +3 -1
  170. package/dist/tests/integration/setup.d.ts.map +1 -1
  171. package/dist/tests/integration/setup.js +4 -1
  172. package/dist/tests/integration/setup.js.map +1 -1
  173. package/dist/tests/recommend.test.js +2 -0
  174. package/dist/tests/recommend.test.js.map +1 -1
  175. package/dist/tests/unit/validate-helpers.test.js +54 -0
  176. package/dist/tests/unit/validate-helpers.test.js.map +1 -1
  177. package/package.json +2 -2
  178. package/server.json +2 -2
@@ -0,0 +1,237 @@
1
+ /**
2
+ * @fileoverview Error Response Builder Functions
3
+ * @module @skillsmith/mcp-server/middleware/errorFormatter.builders
4
+ * @see SMI-1061: MCP Error Formatter for License Errors
5
+ * @see SMI-2741: Split from errorFormatter.ts to meet 500-line standard
6
+ *
7
+ * Pre-built MCP error response factories for common license error scenarios:
8
+ * - Upgrade required (feature tier mismatch)
9
+ * - License expired (renewal needed)
10
+ * - Quota exceeded (usage limit hit)
11
+ * - API authentication errors (401 handling)
12
+ */
13
+ import { DEFAULT_UPGRADE_URL_CONFIG } from './errorFormatter.types.js';
14
+ // ============================================================================
15
+ // Upgrade URL Generation
16
+ // ============================================================================
17
+ /**
18
+ * Generate a customized upgrade URL with tracking parameters
19
+ */
20
+ export function generateUpgradeUrl(error, config = {}) {
21
+ const fullConfig = { ...DEFAULT_UPGRADE_URL_CONFIG, ...config };
22
+ const params = new URLSearchParams();
23
+ if (fullConfig.includeFeature && error.feature) {
24
+ params.set('feature', error.feature);
25
+ }
26
+ if (fullConfig.includeTiers) {
27
+ if (error.currentTier) {
28
+ params.set('from', error.currentTier);
29
+ }
30
+ if (error.requiredTier) {
31
+ params.set('to', error.requiredTier);
32
+ }
33
+ }
34
+ if (fullConfig.includeSource) {
35
+ params.set('source', 'mcp-error');
36
+ if (error.code) {
37
+ params.set('error_code', error.code);
38
+ }
39
+ }
40
+ const queryString = params.toString();
41
+ return queryString ? `${fullConfig.baseUrl}?${queryString}` : fullConfig.baseUrl || '';
42
+ }
43
+ // ============================================================================
44
+ // Response Builders
45
+ // ============================================================================
46
+ /**
47
+ * Build an upgrade required response
48
+ *
49
+ * Use this when a feature requires an upgrade but isn't a full error.
50
+ */
51
+ export function buildUpgradeRequiredResponse(feature, currentTier, requiredTier) {
52
+ const upgradeUrl = `https://skillsmith.app/upgrade?feature=${feature}&from=${currentTier}&to=${requiredTier}`;
53
+ return {
54
+ content: [
55
+ {
56
+ type: 'text',
57
+ text: JSON.stringify({
58
+ error: {
59
+ code: 'E004',
60
+ message: `${feature} requires ${requiredTier} tier`,
61
+ details: {
62
+ feature,
63
+ currentTier,
64
+ requiredTier,
65
+ upgradeUrl,
66
+ },
67
+ },
68
+ }, null, 2),
69
+ },
70
+ ],
71
+ isError: true,
72
+ _meta: {
73
+ upgradeUrl,
74
+ errorCode: 'E004',
75
+ recoverable: false,
76
+ },
77
+ };
78
+ }
79
+ /**
80
+ * Build a license expired response with renewal URL
81
+ */
82
+ export function buildLicenseExpiredResponse(expiredAt) {
83
+ const renewUrl = 'https://skillsmith.app/renew';
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: JSON.stringify({
89
+ error: {
90
+ code: 'E001',
91
+ message: 'Your license has expired',
92
+ details: {
93
+ expiredAt: expiredAt?.toISOString(),
94
+ renewUrl,
95
+ },
96
+ },
97
+ }, null, 2),
98
+ },
99
+ ],
100
+ isError: true,
101
+ _meta: {
102
+ upgradeUrl: renewUrl,
103
+ errorCode: 'E001',
104
+ recoverable: false,
105
+ },
106
+ };
107
+ }
108
+ /**
109
+ * Build a quota exceeded response
110
+ */
111
+ export function buildQuotaExceededResponse(quotaType, current, max) {
112
+ const upgradeUrl = `https://skillsmith.app/upgrade?quota=${quotaType}`;
113
+ return {
114
+ content: [
115
+ {
116
+ type: 'text',
117
+ text: JSON.stringify({
118
+ error: {
119
+ code: 'E005',
120
+ message: `${quotaType} quota exceeded`,
121
+ details: {
122
+ quotaType,
123
+ current,
124
+ max,
125
+ upgradeUrl,
126
+ },
127
+ },
128
+ }, null, 2),
129
+ },
130
+ ],
131
+ isError: true,
132
+ _meta: {
133
+ upgradeUrl,
134
+ errorCode: 'E005',
135
+ recoverable: false,
136
+ },
137
+ };
138
+ }
139
+ // ============================================================================
140
+ // API Authentication Error Formatting (SMI-XXXX)
141
+ // ============================================================================
142
+ /**
143
+ * Format a 401 authentication error for MCP display
144
+ * Provides user-friendly instructions for getting an API key
145
+ *
146
+ * @param details - Error details from the API response
147
+ * @returns MCP-formatted error response with signup instructions
148
+ */
149
+ export function formatAuthenticationError(details = {}) {
150
+ const signupUrl = details.signupUrl || 'https://skillsmith.app/signup';
151
+ const docsUrl = details.docsUrl || 'https://skillsmith.app/docs/getting-started#api-key';
152
+ const trialInfo = details.trialUsed !== undefined && details.trialLimit !== undefined
153
+ ? `\n\nšŸ“Š **Trial Usage**: ${details.trialUsed}/${details.trialLimit} free requests used`
154
+ : '';
155
+ const message = `šŸ” **Authentication Required**
156
+
157
+ ${details.reason || 'API key required for this request.'}
158
+
159
+ **Get Started (Free - 1,000 requests/month):**
160
+ 1. Create account: ${signupUrl}
161
+ 2. Your API key will be generated automatically
162
+ 3. Add to your Claude settings:
163
+
164
+ \`\`\`json
165
+ {
166
+ "mcpServers": {
167
+ "skillsmith": {
168
+ "command": "npx",
169
+ "args": ["-y", "@skillsmith/mcp-server"],
170
+ "env": {
171
+ "SKILLSMITH_API_KEY": "your_key_here"
172
+ }
173
+ }
174
+ }
175
+ }
176
+ \`\`\`${trialInfo}
177
+
178
+ [Documentation](${docsUrl})
179
+ `;
180
+ return {
181
+ content: [
182
+ {
183
+ type: 'text',
184
+ text: message,
185
+ },
186
+ ],
187
+ isError: true,
188
+ _meta: {
189
+ errorCode: 'AUTHENTICATION_REQUIRED',
190
+ recoverable: true,
191
+ upgradeUrl: signupUrl,
192
+ },
193
+ };
194
+ }
195
+ /**
196
+ * Check if an API error is an authentication error (401)
197
+ */
198
+ export function isAuthenticationError(error) {
199
+ if (!error || typeof error !== 'object') {
200
+ return false;
201
+ }
202
+ const e = error;
203
+ // Check for status code
204
+ if (e.statusCode === 401 || e.status === 401) {
205
+ return true;
206
+ }
207
+ // Check for error message patterns
208
+ if (typeof e.message === 'string') {
209
+ const msg = e.message.toLowerCase();
210
+ if (msg.includes('authentication required') || msg.includes('free trial exhausted')) {
211
+ return true;
212
+ }
213
+ }
214
+ // Check for error field
215
+ if (typeof e.error === 'string') {
216
+ const err = e.error.toLowerCase();
217
+ if (err.includes('authentication required')) {
218
+ return true;
219
+ }
220
+ }
221
+ return false;
222
+ }
223
+ /**
224
+ * Extract authentication error details from an API error response
225
+ */
226
+ export function extractAuthErrorDetails(error) {
227
+ if (!error || typeof error !== 'object') {
228
+ return {};
229
+ }
230
+ const e = error;
231
+ // Check for details object
232
+ if (e.details && typeof e.details === 'object') {
233
+ return e.details;
234
+ }
235
+ return {};
236
+ }
237
+ //# sourceMappingURL=errorFormatter.builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorFormatter.builders.js","sourceRoot":"","sources":["../../../src/middleware/errorFormatter.builders.ts"],"names":[],"mappings":"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"}
@@ -1,55 +1,14 @@
1
1
  /**
2
2
  * SMI-1061: MCP Error Formatter for License Errors
3
+ * @see SMI-2741: Types split to errorFormatter.types.ts, builders to errorFormatter.builders.ts
3
4
  *
4
5
  * Formats license errors into MCP protocol-compliant error responses
5
6
  * with actionable information for clients.
6
7
  */
7
- /**
8
- * MCP-formatted error response content
9
- */
10
- export interface MCPErrorContent {
11
- type: 'text';
12
- text: string;
13
- }
14
- /**
15
- * MCP-formatted error response
16
- */
17
- export interface MCPErrorResponse {
18
- content: MCPErrorContent[];
19
- isError: true;
20
- _meta?: {
21
- upgradeUrl?: string;
22
- errorCode?: string;
23
- recoverable?: boolean;
24
- };
25
- }
26
- /**
27
- * License error details structure (mirrors the enterprise package)
28
- */
29
- export interface LicenseErrorDetails {
30
- code: string;
31
- message: string;
32
- feature?: string;
33
- currentTier?: string;
34
- requiredTier?: string;
35
- upgradeUrl?: string;
36
- context?: Record<string, unknown>;
37
- timestamp?: string;
38
- }
39
- /**
40
- * Interface for license errors (duck-typed for optional enterprise package)
41
- */
42
- export interface LicenseErrorLike {
43
- code?: string;
44
- message: string;
45
- feature?: string;
46
- currentTier?: string;
47
- requiredTier?: string;
48
- upgradeUrl?: string;
49
- context?: Record<string, unknown>;
50
- timestamp?: Date;
51
- toJSON?: () => Record<string, unknown>;
52
- }
8
+ export type { MCPErrorContent, MCPErrorResponse, LicenseErrorDetails, LicenseErrorLike, UpgradeUrlConfig, ApiAuthErrorDetails, } from './errorFormatter.types.js';
9
+ export { ERROR_MESSAGES, DEFAULT_UPGRADE_URL_CONFIG } from './errorFormatter.types.js';
10
+ export { generateUpgradeUrl, buildUpgradeRequiredResponse, buildLicenseExpiredResponse, buildQuotaExceededResponse, formatAuthenticationError, isAuthenticationError, extractAuthErrorDetails, } from './errorFormatter.builders.js';
11
+ import type { MCPErrorResponse, LicenseErrorLike } from './errorFormatter.types.js';
53
12
  /**
54
13
  * Format a license error into an MCP-compliant error response
55
14
  *
@@ -81,33 +40,6 @@ export declare function formatGenericError(error: Error, code?: string): MCPErro
81
40
  * Get a user-friendly message for an error code
82
41
  */
83
42
  export declare function getUserFriendlyMessage(code: string): string;
84
- /**
85
- * Configuration for upgrade URLs
86
- */
87
- export interface UpgradeUrlConfig {
88
- baseUrl?: string;
89
- includeFeature?: boolean;
90
- includeTiers?: boolean;
91
- includeSource?: boolean;
92
- }
93
- /**
94
- * Generate a customized upgrade URL with tracking parameters
95
- */
96
- export declare function generateUpgradeUrl(error: LicenseErrorLike, config?: Partial<UpgradeUrlConfig>): string;
97
- /**
98
- * Build an upgrade required response
99
- *
100
- * Use this when a feature requires an upgrade but isn't a full error.
101
- */
102
- export declare function buildUpgradeRequiredResponse(feature: string, currentTier: string, requiredTier: string): MCPErrorResponse;
103
- /**
104
- * Build a license expired response with renewal URL
105
- */
106
- export declare function buildLicenseExpiredResponse(expiredAt?: Date): MCPErrorResponse;
107
- /**
108
- * Build a quota exceeded response
109
- */
110
- export declare function buildQuotaExceededResponse(quotaType: string, current: number, max: number): MCPErrorResponse;
111
43
  /**
112
44
  * Check if an object looks like a license error
113
45
  */
@@ -116,31 +48,4 @@ export declare function isLicenseErrorLike(error: unknown): error is LicenseErro
116
48
  * Safely convert any error to MCP format
117
49
  */
118
50
  export declare function safeFormatError(error: unknown): MCPErrorResponse;
119
- /**
120
- * Details from a 401 API authentication error
121
- */
122
- export interface ApiAuthErrorDetails {
123
- reason?: string;
124
- signupUrl?: string;
125
- docsUrl?: string;
126
- hint?: string;
127
- trialUsed?: number;
128
- trialLimit?: number;
129
- }
130
- /**
131
- * Format a 401 authentication error for MCP display
132
- * Provides user-friendly instructions for getting an API key
133
- *
134
- * @param details - Error details from the API response
135
- * @returns MCP-formatted error response with signup instructions
136
- */
137
- export declare function formatAuthenticationError(details?: ApiAuthErrorDetails): MCPErrorResponse;
138
- /**
139
- * Check if an API error is an authentication error (401)
140
- */
141
- export declare function isAuthenticationError(error: unknown): boolean;
142
- /**
143
- * Extract authentication error details from an API error response
144
- */
145
- export declare function extractAuthErrorDetails(error: unknown): ApiAuthErrorDetails;
146
51
  //# sourceMappingURL=errorFormatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errorFormatter.d.ts","sourceRoot":"","sources":["../../../src/middleware/errorFormatter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errorFormatter.d.ts","sourceRoot":"","sources":["../../../src/middleware/errorFormatter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AAGtF,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,8BAA8B,CAAA;AAGrC,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAEjB,MAAM,2BAA2B,CAAA;AAMlC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAsD5E;AAYD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,SAAmB,GAAG,gBAAgB,CAmB1F;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe3D;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAiB5E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAUhE"}
@@ -1,9 +1,13 @@
1
1
  /**
2
2
  * SMI-1061: MCP Error Formatter for License Errors
3
+ * @see SMI-2741: Types split to errorFormatter.types.ts, builders to errorFormatter.builders.ts
3
4
  *
4
5
  * Formats license errors into MCP protocol-compliant error responses
5
6
  * with actionable information for clients.
6
7
  */
8
+ export { ERROR_MESSAGES, DEFAULT_UPGRADE_URL_CONFIG } from './errorFormatter.types.js';
9
+ // Re-export builders from companion file
10
+ export { generateUpgradeUrl, buildUpgradeRequiredResponse, buildLicenseExpiredResponse, buildQuotaExceededResponse, formatAuthenticationError, isAuthenticationError, extractAuthErrorDetails, } from './errorFormatter.builders.js';
7
11
  // ============================================================================
8
12
  // Error Formatting
9
13
  // ============================================================================
@@ -111,154 +115,23 @@ export function formatGenericError(error, code = 'INTERNAL_ERROR') {
111
115
  // ============================================================================
112
116
  // Error Code Mapping
113
117
  // ============================================================================
114
- /**
115
- * Map internal license error codes to user-friendly messages
116
- */
117
- const ERROR_MESSAGES = {
118
- E001: 'Your license has expired. Please renew to continue using premium features.',
119
- E002: 'Your license key is invalid. Please verify the key format or contact support.',
120
- E003: 'No license key found. Set SKILLSMITH_LICENSE_KEY environment variable.',
121
- E004: 'This feature is not available in your current license tier.',
122
- E005: 'You have exceeded your license quota. Please upgrade or reduce usage.',
123
- LICENSE_EXPIRED: 'Your license has expired. Please renew to continue using premium features.',
124
- LICENSE_INVALID: 'Your license key is invalid. Please verify the key format or contact support.',
125
- LICENSE_NOT_FOUND: 'No license key found. Set SKILLSMITH_LICENSE_KEY environment variable.',
126
- FEATURE_NOT_AVAILABLE: 'This feature is not available in your current license tier.',
127
- QUOTA_EXCEEDED: 'You have exceeded your license quota. Please upgrade or reduce usage.',
128
- };
129
118
  /**
130
119
  * Get a user-friendly message for an error code
131
120
  */
132
121
  export function getUserFriendlyMessage(code) {
133
- return ERROR_MESSAGES[code] || 'An error occurred with your license. Please contact support.';
134
- }
135
- const DEFAULT_UPGRADE_URL_CONFIG = {
136
- baseUrl: 'https://skillsmith.app/upgrade',
137
- includeFeature: true,
138
- includeTiers: true,
139
- includeSource: true,
140
- };
141
- /**
142
- * Generate a customized upgrade URL with tracking parameters
143
- */
144
- export function generateUpgradeUrl(error, config = {}) {
145
- const fullConfig = { ...DEFAULT_UPGRADE_URL_CONFIG, ...config };
146
- const params = new URLSearchParams();
147
- if (fullConfig.includeFeature && error.feature) {
148
- params.set('feature', error.feature);
149
- }
150
- if (fullConfig.includeTiers) {
151
- if (error.currentTier) {
152
- params.set('from', error.currentTier);
153
- }
154
- if (error.requiredTier) {
155
- params.set('to', error.requiredTier);
156
- }
157
- }
158
- if (fullConfig.includeSource) {
159
- params.set('source', 'mcp-error');
160
- if (error.code) {
161
- params.set('error_code', error.code);
162
- }
163
- }
164
- const queryString = params.toString();
165
- return queryString ? `${fullConfig.baseUrl}?${queryString}` : fullConfig.baseUrl || '';
166
- }
167
- // ============================================================================
168
- // Response Builders
169
- // ============================================================================
170
- /**
171
- * Build an upgrade required response
172
- *
173
- * Use this when a feature requires an upgrade but isn't a full error.
174
- */
175
- export function buildUpgradeRequiredResponse(feature, currentTier, requiredTier) {
176
- const upgradeUrl = `https://skillsmith.app/upgrade?feature=${feature}&from=${currentTier}&to=${requiredTier}`;
177
- return {
178
- content: [
179
- {
180
- type: 'text',
181
- text: JSON.stringify({
182
- error: {
183
- code: 'E004',
184
- message: `${feature} requires ${requiredTier} tier`,
185
- details: {
186
- feature,
187
- currentTier,
188
- requiredTier,
189
- upgradeUrl,
190
- },
191
- },
192
- }, null, 2),
193
- },
194
- ],
195
- isError: true,
196
- _meta: {
197
- upgradeUrl,
198
- errorCode: 'E004',
199
- recoverable: false,
200
- },
201
- };
202
- }
203
- /**
204
- * Build a license expired response with renewal URL
205
- */
206
- export function buildLicenseExpiredResponse(expiredAt) {
207
- const renewUrl = 'https://skillsmith.app/renew';
208
- return {
209
- content: [
210
- {
211
- type: 'text',
212
- text: JSON.stringify({
213
- error: {
214
- code: 'E001',
215
- message: 'Your license has expired',
216
- details: {
217
- expiredAt: expiredAt?.toISOString(),
218
- renewUrl,
219
- },
220
- },
221
- }, null, 2),
222
- },
223
- ],
224
- isError: true,
225
- _meta: {
226
- upgradeUrl: renewUrl,
227
- errorCode: 'E001',
228
- recoverable: false,
229
- },
230
- };
231
- }
232
- /**
233
- * Build a quota exceeded response
234
- */
235
- export function buildQuotaExceededResponse(quotaType, current, max) {
236
- const upgradeUrl = `https://skillsmith.app/upgrade?quota=${quotaType}`;
237
- return {
238
- content: [
239
- {
240
- type: 'text',
241
- text: JSON.stringify({
242
- error: {
243
- code: 'E005',
244
- message: `${quotaType} quota exceeded`,
245
- details: {
246
- quotaType,
247
- current,
248
- max,
249
- upgradeUrl,
250
- },
251
- },
252
- }, null, 2),
253
- },
254
- ],
255
- isError: true,
256
- _meta: {
257
- upgradeUrl,
258
- errorCode: 'E005',
259
- recoverable: false,
260
- },
122
+ const ERROR_MESSAGES = {
123
+ E001: 'Your license has expired. Please renew to continue using premium features.',
124
+ E002: 'Your license key is invalid. Please verify the key format or contact support.',
125
+ E003: 'No license key found. Set SKILLSMITH_LICENSE_KEY environment variable.',
126
+ E004: 'This feature is not available in your current license tier.',
127
+ E005: 'You have exceeded your license quota. Please upgrade or reduce usage.',
128
+ LICENSE_EXPIRED: 'Your license has expired. Please renew to continue using premium features.',
129
+ LICENSE_INVALID: 'Your license key is invalid. Please verify the key format or contact support.',
130
+ LICENSE_NOT_FOUND: 'No license key found. Set SKILLSMITH_LICENSE_KEY environment variable.',
131
+ FEATURE_NOT_AVAILABLE: 'This feature is not available in your current license tier.',
132
+ QUOTA_EXCEEDED: 'You have exceeded your license quota. Please upgrade or reduce usage.',
261
133
  };
134
+ return ERROR_MESSAGES[code] || 'An error occurred with your license. Please contact support.';
262
135
  }
263
136
  // ============================================================================
264
137
  // Validation Helpers
@@ -291,99 +164,4 @@ export function safeFormatError(error) {
291
164
  }
292
165
  return formatGenericError(new Error(String(error)));
293
166
  }
294
- /**
295
- * Format a 401 authentication error for MCP display
296
- * Provides user-friendly instructions for getting an API key
297
- *
298
- * @param details - Error details from the API response
299
- * @returns MCP-formatted error response with signup instructions
300
- */
301
- export function formatAuthenticationError(details = {}) {
302
- const signupUrl = details.signupUrl || 'https://skillsmith.app/signup';
303
- const docsUrl = details.docsUrl || 'https://skillsmith.app/docs/getting-started#api-key';
304
- const trialInfo = details.trialUsed !== undefined && details.trialLimit !== undefined
305
- ? `\n\nšŸ“Š **Trial Usage**: ${details.trialUsed}/${details.trialLimit} free requests used`
306
- : '';
307
- const message = `šŸ” **Authentication Required**
308
-
309
- ${details.reason || 'API key required for this request.'}
310
-
311
- **Get Started (Free - 1,000 requests/month):**
312
- 1. Create account: ${signupUrl}
313
- 2. Your API key will be generated automatically
314
- 3. Add to your Claude settings:
315
-
316
- \`\`\`json
317
- {
318
- "mcpServers": {
319
- "skillsmith": {
320
- "command": "npx",
321
- "args": ["-y", "@skillsmith/mcp-server"],
322
- "env": {
323
- "SKILLSMITH_API_KEY": "your_key_here"
324
- }
325
- }
326
- }
327
- }
328
- \`\`\`${trialInfo}
329
-
330
- [Documentation](${docsUrl})
331
- `;
332
- return {
333
- content: [
334
- {
335
- type: 'text',
336
- text: message,
337
- },
338
- ],
339
- isError: true,
340
- _meta: {
341
- errorCode: 'AUTHENTICATION_REQUIRED',
342
- recoverable: true,
343
- upgradeUrl: signupUrl,
344
- },
345
- };
346
- }
347
- /**
348
- * Check if an API error is an authentication error (401)
349
- */
350
- export function isAuthenticationError(error) {
351
- if (!error || typeof error !== 'object') {
352
- return false;
353
- }
354
- const e = error;
355
- // Check for status code
356
- if (e.statusCode === 401 || e.status === 401) {
357
- return true;
358
- }
359
- // Check for error message patterns
360
- if (typeof e.message === 'string') {
361
- const msg = e.message.toLowerCase();
362
- if (msg.includes('authentication required') || msg.includes('free trial exhausted')) {
363
- return true;
364
- }
365
- }
366
- // Check for error field
367
- if (typeof e.error === 'string') {
368
- const err = e.error.toLowerCase();
369
- if (err.includes('authentication required')) {
370
- return true;
371
- }
372
- }
373
- return false;
374
- }
375
- /**
376
- * Extract authentication error details from an API error response
377
- */
378
- export function extractAuthErrorDetails(error) {
379
- if (!error || typeof error !== 'object') {
380
- return {};
381
- }
382
- const e = error;
383
- // Check for details object
384
- if (e.details && typeof e.details === 'object') {
385
- return e.details;
386
- }
387
- return {};
388
- }
389
167
  //# sourceMappingURL=errorFormatter.js.map