shell-mirror 1.5.23 → 1.5.24

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/lib/auto-start.js CHANGED
@@ -445,68 +445,25 @@ WS_URL=${wsConfig.wsUrl}` : ''}
445
445
 
446
446
  async startAuthenticatedServer(authInfo) {
447
447
  console.log('');
448
- console.log('🚀 Starting authenticated Shell Mirror with local WebSocket server...');
448
+ console.log('🚀 Starting authenticated Shell Mirror with cloud WebSocket connection...');
449
449
 
450
450
  try {
451
- // Set up local WebSocket server configuration
452
- const wsPort = await NetworkUtils.findAvailablePort(8080, 10);
453
- const wsConfig = NetworkUtils.generateWebSocketConfig(wsPort);
451
+ // Register this agent with the cloud backend
452
+ await this.registerAsMacAgent(authInfo);
454
453
 
455
- // Display network information
456
- NetworkUtils.displayNetworkInfo(wsConfig);
457
-
458
- // Create .env file with authentication and WebSocket config
459
- await this.createEnvFile(authInfo, wsConfig);
460
-
461
- // Register this server as a Mac agent with WebSocket endpoint
462
- await this.registerAsMacAgent(authInfo, wsConfig);
463
-
464
- // Start the local WebSocket server process
465
- const packageRoot = path.resolve(__dirname, '..');
466
- const serverPath = path.join(packageRoot, 'server.js');
467
-
468
- console.log('🔄 Starting local WebSocket server...');
469
- const serverProcess = spawn('node', [serverPath], {
470
- stdio: 'inherit',
471
- cwd: path.dirname(this.envFile),
472
- env: {
473
- ...process.env,
474
- WS_PORT: wsConfig.port.toString(),
475
- WS_HOST: wsConfig.host,
476
- LOCAL_IP: wsConfig.localIP
477
- }
478
- });
479
-
480
- // Display status information
481
- this.displayStatus(authInfo, wsConfig);
482
-
483
- // Handle Ctrl+C gracefully
484
- process.on('SIGINT', () => {
485
- console.log('');
486
- console.log('🛑 Stopping Shell Mirror and WebSocket server...');
487
- serverProcess.kill('SIGINT');
488
- process.exit(0);
489
- });
490
-
491
- // Wait for server process
492
- serverProcess.on('close', (code) => {
493
- if (code !== 0) {
494
- console.error(`❌ Server exited with code ${code}`);
495
- process.exit(code);
496
- }
497
- });
454
+ // Start the terminal agent with cloud WebSocket connection
455
+ await this.startTerminalAgent(authInfo);
498
456
 
499
457
  } catch (error) {
500
- console.error('❌ Failed to start WebSocket server:', error.message);
458
+ console.error('❌ Failed to start Shell Mirror:', error.message);
501
459
  process.exit(1);
502
460
  }
503
461
  }
504
462
 
505
- async registerAsMacAgent(authInfo, wsConfig) {
506
- console.log('🔗 Registering as Mac agent with WebSocket endpoint...');
463
+ async registerAsMacAgent(authInfo) {
464
+ console.log('🔗 Registering as Mac agent with cloud WebSocket...');
507
465
  console.log(` User: ${authInfo.email}`);
508
466
  console.log(` Machine: ${os.hostname()}`);
509
- console.log(` WebSocket: ${wsConfig.wsUrl}`);
510
467
 
511
468
  try {
512
469
  const agentId = `local-${os.hostname()}-${Date.now()}`;
@@ -516,11 +473,9 @@ WS_URL=${wsConfig.wsUrl}` : ''}
516
473
  ownerName: authInfo.name,
517
474
  ownerToken: authInfo.accessToken,
518
475
  machineName: os.hostname(),
519
- agentVersion: '1.5.17',
520
- capabilities: ['terminal', 'websocket'],
521
- serverPort: wsConfig.port,
522
- websocketUrl: wsConfig.wsUrl,
523
- localIP: wsConfig.localIP
476
+ agentVersion: '1.5.23',
477
+ capabilities: ['terminal', 'cloud-websocket'],
478
+ connectionType: 'cloud-websocket'
524
479
  };
525
480
 
526
481
  console.log(` Agent ID: ${agentId}`);
@@ -577,6 +532,58 @@ WS_URL=${wsConfig.wsUrl}` : ''}
577
532
  }
578
533
  }
579
534
 
535
+ async startTerminalAgent(authInfo) {
536
+ console.log('');
537
+ console.log('🔄 Starting terminal agent with cloud WebSocket connection...');
538
+
539
+ // Find the package root directory (where agent files are located)
540
+ const packageRoot = path.resolve(__dirname, '..');
541
+ const agentPath = path.join(packageRoot, 'mac-agent', 'agent.js');
542
+
543
+ // Create environment for agent
544
+ const agentEnv = {
545
+ ...process.env,
546
+ USER_EMAIL: authInfo.email,
547
+ USER_NAME: authInfo.name,
548
+ ACCESS_TOKEN: authInfo.accessToken,
549
+ WEBSOCKET_URL: 'wss://shellmirror.app',
550
+ CONNECTION_TYPE: 'cloud-websocket'
551
+ };
552
+
553
+ console.log('🌐 Connecting to: wss://shellmirror.app');
554
+ console.log('📱 Access from browser: https://shellmirror.app/app/terminal.html');
555
+ console.log('');
556
+
557
+ // Start the terminal agent process
558
+ const agentProcess = spawn('node', [agentPath], {
559
+ stdio: 'inherit',
560
+ env: agentEnv
561
+ });
562
+
563
+ // Display final status
564
+ const pkg = require('../package.json');
565
+ console.log(`✅ Shell Mirror v${pkg.version} - Running (${authInfo.email})`);
566
+ console.log('🌐 Connection: Cloud WebSocket (wss://shellmirror.app)');
567
+ console.log('Press Ctrl+C to stop');
568
+ console.log('');
569
+
570
+ // Handle Ctrl+C gracefully
571
+ process.on('SIGINT', () => {
572
+ console.log('');
573
+ console.log('🛑 Stopping Shell Mirror agent...');
574
+ agentProcess.kill('SIGINT');
575
+ process.exit(0);
576
+ });
577
+
578
+ // Wait for agent process
579
+ agentProcess.on('close', (code) => {
580
+ if (code !== 0) {
581
+ console.error(`❌ Agent exited with code ${code}`);
582
+ process.exit(code);
583
+ }
584
+ });
585
+ }
586
+
580
587
  async makeHttpsRequest(options, postData = null) {
581
588
  return new Promise((resolve, reject) => {
582
589
  const req = https.request(options, (res) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shell-mirror",
3
- "version": "1.5.23",
3
+ "version": "1.5.24",
4
4
  "description": "Access your Mac shell from any device securely. Perfect for mobile coding with Claude Code CLI, Gemini CLI, and any shell tool.",
5
5
  "main": "server.js",
6
6
  "bin": {
@@ -228,46 +228,9 @@ async function initialize() {
228
228
  console.log('[CLIENT] 🚀 Initializing WebRTC connection to agent:', AGENT_ID);
229
229
  console.log('[CLIENT] 📋 Selected agent data:', SELECTED_AGENT);
230
230
 
231
- // Determine WebSocket URL - use agent's local WebSocket server if available
232
- let signalingUrl;
233
- if (SELECTED_AGENT && SELECTED_AGENT.websocketUrl) {
234
- signalingUrl = SELECTED_AGENT.websocketUrl;
235
- console.log('[CLIENT] 🌐 Agent WebSocket URL:', signalingUrl);
236
-
237
- // Check for mixed content issue (HTTPS page + WS:// URL)
238
- const isHttpsPage = window.location.protocol === 'https:';
239
- const isInsecureWebSocket = signalingUrl.startsWith('ws://');
240
-
241
- if (isHttpsPage && isInsecureWebSocket) {
242
- console.warn('[CLIENT] ⚠️ Mixed content detected: HTTPS page cannot connect to insecure WebSocket');
243
- console.log('[CLIENT] 💡 Solution: Use HTTP terminal page for local WebSocket connections');
244
-
245
- // Provide user with HTTP terminal URL
246
- const httpTerminalUrl = `http://shellmirror.app/app/terminal-http.html`;
247
- console.log(`[CLIENT] 🔗 Redirect to HTTP terminal: ${httpTerminalUrl}`);
248
-
249
- // Show user-friendly error message
250
- term.write('\r\n\x1b[33m⚠️ Mixed Content Security Issue\x1b[0m\r\n');
251
- term.write('\r\nHTTPS pages cannot connect to local WebSocket servers.\r\n');
252
- term.write('\r\n\x1b[32mSolution:\x1b[0m\r\n');
253
- term.write(`1. Open: \x1b[36m${httpTerminalUrl}\x1b[0m\r\n`);
254
- term.write('2. Click on your agent again\r\n');
255
- term.write('\r\nThis will allow the local WebSocket connection.\r\n');
256
-
257
- // Auto-redirect after showing message
258
- setTimeout(() => {
259
- window.location.href = httpTerminalUrl;
260
- }, 5000);
261
-
262
- return; // Don't attempt WebSocket connection
263
- }
264
-
265
- console.log('[CLIENT] ✅ Using agent\'s local WebSocket server:', signalingUrl);
266
- } else {
267
- // Fallback to web app domain (old behavior)
268
- signalingUrl = (window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host;
269
- console.log('[CLIENT] 🌐 Using fallback WebSocket server:', signalingUrl);
270
- }
231
+ // Use cloud WebSocket for all connections (solves HTTPS mixed content issue)
232
+ const signalingUrl = (window.location.protocol === 'https:' ? 'wss://' : 'ws://') + window.location.host;
233
+ console.log('[CLIENT] 🌐 Using cloud WebSocket server:', signalingUrl);
271
234
 
272
235
  ws = new WebSocket(`${signalingUrl}?role=client`);
273
236