polydev-ai 1.8.80 → 1.8.82
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/mcp/login.js +95 -29
- package/mcp/stdio-wrapper.js +188 -62
- package/package.json +2 -1
package/mcp/login.js
CHANGED
|
@@ -444,49 +444,115 @@ function getSuccessHTML() {
|
|
|
444
444
|
<html>
|
|
445
445
|
<head>
|
|
446
446
|
<meta charset="utf-8">
|
|
447
|
-
<title>Polydev -
|
|
447
|
+
<title>Polydev - Login Successful</title>
|
|
448
448
|
<style>
|
|
449
449
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
450
|
-
body {
|
|
451
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
452
|
-
display: flex; justify-content: center; align-items: center;
|
|
453
|
-
height: 100vh; background: #
|
|
450
|
+
body {
|
|
451
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
452
|
+
display: flex; justify-content: center; align-items: center;
|
|
453
|
+
min-height: 100vh; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
454
|
+
padding: 20px;
|
|
454
455
|
}
|
|
455
|
-
.container {
|
|
456
|
-
text-align: center; padding:
|
|
457
|
-
background: white; border-radius:
|
|
458
|
-
box-shadow: 0
|
|
456
|
+
.container {
|
|
457
|
+
text-align: center; padding: 40px; max-width: 480px; width: 100%;
|
|
458
|
+
background: white; border-radius: 16px;
|
|
459
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
459
460
|
}
|
|
460
|
-
.logo {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
display: flex; align-items: center; justify-content: center;
|
|
464
|
-
|
|
461
|
+
.logo {
|
|
462
|
+
width: 80px; height: 80px; margin: 0 auto 20px;
|
|
463
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
464
|
+
border-radius: 20px; display: flex; align-items: center; justify-content: center;
|
|
465
|
+
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
|
|
466
|
+
}
|
|
467
|
+
.logo svg { width: 48px; height: 48px; }
|
|
468
|
+
.brand { font-size: 28px; font-weight: 700; color: #111; margin-bottom: 8px; letter-spacing: -0.5px; }
|
|
469
|
+
.tagline { color: #666; font-size: 14px; margin-bottom: 24px; }
|
|
470
|
+
.success-badge {
|
|
471
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
472
|
+
background: #ecfdf5; color: #059669; padding: 12px 24px;
|
|
473
|
+
border-radius: 100px; font-weight: 600; font-size: 15px;
|
|
474
|
+
margin-bottom: 28px;
|
|
475
|
+
}
|
|
476
|
+
.success-badge svg { width: 20px; height: 20px; }
|
|
477
|
+
.section { text-align: left; margin-bottom: 20px; }
|
|
478
|
+
.section-title { font-size: 12px; font-weight: 600; color: #999; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
|
|
479
|
+
.api-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
|
|
480
|
+
.api-item {
|
|
481
|
+
padding: 12px; background: #f9fafb; border-radius: 8px;
|
|
482
|
+
font-size: 13px; color: #374151; text-align: center;
|
|
465
483
|
}
|
|
466
|
-
h1 { color: #111; font-size: 20px; font-weight: 600; margin-bottom: 12px; }
|
|
467
|
-
p { color: #666; font-size: 14px; line-height: 1.6; margin-bottom: 8px; }
|
|
468
484
|
.steps {
|
|
469
|
-
background: #
|
|
470
|
-
margin: 20px
|
|
485
|
+
background: #f9fafb; border-radius: 10px; padding: 16px;
|
|
486
|
+
margin-bottom: 20px; text-align: left;
|
|
471
487
|
}
|
|
472
|
-
.step { color: #
|
|
488
|
+
.step { color: #374151; font-size: 13px; margin-bottom: 10px; display: flex; gap: 10px; }
|
|
473
489
|
.step:last-child { margin-bottom: 0; }
|
|
474
|
-
|
|
475
|
-
|
|
490
|
+
.step-num {
|
|
491
|
+
width: 20px; height: 20px; background: #667eea; color: white;
|
|
492
|
+
border-radius: 50%; font-size: 11px; font-weight: 600;
|
|
493
|
+
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
|
|
494
|
+
}
|
|
495
|
+
code { background: #e5e7eb; padding: 2px 6px; border-radius: 4px; font-size: 12px; }
|
|
496
|
+
.divider { height: 1px; background: #e5e7eb; margin: 24px 0; }
|
|
497
|
+
.action-btn {
|
|
498
|
+
display: block; width: 100%; padding: 14px 20px;
|
|
499
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
500
|
+
color: white; border: none; border-radius: 10px;
|
|
501
|
+
font-size: 15px; font-weight: 600; cursor: pointer;
|
|
502
|
+
text-decoration: none; margin-bottom: 12px;
|
|
503
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
504
|
+
}
|
|
505
|
+
.action-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); }
|
|
506
|
+
.secondary-btn {
|
|
507
|
+
display: block; width: 100%; padding: 12px 20px;
|
|
508
|
+
background: #f3f4f6; color: #374151; border: none; border-radius: 10px;
|
|
509
|
+
font-size: 14px; font-weight: 500; cursor: pointer; text-decoration: none;
|
|
510
|
+
}
|
|
511
|
+
.note { color: #9ca3af; font-size: 12px; margin-top: 20px; }
|
|
476
512
|
</style>
|
|
477
513
|
</head>
|
|
478
514
|
<body>
|
|
479
515
|
<div class="container">
|
|
480
|
-
<div class="logo">
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
516
|
+
<div class="logo">
|
|
517
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
518
|
+
<path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
519
|
+
<path d="M2 17L12 22L22 17" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
520
|
+
<path d="M2 12L12 17L22 12" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
521
|
+
</svg>
|
|
522
|
+
</div>
|
|
523
|
+
<div class="brand">Polydev</div>
|
|
524
|
+
<div class="tagline">Multi-Model AI Perspectives</div>
|
|
525
|
+
|
|
526
|
+
<div class="success-badge">
|
|
527
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
528
|
+
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
|
|
529
|
+
<polyline points="22 4 12 14.01 9 11.01"/>
|
|
530
|
+
</svg>
|
|
531
|
+
Login Successful
|
|
532
|
+
</div>
|
|
533
|
+
|
|
534
|
+
<div class="section">
|
|
535
|
+
<div class="section-title">API Models Available</div>
|
|
536
|
+
<div class="api-grid">
|
|
537
|
+
<div class="api-item">GPT-5.2</div>
|
|
538
|
+
<div class="api-item">Claude Opus</div>
|
|
539
|
+
<div class="api-item">Gemini 3</div>
|
|
540
|
+
<div class="api-item">Grok 4.1</div>
|
|
541
|
+
</div>
|
|
542
|
+
</div>
|
|
543
|
+
|
|
484
544
|
<div class="steps">
|
|
485
|
-
<div class="step">1
|
|
486
|
-
<div class="step">2
|
|
487
|
-
<div class="step">3
|
|
545
|
+
<div class="step"><span class="step-num">1</span>Restart terminal or run <code>source ~/.zshrc</code></div>
|
|
546
|
+
<div class="step"><span class="step-num">2</span>Start your IDE (Claude Code, Cursor, etc.)</div>
|
|
547
|
+
<div class="step"><span class="step-num">3</span>Use <code>get_perspectives</code> tool</div>
|
|
488
548
|
</div>
|
|
489
|
-
|
|
549
|
+
|
|
550
|
+
<a href="https://www.polydev.ai/dashboard/models" target="_blank" class="action-btn">
|
|
551
|
+
Configure API Keys
|
|
552
|
+
</a>
|
|
553
|
+
<button onclick="window.close()" class="secondary-btn">Close Window</button>
|
|
554
|
+
|
|
555
|
+
<p class="note">Your token has been saved automatically</p>
|
|
490
556
|
</div>
|
|
491
557
|
</body>
|
|
492
558
|
</html>`;
|
package/mcp/stdio-wrapper.js
CHANGED
|
@@ -411,7 +411,7 @@ class StdioMCPWrapper {
|
|
|
411
411
|
result: {
|
|
412
412
|
content: [{
|
|
413
413
|
type: 'text',
|
|
414
|
-
text: `Already authenticated.\n\nYour token is configured. Use get_perspectives to query multiple AI models.\n\nTo re-login, run in terminal: npx polydev-ai
|
|
414
|
+
text: `Already authenticated.\n\nYour token is configured. Use get_perspectives to query multiple AI models.\n\nTo re-login, run in terminal: npx polydev-ai`
|
|
415
415
|
}]
|
|
416
416
|
}
|
|
417
417
|
});
|
|
@@ -479,29 +479,11 @@ class StdioMCPWrapper {
|
|
|
479
479
|
|
|
480
480
|
console.error(`[Polydev] Opening browser for authentication: ${authUrl}`);
|
|
481
481
|
|
|
482
|
-
//
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
if (platform === 'darwin') {
|
|
488
|
-
// Use osascript for more reliable browser opening on macOS
|
|
489
|
-
openCommand = `osascript -e 'open location "${authUrl}"'`;
|
|
490
|
-
} else if (platform === 'win32') {
|
|
491
|
-
openCommand = `start "" "${authUrl}"`;
|
|
492
|
-
} else {
|
|
493
|
-
openCommand = `xdg-open "${authUrl}"`;
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
exec(openCommand, (error) => {
|
|
497
|
-
if (error) {
|
|
498
|
-
console.error('[Polydev] Browser open failed, trying fallback...');
|
|
499
|
-
// Fallback to spawn
|
|
500
|
-
const { spawn } = require('child_process');
|
|
501
|
-
if (platform === 'darwin') {
|
|
502
|
-
spawn('open', [authUrl], { detached: true, stdio: 'ignore' }).unref();
|
|
503
|
-
}
|
|
504
|
-
}
|
|
482
|
+
// Best-in-class browser opening using 'open' package (cross-platform)
|
|
483
|
+
// Falls back to platform-specific commands if package fails
|
|
484
|
+
this.openBrowser(authUrl).catch(() => {
|
|
485
|
+
console.error('[Polydev] All browser open methods failed');
|
|
486
|
+
console.error('[Polydev] Please open this URL manually:', authUrl);
|
|
505
487
|
});
|
|
506
488
|
|
|
507
489
|
// Timeout after 5 minutes
|
|
@@ -609,6 +591,64 @@ class StdioMCPWrapper {
|
|
|
609
591
|
}
|
|
610
592
|
}
|
|
611
593
|
|
|
594
|
+
/**
|
|
595
|
+
* Open URL in browser - best-in-class cross-platform implementation
|
|
596
|
+
* Uses 'open' npm package with fallbacks for reliability in MCP/stdio context
|
|
597
|
+
*/
|
|
598
|
+
async openBrowser(url) {
|
|
599
|
+
// Try the 'open' package first (ESM, requires dynamic import)
|
|
600
|
+
try {
|
|
601
|
+
const open = await import('open');
|
|
602
|
+
await open.default(url);
|
|
603
|
+
console.error('[Polydev] Browser opened successfully');
|
|
604
|
+
return;
|
|
605
|
+
} catch (openError) {
|
|
606
|
+
console.error('[Polydev] open package failed:', openError.message);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Fallback 1: Platform-specific commands with exec
|
|
610
|
+
const { exec } = require('child_process');
|
|
611
|
+
const platform = process.platform;
|
|
612
|
+
|
|
613
|
+
return new Promise((resolve, reject) => {
|
|
614
|
+
let command;
|
|
615
|
+
if (platform === 'darwin') {
|
|
616
|
+
// macOS: try osascript first (more reliable in headless contexts)
|
|
617
|
+
command = `osascript -e 'open location "${url}"'`;
|
|
618
|
+
} else if (platform === 'win32') {
|
|
619
|
+
command = `start "" "${url}"`;
|
|
620
|
+
} else {
|
|
621
|
+
command = `xdg-open "${url}"`;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
exec(command, (error) => {
|
|
625
|
+
if (error) {
|
|
626
|
+
console.error('[Polydev] exec command failed:', error.message);
|
|
627
|
+
|
|
628
|
+
// Fallback 2: spawn with detached
|
|
629
|
+
const { spawn } = require('child_process');
|
|
630
|
+
try {
|
|
631
|
+
if (platform === 'darwin') {
|
|
632
|
+
spawn('open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
633
|
+
} else if (platform === 'win32') {
|
|
634
|
+
spawn('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore', shell: true }).unref();
|
|
635
|
+
} else {
|
|
636
|
+
spawn('xdg-open', [url], { detached: true, stdio: 'ignore' }).unref();
|
|
637
|
+
}
|
|
638
|
+
console.error('[Polydev] Browser opened via spawn fallback');
|
|
639
|
+
resolve();
|
|
640
|
+
} catch (spawnError) {
|
|
641
|
+
console.error('[Polydev] spawn fallback failed:', spawnError.message);
|
|
642
|
+
reject(new Error('All browser open methods failed'));
|
|
643
|
+
}
|
|
644
|
+
} else {
|
|
645
|
+
console.error('[Polydev] Browser opened via exec');
|
|
646
|
+
resolve();
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
|
|
612
652
|
/**
|
|
613
653
|
* Save token to shell config files
|
|
614
654
|
*/
|
|
@@ -640,33 +680,136 @@ class StdioMCPWrapper {
|
|
|
640
680
|
* Get login success HTML page
|
|
641
681
|
*/
|
|
642
682
|
getLoginSuccessHTML() {
|
|
683
|
+
// Get CLI status for display
|
|
684
|
+
const cliStatus = this.cliManager ? this.cliManager.getCachedStatus() : {};
|
|
685
|
+
const detectedCLIs = Object.entries(cliStatus)
|
|
686
|
+
.filter(([_, status]) => status && status.available)
|
|
687
|
+
.map(([id, status]) => ({
|
|
688
|
+
name: id === 'claude_code' ? 'Claude Code' :
|
|
689
|
+
id === 'codex_cli' ? 'Codex CLI' :
|
|
690
|
+
id === 'gemini_cli' ? 'Gemini CLI' : id,
|
|
691
|
+
authenticated: status.authenticated
|
|
692
|
+
}));
|
|
693
|
+
|
|
694
|
+
const cliListHTML = detectedCLIs.length > 0
|
|
695
|
+
? detectedCLIs.map(cli =>
|
|
696
|
+
`<div class="cli-item"><span class="cli-dot ${cli.authenticated ? 'green' : 'yellow'}"></span>${cli.name}</div>`
|
|
697
|
+
).join('')
|
|
698
|
+
: '<div class="cli-item"><span class="cli-dot gray"></span>No local CLIs detected</div>';
|
|
699
|
+
|
|
643
700
|
return `<!DOCTYPE html>
|
|
644
701
|
<html>
|
|
645
702
|
<head>
|
|
646
703
|
<meta charset="utf-8">
|
|
647
|
-
<title>Polydev -
|
|
704
|
+
<title>Polydev - Login Successful</title>
|
|
648
705
|
<style>
|
|
649
706
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
650
|
-
body {
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
.
|
|
657
|
-
|
|
707
|
+
body {
|
|
708
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
709
|
+
display: flex; justify-content: center; align-items: center;
|
|
710
|
+
min-height: 100vh; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
711
|
+
padding: 20px;
|
|
712
|
+
}
|
|
713
|
+
.container {
|
|
714
|
+
text-align: center; padding: 40px; max-width: 480px; width: 100%;
|
|
715
|
+
background: white; border-radius: 16px;
|
|
716
|
+
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
|
717
|
+
}
|
|
718
|
+
.logo {
|
|
719
|
+
width: 80px; height: 80px; margin: 0 auto 20px;
|
|
720
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
721
|
+
border-radius: 20px; display: flex; align-items: center; justify-content: center;
|
|
722
|
+
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
|
|
723
|
+
}
|
|
724
|
+
.logo svg { width: 48px; height: 48px; }
|
|
725
|
+
.brand { font-size: 28px; font-weight: 700; color: #111; margin-bottom: 8px; letter-spacing: -0.5px; }
|
|
726
|
+
.tagline { color: #666; font-size: 14px; margin-bottom: 24px; }
|
|
727
|
+
.success-badge {
|
|
728
|
+
display: inline-flex; align-items: center; gap: 8px;
|
|
729
|
+
background: #ecfdf5; color: #059669; padding: 12px 24px;
|
|
730
|
+
border-radius: 100px; font-weight: 600; font-size: 15px;
|
|
731
|
+
margin-bottom: 28px;
|
|
732
|
+
}
|
|
733
|
+
.success-badge svg { width: 20px; height: 20px; }
|
|
734
|
+
.section {
|
|
735
|
+
text-align: left; margin-bottom: 20px;
|
|
736
|
+
}
|
|
737
|
+
.section-title { font-size: 12px; font-weight: 600; color: #999; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
|
|
738
|
+
.cli-item {
|
|
739
|
+
display: flex; align-items: center; gap: 10px;
|
|
740
|
+
padding: 10px 14px; background: #f9fafb; border-radius: 8px;
|
|
741
|
+
margin-bottom: 8px; font-size: 14px; color: #374151;
|
|
742
|
+
}
|
|
743
|
+
.cli-dot { width: 8px; height: 8px; border-radius: 50%; }
|
|
744
|
+
.cli-dot.green { background: #10b981; }
|
|
745
|
+
.cli-dot.yellow { background: #f59e0b; }
|
|
746
|
+
.cli-dot.gray { background: #9ca3af; }
|
|
747
|
+
.api-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
|
|
748
|
+
.api-item {
|
|
749
|
+
padding: 12px; background: #f9fafb; border-radius: 8px;
|
|
750
|
+
font-size: 13px; color: #374151; text-align: center;
|
|
751
|
+
}
|
|
752
|
+
.divider { height: 1px; background: #e5e7eb; margin: 24px 0; }
|
|
753
|
+
.action-btn {
|
|
754
|
+
display: block; width: 100%; padding: 14px 20px;
|
|
755
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
756
|
+
color: white; border: none; border-radius: 10px;
|
|
757
|
+
font-size: 15px; font-weight: 600; cursor: pointer;
|
|
758
|
+
text-decoration: none; margin-bottom: 12px;
|
|
759
|
+
transition: transform 0.2s, box-shadow 0.2s;
|
|
760
|
+
}
|
|
761
|
+
.action-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); }
|
|
762
|
+
.secondary-btn {
|
|
763
|
+
display: block; width: 100%; padding: 12px 20px;
|
|
764
|
+
background: #f3f4f6; color: #374151; border: none; border-radius: 10px;
|
|
765
|
+
font-size: 14px; font-weight: 500; cursor: pointer; text-decoration: none;
|
|
766
|
+
}
|
|
767
|
+
.note { color: #9ca3af; font-size: 12px; margin-top: 20px; }
|
|
658
768
|
</style>
|
|
659
769
|
</head>
|
|
660
770
|
<body>
|
|
661
771
|
<div class="container">
|
|
662
|
-
<div class="logo">
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
772
|
+
<div class="logo">
|
|
773
|
+
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
774
|
+
<path d="M12 2L2 7L12 12L22 7L12 2Z" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
775
|
+
<path d="M2 17L12 22L22 17" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
776
|
+
<path d="M2 12L12 17L22 12" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
777
|
+
</svg>
|
|
778
|
+
</div>
|
|
779
|
+
<div class="brand">Polydev</div>
|
|
780
|
+
<div class="tagline">Multi-Model AI Perspectives</div>
|
|
781
|
+
|
|
782
|
+
<div class="success-badge">
|
|
783
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
784
|
+
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
|
|
785
|
+
<polyline points="22 4 12 14.01 9 11.01"/>
|
|
786
|
+
</svg>
|
|
787
|
+
Login Successful
|
|
668
788
|
</div>
|
|
669
|
-
|
|
789
|
+
|
|
790
|
+
<div class="section">
|
|
791
|
+
<div class="section-title">Local CLI Tools (Free)</div>
|
|
792
|
+
${cliListHTML}
|
|
793
|
+
</div>
|
|
794
|
+
|
|
795
|
+
<div class="section">
|
|
796
|
+
<div class="section-title">API Models Available</div>
|
|
797
|
+
<div class="api-grid">
|
|
798
|
+
<div class="api-item">GPT-5.2</div>
|
|
799
|
+
<div class="api-item">Claude Opus</div>
|
|
800
|
+
<div class="api-item">Gemini 3</div>
|
|
801
|
+
<div class="api-item">Grok 4.1</div>
|
|
802
|
+
</div>
|
|
803
|
+
</div>
|
|
804
|
+
|
|
805
|
+
<div class="divider"></div>
|
|
806
|
+
|
|
807
|
+
<a href="https://www.polydev.ai/dashboard/models" target="_blank" class="action-btn">
|
|
808
|
+
Configure API Keys
|
|
809
|
+
</a>
|
|
810
|
+
<button onclick="window.close()" class="secondary-btn">Close Window</button>
|
|
811
|
+
|
|
812
|
+
<p class="note">Restart your IDE to use the new token</p>
|
|
670
813
|
</div>
|
|
671
814
|
</body>
|
|
672
815
|
</html>`;
|
|
@@ -2112,28 +2255,11 @@ class StdioMCPWrapper {
|
|
|
2112
2255
|
console.error(authUrl);
|
|
2113
2256
|
console.error('');
|
|
2114
2257
|
|
|
2115
|
-
//
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
// Use osascript for more reliable browser opening on macOS
|
|
2121
|
-
openCommand = `osascript -e 'open location "${authUrl}"'`;
|
|
2122
|
-
} else if (platform === 'win32') {
|
|
2123
|
-
openCommand = `start "" "${authUrl}"`;
|
|
2124
|
-
} else {
|
|
2125
|
-
openCommand = `xdg-open "${authUrl}"`;
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
exec(openCommand, (error) => {
|
|
2129
|
-
if (error) {
|
|
2130
|
-
console.error('[Polydev] Browser open failed, trying fallback...');
|
|
2131
|
-
// Fallback to spawn
|
|
2132
|
-
const { spawn } = require('child_process');
|
|
2133
|
-
if (platform === 'darwin') {
|
|
2134
|
-
spawn('open', [authUrl], { detached: true, stdio: 'ignore' }).unref();
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2258
|
+
// Best-in-class browser opening using 'open' package (cross-platform)
|
|
2259
|
+
// Falls back to platform-specific commands if package fails
|
|
2260
|
+
this.openBrowser(authUrl).catch(() => {
|
|
2261
|
+
console.error('[Polydev] All browser open methods failed');
|
|
2262
|
+
console.error('[Polydev] Please open this URL manually:', authUrl);
|
|
2137
2263
|
});
|
|
2138
2264
|
|
|
2139
2265
|
// Don't block forever - resolve after timeout
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polydev-ai",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.82",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.x <=22.x"
|
|
6
6
|
},
|
|
@@ -73,6 +73,7 @@
|
|
|
73
73
|
"lucide-react": "^0.542.0",
|
|
74
74
|
"marked": "^16.2.1",
|
|
75
75
|
"next": "^15.5.7",
|
|
76
|
+
"open": "^11.0.0",
|
|
76
77
|
"polydev-ai": "^1.8.42",
|
|
77
78
|
"posthog-js": "^1.157.2",
|
|
78
79
|
"prismjs": "^1.30.0",
|