shell-mirror 1.5.110 → 1.5.112
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/package.json +1 -1
- package/public/app/dashboard.css +626 -1128
- package/public/app/dashboard.html +2 -5
- package/public/app/dashboard.js +24 -85
|
@@ -60,7 +60,6 @@
|
|
|
60
60
|
<div class="logo">
|
|
61
61
|
<a href="/" style="text-decoration: none; color: inherit;">
|
|
62
62
|
<h1>Shell Mirror</h1>
|
|
63
|
-
<span class="subtitle">Dashboard</span>
|
|
64
63
|
</a>
|
|
65
64
|
</div>
|
|
66
65
|
<div class="header-right">
|
|
@@ -98,10 +97,8 @@
|
|
|
98
97
|
</div>
|
|
99
98
|
|
|
100
99
|
<!-- Version Footer -->
|
|
101
|
-
<footer style="background: #
|
|
102
|
-
<
|
|
103
|
-
<p id="dashboard-version-info">Shell Mirror Dashboard • Loading version...</p>
|
|
104
|
-
</div>
|
|
100
|
+
<footer id="version-footer" style="background: var(--bg-secondary, #141519); color: var(--text-secondary, #8a8f98); text-align: center; padding: 8px 0; font-size: 0.75rem; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000; border-top: 1px solid var(--border, #2a2b30);">
|
|
101
|
+
<p id="dashboard-version-info" style="margin: 0;">Shell Mirror • Loading...</p>
|
|
105
102
|
</footer>
|
|
106
103
|
|
|
107
104
|
<script src="dashboard.js"></script>
|
package/public/app/dashboard.js
CHANGED
|
@@ -31,13 +31,13 @@ class ShellMirrorDashboard {
|
|
|
31
31
|
async init() {
|
|
32
32
|
this.showLoading();
|
|
33
33
|
this.loadVersionInfo(); // Load version info immediately
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
// Wait for GA script to load and send page view
|
|
36
36
|
setTimeout(() => {
|
|
37
37
|
console.log('🔍 [DASHBOARD DEBUG] Checking Google Analytics setup...');
|
|
38
38
|
console.log('🔍 [DASHBOARD DEBUG] gtag function type:', typeof gtag);
|
|
39
39
|
console.log('🔍 [DASHBOARD DEBUG] gtagLoaded flag:', window.gtagLoaded);
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
// Send dashboard page view event
|
|
42
42
|
if (typeof sendGAEvent === 'function') {
|
|
43
43
|
sendGAEvent('page_view', {
|
|
@@ -48,10 +48,10 @@ class ShellMirrorDashboard {
|
|
|
48
48
|
console.warn('❌ [DASHBOARD DEBUG] sendGAEvent function not available');
|
|
49
49
|
}
|
|
50
50
|
}, 1000);
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
try {
|
|
53
53
|
const authStatus = await this.checkAuthStatus();
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
if (authStatus.isAuthenticated) {
|
|
56
56
|
this.isAuthenticated = true;
|
|
57
57
|
this.user = authStatus.user;
|
|
@@ -501,14 +501,6 @@ class ShellMirrorDashboard {
|
|
|
501
501
|
<div class="dashboard-card">
|
|
502
502
|
${this.renderActiveAgentsPreview()}
|
|
503
503
|
</div>
|
|
504
|
-
|
|
505
|
-
<div class="dashboard-card">
|
|
506
|
-
${this.renderQuickActions()}
|
|
507
|
-
</div>
|
|
508
|
-
|
|
509
|
-
<div class="dashboard-card full-width">
|
|
510
|
-
${this.renderRecentSessionsPreview()}
|
|
511
|
-
</div>
|
|
512
504
|
</div>
|
|
513
505
|
`;
|
|
514
506
|
|
|
@@ -520,32 +512,26 @@ class ShellMirrorDashboard {
|
|
|
520
512
|
}
|
|
521
513
|
|
|
522
514
|
renderAuthenticatedDashboard() {
|
|
523
|
-
// Update user section -
|
|
515
|
+
// Update user section - minimal design
|
|
524
516
|
document.getElementById('user-section').innerHTML = `
|
|
525
|
-
<
|
|
526
|
-
<span id="connection-status" class="connection-status" style="display: none;"></span>
|
|
527
|
-
</div>
|
|
528
|
-
<button class="help-button" onclick="dashboard.showAgentInstructions()" title="How to Use">
|
|
529
|
-
How to Use
|
|
530
|
-
</button>
|
|
517
|
+
<span id="connection-status" class="connection-status" style="display: none;"></span>
|
|
531
518
|
<div class="user-info">
|
|
532
519
|
<span class="user-name">${this.user?.name || this.user?.email || 'User'}</span>
|
|
533
520
|
<div class="user-dropdown">
|
|
534
521
|
<button class="dropdown-btn">⚙️</button>
|
|
535
522
|
<div class="dropdown-content">
|
|
536
|
-
<a href="#" onclick="dashboard.
|
|
523
|
+
<a href="#" onclick="dashboard.showAgentInstructions()">Help</a>
|
|
537
524
|
<a href="/">Home</a>
|
|
525
|
+
<a href="#" onclick="dashboard.logout()">Logout</a>
|
|
538
526
|
</div>
|
|
539
527
|
</div>
|
|
540
528
|
</div>
|
|
541
529
|
`;
|
|
542
530
|
|
|
543
|
-
// Render main dashboard content
|
|
531
|
+
// Render main dashboard content - agents only
|
|
544
532
|
document.getElementById('dashboard-main').innerHTML = `
|
|
545
533
|
<div class="dashboard-grid">
|
|
546
534
|
${this.renderActiveAgents()}
|
|
547
|
-
${this.renderQuickActions()}
|
|
548
|
-
${this.renderRecentSessions()}
|
|
549
535
|
</div>
|
|
550
536
|
`;
|
|
551
537
|
|
|
@@ -570,12 +556,6 @@ class ShellMirrorDashboard {
|
|
|
570
556
|
const sessionCount = sessions.length;
|
|
571
557
|
|
|
572
558
|
const isConnectable = agent.status === 'online' || agent.status === 'recent';
|
|
573
|
-
const statusIcon = {
|
|
574
|
-
'online': '🟢',
|
|
575
|
-
'recent': '🟡',
|
|
576
|
-
'offline': '🔴'
|
|
577
|
-
}[agent.status] || '❓';
|
|
578
|
-
|
|
579
559
|
const statusText = {
|
|
580
560
|
'online': 'Live',
|
|
581
561
|
'recent': 'Recent',
|
|
@@ -588,14 +568,11 @@ class ShellMirrorDashboard {
|
|
|
588
568
|
|
|
589
569
|
// Build inline session list with colors
|
|
590
570
|
const sessionsHtml = sessions.map((session, index) => {
|
|
591
|
-
const sessionStatus = session.status === 'active' ? 'active' : 'crashed';
|
|
592
|
-
const activityText = this.formatLastActivity(session.lastActivity);
|
|
593
571
|
const color = SESSION_COLORS[index % SESSION_COLORS.length];
|
|
594
572
|
return `
|
|
595
573
|
<div class="inline-session-item" style="border-left: 3px solid ${color.border};">
|
|
596
574
|
<span class="session-status-dot" style="background-color: ${color.border};"></span>
|
|
597
|
-
<span class="session-name" style="color: ${color.
|
|
598
|
-
<span class="session-activity">${activityText}</span>
|
|
575
|
+
<span class="session-name" style="color: ${color.border};">${session.name}</span>
|
|
599
576
|
<button class="btn-session-connect" onclick="dashboard.connectToSession('${agent.agentId}', '${session.id}')" style="background-color: ${color.border};">
|
|
600
577
|
Connect
|
|
601
578
|
</button>
|
|
@@ -614,16 +591,13 @@ class ShellMirrorDashboard {
|
|
|
614
591
|
</button>
|
|
615
592
|
</div>
|
|
616
593
|
<div class="agent-status ${agent.status}">
|
|
617
|
-
${
|
|
618
|
-
${sessionCount > 0 ? `<span class="agent-session-count">(${sessionCount} session${sessionCount !== 1 ? 's' : ''})</span>` : ''}
|
|
594
|
+
${statusText}${sessionCount > 0 ? ` · ${sessionCount} session${sessionCount !== 1 ? 's' : ''}` : ''}
|
|
619
595
|
</div>
|
|
620
|
-
<div class="agent-last-seen">Last seen: ${lastSeenText}</div>
|
|
621
596
|
</div>
|
|
622
597
|
</div>
|
|
623
598
|
${isConnectable ? `
|
|
624
599
|
<div class="agent-sessions-inline">
|
|
625
600
|
${sessionCount > 0 ? `
|
|
626
|
-
<div class="sessions-label">Active Sessions</div>
|
|
627
601
|
<div class="sessions-list">
|
|
628
602
|
${sessionsHtml}
|
|
629
603
|
</div>
|
|
@@ -639,31 +613,11 @@ class ShellMirrorDashboard {
|
|
|
639
613
|
`;
|
|
640
614
|
}).join('');
|
|
641
615
|
|
|
642
|
-
// Check if there are any offline agents to show cleanup option
|
|
643
|
-
const offlineAgents = this.agents.filter(agent => agent.status === 'offline');
|
|
644
|
-
const showCleanup = offlineAgents.length > 0;
|
|
645
|
-
|
|
646
|
-
// Format last refresh time
|
|
647
|
-
const refreshTime = this.lastRefresh
|
|
648
|
-
? new Date(this.lastRefresh).toLocaleTimeString()
|
|
649
|
-
: '<span class="loading-dots"><span>.</span><span>.</span><span>.</span></span>';
|
|
650
|
-
|
|
651
616
|
return `
|
|
652
617
|
<div class="dashboard-card">
|
|
653
618
|
<div class="card-header">
|
|
654
|
-
<
|
|
655
|
-
|
|
656
|
-
<span class="agent-count">${agentCount}</span>
|
|
657
|
-
<span class="refresh-time">${this.lastRefresh ? 'Updated ' : ''}${refreshTime}</span>
|
|
658
|
-
</div>
|
|
659
|
-
<div class="agent-actions-header">
|
|
660
|
-
<button id="refresh-btn" class="btn-text-action" onclick="dashboard.manualRefresh()" title="Refresh agents">
|
|
661
|
-
Refresh
|
|
662
|
-
</button>
|
|
663
|
-
${showCleanup ? `<button class="btn-text-action btn-cleanup" onclick="dashboard.cleanupOfflineAgents()" title="Remove offline agents">
|
|
664
|
-
Clean
|
|
665
|
-
</button>` : ''}
|
|
666
|
-
</div>
|
|
619
|
+
<h2>Agents</h2>
|
|
620
|
+
${agentCount > 0 ? `<span class="agent-count">${agentCount}</span>` : ''}
|
|
667
621
|
</div>
|
|
668
622
|
<div class="card-content">
|
|
669
623
|
${agentCount > 0 ? agentsHtml : this.renderEmptyAgentState()}
|
|
@@ -675,38 +629,23 @@ class ShellMirrorDashboard {
|
|
|
675
629
|
renderEmptyAgentState() {
|
|
676
630
|
return `
|
|
677
631
|
<div class="empty-agent-state">
|
|
678
|
-
<
|
|
679
|
-
<h3>Get Started with Shell Mirror</h3>
|
|
680
|
-
<p>Connect your Mac in 2 simple steps:</p>
|
|
681
|
-
</div>
|
|
682
|
-
|
|
632
|
+
<p class="empty-state-title">No agents connected</p>
|
|
683
633
|
<div class="empty-state-steps">
|
|
684
|
-
<div class="
|
|
685
|
-
<
|
|
686
|
-
<div class="
|
|
687
|
-
<
|
|
688
|
-
<
|
|
689
|
-
<code>npm install -g shell-mirror</code>
|
|
690
|
-
<button class="inline-copy-btn" onclick="navigator.clipboard.writeText('npm install -g shell-mirror'); this.textContent = 'Copied!'; setTimeout(() => this.textContent = 'Copy', 2000)">Copy</button>
|
|
691
|
-
</div>
|
|
634
|
+
<div class="command-step">
|
|
635
|
+
<span class="step-label">1. Install</span>
|
|
636
|
+
<div class="command-box">
|
|
637
|
+
<code>npm install -g shell-mirror</code>
|
|
638
|
+
<button class="copy-btn" onclick="navigator.clipboard.writeText('npm install -g shell-mirror'); this.textContent = '✓'; setTimeout(() => this.textContent = 'Copy', 1500)">Copy</button>
|
|
692
639
|
</div>
|
|
693
640
|
</div>
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
<div class="
|
|
697
|
-
|
|
698
|
-
<
|
|
699
|
-
<div class="inline-command-box">
|
|
700
|
-
<code>shell-mirror</code>
|
|
701
|
-
<button class="inline-copy-btn" onclick="navigator.clipboard.writeText('shell-mirror'); this.textContent = 'Copied!'; setTimeout(() => this.textContent = 'Copy', 2000)">Copy</button>
|
|
702
|
-
</div>
|
|
641
|
+
<div class="command-step">
|
|
642
|
+
<span class="step-label">2. Run</span>
|
|
643
|
+
<div class="command-box">
|
|
644
|
+
<code>shell-mirror</code>
|
|
645
|
+
<button class="copy-btn" onclick="navigator.clipboard.writeText('shell-mirror'); this.textContent = '✓'; setTimeout(() => this.textContent = 'Copy', 1500)">Copy</button>
|
|
703
646
|
</div>
|
|
704
647
|
</div>
|
|
705
648
|
</div>
|
|
706
|
-
|
|
707
|
-
<div class="empty-state-footer">
|
|
708
|
-
<p>Your agent will appear here once connected</p>
|
|
709
|
-
</div>
|
|
710
649
|
</div>
|
|
711
650
|
`;
|
|
712
651
|
}
|