shell-mirror 1.5.41 → 1.5.42
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 +6 -0
- package/package.json +1 -1
- package/public/app/dashboard.js +56 -28
- package/public/app/terminal.js +35 -0
package/mac-agent/agent.js
CHANGED
|
@@ -146,6 +146,12 @@ class SessionManager {
|
|
|
146
146
|
});
|
|
147
147
|
});
|
|
148
148
|
|
|
149
|
+
// Send initial prompt after terminal is ready
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
// Send a newline to trigger the shell prompt
|
|
152
|
+
terminal.write('\n');
|
|
153
|
+
}, 500);
|
|
154
|
+
|
|
149
155
|
terminal.on('exit', (code) => {
|
|
150
156
|
logToFile(`[SESSION] Terminal process exited for session ${sessionId} with code ${code}`);
|
|
151
157
|
session.status = 'crashed';
|
package/package.json
CHANGED
package/public/app/dashboard.js
CHANGED
|
@@ -82,30 +82,8 @@ class ShellMirrorDashboard {
|
|
|
82
82
|
if (agentsData.success && agentsData.data && agentsData.data.agents) {
|
|
83
83
|
this.agents = agentsData.data.agents;
|
|
84
84
|
|
|
85
|
-
//
|
|
86
|
-
this.
|
|
87
|
-
if (agent.onlineStatus === 'online') {
|
|
88
|
-
// Mock sessions for online agents
|
|
89
|
-
this.agentSessions[agent.agentId] = [
|
|
90
|
-
{
|
|
91
|
-
id: `ses_${Date.now()}_main`,
|
|
92
|
-
name: 'Main Terminal',
|
|
93
|
-
lastActivity: Date.now() - 5 * 60 * 1000, // 5 minutes ago
|
|
94
|
-
createdAt: Date.now() - 2 * 60 * 60 * 1000, // 2 hours ago
|
|
95
|
-
status: 'active',
|
|
96
|
-
connectedClients: 0
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
id: `ses_${Date.now()}_debug`,
|
|
100
|
-
name: 'Debug Server',
|
|
101
|
-
lastActivity: Date.now() - 15 * 60 * 1000, // 15 minutes ago
|
|
102
|
-
createdAt: Date.now() - 1 * 60 * 60 * 1000, // 1 hour ago
|
|
103
|
-
status: 'active',
|
|
104
|
-
connectedClients: 0
|
|
105
|
-
}
|
|
106
|
-
];
|
|
107
|
-
}
|
|
108
|
-
});
|
|
85
|
+
// Load session data from localStorage (persisted from terminal connections)
|
|
86
|
+
this.loadSessionsFromStorage();
|
|
109
87
|
}
|
|
110
88
|
|
|
111
89
|
// TODO: Load session history when API is available
|
|
@@ -214,10 +192,10 @@ class ShellMirrorDashboard {
|
|
|
214
192
|
</div>
|
|
215
193
|
<div class="agent-actions">
|
|
216
194
|
<button class="btn-connect" onclick="dashboard.connectToAgent('${agent.agentId}')">
|
|
217
|
-
New Session
|
|
195
|
+
${sessionCount > 0 ? 'Resume Session' : 'New Session'}
|
|
218
196
|
</button>
|
|
219
197
|
${sessionCount > 0 ? `<button class="btn-sessions" onclick="dashboard.showAgentSessions('${agent.agentId}')">
|
|
220
|
-
|
|
198
|
+
All Sessions
|
|
221
199
|
</button>` : ''}
|
|
222
200
|
</div>
|
|
223
201
|
</div>
|
|
@@ -435,13 +413,34 @@ class ShellMirrorDashboard {
|
|
|
435
413
|
|
|
436
414
|
// Action handlers
|
|
437
415
|
async connectToAgent(agentId) {
|
|
438
|
-
|
|
416
|
+
// Check if there are existing sessions for this agent
|
|
417
|
+
const sessions = this.agentSessions[agentId] || [];
|
|
418
|
+
const activeSessions = sessions.filter(s => s.status === 'active');
|
|
419
|
+
|
|
420
|
+
if (activeSessions.length > 0) {
|
|
421
|
+
// Reconnect to the most recently active session
|
|
422
|
+
const mostRecentSession = activeSessions.reduce((latest, session) =>
|
|
423
|
+
session.lastActivity > latest.lastActivity ? session : latest
|
|
424
|
+
);
|
|
425
|
+
console.log(`[DASHBOARD] Reconnecting to existing session: ${mostRecentSession.id}`);
|
|
426
|
+
window.location.href = `/app/terminal.html?agent=${agentId}&session=${mostRecentSession.id}`;
|
|
427
|
+
} else {
|
|
428
|
+
// No existing sessions, create new one
|
|
429
|
+
console.log(`[DASHBOARD] Creating new session for agent: ${agentId}`);
|
|
430
|
+
window.location.href = `/app/terminal.html?agent=${agentId}`;
|
|
431
|
+
}
|
|
439
432
|
}
|
|
440
433
|
|
|
441
434
|
async connectToSession(agentId, sessionId) {
|
|
442
435
|
window.location.href = `/app/terminal.html?agent=${agentId}&session=${sessionId}`;
|
|
443
436
|
}
|
|
444
437
|
|
|
438
|
+
async createNewSession(agentId) {
|
|
439
|
+
// Force creation of new session by not passing session parameter
|
|
440
|
+
console.log(`[DASHBOARD] Creating new session for agent: ${agentId}`);
|
|
441
|
+
window.location.href = `/app/terminal.html?agent=${agentId}`;
|
|
442
|
+
}
|
|
443
|
+
|
|
445
444
|
startNewSession() {
|
|
446
445
|
// Get first available agent for new session
|
|
447
446
|
const activeAgents = this.agents.filter(agent => {
|
|
@@ -488,7 +487,7 @@ class ShellMirrorDashboard {
|
|
|
488
487
|
${sessionsList}
|
|
489
488
|
</div>
|
|
490
489
|
<div class="sessions-modal-actions">
|
|
491
|
-
<button class="btn-primary" onclick="dashboard.
|
|
490
|
+
<button class="btn-primary" onclick="dashboard.createNewSession('${agentId}')">
|
|
492
491
|
+ Create New Session
|
|
493
492
|
</button>
|
|
494
493
|
</div>
|
|
@@ -530,6 +529,35 @@ class ShellMirrorDashboard {
|
|
|
530
529
|
return `${days}d ago`;
|
|
531
530
|
}
|
|
532
531
|
|
|
532
|
+
// Session storage management
|
|
533
|
+
loadSessionsFromStorage() {
|
|
534
|
+
try {
|
|
535
|
+
const storedSessions = localStorage.getItem('shell-mirror-sessions');
|
|
536
|
+
if (storedSessions) {
|
|
537
|
+
const sessionData = JSON.parse(storedSessions);
|
|
538
|
+
|
|
539
|
+
// Filter out old sessions (older than 24 hours)
|
|
540
|
+
const now = Date.now();
|
|
541
|
+
const maxAge = 24 * 60 * 60 * 1000; // 24 hours
|
|
542
|
+
|
|
543
|
+
Object.keys(sessionData).forEach(agentId => {
|
|
544
|
+
const validSessions = sessionData[agentId].filter(session =>
|
|
545
|
+
(now - session.lastActivity) < maxAge
|
|
546
|
+
);
|
|
547
|
+
|
|
548
|
+
if (validSessions.length > 0) {
|
|
549
|
+
this.agentSessions[agentId] = validSessions;
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
console.log('[DASHBOARD] Loaded sessions from storage:', this.agentSessions);
|
|
554
|
+
}
|
|
555
|
+
} catch (error) {
|
|
556
|
+
console.error('[DASHBOARD] Error loading sessions from storage:', error);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
|
|
533
561
|
showAgentInstructions() {
|
|
534
562
|
// TODO: Show modal with agent setup instructions
|
|
535
563
|
alert('Agent setup instructions coming soon!');
|
package/public/app/terminal.js
CHANGED
|
@@ -224,6 +224,9 @@ async function initialize() {
|
|
|
224
224
|
|
|
225
225
|
// Update UI to show session info
|
|
226
226
|
updateSessionDisplay();
|
|
227
|
+
|
|
228
|
+
// Save session info to localStorage for dashboard
|
|
229
|
+
saveSessionToLocalStorage(AGENT_ID, currentSession);
|
|
227
230
|
}
|
|
228
231
|
|
|
229
232
|
if (nextData.availableSessions) {
|
|
@@ -679,6 +682,9 @@ function handleSessionMessage(message) {
|
|
|
679
682
|
updateSessionDisplay();
|
|
680
683
|
term.clear(); // Clear terminal for new session
|
|
681
684
|
console.log('[CLIENT] ✅ Switched to session:', currentSession);
|
|
685
|
+
|
|
686
|
+
// Save updated session info
|
|
687
|
+
saveSessionToLocalStorage(AGENT_ID, currentSession);
|
|
682
688
|
break;
|
|
683
689
|
case 'session-ended':
|
|
684
690
|
term.write(`\r\n\x1b[31m❌ Session ended: ${message.reason}\x1b[0m\r\n`);
|
|
@@ -694,4 +700,33 @@ function handleSessionMessage(message) {
|
|
|
694
700
|
term.write(`\r\n\x1b[31m❌ Error: ${message.message}\x1b[0m\r\n`);
|
|
695
701
|
break;
|
|
696
702
|
}
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
// Session storage helper
|
|
706
|
+
function saveSessionToLocalStorage(agentId, sessionInfo) {
|
|
707
|
+
try {
|
|
708
|
+
const storedSessions = localStorage.getItem('shell-mirror-sessions');
|
|
709
|
+
let sessionData = storedSessions ? JSON.parse(storedSessions) : {};
|
|
710
|
+
|
|
711
|
+
if (!sessionData[agentId]) {
|
|
712
|
+
sessionData[agentId] = [];
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
// Remove existing session with same ID
|
|
716
|
+
sessionData[agentId] = sessionData[agentId].filter(s => s.id !== sessionInfo.id);
|
|
717
|
+
|
|
718
|
+
// Add updated session info
|
|
719
|
+
sessionData[agentId].push({
|
|
720
|
+
id: sessionInfo.id,
|
|
721
|
+
name: sessionInfo.name,
|
|
722
|
+
lastActivity: Date.now(),
|
|
723
|
+
createdAt: sessionInfo.createdAt || Date.now(),
|
|
724
|
+
status: 'active'
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
localStorage.setItem('shell-mirror-sessions', JSON.stringify(sessionData));
|
|
728
|
+
console.log('[CLIENT] 💾 Session saved to storage:', sessionInfo);
|
|
729
|
+
} catch (error) {
|
|
730
|
+
console.error('[CLIENT] Error saving session to storage:', error);
|
|
731
|
+
}
|
|
697
732
|
}
|