polydev-ai 1.8.93 → 1.8.95
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/stdio-wrapper.js +101 -3
- package/package.json +1 -1
package/mcp/stdio-wrapper.js
CHANGED
|
@@ -253,6 +253,9 @@ class StdioMCPWrapper {
|
|
|
253
253
|
// Server URL for API calls
|
|
254
254
|
this.serverUrl = 'https://www.polydev.ai/api/mcp';
|
|
255
255
|
|
|
256
|
+
// Pending session file for surviving restarts
|
|
257
|
+
this.PENDING_SESSION_FILE = path.join(os.homedir(), '.polydev-pending-session');
|
|
258
|
+
|
|
256
259
|
// Initialize CLI Manager for local CLI functionality
|
|
257
260
|
this.cliManager = new CLIManager();
|
|
258
261
|
|
|
@@ -264,6 +267,12 @@ class StdioMCPWrapper {
|
|
|
264
267
|
this.reloadTokenFromFiles();
|
|
265
268
|
}
|
|
266
269
|
|
|
270
|
+
// Check for pending login session from previous process
|
|
271
|
+
// This allows login to survive MCP reconnections
|
|
272
|
+
if (!this.isAuthenticated) {
|
|
273
|
+
this.resumePendingLoginSession();
|
|
274
|
+
}
|
|
275
|
+
|
|
267
276
|
// Log startup status
|
|
268
277
|
if (this.userToken) {
|
|
269
278
|
console.error('[Polydev] Starting with authentication token');
|
|
@@ -475,6 +484,9 @@ To re-login: npx polydev-ai`
|
|
|
475
484
|
console.error('[Polydev] Please open this URL manually:', authUrl);
|
|
476
485
|
});
|
|
477
486
|
|
|
487
|
+
// Save pending session to file (allows resuming after MCP reconnect)
|
|
488
|
+
this.savePendingSession(sessionId);
|
|
489
|
+
|
|
478
490
|
// Start polling in background (survives reconnections because
|
|
479
491
|
// if this process dies, the new one can resume polling with same session)
|
|
480
492
|
this.startLoginPolling(sessionId);
|
|
@@ -521,12 +533,18 @@ After login:
|
|
|
521
533
|
|
|
522
534
|
/**
|
|
523
535
|
* Poll for login session completion
|
|
536
|
+
* @param {string} sessionId - The session ID to poll
|
|
537
|
+
* @param {boolean} isResume - Whether this is resuming from a previous process
|
|
524
538
|
*/
|
|
525
|
-
async startLoginPolling(sessionId) {
|
|
539
|
+
async startLoginPolling(sessionId, isResume = false) {
|
|
526
540
|
const pollInterval = 2000; // 2 seconds
|
|
527
541
|
const maxPolls = 300; // 10 minutes max
|
|
528
542
|
let polls = 0;
|
|
529
543
|
|
|
544
|
+
if (isResume) {
|
|
545
|
+
console.error('[Polydev] Resuming login polling from previous session...');
|
|
546
|
+
}
|
|
547
|
+
|
|
530
548
|
const poll = async () => {
|
|
531
549
|
polls++;
|
|
532
550
|
|
|
@@ -535,7 +553,8 @@ After login:
|
|
|
535
553
|
const data = await response.json();
|
|
536
554
|
|
|
537
555
|
if (data.status === 'completed' && data.token) {
|
|
538
|
-
// Success! Save the token
|
|
556
|
+
// Success! Save the token and clear pending session
|
|
557
|
+
this.clearPendingSession();
|
|
539
558
|
this.saveTokenToFiles(data.token);
|
|
540
559
|
this.userToken = data.token;
|
|
541
560
|
this.isAuthenticated = true;
|
|
@@ -543,15 +562,18 @@ After login:
|
|
|
543
562
|
|
|
544
563
|
console.error('[Polydev] ✓ Login successful! Token saved.');
|
|
545
564
|
console.error('[Polydev] You can now use Polydev tools.');
|
|
565
|
+
console.error('[Polydev] No restart required - token is active immediately.');
|
|
546
566
|
return; // Stop polling
|
|
547
567
|
}
|
|
548
568
|
|
|
549
569
|
if (data.status === 'expired' || response.status === 410) {
|
|
570
|
+
this.clearPendingSession();
|
|
550
571
|
console.error('[Polydev] Login session expired. Please try again.');
|
|
551
572
|
return; // Stop polling
|
|
552
573
|
}
|
|
553
574
|
|
|
554
575
|
if (data.status === 'not_found' || response.status === 404) {
|
|
576
|
+
this.clearPendingSession();
|
|
555
577
|
console.error('[Polydev] Login session not found.');
|
|
556
578
|
return; // Stop polling
|
|
557
579
|
}
|
|
@@ -560,6 +582,7 @@ After login:
|
|
|
560
582
|
if (polls < maxPolls) {
|
|
561
583
|
setTimeout(poll, pollInterval);
|
|
562
584
|
} else {
|
|
585
|
+
this.clearPendingSession();
|
|
563
586
|
console.error('[Polydev] Login polling timed out.');
|
|
564
587
|
}
|
|
565
588
|
|
|
@@ -568,6 +591,8 @@ After login:
|
|
|
568
591
|
// Continue polling on network errors
|
|
569
592
|
if (polls < maxPolls) {
|
|
570
593
|
setTimeout(poll, pollInterval);
|
|
594
|
+
} else {
|
|
595
|
+
this.clearPendingSession();
|
|
571
596
|
}
|
|
572
597
|
}
|
|
573
598
|
};
|
|
@@ -827,6 +852,79 @@ Error: ${error.message}`
|
|
|
827
852
|
return false;
|
|
828
853
|
}
|
|
829
854
|
|
|
855
|
+
/**
|
|
856
|
+
* Save pending login session ID to file
|
|
857
|
+
* Allows login to survive MCP reconnections
|
|
858
|
+
*/
|
|
859
|
+
savePendingSession(sessionId) {
|
|
860
|
+
try {
|
|
861
|
+
const data = {
|
|
862
|
+
sessionId,
|
|
863
|
+
createdAt: Date.now(),
|
|
864
|
+
expiresAt: Date.now() + (10 * 60 * 1000) // 10 minutes
|
|
865
|
+
};
|
|
866
|
+
fs.writeFileSync(this.PENDING_SESSION_FILE, JSON.stringify(data));
|
|
867
|
+
console.error(`[Polydev] Saved pending session: ${sessionId.slice(0, 8)}...`);
|
|
868
|
+
} catch (error) {
|
|
869
|
+
console.error('[Polydev] Failed to save pending session:', error.message);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Load pending login session from file
|
|
875
|
+
*/
|
|
876
|
+
loadPendingSession() {
|
|
877
|
+
try {
|
|
878
|
+
if (!fs.existsSync(this.PENDING_SESSION_FILE)) {
|
|
879
|
+
return null;
|
|
880
|
+
}
|
|
881
|
+
const content = fs.readFileSync(this.PENDING_SESSION_FILE, 'utf8');
|
|
882
|
+
const data = JSON.parse(content);
|
|
883
|
+
|
|
884
|
+
// Check if expired
|
|
885
|
+
if (data.expiresAt && Date.now() > data.expiresAt) {
|
|
886
|
+
this.clearPendingSession();
|
|
887
|
+
console.error('[Polydev] Pending session expired, cleared');
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
return data;
|
|
892
|
+
} catch (error) {
|
|
893
|
+
console.error('[Polydev] Failed to load pending session:', error.message);
|
|
894
|
+
return null;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* Clear pending login session file
|
|
900
|
+
*/
|
|
901
|
+
clearPendingSession() {
|
|
902
|
+
try {
|
|
903
|
+
if (fs.existsSync(this.PENDING_SESSION_FILE)) {
|
|
904
|
+
fs.unlinkSync(this.PENDING_SESSION_FILE);
|
|
905
|
+
console.error('[Polydev] Cleared pending session file');
|
|
906
|
+
}
|
|
907
|
+
} catch (error) {
|
|
908
|
+
// Ignore errors
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
/**
|
|
913
|
+
* Resume polling for a pending login session (called on startup)
|
|
914
|
+
*/
|
|
915
|
+
resumePendingLoginSession() {
|
|
916
|
+
const pending = this.loadPendingSession();
|
|
917
|
+
if (!pending || !pending.sessionId) {
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
console.error(`[Polydev] Found pending login session: ${pending.sessionId.slice(0, 8)}...`);
|
|
922
|
+
console.error('[Polydev] Resuming authentication polling...');
|
|
923
|
+
|
|
924
|
+
// Resume polling (this will auto-clear on success/failure)
|
|
925
|
+
this.startLoginPolling(pending.sessionId, true /* isResume */);
|
|
926
|
+
}
|
|
927
|
+
|
|
830
928
|
/**
|
|
831
929
|
* Get login success HTML page
|
|
832
930
|
*/
|
|
@@ -1444,7 +1542,7 @@ Error: ${error.message}`
|
|
|
1444
1542
|
try {
|
|
1445
1543
|
// Wait for initial CLI detection to complete if it's still running
|
|
1446
1544
|
if (this._cliDetectionReady && !this._cliDetectionComplete) {
|
|
1447
|
-
console.error('[
|
|
1545
|
+
console.error('[Polydev] Waiting for initial CLI detection to complete...');
|
|
1448
1546
|
await this._cliDetectionReady;
|
|
1449
1547
|
console.error('[Polydev] CLI detection ready, proceeding with request');
|
|
1450
1548
|
}
|