shell-mirror 1.5.96 → 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.
@@ -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
- sendMessage({
573
- type: 'offer',
574
- sdp: offer.sdp,
575
- to: data.from,
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: 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
- // Create new terminal session for direct connection
1043
- const sessionId = uuidv4();
1044
- const ptyProcess = pty.spawn(shell, [], {
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
- // Store session
1053
- sessions[sessionId] = {
1054
- pty: ptyProcess,
1055
- buffer: new CircularBuffer(),
1056
- lastActivity: Date.now()
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
- // Send session output to direct connection
1060
- ptyProcess.onData((data) => {
1061
- if (localWs.readyState === WebSocket.OPEN) {
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 (sessions[message.sessionId]) {
1084
- sessions[message.sessionId].pty.write(message.data);
1085
- sessions[message.sessionId].lastActivity = Date.now();
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 (sessions[message.sessionId]) {
1092
- sessions[message.sessionId].pty.resize(message.cols, message.rows);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shell-mirror",
3
- "version": "1.5.96",
3
+ "version": "1.5.98",
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": {
@@ -383,7 +383,8 @@ class ShellMirrorDashboard {
383
383
  updateAgentsDisplay() {
384
384
  const agentsCard = document.querySelector('.dashboard-card');
385
385
  if (agentsCard) {
386
- agentsCard.innerHTML = this.renderActiveAgents();
386
+ // Use outerHTML to replace the entire card, not nest inside it
387
+ agentsCard.outerHTML = this.renderActiveAgents();
387
388
  }
388
389
  }
389
390
 
@@ -946,7 +947,7 @@ class ShellMirrorDashboard {
946
947
  if (response.ok) {
947
948
  const data = await response.json();
948
949
  console.log('[DASHBOARD] 🔍 Ping response:', data);
949
- return data.success && data.reachable;
950
+ return data.success && data.data && data.data.reachable;
950
951
  }
951
952
 
952
953
  console.log('[DASHBOARD] ⚠️ Ping request failed:', response.status);