mcp-prompt-optimizer 1.5.0 → 2.2.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.
- package/CHANGELOG.md +26 -9
- package/CROSS-PLATFORM.md +3 -3
- package/README.md +99 -39
- package/index.js +311 -130
- package/lib/api-key-manager.js +191 -138
- package/lib/check-status.js +1 -1
- package/package.json +3 -3
- package/tests/README.md +0 -232
- package/tests/comprehensive-test.js +0 -692
- package/tests/integration-test.js +0 -446
- package/tests/minimal-test.js +0 -265
- package/tests/quick-test.js +0 -282
- package/tests/simple-test.js +0 -171
- package/tests/test-runner.js +0 -322
package/lib/api-key-manager.js
CHANGED
|
@@ -15,7 +15,7 @@ const packageJson = require('../package.json');
|
|
|
15
15
|
class CloudApiKeyManager {
|
|
16
16
|
constructor(apiKey, options = {}) {
|
|
17
17
|
this.apiKey = apiKey;
|
|
18
|
-
this.backendUrl = options.backendUrl || process.env.OPTIMIZER_BACKEND_URL || 'https://p01--project-optimizer--
|
|
18
|
+
this.backendUrl = options.backendUrl || process.env.OPTIMIZER_BACKEND_URL || 'https://p01--project-optimizer--fvmrdk8m9k9j.code.run';
|
|
19
19
|
this.cacheFile = path.join(os.homedir(), '.mcp-cloud-api-cache.json');
|
|
20
20
|
this.healthFile = path.join(os.homedir(), '.mcp-cloud-health.json');
|
|
21
21
|
this.cacheExpiry = options.cacheExpiry || 24 * 60 * 60 * 1000; // 24 hours
|
|
@@ -196,8 +196,7 @@ class CloudApiKeyManager {
|
|
|
196
196
|
|
|
197
197
|
this.log(`API key format valid: ${formatCheck.keyType}`);
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
if (this.developmentMode || formatCheck.keyType === 'development' || formatCheck.keyType === 'testing') {
|
|
199
|
+
if (this.developmentMode || formatCheck.keyType === 'testing') {
|
|
201
200
|
this.log('Development/testing mode detected, using mock validation', 'warn');
|
|
202
201
|
const mockValidation = this.generateMockValidation(formatCheck.keyType);
|
|
203
202
|
await this.cacheValidation(mockValidation);
|
|
@@ -290,99 +289,23 @@ class CloudApiKeyManager {
|
|
|
290
289
|
|
|
291
290
|
// ✅ FIXED: Correct API endpoint URL
|
|
292
291
|
async validateWithBackend() {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
},
|
|
305
|
-
timeout: this.requestTimeout
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
this.log(`Making request to: ${url}`);
|
|
309
|
-
this.log(`Using API key: ${this.apiKey.substring(0, 16)}...`);
|
|
310
|
-
|
|
311
|
-
const client = this.backendUrl.startsWith('https://') ? https : http;
|
|
312
|
-
const req = client.request(url, options, (res) => {
|
|
313
|
-
let data = '';
|
|
314
|
-
|
|
315
|
-
res.on('data', (chunk) => {
|
|
316
|
-
data += chunk;
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
res.on('end', () => {
|
|
320
|
-
this.log(`Response status: ${res.statusCode}`);
|
|
321
|
-
|
|
322
|
-
try {
|
|
323
|
-
if (res.statusCode === 200) {
|
|
324
|
-
const validation = JSON.parse(data);
|
|
325
|
-
this.log(`Validation successful: ${JSON.stringify(validation, null, 2)}`);
|
|
326
|
-
resolve(validation);
|
|
327
|
-
} else if (res.statusCode === 401) {
|
|
328
|
-
reject(new Error('Invalid API key or unauthorized access'));
|
|
329
|
-
} else if (res.statusCode === 403) {
|
|
330
|
-
reject(new Error('API key expired or quota exceeded'));
|
|
331
|
-
} else if (res.statusCode === 429) {
|
|
332
|
-
reject(new Error('Rate limit exceeded. Please try again later.'));
|
|
333
|
-
} else if (res.statusCode === 500) {
|
|
334
|
-
reject(new Error('Backend server error. Please try again later.'));
|
|
335
|
-
} else if (res.statusCode === 503) {
|
|
336
|
-
reject(new Error('Backend service temporarily unavailable. Please try again later.'));
|
|
337
|
-
} else {
|
|
338
|
-
let errorMessage;
|
|
339
|
-
try {
|
|
340
|
-
const error = JSON.parse(data);
|
|
341
|
-
errorMessage = error.detail || error.message || `HTTP ${res.statusCode}`;
|
|
342
|
-
} catch {
|
|
343
|
-
errorMessage = `HTTP ${res.statusCode}: ${data}`;
|
|
344
|
-
}
|
|
345
|
-
reject(new Error(errorMessage));
|
|
346
|
-
}
|
|
347
|
-
} catch (parseError) {
|
|
348
|
-
this.log(`Parse error: ${parseError.message}`, 'error');
|
|
349
|
-
this.log(`Raw response: ${data}`, 'error');
|
|
350
|
-
reject(new Error(`Invalid response format: ${parseError.message}`));
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
req.on('error', (error) => {
|
|
356
|
-
this.log(`Network error: ${error.message}`, 'error');
|
|
357
|
-
|
|
358
|
-
// Enhanced error classification
|
|
359
|
-
if (error.code === 'ENOTFOUND') {
|
|
360
|
-
reject(new Error(`DNS resolution failed: Cannot resolve ${this.backendUrl.replace(/^https?:\/\//, '')}`));
|
|
361
|
-
} else if (error.code === 'ECONNREFUSED') {
|
|
362
|
-
reject(new Error(`Connection refused: Backend server may be down`));
|
|
363
|
-
} else if (error.code === 'ETIMEDOUT') {
|
|
364
|
-
reject(new Error(`Connection timeout: Backend server is not responding`));
|
|
365
|
-
} else if (error.code === 'ECONNRESET') {
|
|
366
|
-
reject(new Error(`Connection reset: Network instability detected`));
|
|
367
|
-
} else {
|
|
368
|
-
reject(new Error(`Network error: ${error.message}`));
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
req.on('timeout', () => {
|
|
373
|
-
req.destroy();
|
|
374
|
-
reject(new Error('Request timeout - backend may be unavailable'));
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
req.setTimeout(this.requestTimeout);
|
|
378
|
-
req.end();
|
|
379
|
-
});
|
|
292
|
+
const endpoint = '/api/v1/api-keys/validate';
|
|
293
|
+
const method = 'POST';
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
const validation = await this._makeBackendRequest(endpoint, null, method);
|
|
297
|
+
this.log(`Validation successful: ${JSON.stringify(validation, null, 2)}`);
|
|
298
|
+
return validation;
|
|
299
|
+
} catch (error) {
|
|
300
|
+
this.log(`Backend validation request failed: ${error.message}`, 'error');
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
380
303
|
}
|
|
381
304
|
|
|
382
305
|
// ✅ FIXED: Correct API endpoint URL
|
|
383
306
|
async getQuotaStatus() {
|
|
384
307
|
try {
|
|
385
|
-
const url = `${this.backendUrl}/api/v1/
|
|
308
|
+
const url = `${this.backendUrl}/api/v1/api-keys/quota-status`;
|
|
386
309
|
|
|
387
310
|
const options = {
|
|
388
311
|
method: 'GET',
|
|
@@ -462,38 +385,7 @@ class CloudApiKeyManager {
|
|
|
462
385
|
}
|
|
463
386
|
}
|
|
464
387
|
|
|
465
|
-
// Enhanced quota status checking
|
|
466
|
-
async checkQuotaStatus(validation) {
|
|
467
|
-
const quota = validation.quota || {};
|
|
468
|
-
|
|
469
|
-
if (quota.unlimited) {
|
|
470
|
-
return { allowed: true, unlimited: true };
|
|
471
|
-
}
|
|
472
388
|
|
|
473
|
-
const quotaUsed = quota.used || 0;
|
|
474
|
-
const quotaLimit = quota.limit || 5000;
|
|
475
|
-
const quotaRemaining = quota.remaining || (quotaLimit - quotaUsed);
|
|
476
|
-
|
|
477
|
-
if (quotaUsed >= quotaLimit) {
|
|
478
|
-
const tier = validation.tier || 'explorer';
|
|
479
|
-
const upgradeMessage = tier === 'explorer'
|
|
480
|
-
? 'Upgrade to Creator ($25.99/mo) for 18,000 optimizations: https://promptoptimizer-blog.vercel.app/pricing'
|
|
481
|
-
: 'Quota will reset on your next billing cycle.';
|
|
482
|
-
|
|
483
|
-
throw new Error(
|
|
484
|
-
`Monthly quota exceeded (${quotaUsed}/${quotaLimit}). ${upgradeMessage}`
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
return {
|
|
489
|
-
allowed: true,
|
|
490
|
-
unlimited: false,
|
|
491
|
-
used: quotaUsed,
|
|
492
|
-
limit: quotaLimit,
|
|
493
|
-
remaining: quotaRemaining,
|
|
494
|
-
usage_percentage: (quotaUsed / quotaLimit) * 100
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
389
|
|
|
498
390
|
// Enhanced caching with metadata
|
|
499
391
|
async cacheValidation(validation) {
|
|
@@ -593,13 +485,10 @@ class CloudApiKeyManager {
|
|
|
593
485
|
// Step 1: Validate API key
|
|
594
486
|
const validation = await this.validateApiKey();
|
|
595
487
|
|
|
596
|
-
// Step 2:
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
} else {
|
|
601
|
-
quotaStatus = await this.checkQuotaStatus(validation);
|
|
602
|
-
}
|
|
488
|
+
// Step 2: Get comprehensive quota status
|
|
489
|
+
const info = await this.getApiKeyInfo();
|
|
490
|
+
let quotaStatus = info.quota;
|
|
491
|
+
validation = info; // Use info as the main validation object for consistency
|
|
603
492
|
|
|
604
493
|
// Step 3: Log success
|
|
605
494
|
const mode = validation.mock_mode ? '(mock)' :
|
|
@@ -633,24 +522,57 @@ class CloudApiKeyManager {
|
|
|
633
522
|
|
|
634
523
|
// Enhanced API key info with mode detection
|
|
635
524
|
async getApiKeyInfo() {
|
|
525
|
+
const formatCheck = this.validateApiKeyFormat(this.apiKey);
|
|
526
|
+
if (this.developmentMode || formatCheck.keyType === 'development' || formatCheck.keyType === 'testing') {
|
|
527
|
+
this.log('Development/testing mode detected for getApiKeyInfo, returning mock data.', 'warn');
|
|
528
|
+
return {
|
|
529
|
+
tier: 'testing',
|
|
530
|
+
features: {
|
|
531
|
+
optimization: true,
|
|
532
|
+
template_search: true,
|
|
533
|
+
template_auto_save: true,
|
|
534
|
+
optimization_insights: true,
|
|
535
|
+
bayesian_optimization: true,
|
|
536
|
+
agui_features: true
|
|
537
|
+
},
|
|
538
|
+
quota: {
|
|
539
|
+
unlimited: false,
|
|
540
|
+
used: Math.floor(Math.random() * 100),
|
|
541
|
+
limit: 1000,
|
|
542
|
+
remaining: 1000 - Math.floor(Math.random() * 100)
|
|
543
|
+
},
|
|
544
|
+
isValid: true,
|
|
545
|
+
keyType: formatCheck.keyType,
|
|
546
|
+
mode: {
|
|
547
|
+
mock: true,
|
|
548
|
+
fallback: false,
|
|
549
|
+
offline: false,
|
|
550
|
+
development: this.developmentMode
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
|
|
636
555
|
try {
|
|
637
|
-
|
|
638
|
-
const
|
|
556
|
+
// Directly call the new quota-status endpoint
|
|
557
|
+
const quotaStatusResponse = await this._makeBackendRequest('/api/v1/api-keys/quota-status', null, 'GET');
|
|
639
558
|
|
|
559
|
+
// The backend /mcp/quota-status endpoint returns a comprehensive object
|
|
560
|
+
// that includes tier, quota details, and features.
|
|
640
561
|
return {
|
|
641
|
-
tier:
|
|
642
|
-
features:
|
|
643
|
-
quota:
|
|
562
|
+
tier: quotaStatusResponse.tier,
|
|
563
|
+
features: quotaStatusResponse.features_available || {},
|
|
564
|
+
quota: quotaStatusResponse.quota,
|
|
644
565
|
isValid: true,
|
|
645
|
-
keyType:
|
|
566
|
+
keyType: quotaStatusResponse.account_type || this.validateApiKeyFormat(this.apiKey).keyType,
|
|
646
567
|
mode: {
|
|
647
|
-
mock:
|
|
648
|
-
fallback:
|
|
649
|
-
offline:
|
|
568
|
+
mock: false, // This endpoint doesn't return mock status
|
|
569
|
+
fallback: false,
|
|
570
|
+
offline: false,
|
|
650
571
|
development: this.developmentMode
|
|
651
572
|
}
|
|
652
573
|
};
|
|
653
574
|
} catch (error) {
|
|
575
|
+
this.log(`Error getting API key info: ${error.message}`, 'error');
|
|
654
576
|
return {
|
|
655
577
|
tier: null,
|
|
656
578
|
features: {},
|
|
@@ -692,6 +614,137 @@ class CloudApiKeyManager {
|
|
|
692
614
|
if (!this.apiKey) return 'No key';
|
|
693
615
|
return `${this.apiKey.substring(0, 8)}...${this.apiKey.slice(-4)}`;
|
|
694
616
|
}
|
|
617
|
+
|
|
618
|
+
async getDiagnosticInfo() {
|
|
619
|
+
const diagnosticInfo = {
|
|
620
|
+
apiKey: this.apiKey ? this.formatKeyForDisplay() : 'Not set',
|
|
621
|
+
backendUrl: this.backendUrl,
|
|
622
|
+
cacheFile: this.cacheFile,
|
|
623
|
+
healthFile: this.healthFile,
|
|
624
|
+
cacheExpiry: this.cacheExpiry,
|
|
625
|
+
fallbackCacheExpiry: this.fallbackCacheExpiry,
|
|
626
|
+
offlineMode: this.offlineMode,
|
|
627
|
+
developmentMode: this.developmentMode,
|
|
628
|
+
maxRetries: this.maxRetries,
|
|
629
|
+
requestTimeout: this.requestTimeout,
|
|
630
|
+
nodeEnv: process.env.NODE_ENV || 'not set',
|
|
631
|
+
packageVersion: packageJson.version,
|
|
632
|
+
networkHealth: { ...this.networkHealth },
|
|
633
|
+
cache: {},
|
|
634
|
+
keyFormat: this.validateApiKeyFormat(this.apiKey),
|
|
635
|
+
backendConnectivity: { status: 'unknown', error: null, responseTime: null }
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
// Get cache status
|
|
639
|
+
try {
|
|
640
|
+
const cached = await this.getCachedValidation();
|
|
641
|
+
if (cached) {
|
|
642
|
+
diagnosticInfo.cache.exists = true;
|
|
643
|
+
diagnosticInfo.cache.expired = this.isCacheExpired(cached);
|
|
644
|
+
diagnosticInfo.cache.fallbackExpired = this.isFallbackCacheExpired(cached);
|
|
645
|
+
diagnosticInfo.cache.age = Math.round((Date.now() - cached.timestamp) / 1000 / 60);
|
|
646
|
+
diagnosticInfo.cache.backendUrl = cached.backendUrl;
|
|
647
|
+
diagnosticInfo.cache.packageVersion = cached.packageVersion;
|
|
648
|
+
} else {
|
|
649
|
+
diagnosticInfo.cache.exists = false;
|
|
650
|
+
}
|
|
651
|
+
} catch (error) {
|
|
652
|
+
diagnosticInfo.cache.error = error.message;
|
|
653
|
+
diagnosticInfo.cache.exists = false;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Check backend connectivity
|
|
657
|
+
if (this.apiKey) { // Only check if API key is present
|
|
658
|
+
try {
|
|
659
|
+
const startTime = Date.now();
|
|
660
|
+
await this.validateWithBackend(); // This will attempt to connect to the backend
|
|
661
|
+
const responseTime = Date.now() - startTime;
|
|
662
|
+
diagnosticInfo.backendConnectivity.status = 'success';
|
|
663
|
+
diagnosticInfo.backendConnectivity.responseTime = responseTime;
|
|
664
|
+
} catch (error) {
|
|
665
|
+
diagnosticInfo.backendConnectivity.status = 'failed';
|
|
666
|
+
diagnosticInfo.backendConnectivity.error = error.message;
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
diagnosticInfo.backendConnectivity.status = 'skipped';
|
|
670
|
+
diagnosticInfo.backendConnectivity.error = 'No API key provided for connectivity check.';
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return diagnosticInfo;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
async _makeBackendRequest(endpoint, data, method = 'POST') {
|
|
677
|
+
return new Promise((resolve, reject) => {
|
|
678
|
+
const url = `${this.backendUrl}${endpoint}`;
|
|
679
|
+
|
|
680
|
+
const options = {
|
|
681
|
+
method: method,
|
|
682
|
+
headers: {
|
|
683
|
+
'x-api-key': this.apiKey,
|
|
684
|
+
'Content-Type': 'application/json',
|
|
685
|
+
'User-Agent': `mcp-prompt-optimizer/${packageJson.version}`,
|
|
686
|
+
'Accept': 'application/json',
|
|
687
|
+
'Connection': 'close'
|
|
688
|
+
},
|
|
689
|
+
timeout: this.requestTimeout
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
const client = this.backendUrl.startsWith('https://') ? https : http;
|
|
693
|
+
const req = client.request(url, options, (res) => {
|
|
694
|
+
let responseData = '';
|
|
695
|
+
|
|
696
|
+
res.on('data', (chunk) => {
|
|
697
|
+
responseData += chunk;
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
res.on('end', () => {
|
|
701
|
+
try {
|
|
702
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
703
|
+
const parsed = JSON.parse(responseData);
|
|
704
|
+
resolve(parsed);
|
|
705
|
+
} else {
|
|
706
|
+
let errorMessage;
|
|
707
|
+
try {
|
|
708
|
+
const error = JSON.parse(responseData);
|
|
709
|
+
errorMessage = error.detail || error.message || `HTTP ${res.statusCode}`;
|
|
710
|
+
} catch {
|
|
711
|
+
errorMessage = `HTTP ${res.statusCode}: ${responseData}`;
|
|
712
|
+
}
|
|
713
|
+
reject(new Error(errorMessage));
|
|
714
|
+
}
|
|
715
|
+
} catch (parseError) {
|
|
716
|
+
reject(new Error(`Invalid response format: ${parseError.message}`));
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
req.on('error', (error) => {
|
|
722
|
+
if (error.code === 'ENOTFOUND') {
|
|
723
|
+
reject(new Error(`DNS resolution failed: Cannot resolve ${this.backendUrl.replace(/^https?:\/\//, '')}`));
|
|
724
|
+
} else if (error.code === 'ECONNREFUSED') {
|
|
725
|
+
reject(new Error(`Connection refused: Backend server may be down`));
|
|
726
|
+
} else if (error.code === 'ETIMEDOUT') {
|
|
727
|
+
reject(new Error(`Connection timeout: Backend server is not responding`));
|
|
728
|
+
} else if (error.code === 'ECONNRESET') {
|
|
729
|
+
reject(new Error(`Connection reset: Network instability detected`));
|
|
730
|
+
} else {
|
|
731
|
+
reject(new Error(`Network error: ${error.message}`));
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
req.on('timeout', () => {
|
|
736
|
+
req.destroy();
|
|
737
|
+
reject(new Error('Request timeout - backend may be unavailable'));
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
req.setTimeout(this.requestTimeout);
|
|
741
|
+
|
|
742
|
+
if (method !== 'GET' && data) {
|
|
743
|
+
req.write(JSON.stringify(data));
|
|
744
|
+
}
|
|
745
|
+
req.end();
|
|
746
|
+
});
|
|
747
|
+
}
|
|
695
748
|
}
|
|
696
749
|
|
|
697
750
|
module.exports = CloudApiKeyManager;
|
package/lib/check-status.js
CHANGED
|
@@ -10,7 +10,7 @@ async function checkStatus() {
|
|
|
10
10
|
if (!apiKey) {
|
|
11
11
|
console.error('❌ No API key found');
|
|
12
12
|
console.log('\n📝 Set your API key to check status:');
|
|
13
|
-
console.log(' export OPTIMIZER_API_KEY=sk-
|
|
13
|
+
console.log(' export OPTIMIZER_API_KEY=sk-local-your-key-here'); // Aligned with free tier/development
|
|
14
14
|
if (developmentMode) {
|
|
15
15
|
console.log('\n🧪 Development Mode Options:');
|
|
16
16
|
console.log(' export OPTIMIZER_API_KEY=sk-dev-test-key');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-prompt-optimizer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "Professional cloud-based MCP server for AI-powered prompt optimization with intelligent context detection, Bayesian optimization, AG-UI real-time optimization, template auto-save, optimization insights, personal model configuration via WebUI, team collaboration, enterprise-grade features, production resilience, and startup validation. Universal compatibility with Claude Desktop, Cursor, Windsurf, and 17+ MCP clients.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"test:integration": "node tests/integration-test.js",
|
|
24
24
|
"test:comprehensive": "node tests/comprehensive-test.js",
|
|
25
25
|
"test:runner": "node tests/test-runner.js",
|
|
26
|
+
"test:simple": "node tests/simple-test.js",
|
|
26
27
|
"pretest": "npm run health-check",
|
|
27
28
|
"prepublishOnly": "npm run test:quick",
|
|
28
29
|
"version": "echo 'Updating version...' && npm run test:quick"
|
|
@@ -111,7 +112,6 @@
|
|
|
111
112
|
"files": [
|
|
112
113
|
"index.js",
|
|
113
114
|
"lib/",
|
|
114
|
-
"tests/",
|
|
115
115
|
"README.md",
|
|
116
116
|
"CHANGELOG.md",
|
|
117
117
|
"CROSS-PLATFORM.md",
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
}
|
|
219
219
|
},
|
|
220
220
|
"backend_alignment": {
|
|
221
|
-
"version": "production-v2.
|
|
221
|
+
"version": "production-v2.2.0-stable",
|
|
222
222
|
"api_version": "v1",
|
|
223
223
|
"endpoints_aligned": true,
|
|
224
224
|
"feature_parity": true,
|
package/tests/README.md
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
# 🧪 MCP Prompt Optimizer Test Suite
|
|
2
|
-
|
|
3
|
-
Comprehensive testing framework for validating package functionality before NPM publication.
|
|
4
|
-
|
|
5
|
-
## 📋 Test Overview
|
|
6
|
-
|
|
7
|
-
### 🚀 Quick Test (`npm run test:quick`)
|
|
8
|
-
**Duration:** ~30 seconds
|
|
9
|
-
**Purpose:** Rapid validation of core functionality
|
|
10
|
-
**API Key:** Not required (uses mock mode)
|
|
11
|
-
|
|
12
|
-
Tests:
|
|
13
|
-
- ✅ Package structure validation
|
|
14
|
-
- ✅ Cross-platform compatibility
|
|
15
|
-
- ✅ MCP server instantiation
|
|
16
|
-
- ✅ API key format validation
|
|
17
|
-
- ✅ AI context detection
|
|
18
|
-
- ✅ Mock optimization generation
|
|
19
|
-
- ✅ Response formatting
|
|
20
|
-
- ✅ Environment variable support
|
|
21
|
-
|
|
22
|
-
**Use Case:** Quick verification during development
|
|
23
|
-
|
|
24
|
-
### 🔌 Integration Test (`npm run test:integration`)
|
|
25
|
-
**Duration:** ~60 seconds
|
|
26
|
-
**Purpose:** Validate API connectivity and real backend integration
|
|
27
|
-
**API Key:** Optional (falls back to mock mode)
|
|
28
|
-
|
|
29
|
-
Tests:
|
|
30
|
-
- ✅ Backend connectivity
|
|
31
|
-
- ✅ Real API key validation
|
|
32
|
-
- ✅ Live optimization requests
|
|
33
|
-
- ✅ Quota status retrieval
|
|
34
|
-
- ✅ Template search functionality
|
|
35
|
-
- ✅ Error recovery mechanisms
|
|
36
|
-
- ✅ Network resilience
|
|
37
|
-
|
|
38
|
-
**Use Case:** Pre-deployment validation with real backend
|
|
39
|
-
|
|
40
|
-
### 🔬 Comprehensive Test (`npm run test:comprehensive`)
|
|
41
|
-
**Duration:** ~2 minutes
|
|
42
|
-
**Purpose:** Exhaustive validation of all features and edge cases
|
|
43
|
-
**API Key:** Optional (extensive mock testing)
|
|
44
|
-
|
|
45
|
-
Tests:
|
|
46
|
-
- ✅ All quick test features
|
|
47
|
-
- ✅ All integration test features
|
|
48
|
-
- ✅ Command-line interface testing
|
|
49
|
-
- ✅ Network resilience scenarios
|
|
50
|
-
- ✅ Error handling edge cases
|
|
51
|
-
- ✅ Package integrity validation
|
|
52
|
-
- ✅ MCP protocol compliance
|
|
53
|
-
- ✅ Cross-platform script testing
|
|
54
|
-
|
|
55
|
-
**Use Case:** Full validation before major releases
|
|
56
|
-
|
|
57
|
-
### 🎯 Test Runner (`npm test` or `npm run test:runner`)
|
|
58
|
-
**Duration:** ~3-4 minutes
|
|
59
|
-
**Purpose:** Orchestrates all test suites in optimal order
|
|
60
|
-
**API Key:** Optional (runs all modes)
|
|
61
|
-
|
|
62
|
-
**Use Case:** Complete pre-publication validation
|
|
63
|
-
|
|
64
|
-
## 🛠️ Usage Examples
|
|
65
|
-
|
|
66
|
-
### Basic Testing (No API Key Required)
|
|
67
|
-
```bash
|
|
68
|
-
# Quick validation
|
|
69
|
-
npm run test:quick
|
|
70
|
-
|
|
71
|
-
# Full test suite in mock mode
|
|
72
|
-
npm test
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
### Testing with Real API Key
|
|
76
|
-
```bash
|
|
77
|
-
# Set your API key
|
|
78
|
-
export OPTIMIZER_API_KEY=sk-opt-your-actual-key
|
|
79
|
-
|
|
80
|
-
# Run integration tests
|
|
81
|
-
npm run test:integration
|
|
82
|
-
|
|
83
|
-
# Run full test suite
|
|
84
|
-
npm test
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Development Mode Testing
|
|
88
|
-
```bash
|
|
89
|
-
# Enable development mode
|
|
90
|
-
export OPTIMIZER_DEV_MODE=true
|
|
91
|
-
export OPTIMIZER_API_KEY=sk-dev-test-key
|
|
92
|
-
|
|
93
|
-
# Run tests
|
|
94
|
-
npm test
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Custom Backend Testing
|
|
98
|
-
```bash
|
|
99
|
-
# Test against custom backend
|
|
100
|
-
export OPTIMIZER_BACKEND_URL=https://your-backend.com
|
|
101
|
-
export OPTIMIZER_API_KEY=your-key
|
|
102
|
-
|
|
103
|
-
# Run integration tests
|
|
104
|
-
npm run test:integration
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## 📊 Test Output Examples
|
|
108
|
-
|
|
109
|
-
### ✅ Success Output
|
|
110
|
-
```
|
|
111
|
-
🎉 ALL TESTS PASSED - READY FOR PUBLICATION!
|
|
112
|
-
|
|
113
|
-
🚀 Recommended publication commands:
|
|
114
|
-
npm publish
|
|
115
|
-
git tag v1.4.0
|
|
116
|
-
git push --tags
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### ❌ Failure Output
|
|
120
|
-
```
|
|
121
|
-
❌ SOME TESTS FAILED - FIX ISSUES BEFORE PUBLICATION
|
|
122
|
-
Run the comprehensive test suite for detailed analysis:
|
|
123
|
-
node tests/comprehensive-test.js
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
## 🔧 Test Modes
|
|
127
|
-
|
|
128
|
-
### Mock Mode (Default)
|
|
129
|
-
- **Trigger:** No API key provided
|
|
130
|
-
- **Behavior:** Uses simulated responses
|
|
131
|
-
- **Tests:** All functionality except live API calls
|
|
132
|
-
- **Advantage:** Fast, no dependencies
|
|
133
|
-
|
|
134
|
-
### Development Mode
|
|
135
|
-
- **Trigger:** `OPTIMIZER_DEV_MODE=true`
|
|
136
|
-
- **Behavior:** Enhanced logging, extended timeouts
|
|
137
|
-
- **Tests:** All functionality with debug output
|
|
138
|
-
- **Advantage:** Detailed debugging information
|
|
139
|
-
|
|
140
|
-
### Production Mode
|
|
141
|
-
- **Trigger:** Real API key provided
|
|
142
|
-
- **Behavior:** Tests against live backend
|
|
143
|
-
- **Tests:** Full end-to-end validation
|
|
144
|
-
- **Advantage:** Real-world validation
|
|
145
|
-
|
|
146
|
-
## 🎯 Pre-Publication Checklist
|
|
147
|
-
|
|
148
|
-
Run this checklist before publishing to NPM:
|
|
149
|
-
|
|
150
|
-
1. **Quick Test** ✅
|
|
151
|
-
```bash
|
|
152
|
-
npm run test:quick
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
2. **Integration Test** (if you have API key) ✅
|
|
156
|
-
```bash
|
|
157
|
-
OPTIMIZER_API_KEY=your-key npm run test:integration
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
3. **Full Test Suite** ✅
|
|
161
|
-
```bash
|
|
162
|
-
npm test
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
4. **Manual Verification** ✅
|
|
166
|
-
- [ ] Version number updated in package.json
|
|
167
|
-
- [ ] CHANGELOG.md updated
|
|
168
|
-
- [ ] README.md current
|
|
169
|
-
- [ ] All files included in `files` array
|
|
170
|
-
|
|
171
|
-
5. **Publication** 🚀
|
|
172
|
-
```bash
|
|
173
|
-
npm publish
|
|
174
|
-
git tag v$(node -p "require('./package.json').version")
|
|
175
|
-
git push --tags
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## 🚨 Troubleshooting
|
|
179
|
-
|
|
180
|
-
### Common Issues
|
|
181
|
-
|
|
182
|
-
**"Tests failed with exit code 1"**
|
|
183
|
-
- Run individual test suites to identify specific failures
|
|
184
|
-
- Check error messages for detailed debugging information
|
|
185
|
-
|
|
186
|
-
**"Network error during integration tests"**
|
|
187
|
-
- Verify internet connection
|
|
188
|
-
- Check if backend URL is accessible
|
|
189
|
-
- Try running in mock mode first
|
|
190
|
-
|
|
191
|
-
**"API key validation failed"**
|
|
192
|
-
- Verify API key format: `sk-opt-`, `sk-team-`, `sk-dev-`, or `sk-local-`
|
|
193
|
-
- Check API key permissions and quota
|
|
194
|
-
- Try development mode: `OPTIMIZER_DEV_MODE=true`
|
|
195
|
-
|
|
196
|
-
**"Cross-platform script issues"**
|
|
197
|
-
- Ensure `cross-env` is installed: `npm install`
|
|
198
|
-
- Use platform-specific commands if needed:
|
|
199
|
-
- Windows: `npm run dev:windows`
|
|
200
|
-
- Unix/Mac: `npm run dev:unix`
|
|
201
|
-
|
|
202
|
-
### Debug Commands
|
|
203
|
-
|
|
204
|
-
```bash
|
|
205
|
-
# Verbose test output
|
|
206
|
-
DEBUG=* npm test
|
|
207
|
-
|
|
208
|
-
# Individual test suites
|
|
209
|
-
npm run test:quick
|
|
210
|
-
npm run test:integration
|
|
211
|
-
npm run test:comprehensive
|
|
212
|
-
|
|
213
|
-
# Test specific functionality
|
|
214
|
-
node lib/validate-key.js
|
|
215
|
-
node lib/diagnose.js
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
## 📈 Continuous Integration
|
|
219
|
-
|
|
220
|
-
For CI/CD pipelines, use:
|
|
221
|
-
|
|
222
|
-
```yaml
|
|
223
|
-
# GitHub Actions example
|
|
224
|
-
- name: Run tests
|
|
225
|
-
run: |
|
|
226
|
-
npm ci
|
|
227
|
-
npm run test:quick
|
|
228
|
-
env:
|
|
229
|
-
OPTIMIZER_DEV_MODE: true
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
The test suite is designed to work in CI environments without requiring real API keys.
|