shell-mirror 1.5.48 → 1.5.50

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.48",
3
+ "version": "1.5.50",
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": {
@@ -6,12 +6,40 @@
6
6
  <title>Shell Mirror Dashboard</title>
7
7
 
8
8
  <!-- Google Analytics 4 -->
9
- <script async src="https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK"></script>
10
9
  <script>
10
+ // Initialize dataLayer and gtag function first
11
11
  window.dataLayer = window.dataLayer || [];
12
12
  function gtag(){dataLayer.push(arguments);}
13
13
  gtag('js', new Date());
14
14
  gtag('config', 'G-LG7ZGLB8FK');
15
+
16
+ // Load gtag script with proper error handling
17
+ (function() {
18
+ var script = document.createElement('script');
19
+ script.async = true;
20
+ script.src = 'https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK';
21
+ script.onload = function() {
22
+ console.log('✅ Google Analytics script loaded successfully');
23
+ window.gtagLoaded = true;
24
+ };
25
+ script.onerror = function() {
26
+ console.warn('❌ Failed to load Google Analytics script');
27
+ window.gtagLoaded = false;
28
+ };
29
+ document.head.appendChild(script);
30
+ })();
31
+
32
+ // Google Analytics helper function
33
+ function sendGAEvent(eventName, eventParams) {
34
+ if (typeof gtag === 'function') {
35
+ console.log('📊 [GA] Sending event:', eventName, eventParams);
36
+ gtag('event', eventName, eventParams);
37
+ return true;
38
+ } else {
39
+ console.warn('❌ [GA] gtag not available, event not sent:', eventName);
40
+ return false;
41
+ }
42
+ }
15
43
  </script>
16
44
 
17
45
  <!-- Microsoft Clarity -->
@@ -20,7 +48,7 @@
20
48
  c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
21
49
  t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
22
50
  y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
23
- })(window, document, "clarity", "script", "CLARITY_PROJECT_ID");
51
+ })(window, document, "clarity", "script", "sy1w2d7il7");
24
52
  </script>
25
53
 
26
54
  <link rel="stylesheet" href="dashboard.css">
@@ -13,22 +13,22 @@ class ShellMirrorDashboard {
13
13
  this.showLoading();
14
14
  this.loadVersionInfo(); // Load version info immediately
15
15
 
16
- // Debug Google Analytics setup
17
- console.log('🔍 [DASHBOARD DEBUG] Checking Google Analytics setup...');
18
- console.log('🔍 [DASHBOARD DEBUG] gtag function available:', typeof gtag !== 'undefined');
19
- console.log('🔍 [DASHBOARD DEBUG] dataLayer exists:', typeof window.dataLayer !== 'undefined');
20
-
21
- if (typeof gtag !== 'undefined') {
22
- console.log('✅ [DASHBOARD DEBUG] Google Analytics is available');
23
- // Send dashboard page view debug event
24
- gtag('event', 'page_debug', {
25
- event_category: 'debug',
26
- event_label: 'dashboard_page_loaded'
27
- });
28
- console.log('📊 [DASHBOARD DEBUG] Dashboard page debug event sent');
29
- } else {
30
- console.warn('❌ [DASHBOARD DEBUG] Google Analytics gtag function not available');
31
- }
16
+ // Wait for GA script to load and send page view
17
+ setTimeout(() => {
18
+ console.log('🔍 [DASHBOARD DEBUG] Checking Google Analytics setup...');
19
+ console.log('🔍 [DASHBOARD DEBUG] gtag function type:', typeof gtag);
20
+ console.log('🔍 [DASHBOARD DEBUG] gtagLoaded flag:', window.gtagLoaded);
21
+
22
+ // Send dashboard page view event
23
+ if (typeof sendGAEvent === 'function') {
24
+ sendGAEvent('page_view', {
25
+ page_title: 'Shell Mirror Dashboard',
26
+ page_location: window.location.href
27
+ });
28
+ } else {
29
+ console.warn('❌ [DASHBOARD DEBUG] sendGAEvent function not available');
30
+ }
31
+ }, 1000);
32
32
 
33
33
  try {
34
34
  const authStatus = await this.checkAuthStatus();
@@ -448,18 +448,13 @@ class ShellMirrorDashboard {
448
448
  console.log(`[DASHBOARD] ✅ Reconnecting to existing session: ${mostRecentSession.id}`);
449
449
 
450
450
  // Track terminal connection in Google Analytics
451
- console.log('🔍 [DASHBOARD DEBUG] Attempting to track terminal_connect (existing_session)');
452
- if (typeof gtag !== 'undefined') {
453
- console.log('📊 [DASHBOARD DEBUG] Sending terminal_connect event (existing_session) to Google Analytics');
454
- gtag('event', 'terminal_connect', {
451
+ if (typeof sendGAEvent === 'function') {
452
+ sendGAEvent('terminal_connect', {
455
453
  event_category: 'terminal',
456
454
  event_label: 'existing_session',
457
455
  agent_id: agentId,
458
456
  session_id: mostRecentSession.id
459
457
  });
460
- console.log('✅ [DASHBOARD DEBUG] terminal_connect (existing_session) event sent successfully');
461
- } else {
462
- console.warn('❌ [DASHBOARD DEBUG] Cannot send terminal_connect event - gtag not available');
463
458
  }
464
459
 
465
460
  window.location.href = `/app/terminal.html?agent=${agentId}&session=${mostRecentSession.id}`;
@@ -468,17 +463,12 @@ class ShellMirrorDashboard {
468
463
  console.log(`[DASHBOARD] 🆕 Creating new session for agent: ${agentId}`);
469
464
 
470
465
  // Track new session creation in Google Analytics
471
- console.log('🔍 [DASHBOARD DEBUG] Attempting to track terminal_connect (new_session)');
472
- if (typeof gtag !== 'undefined') {
473
- console.log('📊 [DASHBOARD DEBUG] Sending terminal_connect event (new_session) to Google Analytics');
474
- gtag('event', 'terminal_connect', {
466
+ if (typeof sendGAEvent === 'function') {
467
+ sendGAEvent('terminal_connect', {
475
468
  event_category: 'terminal',
476
469
  event_label: 'new_session',
477
470
  agent_id: agentId
478
471
  });
479
- console.log('✅ [DASHBOARD DEBUG] terminal_connect (new_session) event sent successfully');
480
- } else {
481
- console.warn('❌ [DASHBOARD DEBUG] Cannot send terminal_connect event - gtag not available');
482
472
  }
483
473
 
484
474
  window.location.href = `/app/terminal.html?agent=${agentId}`;
@@ -487,8 +477,8 @@ class ShellMirrorDashboard {
487
477
 
488
478
  async connectToSession(agentId, sessionId) {
489
479
  // Track specific session connection in Google Analytics
490
- if (typeof gtag !== 'undefined') {
491
- gtag('event', 'terminal_connect', {
480
+ if (typeof sendGAEvent === 'function') {
481
+ sendGAEvent('terminal_connect', {
492
482
  event_category: 'terminal',
493
483
  event_label: 'specific_session',
494
484
  agent_id: agentId,
@@ -504,8 +494,8 @@ class ShellMirrorDashboard {
504
494
  console.log(`[DASHBOARD] Creating new session for agent: ${agentId}`);
505
495
 
506
496
  // Track explicit new session creation in Google Analytics
507
- if (typeof gtag !== 'undefined') {
508
- gtag('event', 'terminal_connect', {
497
+ if (typeof sendGAEvent === 'function') {
498
+ sendGAEvent('terminal_connect', {
509
499
  event_category: 'terminal',
510
500
  event_label: 'force_new_session',
511
501
  agent_id: agentId
@@ -4,12 +4,40 @@
4
4
  <title>Terminal Mirror</title>
5
5
 
6
6
  <!-- Google Analytics 4 -->
7
- <script async src="https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK"></script>
8
7
  <script>
8
+ // Initialize dataLayer and gtag function first
9
9
  window.dataLayer = window.dataLayer || [];
10
10
  function gtag(){dataLayer.push(arguments);}
11
11
  gtag('js', new Date());
12
12
  gtag('config', 'G-LG7ZGLB8FK');
13
+
14
+ // Load gtag script with proper error handling
15
+ (function() {
16
+ var script = document.createElement('script');
17
+ script.async = true;
18
+ script.src = 'https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK';
19
+ script.onload = function() {
20
+ console.log('✅ Google Analytics script loaded successfully');
21
+ window.gtagLoaded = true;
22
+ };
23
+ script.onerror = function() {
24
+ console.warn('❌ Failed to load Google Analytics script');
25
+ window.gtagLoaded = false;
26
+ };
27
+ document.head.appendChild(script);
28
+ })();
29
+
30
+ // Google Analytics helper function
31
+ function sendGAEvent(eventName, eventParams) {
32
+ if (typeof gtag === 'function') {
33
+ console.log('📊 [GA] Sending event:', eventName, eventParams);
34
+ gtag('event', eventName, eventParams);
35
+ return true;
36
+ } else {
37
+ console.warn('❌ [GA] gtag not available, event not sent:', eventName);
38
+ return false;
39
+ }
40
+ }
13
41
  </script>
14
42
 
15
43
  <!-- Microsoft Clarity -->
@@ -18,7 +46,7 @@
18
46
  c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
19
47
  t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
20
48
  y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
21
- })(window, document, "clarity", "script", "CLARITY_PROJECT_ID");
49
+ })(window, document, "clarity", "script", "sy1w2d7il7");
22
50
  </script>
23
51
 
24
52
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.15.0/css/xterm.css" />
@@ -180,22 +180,20 @@ setInterval(() => {
180
180
  window.addEventListener('load', () => {
181
181
  loadVersionInfo();
182
182
 
183
- // Debug Google Analytics setup
184
- console.log('🔍 [TERMINAL DEBUG] Checking Google Analytics setup...');
185
- console.log('🔍 [TERMINAL DEBUG] gtag function available:', typeof gtag !== 'undefined');
186
- console.log('🔍 [TERMINAL DEBUG] dataLayer exists:', typeof window.dataLayer !== 'undefined');
187
-
188
- if (typeof gtag !== 'undefined') {
189
- console.log('✅ [TERMINAL DEBUG] Google Analytics is available');
190
- // Send terminal page view debug event
191
- gtag('event', 'page_debug', {
192
- event_category: 'debug',
193
- event_label: 'terminal_page_loaded'
194
- });
195
- console.log('📊 [TERMINAL DEBUG] Terminal page debug event sent');
196
- } else {
197
- console.warn('❌ [TERMINAL DEBUG] Google Analytics gtag function not available');
198
- }
183
+ // Wait for GA script to load and send page view
184
+ setTimeout(() => {
185
+ console.log('🔍 [TERMINAL DEBUG] Checking Google Analytics setup...');
186
+ console.log('🔍 [TERMINAL DEBUG] gtag function type:', typeof gtag);
187
+ console.log('🔍 [TERMINAL DEBUG] gtagLoaded flag:', window.gtagLoaded);
188
+
189
+ // Send terminal page view event
190
+ if (typeof sendGAEvent === 'function') {
191
+ sendGAEvent('page_view', {
192
+ page_title: 'Shell Mirror Terminal',
193
+ page_location: window.location.href
194
+ });
195
+ }
196
+ }, 1000);
199
197
 
200
198
  // Get agent ID and session ID from URL parameters
201
199
  const urlParams = new URLSearchParams(window.location.search);
@@ -252,18 +250,13 @@ function startConnection() {
252
250
  term.open(document.getElementById('terminal'));
253
251
 
254
252
  // Track terminal session start in Google Analytics
255
- console.log('🔍 [TERMINAL DEBUG] Attempting to track terminal_session_start');
256
- if (typeof gtag !== 'undefined') {
257
- console.log('📊 [TERMINAL DEBUG] Sending terminal_session_start event to Google Analytics');
258
- gtag('event', 'terminal_session_start', {
253
+ if (typeof sendGAEvent === 'function') {
254
+ sendGAEvent('terminal_session_start', {
259
255
  event_category: 'terminal',
260
256
  event_label: requestedSessionId ? 'existing_session' : 'new_session',
261
257
  agent_id: AGENT_ID,
262
258
  session_id: requestedSessionId || 'new'
263
259
  });
264
- console.log('✅ [TERMINAL DEBUG] terminal_session_start event sent successfully');
265
- } else {
266
- console.warn('❌ [TERMINAL DEBUG] Cannot send terminal_session_start event - gtag not available');
267
260
  }
268
261
 
269
262
  // Delay fit to ensure proper dimensions after CSS transitions
@@ -555,17 +548,12 @@ async function createPeerConnection() {
555
548
  updateConnectionStatus('connected');
556
549
 
557
550
  // Track successful connection in Google Analytics
558
- console.log('🔍 [TERMINAL DEBUG] Attempting to track terminal_connection_success');
559
- if (typeof gtag !== 'undefined') {
560
- console.log('📊 [TERMINAL DEBUG] Sending terminal_connection_success event to Google Analytics');
561
- gtag('event', 'terminal_connection_success', {
551
+ if (typeof sendGAEvent === 'function') {
552
+ sendGAEvent('terminal_connection_success', {
562
553
  event_category: 'terminal',
563
554
  event_label: 'webrtc_established',
564
555
  agent_id: AGENT_ID
565
556
  });
566
- console.log('✅ [TERMINAL DEBUG] terminal_connection_success event sent successfully');
567
- } else {
568
- console.warn('❌ [TERMINAL DEBUG] Cannot send terminal_connection_success event - gtag not available');
569
557
  }
570
558
 
571
559
  break;
package/public/index.html CHANGED
@@ -19,12 +19,28 @@
19
19
  <meta property="twitter:description" content="Access your Mac terminal from your phone to use Claude Code CLI, Gemini CLI, and other command-line tools.">
20
20
 
21
21
  <!-- Google Analytics 4 -->
22
- <script async src="https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK"></script>
23
22
  <script>
23
+ // Initialize dataLayer and gtag function first
24
24
  window.dataLayer = window.dataLayer || [];
25
25
  function gtag(){dataLayer.push(arguments);}
26
26
  gtag('js', new Date());
27
27
  gtag('config', 'G-LG7ZGLB8FK');
28
+
29
+ // Load gtag script with proper error handling
30
+ (function() {
31
+ var script = document.createElement('script');
32
+ script.async = true;
33
+ script.src = 'https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK';
34
+ script.onload = function() {
35
+ console.log('✅ Google Analytics script loaded successfully');
36
+ window.gtagLoaded = true;
37
+ };
38
+ script.onerror = function() {
39
+ console.warn('❌ Failed to load Google Analytics script');
40
+ window.gtagLoaded = false;
41
+ };
42
+ document.head.appendChild(script);
43
+ })();
28
44
  </script>
29
45
 
30
46
  <!-- Microsoft Clarity -->
@@ -33,7 +49,7 @@
33
49
  c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
34
50
  t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
35
51
  y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
36
- })(window, document, "clarity", "script", "CLARITY_PROJECT_ID");
52
+ })(window, document, "clarity", "script", "sy1w2d7il7");
37
53
  </script>
38
54
 
39
55
  <style>
@@ -700,16 +716,10 @@
700
716
  console.log('🔍 [DEBUG] Login button clicked');
701
717
 
702
718
  // Track login attempt in Google Analytics
703
- if (typeof gtag !== 'undefined') {
704
- console.log('📊 [DEBUG] Sending login_attempt event to Google Analytics');
705
- gtag('event', 'login_attempt', {
706
- event_category: 'authentication',
707
- event_label: 'google_oauth'
708
- });
709
- console.log('✅ [DEBUG] login_attempt event sent successfully');
710
- } else {
711
- console.warn('❌ [DEBUG] Cannot send login_attempt event - gtag not available');
712
- }
719
+ sendGAEvent('login_attempt', {
720
+ event_category: 'authentication',
721
+ event_label: 'google_oauth'
722
+ });
713
723
 
714
724
  // Direct OAuth flow using the web backend
715
725
  window.location.href = '/php-backend/api/auth-login.php?return=' + encodeURIComponent('/app/dashboard');
@@ -720,16 +730,10 @@
720
730
  console.log('🔍 [DEBUG] Dashboard button clicked');
721
731
 
722
732
  // Track dashboard access in Google Analytics
723
- if (typeof gtag !== 'undefined') {
724
- console.log('📊 [DEBUG] Sending dashboard_access event to Google Analytics');
725
- gtag('event', 'dashboard_access', {
726
- event_category: 'navigation',
727
- event_label: 'from_landing_page'
728
- });
729
- console.log('✅ [DEBUG] dashboard_access event sent successfully');
730
- } else {
731
- console.warn('❌ [DEBUG] Cannot send dashboard_access event - gtag not available');
732
- }
733
+ sendGAEvent('dashboard_access', {
734
+ event_category: 'navigation',
735
+ event_label: 'from_landing_page'
736
+ });
733
737
 
734
738
  window.location.href = '/app/dashboard.html';
735
739
  }
@@ -757,26 +761,33 @@
757
761
  }
758
762
  }
759
763
 
764
+ // Google Analytics helper function
765
+ function sendGAEvent(eventName, eventParams) {
766
+ if (typeof gtag === 'function') {
767
+ console.log('📊 [GA] Sending event:', eventName, eventParams);
768
+ gtag('event', eventName, eventParams);
769
+ return true;
770
+ } else {
771
+ console.warn('❌ [GA] gtag not available, event not sent:', eventName);
772
+ return false;
773
+ }
774
+ }
775
+
760
776
  // Initialize page on load
761
777
  document.addEventListener('DOMContentLoaded', async () => {
762
- // Debug Google Analytics setup
763
- console.log('🔍 [DEBUG] Checking Google Analytics setup...');
764
- console.log('🔍 [DEBUG] gtag function available:', typeof gtag !== 'undefined');
765
- console.log('🔍 [DEBUG] dataLayer exists:', typeof window.dataLayer !== 'undefined');
766
- console.log('🔍 [DEBUG] dataLayer contents:', window.dataLayer);
767
-
768
- // Test if gtag is working
769
- if (typeof gtag !== 'undefined') {
770
- console.log(' [DEBUG] Google Analytics gtag function is available');
771
- // Send a test event
772
- gtag('event', 'page_debug', {
773
- event_category: 'debug',
774
- event_label: 'landing_page_loaded'
778
+ // Wait a moment for GA script to load
779
+ setTimeout(() => {
780
+ console.log('🔍 [DEBUG] Checking Google Analytics setup...');
781
+ console.log('🔍 [DEBUG] gtag function type:', typeof gtag);
782
+ console.log('🔍 [DEBUG] dataLayer exists:', typeof window.dataLayer !== 'undefined');
783
+ console.log('🔍 [DEBUG] gtagLoaded flag:', window.gtagLoaded);
784
+
785
+ // Send test event
786
+ sendGAEvent('page_view', {
787
+ page_title: 'Shell Mirror Landing',
788
+ page_location: window.location.href
775
789
  });
776
- console.log('📊 [DEBUG] Test event sent: page_debug');
777
- } else {
778
- console.warn('❌ [DEBUG] Google Analytics gtag function not available');
779
- }
790
+ }, 1000);
780
791
 
781
792
  await updateHeaderAndCTA();
782
793
  loadVersionInfo();