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.
@@ -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('[Stdio Wrapper] Waiting for initial CLI detection to complete...');
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polydev-ai",
3
- "version": "1.8.93",
3
+ "version": "1.8.95",
4
4
  "engines": {
5
5
  "node": ">=20.x <=22.x"
6
6
  },