shell-mirror 1.5.122 → 1.5.124

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shell-mirror",
3
- "version": "1.5.122",
3
+ "version": "1.5.124",
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": {
@@ -647,6 +647,125 @@ body {
647
647
  border-color: var(--accent);
648
648
  }
649
649
 
650
+ /* Empty state - additional content */
651
+ .empty-state-note {
652
+ color: var(--text-muted);
653
+ font-size: 0.75rem;
654
+ margin: 16px 0;
655
+ text-align: center;
656
+ }
657
+
658
+ .empty-state-troubleshooting {
659
+ margin-top: 24px;
660
+ padding-top: 16px;
661
+ border-top: 1px solid var(--border);
662
+ }
663
+
664
+ .troubleshooting-title {
665
+ color: var(--text-muted);
666
+ font-size: 0.75rem;
667
+ font-weight: 500;
668
+ display: block;
669
+ margin-bottom: 8px;
670
+ text-transform: uppercase;
671
+ letter-spacing: 0.5px;
672
+ }
673
+
674
+ .empty-state-troubleshooting ul {
675
+ list-style: none;
676
+ margin: 0;
677
+ padding: 0;
678
+ }
679
+
680
+ .empty-state-troubleshooting li {
681
+ color: var(--text-muted);
682
+ font-size: 0.75rem;
683
+ padding: 4px 0;
684
+ padding-left: 12px;
685
+ position: relative;
686
+ }
687
+
688
+ .empty-state-troubleshooting li::before {
689
+ content: '•';
690
+ position: absolute;
691
+ left: 0;
692
+ color: var(--text-muted);
693
+ }
694
+
695
+ /* Collapsible help section */
696
+ .collapsible-help {
697
+ margin-top: 32px;
698
+ padding: 0 32px;
699
+ }
700
+
701
+ .help-toggle {
702
+ width: 100%;
703
+ background: transparent;
704
+ border: none;
705
+ padding: 12px 0;
706
+ display: flex;
707
+ align-items: center;
708
+ justify-content: space-between;
709
+ color: var(--text-muted);
710
+ font-size: 0.8rem;
711
+ cursor: pointer;
712
+ transition: color 0.2s ease;
713
+ }
714
+
715
+ .help-toggle:hover {
716
+ color: var(--text-secondary);
717
+ }
718
+
719
+ .help-arrow {
720
+ transition: transform 0.2s ease;
721
+ color: var(--text-muted);
722
+ }
723
+
724
+ .help-arrow.rotated {
725
+ transform: rotate(180deg);
726
+ }
727
+
728
+ .help-content {
729
+ max-height: 0;
730
+ overflow: hidden;
731
+ transition: max-height 0.3s ease;
732
+ }
733
+
734
+ .help-content.expanded {
735
+ max-height: 300px;
736
+ padding: 16px 0;
737
+ }
738
+
739
+ .help-step {
740
+ display: flex;
741
+ flex-direction: column;
742
+ gap: 6px;
743
+ margin-bottom: 12px;
744
+ }
745
+
746
+ .help-step-label {
747
+ font-size: 0.75rem;
748
+ font-weight: 500;
749
+ color: var(--text-muted);
750
+ }
751
+
752
+ .help-step code {
753
+ background: var(--bg-tertiary);
754
+ padding: 8px 12px;
755
+ border-radius: 4px;
756
+ font-family: 'Monaco', 'Menlo', monospace;
757
+ font-size: 0.75rem;
758
+ color: var(--text-muted);
759
+ display: inline-block;
760
+ }
761
+
762
+ .help-note {
763
+ color: var(--text-muted);
764
+ font-size: 0.7rem;
765
+ margin-top: 8px;
766
+ font-style: italic;
767
+ }
768
+
650
769
  /* Modals */
651
770
  .modal-overlay {
652
771
  position: fixed;
@@ -679,31 +679,7 @@ class ShellMirrorDashboard {
679
679
  ${agentCount > 0 ? agentsHtml : this.renderEmptyAgentState()}
680
680
  </div>
681
681
  </div>
682
- <div class="usage-instructions">
683
- <div class="usage-step">
684
- <span class="usage-step-num">1</span>
685
- <div class="usage-step-content">
686
- <span class="usage-step-title">Install the agent (on Mac)</span>
687
- <code>npm install -g shell-mirror</code>
688
- </div>
689
- </div>
690
- <div class="usage-step">
691
- <span class="usage-step-num">2</span>
692
- <div class="usage-step-content">
693
- <span class="usage-step-title">Run the agent</span>
694
- <code>shell-mirror</code>
695
- </div>
696
- </div>
697
- <p class="usage-note">The agent will automatically connect to your dashboard</p>
698
- <div class="usage-troubleshooting">
699
- <span class="usage-trouble-title">Troubleshooting</span>
700
- <ul>
701
- <li>Make sure you're logged in with the same Google account</li>
702
- <li>Check that the agent is running in your terminal</li>
703
- <li>Refresh this dashboard after starting the agent</li>
704
- </ul>
705
- </div>
706
- </div>
682
+ ${agentCount > 0 ? this.renderCollapsibleHelp() : ''}
707
683
  </div>
708
684
  `;
709
685
  }
@@ -728,10 +704,57 @@ class ShellMirrorDashboard {
728
704
  </div>
729
705
  </div>
730
706
  </div>
707
+ <p class="empty-state-note">The agent will automatically connect to your dashboard</p>
708
+ <div class="empty-state-troubleshooting">
709
+ <span class="troubleshooting-title">Troubleshooting</span>
710
+ <ul>
711
+ <li>Make sure you're logged in with the same Google account</li>
712
+ <li>Check that the agent is running in your terminal</li>
713
+ <li>Refresh this dashboard after starting the agent</li>
714
+ </ul>
715
+ </div>
716
+ </div>
717
+ `;
718
+ }
719
+
720
+ renderCollapsibleHelp() {
721
+ return `
722
+ <div class="collapsible-help">
723
+ <button class="help-toggle" onclick="dashboard.toggleHelp()">
724
+ <span>Need help adding another agent?</span>
725
+ <svg class="help-arrow" width="12" height="12" viewBox="0 0 12 12">
726
+ <path d="M2 4l4 4 4-4" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round"/>
727
+ </svg>
728
+ </button>
729
+ <div class="help-content" id="help-content">
730
+ <div class="help-step">
731
+ <span class="help-step-label">1. Install</span>
732
+ <code>npm install -g shell-mirror</code>
733
+ </div>
734
+ <div class="help-step">
735
+ <span class="help-step-label">2. Run</span>
736
+ <code>shell-mirror</code>
737
+ </div>
738
+ <p class="help-note">The agent will automatically connect to your dashboard</p>
739
+ </div>
731
740
  </div>
732
741
  `;
733
742
  }
734
743
 
744
+ toggleHelp() {
745
+ const content = document.getElementById('help-content');
746
+ const arrow = document.querySelector('.help-arrow');
747
+ const isExpanded = content.classList.contains('expanded');
748
+
749
+ if (isExpanded) {
750
+ content.classList.remove('expanded');
751
+ arrow.classList.remove('rotated');
752
+ } else {
753
+ content.classList.add('expanded');
754
+ arrow.classList.add('rotated');
755
+ }
756
+ }
757
+
735
758
  renderQuickActions() {
736
759
  return `
737
760
  <div class="dashboard-card">
@@ -363,7 +363,7 @@
363
363
  <p>Connecting to terminal...</p>
364
364
  </div>
365
365
  <div id="terminal-container">
366
- <div class="session-header" id="session-header" style="display: none;">
366
+ <div class="session-header" id="session-header">
367
367
  <!-- Connection Status Indicator -->
368
368
  <div class="connection-status" id="connection-status"></div>
369
369
 
@@ -243,7 +243,10 @@ function startConnection() {
243
243
  connectContainer.style.display = 'none';
244
244
  terminalContainer.classList.add('show');
245
245
  term.open(document.getElementById('terminal'));
246
-
246
+
247
+ // Initialize session display (shows header with connection status even before session exists)
248
+ updateSessionDisplay();
249
+
247
250
  // Track terminal session start in Google Analytics
248
251
  if (typeof sendGAEvent === 'function') {
249
252
  sendGAEvent('terminal_session_start', {
@@ -955,14 +958,14 @@ function updateSessionDisplay() {
955
958
  return;
956
959
  }
957
960
 
958
- if (currentSession) {
959
- sessionHeader.style.display = 'flex';
960
-
961
- // Update tabs
962
- console.log('[CLIENT] 📋 Rendering tabs, availableSessions:', availableSessions);
963
- renderTabs();
961
+ // Always render tabs (they will show appropriate state even if no sessions)
962
+ console.log('[CLIENT] 📋 Rendering tabs, availableSessions:', availableSessions, 'currentSession:', currentSession);
963
+ renderTabs();
964
964
 
965
+ if (currentSession) {
965
966
  console.log('[CLIENT] 📋 Session display updated:', currentSession);
967
+ } else {
968
+ console.log('[CLIENT] 📋 No current session - showing connection state only');
966
969
  }
967
970
  }
968
971
 
@@ -1036,10 +1039,13 @@ function renderTabs() {
1036
1039
  </div>
1037
1040
  `;
1038
1041
  }).join('');
1039
- }
1040
1042
 
1041
- // Add new session button
1042
- tabsHTML += '<button class="session-tab-new" onclick="createNewSession()" title="New Session">+</button>';
1043
+ // Add new session button only when we have sessions
1044
+ tabsHTML += '<button class="session-tab-new" onclick="createNewSession()" title="New Session">+</button>';
1045
+ } else {
1046
+ // No sessions available - show status message
1047
+ tabsHTML = '<div style="color: #888; font-size: 0.85rem; padding: 6px 12px;">No sessions available</div>';
1048
+ }
1043
1049
 
1044
1050
  tabBar.innerHTML = tabsHTML;
1045
1051
  console.log('[CLIENT] ✅ Tabs rendered:', sessionsToRender.length, 'tabs');