shell-mirror 1.5.127 → 1.5.129
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/mac-agent/agent.js +15 -1
- package/package.json +1 -1
- package/public/app/terminal.html +3 -3
- package/public/app/terminal.js +26 -26
package/mac-agent/agent.js
CHANGED
|
@@ -7,6 +7,7 @@ const os = require('os');
|
|
|
7
7
|
const { v4: uuidv4 } = require('uuid');
|
|
8
8
|
const fs = require('fs');
|
|
9
9
|
const https = require('https');
|
|
10
|
+
const { exec } = require('child_process');
|
|
10
11
|
|
|
11
12
|
// Enhanced logging to file
|
|
12
13
|
const LOG_FILE = path.join(__dirname, 'agent-debug.log');
|
|
@@ -532,9 +533,22 @@ function connectToSignalingServer() {
|
|
|
532
533
|
|
|
533
534
|
ws.on('open', () => {
|
|
534
535
|
logToFile('✅ Connected to signaling server.');
|
|
535
|
-
|
|
536
|
+
|
|
536
537
|
// Start heartbeat system to maintain agent status
|
|
537
538
|
startHeartbeatSystem();
|
|
539
|
+
|
|
540
|
+
// Open dashboard in default browser
|
|
541
|
+
const dashboardUrl = 'https://shellmirror.app/app/dashboard.html';
|
|
542
|
+
logToFile(`🌐 Opening dashboard in browser: ${dashboardUrl}`);
|
|
543
|
+
|
|
544
|
+
exec(`open "${dashboardUrl}"`, (error) => {
|
|
545
|
+
if (error) {
|
|
546
|
+
logToFile(`⚠️ Could not open browser automatically: ${error.message}`);
|
|
547
|
+
logToFile(`💡 Please open ${dashboardUrl} manually in your browser`);
|
|
548
|
+
} else {
|
|
549
|
+
logToFile('✅ Dashboard opened in browser');
|
|
550
|
+
}
|
|
551
|
+
});
|
|
538
552
|
});
|
|
539
553
|
|
|
540
554
|
ws.on('message', async (message) => {
|
package/package.json
CHANGED
package/public/app/terminal.html
CHANGED
|
@@ -233,12 +233,12 @@
|
|
|
233
233
|
|
|
234
234
|
@keyframes calm-pulsate {
|
|
235
235
|
0%, 100% {
|
|
236
|
-
box-shadow: 0 0 0 rgba(
|
|
236
|
+
box-shadow: 0 0 0 rgba(255, 170, 68, 0);
|
|
237
237
|
border-color: #444;
|
|
238
238
|
}
|
|
239
239
|
50% {
|
|
240
|
-
box-shadow: 0 0 12px rgba(
|
|
241
|
-
border-color: #
|
|
240
|
+
box-shadow: 0 0 12px rgba(255, 170, 68, 0.6);
|
|
241
|
+
border-color: #ffaa44;
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
|
package/public/app/terminal.js
CHANGED
|
@@ -274,7 +274,7 @@ function startConnection() {
|
|
|
274
274
|
term.open(document.getElementById('terminal'));
|
|
275
275
|
|
|
276
276
|
// Show initial connection message
|
|
277
|
-
setConnectionMessage('
|
|
277
|
+
setConnectionMessage('Connecting to agent...', true);
|
|
278
278
|
|
|
279
279
|
// Initialize session display (shows header with connection status even before session exists)
|
|
280
280
|
updateSessionDisplay();
|
|
@@ -298,30 +298,30 @@ function startConnection() {
|
|
|
298
298
|
// Set up connection timeout warnings
|
|
299
299
|
const timeout10s = setTimeout(() => {
|
|
300
300
|
if (!currentSession) {
|
|
301
|
-
setConnectionMessage('
|
|
302
|
-
term.write('\r\n\x1b[
|
|
301
|
+
setConnectionMessage('Taking longer than usual... Please wait', true);
|
|
302
|
+
term.write('\r\n\x1b[33mConnection is taking longer than expected...\x1b[0m\r\n');
|
|
303
303
|
}
|
|
304
304
|
}, 10000);
|
|
305
305
|
|
|
306
306
|
const timeout30s = setTimeout(() => {
|
|
307
307
|
if (!currentSession) {
|
|
308
|
-
setConnectionMessage('
|
|
309
|
-
term.write('\x1b[
|
|
310
|
-
term.write('\x1b[
|
|
308
|
+
setConnectionMessage('Connection very slow - Agent may be offline', true);
|
|
309
|
+
term.write('\x1b[33mStill trying to connect. The agent may be offline or unreachable.\x1b[0m\r\n');
|
|
310
|
+
term.write('\x1b[36mTip: Check the agent status on the Dashboard\x1b[0m\r\n');
|
|
311
311
|
}
|
|
312
312
|
}, 30000);
|
|
313
313
|
|
|
314
314
|
const timeout60s = setTimeout(() => {
|
|
315
315
|
if (!currentSession) {
|
|
316
316
|
updateConnectionStatus('disconnected');
|
|
317
|
-
setConnectionMessage('
|
|
318
|
-
term.write('\r\n\r\n\x1b[
|
|
317
|
+
setConnectionMessage('Failed to connect - Agent or session unavailable', false);
|
|
318
|
+
term.write('\r\n\r\n\x1b[31mConnection Failed\x1b[0m\r\n');
|
|
319
319
|
term.write('\x1b[33mThe agent or session you requested is not available.\x1b[0m\r\n');
|
|
320
320
|
term.write('\r\n\x1b[36mPossible reasons:\x1b[0m\r\n');
|
|
321
321
|
term.write(' • Agent is offline or shut down\r\n');
|
|
322
322
|
term.write(' • Session was terminated\r\n');
|
|
323
323
|
term.write(' • Network connectivity issues\r\n');
|
|
324
|
-
term.write('\r\n\x1b[
|
|
324
|
+
term.write('\r\n\x1b[36mClick Dashboard to return and try another session\x1b[0m\r\n');
|
|
325
325
|
|
|
326
326
|
// Make Dashboard button pulsate calmly to guide user back
|
|
327
327
|
const dashboardBtn = document.querySelector('.dashboard-btn');
|
|
@@ -347,19 +347,19 @@ async function initialize() {
|
|
|
347
347
|
|
|
348
348
|
if (directConnectionSuccess) {
|
|
349
349
|
console.log('[CLIENT] ✅ Direct connection established - no server needed!');
|
|
350
|
-
setConnectionMessage('
|
|
350
|
+
setConnectionMessage('Connected via local network!', true);
|
|
351
351
|
return;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
console.log('[CLIENT] ⚠️ Direct connection failed, falling back to WebRTC signaling...');
|
|
355
|
-
setConnectionMessage('
|
|
355
|
+
setConnectionMessage('Attempting WebRTC connection...', true);
|
|
356
356
|
await initializeWebRTCSignaling();
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
async function tryDirectConnection() {
|
|
360
360
|
console.log('[CLIENT] 🔗 Attempting direct connection to agent...');
|
|
361
361
|
updateConnectionStatus('connecting');
|
|
362
|
-
setConnectionMessage('
|
|
362
|
+
setConnectionMessage('Trying direct connection to local network...', true);
|
|
363
363
|
|
|
364
364
|
// Get agent data from API to find local connection details
|
|
365
365
|
try {
|
|
@@ -471,7 +471,7 @@ function setupDirectConnection(directWs) {
|
|
|
471
471
|
|
|
472
472
|
// Clear connection timeout warnings
|
|
473
473
|
clearConnectionTimeouts();
|
|
474
|
-
setConnectionMessage('
|
|
474
|
+
setConnectionMessage('Session created successfully!', false);
|
|
475
475
|
|
|
476
476
|
// Update current session
|
|
477
477
|
currentSession = {
|
|
@@ -651,7 +651,7 @@ async function initializeWebRTCSignaling() {
|
|
|
651
651
|
if (nextData.sessionId) {
|
|
652
652
|
// Clear connection timeout warnings
|
|
653
653
|
clearConnectionTimeouts();
|
|
654
|
-
setConnectionMessage('
|
|
654
|
+
setConnectionMessage('Session connected!', false);
|
|
655
655
|
|
|
656
656
|
currentSession = {
|
|
657
657
|
id: nextData.sessionId,
|
|
@@ -876,9 +876,9 @@ async function createPeerConnection() {
|
|
|
876
876
|
console.log('[CLIENT] ❌ ICE connection failed - no viable candidates');
|
|
877
877
|
console.log('[CLIENT] 💡 Troubleshooting: This may be due to firewall/NAT issues or blocked STUN servers');
|
|
878
878
|
updateConnectionStatus('disconnected');
|
|
879
|
-
setConnectionMessage('
|
|
880
|
-
term.write('\r\n\r\
|
|
881
|
-
term.write('
|
|
879
|
+
setConnectionMessage('Unable to connect - Agent may be offline', false);
|
|
880
|
+
term.write('\r\n\r\nConnection failed: Network connectivity issues\r\n');
|
|
881
|
+
term.write('This may be due to:\r\n');
|
|
882
882
|
term.write(' • Firewall blocking WebRTC traffic\r\n');
|
|
883
883
|
term.write(' • Corporate network restrictions\r\n');
|
|
884
884
|
term.write(' • STUN/TURN servers unreachable\r\n');
|
|
@@ -979,15 +979,15 @@ function setupDataChannel() {
|
|
|
979
979
|
dataChannel.onclose = () => {
|
|
980
980
|
console.log('[CLIENT] Data channel closed.');
|
|
981
981
|
updateConnectionStatus('disconnected');
|
|
982
|
-
term.write('\r\n\r\n\x1b[
|
|
983
|
-
term.write('
|
|
982
|
+
term.write('\r\n\r\n\x1b[31mTerminal session ended.\x1b[0m\r\n');
|
|
983
|
+
term.write('Click Dashboard to return and start a new session\r\n');
|
|
984
984
|
};
|
|
985
985
|
|
|
986
986
|
dataChannel.onerror = (error) => {
|
|
987
987
|
console.error('[CLIENT] Data channel error:', error);
|
|
988
988
|
updateConnectionStatus('disconnected');
|
|
989
|
-
term.write('\r\n\r\n\x1b[
|
|
990
|
-
term.write('
|
|
989
|
+
term.write('\r\n\r\n\x1b[31mData channel error occurred.\x1b[0m\r\n');
|
|
990
|
+
term.write('Click Dashboard to return and try again\r\n');
|
|
991
991
|
};
|
|
992
992
|
|
|
993
993
|
term.onData((data) => {
|
|
@@ -1291,7 +1291,7 @@ function createNewSession() {
|
|
|
1291
1291
|
console.error('[CLIENT] ❌ Cannot create session - no active connection');
|
|
1292
1292
|
console.error('[CLIENT] ws:', ws ? ws.readyState : 'null',
|
|
1293
1293
|
'dataChannel:', dataChannel ? dataChannel.readyState : 'null');
|
|
1294
|
-
term.write('\r\n\x1b[
|
|
1294
|
+
term.write('\r\n\x1b[31mCannot create session - not connected\x1b[0m\r\n');
|
|
1295
1295
|
}
|
|
1296
1296
|
}
|
|
1297
1297
|
|
|
@@ -1355,7 +1355,7 @@ function handleSessionMessage(message) {
|
|
|
1355
1355
|
case 'session-ended':
|
|
1356
1356
|
// Only show if this is for the current session (ignore closed session messages)
|
|
1357
1357
|
if (!message.sessionId || (currentSession && message.sessionId === currentSession.id)) {
|
|
1358
|
-
term.write(`\r\n\x1b[
|
|
1358
|
+
term.write(`\r\n\x1b[31mSession ended: ${message.reason}\x1b[0m\r\n`);
|
|
1359
1359
|
if (message.code) {
|
|
1360
1360
|
term.write(`Exit code: ${message.code}\r\n`);
|
|
1361
1361
|
}
|
|
@@ -1364,8 +1364,8 @@ function handleSessionMessage(message) {
|
|
|
1364
1364
|
case 'session-terminated':
|
|
1365
1365
|
// Only show if this is for the current session (ignore closed session messages)
|
|
1366
1366
|
if (!message.sessionId || (currentSession && message.sessionId === currentSession.id)) {
|
|
1367
|
-
term.write(`\r\n\x1b[
|
|
1368
|
-
term.write('
|
|
1367
|
+
term.write(`\r\n\x1b[31mSession terminated\x1b[0m\r\n`);
|
|
1368
|
+
term.write('Click Dashboard to start a new session\r\n');
|
|
1369
1369
|
}
|
|
1370
1370
|
break;
|
|
1371
1371
|
case 'session-closed':
|
|
@@ -1377,7 +1377,7 @@ function handleSessionMessage(message) {
|
|
|
1377
1377
|
}
|
|
1378
1378
|
break;
|
|
1379
1379
|
case 'error':
|
|
1380
|
-
term.write(`\r\n\x1b[
|
|
1380
|
+
term.write(`\r\n\x1b[31mError: ${message.message}\x1b[0m\r\n`);
|
|
1381
1381
|
break;
|
|
1382
1382
|
}
|
|
1383
1383
|
}
|