shell-mirror 1.5.46 → 1.5.48

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.46",
3
+ "version": "1.5.48",
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": {
@@ -4,6 +4,25 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Shell Mirror Dashboard</title>
7
+
8
+ <!-- Google Analytics 4 -->
9
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK"></script>
10
+ <script>
11
+ window.dataLayer = window.dataLayer || [];
12
+ function gtag(){dataLayer.push(arguments);}
13
+ gtag('js', new Date());
14
+ gtag('config', 'G-LG7ZGLB8FK');
15
+ </script>
16
+
17
+ <!-- Microsoft Clarity -->
18
+ <script type="text/javascript">
19
+ (function(c,l,a,r,i,t,y){
20
+ c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
21
+ t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
22
+ y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
23
+ })(window, document, "clarity", "script", "CLARITY_PROJECT_ID");
24
+ </script>
25
+
7
26
  <link rel="stylesheet" href="dashboard.css">
8
27
  </head>
9
28
  <body>
@@ -13,6 +13,23 @@ 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
+ }
32
+
16
33
  try {
17
34
  const authStatus = await this.checkAuthStatus();
18
35
 
@@ -429,21 +446,72 @@ class ShellMirrorDashboard {
429
446
  session.lastActivity > latest.lastActivity ? session : latest
430
447
  );
431
448
  console.log(`[DASHBOARD] ✅ Reconnecting to existing session: ${mostRecentSession.id}`);
449
+
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', {
455
+ event_category: 'terminal',
456
+ event_label: 'existing_session',
457
+ agent_id: agentId,
458
+ session_id: mostRecentSession.id
459
+ });
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
+ }
464
+
432
465
  window.location.href = `/app/terminal.html?agent=${agentId}&session=${mostRecentSession.id}`;
433
466
  } else {
434
467
  // No existing sessions, create new one
435
468
  console.log(`[DASHBOARD] 🆕 Creating new session for agent: ${agentId}`);
469
+
470
+ // 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', {
475
+ event_category: 'terminal',
476
+ event_label: 'new_session',
477
+ agent_id: agentId
478
+ });
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
+ }
483
+
436
484
  window.location.href = `/app/terminal.html?agent=${agentId}`;
437
485
  }
438
486
  }
439
487
 
440
488
  async connectToSession(agentId, sessionId) {
489
+ // Track specific session connection in Google Analytics
490
+ if (typeof gtag !== 'undefined') {
491
+ gtag('event', 'terminal_connect', {
492
+ event_category: 'terminal',
493
+ event_label: 'specific_session',
494
+ agent_id: agentId,
495
+ session_id: sessionId
496
+ });
497
+ }
498
+
441
499
  window.location.href = `/app/terminal.html?agent=${agentId}&session=${sessionId}`;
442
500
  }
443
501
 
444
502
  async createNewSession(agentId) {
445
503
  // Force creation of new session by not passing session parameter
446
504
  console.log(`[DASHBOARD] Creating new session for agent: ${agentId}`);
505
+
506
+ // Track explicit new session creation in Google Analytics
507
+ if (typeof gtag !== 'undefined') {
508
+ gtag('event', 'terminal_connect', {
509
+ event_category: 'terminal',
510
+ event_label: 'force_new_session',
511
+ agent_id: agentId
512
+ });
513
+ }
514
+
447
515
  window.location.href = `/app/terminal.html?agent=${agentId}`;
448
516
  }
449
517
 
@@ -2,6 +2,25 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Terminal Mirror</title>
5
+
6
+ <!-- Google Analytics 4 -->
7
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK"></script>
8
+ <script>
9
+ window.dataLayer = window.dataLayer || [];
10
+ function gtag(){dataLayer.push(arguments);}
11
+ gtag('js', new Date());
12
+ gtag('config', 'G-LG7ZGLB8FK');
13
+ </script>
14
+
15
+ <!-- Microsoft Clarity -->
16
+ <script type="text/javascript">
17
+ (function(c,l,a,r,i,t,y){
18
+ c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
19
+ t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
20
+ y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
21
+ })(window, document, "clarity", "script", "CLARITY_PROJECT_ID");
22
+ </script>
23
+
5
24
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.15.0/css/xterm.css" />
6
25
  <script src="https://cdn.jsdelivr.net/npm/xterm@4.15.0/lib/xterm.js"></script>
7
26
  <script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.js"></script>
@@ -180,6 +180,23 @@ 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
+ }
199
+
183
200
  // Get agent ID and session ID from URL parameters
184
201
  const urlParams = new URLSearchParams(window.location.search);
185
202
  const agentId = urlParams.get('agent');
@@ -233,6 +250,22 @@ function startConnection() {
233
250
  connectContainer.style.display = 'none';
234
251
  terminalContainer.classList.add('show');
235
252
  term.open(document.getElementById('terminal'));
253
+
254
+ // 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', {
259
+ event_category: 'terminal',
260
+ event_label: requestedSessionId ? 'existing_session' : 'new_session',
261
+ agent_id: AGENT_ID,
262
+ session_id: requestedSessionId || 'new'
263
+ });
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
+ }
268
+
236
269
  // Delay fit to ensure proper dimensions after CSS transitions
237
270
  setTimeout(() => {
238
271
  fitAddon.fit();
@@ -520,6 +553,21 @@ async function createPeerConnection() {
520
553
  case 'connected':
521
554
  console.log('[CLIENT] ✅ WebRTC connection established!');
522
555
  updateConnectionStatus('connected');
556
+
557
+ // 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', {
562
+ event_category: 'terminal',
563
+ event_label: 'webrtc_established',
564
+ agent_id: AGENT_ID
565
+ });
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
+ }
570
+
523
571
  break;
524
572
  case 'completed':
525
573
  console.log('[CLIENT] ✅ ICE connection completed successfully!');
package/public/index.html CHANGED
@@ -18,6 +18,24 @@
18
18
  <meta property="twitter:title" content="Shell Mirror - Use Claude Code CLI from your phone">
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
+ <!-- Google Analytics 4 -->
22
+ <script async src="https://www.googletagmanager.com/gtag/js?id=G-LG7ZGLB8FK"></script>
23
+ <script>
24
+ window.dataLayer = window.dataLayer || [];
25
+ function gtag(){dataLayer.push(arguments);}
26
+ gtag('js', new Date());
27
+ gtag('config', 'G-LG7ZGLB8FK');
28
+ </script>
29
+
30
+ <!-- Microsoft Clarity -->
31
+ <script type="text/javascript">
32
+ (function(c,l,a,r,i,t,y){
33
+ c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
34
+ t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
35
+ y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
36
+ })(window, document, "clarity", "script", "CLARITY_PROJECT_ID");
37
+ </script>
38
+
21
39
  <style>
22
40
  * {
23
41
  margin: 0;
@@ -679,12 +697,40 @@
679
697
 
680
698
  // Handle Google login - direct web OAuth
681
699
  async function handleGoogleLogin() {
700
+ console.log('🔍 [DEBUG] Login button clicked');
701
+
702
+ // 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
+ }
713
+
682
714
  // Direct OAuth flow using the web backend
683
715
  window.location.href = '/php-backend/api/auth-login.php?return=' + encodeURIComponent('/app/dashboard');
684
716
  }
685
717
 
686
718
  // Handle dashboard navigation
687
719
  async function openDashboard() {
720
+ console.log('🔍 [DEBUG] Dashboard button clicked');
721
+
722
+ // 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
+
688
734
  window.location.href = '/app/dashboard.html';
689
735
  }
690
736
 
@@ -713,6 +759,25 @@
713
759
 
714
760
  // Initialize page on load
715
761
  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'
775
+ });
776
+ console.log('📊 [DEBUG] Test event sent: page_debug');
777
+ } else {
778
+ console.warn('❌ [DEBUG] Google Analytics gtag function not available');
779
+ }
780
+
716
781
  await updateHeaderAndCTA();
717
782
  loadVersionInfo();
718
783
  });