shell-mirror 1.5.97 → 1.5.98
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 +75 -33
- package/package.json +1 -1
- package/public/app/dashboard.js +2 -1
package/mac-agent/agent.js
CHANGED
|
@@ -519,7 +519,6 @@ function connectToSignalingServer() {
|
|
|
519
519
|
try {
|
|
520
520
|
let sessionId;
|
|
521
521
|
let isNewSession = false;
|
|
522
|
-
let availableSessions = sessionManager.getAllSessions();
|
|
523
522
|
|
|
524
523
|
// Handle session request from client
|
|
525
524
|
if (data.sessionRequest) {
|
|
@@ -569,15 +568,16 @@ function connectToSignalingServer() {
|
|
|
569
568
|
await peerConnection.setLocalDescription(offer);
|
|
570
569
|
|
|
571
570
|
// Send WebRTC offer with session assignment
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
571
|
+
// Get availableSessions AFTER session creation so new session is included
|
|
572
|
+
sendMessage({
|
|
573
|
+
type: 'offer',
|
|
574
|
+
sdp: offer.sdp,
|
|
575
|
+
to: data.from,
|
|
576
576
|
from: AGENT_ID,
|
|
577
577
|
sessionId: sessionId,
|
|
578
578
|
sessionName: sessionManager.getSession(sessionId).name,
|
|
579
579
|
isNewSession: isNewSession,
|
|
580
|
-
availableSessions:
|
|
580
|
+
availableSessions: sessionManager.getAllSessions()
|
|
581
581
|
});
|
|
582
582
|
logToFile('✅ WebRTC offer sent with session assignment');
|
|
583
583
|
|
|
@@ -1007,6 +1007,9 @@ process.on('SIGTERM', () => {
|
|
|
1007
1007
|
});
|
|
1008
1008
|
|
|
1009
1009
|
// --- Local WebSocket Server for Direct Connections ---
|
|
1010
|
+
// Sessions storage for direct WebSocket connections
|
|
1011
|
+
const directSessions = {};
|
|
1012
|
+
|
|
1010
1013
|
function startLocalServer() {
|
|
1011
1014
|
const localPort = process.env.LOCAL_PORT || 8080;
|
|
1012
1015
|
const localServer = require('ws').Server;
|
|
@@ -1039,57 +1042,96 @@ function startLocalServer() {
|
|
|
1039
1042
|
break;
|
|
1040
1043
|
|
|
1041
1044
|
case 'create_session':
|
|
1042
|
-
//
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
name: 'xterm-color',
|
|
1046
|
-
cols: message.cols || 120,
|
|
1047
|
-
rows: message.rows || 30,
|
|
1048
|
-
cwd: process.env.HOME,
|
|
1049
|
-
env: process.env
|
|
1050
|
-
});
|
|
1045
|
+
// Check if client requested an existing session
|
|
1046
|
+
let sessionId;
|
|
1047
|
+
let isNewSession = false;
|
|
1051
1048
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1049
|
+
if (message.sessionId && directSessions[message.sessionId]) {
|
|
1050
|
+
// Reconnect to existing session
|
|
1051
|
+
sessionId = message.sessionId;
|
|
1052
|
+
logToFile(`[LOCAL] Reconnecting to existing session: ${sessionId}`);
|
|
1053
|
+
|
|
1054
|
+
// Update activity timestamp
|
|
1055
|
+
directSessions[sessionId].lastActivity = Date.now();
|
|
1056
|
+
|
|
1057
|
+
// Re-attach output handler for this connection
|
|
1058
|
+
directSessions[sessionId].pty.onData((data) => {
|
|
1059
|
+
if (localWs.readyState === WebSocket.OPEN) {
|
|
1060
|
+
localWs.send(JSON.stringify({
|
|
1061
|
+
type: 'output',
|
|
1062
|
+
sessionId,
|
|
1063
|
+
data
|
|
1064
|
+
}));
|
|
1065
|
+
}
|
|
1066
|
+
});
|
|
1058
1067
|
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
if (
|
|
1068
|
+
// Send buffered output if available
|
|
1069
|
+
const bufferedOutput = directSessions[sessionId].buffer.getAll();
|
|
1070
|
+
if (bufferedOutput.length > 0) {
|
|
1062
1071
|
localWs.send(JSON.stringify({
|
|
1063
1072
|
type: 'output',
|
|
1064
1073
|
sessionId,
|
|
1065
|
-
data
|
|
1074
|
+
data: bufferedOutput.join('')
|
|
1066
1075
|
}));
|
|
1067
1076
|
}
|
|
1068
|
-
}
|
|
1077
|
+
} else {
|
|
1078
|
+
// Create new terminal session
|
|
1079
|
+
sessionId = uuidv4();
|
|
1080
|
+
isNewSession = true;
|
|
1081
|
+
|
|
1082
|
+
const ptyProcess = pty.spawn(shell, [], {
|
|
1083
|
+
name: 'xterm-color',
|
|
1084
|
+
cols: message.cols || 120,
|
|
1085
|
+
rows: message.rows || 30,
|
|
1086
|
+
cwd: process.env.HOME,
|
|
1087
|
+
env: process.env
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
// Store session
|
|
1091
|
+
directSessions[sessionId] = {
|
|
1092
|
+
pty: ptyProcess,
|
|
1093
|
+
buffer: new CircularBuffer(),
|
|
1094
|
+
lastActivity: Date.now()
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
// Send session output to direct connection
|
|
1098
|
+
ptyProcess.onData((data) => {
|
|
1099
|
+
if (localWs.readyState === WebSocket.OPEN) {
|
|
1100
|
+
localWs.send(JSON.stringify({
|
|
1101
|
+
type: 'output',
|
|
1102
|
+
sessionId,
|
|
1103
|
+
data
|
|
1104
|
+
}));
|
|
1105
|
+
}
|
|
1106
|
+
// Store in buffer for reconnection
|
|
1107
|
+
directSessions[sessionId].buffer.add(data);
|
|
1108
|
+
});
|
|
1109
|
+
|
|
1110
|
+
logToFile(`[LOCAL] Created new direct session: ${sessionId}`);
|
|
1111
|
+
}
|
|
1069
1112
|
|
|
1070
1113
|
localWs.send(JSON.stringify({
|
|
1071
1114
|
type: 'session_created',
|
|
1072
1115
|
sessionId,
|
|
1073
1116
|
sessionName: `Session ${sessionId.slice(0, 8)}`,
|
|
1117
|
+
isNewSession: isNewSession,
|
|
1074
1118
|
cols: message.cols || 120,
|
|
1075
1119
|
rows: message.rows || 30
|
|
1076
1120
|
}));
|
|
1077
|
-
|
|
1078
|
-
logToFile(`[LOCAL] Created direct session: ${sessionId}`);
|
|
1079
1121
|
break;
|
|
1080
1122
|
|
|
1081
1123
|
case 'input':
|
|
1082
1124
|
// Handle terminal input for direct connection
|
|
1083
|
-
if (
|
|
1084
|
-
|
|
1085
|
-
|
|
1125
|
+
if (directSessions[message.sessionId]) {
|
|
1126
|
+
directSessions[message.sessionId].pty.write(message.data);
|
|
1127
|
+
directSessions[message.sessionId].lastActivity = Date.now();
|
|
1086
1128
|
}
|
|
1087
1129
|
break;
|
|
1088
1130
|
|
|
1089
1131
|
case 'resize':
|
|
1090
1132
|
// Handle terminal resize for direct connection
|
|
1091
|
-
if (
|
|
1092
|
-
|
|
1133
|
+
if (directSessions[message.sessionId]) {
|
|
1134
|
+
directSessions[message.sessionId].pty.resize(message.cols, message.rows);
|
|
1093
1135
|
}
|
|
1094
1136
|
break;
|
|
1095
1137
|
|
package/package.json
CHANGED
package/public/app/dashboard.js
CHANGED
|
@@ -383,7 +383,8 @@ class ShellMirrorDashboard {
|
|
|
383
383
|
updateAgentsDisplay() {
|
|
384
384
|
const agentsCard = document.querySelector('.dashboard-card');
|
|
385
385
|
if (agentsCard) {
|
|
386
|
-
|
|
386
|
+
// Use outerHTML to replace the entire card, not nest inside it
|
|
387
|
+
agentsCard.outerHTML = this.renderActiveAgents();
|
|
387
388
|
}
|
|
388
389
|
}
|
|
389
390
|
|