devicely 2.2.1 → 2.2.2

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.
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @license React
3
+ * react-dom.production.min.js
4
+ *
5
+ * Copyright (c) Facebook, Inc. and its affiliates.
6
+ *
7
+ * This source code is licensed under the MIT license found in the
8
+ * LICENSE file in the root directory of this source tree.
9
+ */
10
+
11
+ /**
12
+ * @license React
13
+ * react-jsx-runtime.production.min.js
14
+ *
15
+ * Copyright (c) Facebook, Inc. and its affiliates.
16
+ *
17
+ * This source code is licensed under the MIT license found in the
18
+ * LICENSE file in the root directory of this source tree.
19
+ */
20
+
21
+ /**
22
+ * @license React
23
+ * react.production.min.js
24
+ *
25
+ * Copyright (c) Facebook, Inc. and its affiliates.
26
+ *
27
+ * This source code is licensed under the MIT license found in the
28
+ * LICENSE file in the root directory of this source tree.
29
+ */
30
+
31
+ /**
32
+ * @license React
33
+ * scheduler.production.min.js
34
+ *
35
+ * Copyright (c) Facebook, Inc. and its affiliates.
36
+ *
37
+ * This source code is licensed under the MIT license found in the
38
+ * LICENSE file in the root directory of this source tree.
39
+ */
40
+
41
+ /** @license React v16.13.1
42
+ * react-is.production.min.js
43
+ *
44
+ * Copyright (c) Facebook, Inc. and its affiliates.
45
+ *
46
+ * This source code is licensed under the MIT license found in the
47
+ * LICENSE file in the root directory of this source tree.
48
+ */
package/lib/server.js CHANGED
@@ -104,7 +104,7 @@ function findScriptFile(filename) {
104
104
 
105
105
  for (const { path: scriptPath, encrypted } of pathsToTry) {
106
106
  if (fsSync.existsSync(scriptPath)) {
107
- console.log(`✅ Found script: ${filename} at ${scriptPath}${encrypted ? ' (encrypted)' : ''}`);
107
+ logger.debug(`✅ Found script: ${filename} at ${scriptPath}${encrypted ? ' (encrypted)' : ''}`);
108
108
 
109
109
  // If encrypted, decrypt to temp directory and return temp path
110
110
  if (encrypted && scriptLoader) {
@@ -120,7 +120,7 @@ function findScriptFile(filename) {
120
120
  try {
121
121
  const content = scriptLoader.decryptScript(scriptPath);
122
122
  fsSync.writeFileSync(tmpScript, content, { mode: 0o755 });
123
- console.log(`🔓 Decrypted ${filename} to temp directory`);
123
+ logger.debug(`🔓 Decrypted ${filename} to temp directory`);
124
124
  } catch (error) {
125
125
  console.error(`❌ Failed to decrypt ${filename}: ${error.message}`);
126
126
  continue;
@@ -538,10 +538,10 @@ function resolveAppPreset(command, platform) {
538
538
  // Execute command on device(s)
539
539
  function executeCommand(deviceNames, command, wsClient) {
540
540
  return new Promise(async (resolve, reject) => {
541
- console.log(`\n${'#'.repeat(60)}`);
542
- console.log(`Device names received: [${deviceNames.join(', ')}]`);
541
+ // separator removed
542
+ logger.debug(`Device names received: [${deviceNames.join(', ')}]`);
543
543
  console.log(`Command: "${command}"`);
544
- console.log(`${'#'.repeat(60)}\n`);
544
+ // separator removed
545
545
 
546
546
  // Get full device objects from connectedDevices cache
547
547
  // Match by name, udid, or serial
@@ -551,7 +551,7 @@ function executeCommand(deviceNames, command, wsClient) {
551
551
  deviceNames.includes(d.serial)
552
552
  );
553
553
 
554
- console.log(`Cache contents:`, connectedDevices.map(d => `${d.name}(${d.status})`).join(', '));
554
+ logger.debug(`Cache contents:`, connectedDevices.map(d => `${d.name}(${d.status})`).join(', '));
555
555
 
556
556
  if (devices.length === 0) {
557
557
  console.error(`❌ No devices found for: [${deviceNames.join(', ')}]`);
@@ -595,7 +595,7 @@ function executeCommand(deviceNames, command, wsClient) {
595
595
  if (iosUSBDevices.length > 0) {
596
596
  const names = iosUSBDevices.map(d => d.name);
597
597
  const iosCommand = resolveAppPreset(command, 'ios');
598
- console.log(`Using iOS USB script for: ${names.join(', ')}`);
598
+ logger.debug(`Using iOS USB script for: ${names.join(', ')}`);
599
599
  promises.push(executeWithScript(USB_SCRIPT_PATH, names, iosCommand, wsClient));
600
600
  }
601
601
 
@@ -610,14 +610,14 @@ function executeCommand(deviceNames, command, wsClient) {
610
610
  // Execute for Android USB devices
611
611
  if (androidUSBDevices.length > 0) {
612
612
  const androidCommand = resolveAppPreset(command, 'android');
613
- console.log(`Using Android control script for USB devices: ${androidUSBDevices.map(d => d.name).join(', ')}`);
613
+ logger.debug(`Using Android control script for USB devices: ${androidUSBDevices.map(d => d.name).join(', ')}`);
614
614
  promises.push(executeAndroidDevices(ANDROID_USB_SCRIPT_PATH, androidUSBDevices, androidCommand, wsClient));
615
615
  }
616
616
 
617
617
  // Execute for Android wireless devices
618
618
  if (androidWirelessDevices.length > 0) {
619
619
  const androidCommand = resolveAppPreset(command, 'android');
620
- console.log(`Using Android control script for wireless devices: ${androidWirelessDevices.map(d => d.name).join(', ')}`);
620
+ logger.debug(`Using Android control script for wireless devices: ${androidWirelessDevices.map(d => d.name).join(', ')}`);
621
621
  promises.push(executeAndroidDevices(ANDROID_WIRELESS_SCRIPT_PATH, androidWirelessDevices, androidCommand, wsClient));
622
622
  }
623
623
 
@@ -631,7 +631,7 @@ function executeCommand(deviceNames, command, wsClient) {
631
631
  const successCount = results.filter(r => r.status === 'fulfilled').length;
632
632
  const failCount = results.filter(r => r.status === 'rejected').length;
633
633
 
634
- console.log(`\nExecuteCommand summary: ${successCount} succeeded, ${failCount} failed`);
634
+ logger.debug(`ExecuteCommand summary: ${successCount} succeeded, ${failCount} failed`);
635
635
 
636
636
  resolve({
637
637
  success: true,
@@ -713,9 +713,9 @@ function executeWithScript(scriptPath, deviceNames, command, wsClient) {
713
713
  const successful = results.filter(r => r.status === 'fulfilled').length;
714
714
  const failed = results.filter(r => r.status === 'rejected').length;
715
715
 
716
- console.log(`\n${'='.repeat(60)}`);
716
+ // separator removed
717
717
 
718
- console.log(`${'='.repeat(60)}\n`);
718
+ // separator removed
719
719
 
720
720
  resolve({
721
721
  success: true,
@@ -793,12 +793,12 @@ function executeAndroidDevices(scriptPath, devices, command, wsClient) {
793
793
 
794
794
  Promise.allSettled(devicePromises)
795
795
  .then(results => {
796
- console.log(`\n${'='.repeat(60)}`);
796
+ // separator removed
797
797
 
798
798
  const successCount = results.filter(r => r.status === 'fulfilled' && r.value.success).length;
799
799
  const failCount = results.length - successCount;
800
800
 
801
- console.log(`${'='.repeat(60)}\n`);
801
+ // separator removed
802
802
 
803
803
  resolve({ success: true, results });
804
804
  })
@@ -836,11 +836,11 @@ async function convertNaturalLanguageToCommand(text, devices, provider = null) {
836
836
  async function executeCommandsSequentially(devices, commandsText, wsClient) {
837
837
  const lines = commandsText.split('\n').map(line => line.trim()).filter(line => line);
838
838
 
839
- console.log(`\n${'~'.repeat(60)}`);
839
+ // separator removed
840
840
 
841
841
  console.log(`Total commands: ${lines.length}`);
842
842
  console.log(`Commands:`, lines);
843
- console.log(`${'~'.repeat(60)}\n`);
843
+ // separator removed
844
844
 
845
845
  const results = [];
846
846
 
@@ -899,10 +899,10 @@ async function executeCommandsSequentially(devices, commandsText, wsClient) {
899
899
  }
900
900
  }
901
901
 
902
- console.log(`\n${'~'.repeat(60)}`);
902
+ // separator removed
903
903
 
904
904
  console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
905
- console.log(`${'~'.repeat(60)}\n`);
905
+ // separator removed
906
906
 
907
907
  return {
908
908
  success: true,
@@ -2063,12 +2063,12 @@ async function replayRecording(filename, targetDevices, wsClient) {
2063
2063
  ? recording.devices
2064
2064
  : targetDevices;
2065
2065
 
2066
- console.log(`\n${'▶'.repeat(60)}`);
2066
+ // separator removed
2067
2067
  console.log(`REPLAYING: ${recording.name}`);
2068
2068
  console.log(`Original devices: ${devices.join(', ')}`);
2069
2069
  console.log(`Target devices: ${targetDevices.join(', ')}`);
2070
2070
  console.log(`Commands to replay: ${commands.length}`);
2071
- console.log(`${'▶'.repeat(60)}\n`);
2071
+ // separator removed
2072
2072
 
2073
2073
  // Reset abort flag at start
2074
2074
  replayAborted = false;
@@ -2149,10 +2149,10 @@ async function replayRecording(filename, targetDevices, wsClient) {
2149
2149
 
2150
2150
  isReplaying = false;
2151
2151
 
2152
- console.log(`\n${'▶'.repeat(60)}`);
2152
+ // separator removed
2153
2153
  console.log(`REPLAY COMPLETE`);
2154
2154
  console.log(`Total: ${results.length}, Success: ${results.filter(r => r.success).length}, Failed: ${results.filter(r => !r.success).length}`);
2155
- console.log(`${'▶'.repeat(60)}\n`);
2155
+ // separator removed
2156
2156
 
2157
2157
  return {
2158
2158
  success: true,
@@ -2555,7 +2555,7 @@ app.post('/api/locators', async (req, res) => {
2555
2555
  return res.status(400).json({ success: false, error: 'Device name required' });
2556
2556
  }
2557
2557
 
2558
- console.log(`\n🔍 API: Getting locators for device: ${deviceName}`);
2558
+ logger.debug(`Getting locators for device: ${deviceName}`);
2559
2559
 
2560
2560
  // Find the device info
2561
2561
  const device = connectedDevices.find(d => d.name === deviceName);
@@ -2592,8 +2592,8 @@ app.post('/api/locators', async (req, res) => {
2592
2592
  // Execute getLocators command - this uses the fast shell script implementation
2593
2593
  const result = await executeCommand([deviceName], 'getLocators', null);
2594
2594
 
2595
- console.log(`Result success: ${result.success}`);
2596
- console.log(`Results array length: ${result.results?.length || 0}`);
2595
+ logger.debug(`Result success: ${result.success}`);
2596
+ logger.debug(`Results array length: ${result.results?.length || 0}`);
2597
2597
 
2598
2598
  if (result.success && result.results) {
2599
2599
  let output = '';
@@ -2604,18 +2604,18 @@ app.post('/api/locators', async (req, res) => {
2604
2604
  // allSettledResults contains: { status: 'fulfilled', value: { success, output, device } }
2605
2605
 
2606
2606
  for (const scriptResult of result.results) {
2607
- console.log(`Script result:`, scriptResult);
2607
+ logger.debug(`Script result:`, scriptResult);
2608
2608
 
2609
2609
  // Check if scriptResult has value.results (fulfilled promise)
2610
2610
  if (scriptResult.status === 'fulfilled' && scriptResult.value && scriptResult.value.results) {
2611
2611
  // This is the result from executeAndroidDevices/executeWithScript
2612
2612
  for (const r of scriptResult.value.results) {
2613
- console.log(`Result status: ${r.status}`);
2613
+ logger.debug(`Result status: ${r.status}`);
2614
2614
  if (r.status === 'fulfilled' && r.value) {
2615
2615
  // Check if it's a successful execution
2616
2616
  if (r.value.success && r.value.output) {
2617
2617
  output = r.value.output;
2618
- console.log(`✅ Found output: ${output.length} characters`);
2618
+ logger.debug(`Found output: ${output.length} characters`);
2619
2619
  break;
2620
2620
  } else if (r.value.error) {
2621
2621
  // Script executed but returned an error
@@ -2693,11 +2693,11 @@ app.post('/api/locators/click', async (req, res) => {
2693
2693
 
2694
2694
  // Helper function to parse locators output
2695
2695
  function parseLocatorsOutput(output) {
2696
- console.log('🔍 Parsing locators output...');
2697
- console.log('Output length:', output?.length || 0);
2696
+ logger.debug('🔍 Parsing locators output...');
2697
+ logger.debug('Output length:', output?.length || 0);
2698
2698
 
2699
2699
  if (!output) {
2700
- console.log('❌ No output to parse');
2700
+ logger.error('❌ No output to parse');
2701
2701
  return [];
2702
2702
  }
2703
2703
 
@@ -2708,19 +2708,19 @@ function parseLocatorsOutput(output) {
2708
2708
  if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
2709
2709
  try {
2710
2710
  const jsonData = JSON.parse(trimmed);
2711
- console.log('✅ Parsed as JSON, elements:', Array.isArray(jsonData) ? jsonData.length : 'not array');
2711
+ logger.debug('✅ Parsed as JSON, elements:', Array.isArray(jsonData) ? jsonData.length : 'not array');
2712
2712
  return Array.isArray(jsonData) ? jsonData : [];
2713
2713
  } catch (err) {
2714
- console.log('⚠️ JSON parse failed:', err.message);
2714
+ logger.debug('⚠️ JSON parse failed:', err.message);
2715
2715
  }
2716
2716
  }
2717
2717
  }
2718
2718
 
2719
- console.log('📝 Fallback to text parsing...');
2719
+ logger.debug('📝 Fallback to text parsing...');
2720
2720
 
2721
2721
  // Fallback to old text parsing
2722
2722
  const locators = [];
2723
- console.log('Total lines:', lines.length);
2723
+ logger.debug('Total lines:', lines.length);
2724
2724
 
2725
2725
  for (const line of lines) {
2726
2726
  // New format: " 1. 📍 ButtonName │ [Button] │ Label:LabelText │ Val:ValueText │ @ (x,y) WxH │ ✓Vis ✓En"
@@ -2822,7 +2822,7 @@ function parseLocatorsOutput(output) {
2822
2822
 
2823
2823
  // Only add if we have meaningful data
2824
2824
  if (locator.name || locator.label || locator.text) {
2825
- console.log('Parsed locator:', locator);
2825
+ logger.debug('Parsed locator:', locator);
2826
2826
  locators.push(locator);
2827
2827
  }
2828
2828
  } catch (e) {
@@ -2848,13 +2848,13 @@ wss.on('connection', (ws) => {
2848
2848
  case 'execute_command':
2849
2849
  const { devices, command, useAI, aiProvider } = data;
2850
2850
 
2851
- console.log(`\n${'*'.repeat(60)}`);
2851
+ // separator removed
2852
2852
  console.log(`WEBSOCKET: Received execute_command`);
2853
2853
  console.log(`Devices received: [${devices.join(', ')}]`);
2854
2854
  console.log(`Command: "${command}"`);
2855
2855
  console.log(`Use AI: ${useAI}`);
2856
2856
  if (aiProvider) console.log(`AI Provider: ${aiProvider}`);
2857
- console.log(`${'*'.repeat(60)}\n`);
2857
+ // separator removed
2858
2858
 
2859
2859
  let finalCommand = command;
2860
2860
 
@@ -3469,12 +3469,12 @@ function startServer(options = {}) {
3469
3469
 
3470
3470
  return new Promise((resolve, reject) => {
3471
3471
  server = app.listen(port, () => {
3472
- console.log(`Server running on port ${port}`);
3473
- console.log(`WebSocket server ready`);
3472
+ console.log(`✅ Server running on port ${port}`);
3473
+ console.log(`✅ WebSocket server ready`);
3474
3474
 
3475
3475
  // Initial device discovery
3476
3476
  discoverDevices().then(devices => {
3477
- console.log(`Discovered ${devices.length} devices`);
3477
+ console.log(`✅ Discovered ${devices.length} devices`);
3478
3478
 
3479
3479
  // Open browser if not disabled
3480
3480
  if (shouldOpenBrowser) {
@@ -3485,17 +3485,30 @@ function startServer(options = {}) {
3485
3485
  });
3486
3486
  }
3487
3487
 
3488
- resolve({ port, devices });
3489
- }).catch(reject);
3488
+ resolve();
3489
+ }).catch(err => {
3490
+ logger.error('Device discovery failed:', err.message);
3491
+ resolve();
3492
+ });
3490
3493
  });
3491
3494
 
3495
+ // Handle WebSocket upgrades
3492
3496
  server.on('upgrade', (request, socket, head) => {
3493
3497
  wss.handleUpgrade(request, socket, head, (ws) => {
3494
3498
  wss.emit('connection', ws, request);
3495
3499
  });
3496
3500
  });
3497
3501
 
3498
- server.on('error', reject);
3502
+ server.on('error', (err) => {
3503
+ if (err.code === 'EADDRINUSE') {
3504
+ logger.error(`\n❌ Port ${port} is already in use!`);
3505
+ logger.error(`\nTry one of these solutions:`);
3506
+ logger.error(` 1. Kill the process using port ${port}: lsof -ti:${port} | xargs kill -9`);
3507
+ logger.error(` 2. Use a different port: PORT=3002 devicely`);
3508
+ logger.error(` 3. Set PORT in .env file\n`);
3509
+ }
3510
+ reject(err);
3511
+ });
3499
3512
  });
3500
3513
  }
3501
3514
 
@@ -3518,7 +3531,16 @@ module.exports = {
3518
3531
  // Start server if run directly (not imported as module)
3519
3532
  if (require.main === module) {
3520
3533
  startServer().catch(err => {
3521
- console.error('Failed to start server:', err);
3534
+ if (err.code === 'EADDRINUSE') {
3535
+ logger.error(`\n❌ Port 3001 is already in use!`);
3536
+ logger.error(`\nTry one of these solutions:`);
3537
+ logger.error(` 1. Kill the process using port 3001: lsof -ti:3001 | xargs kill -9`);
3538
+ logger.error(` 2. Use a different port: PORT=3002 devicely`);
3539
+ logger.error(` Note: Vercel frontend connects to port 3001 by default`);
3540
+ logger.error(` 3. Use local frontend at http://localhost:3001\n`);
3541
+ } else {
3542
+ console.error('Failed to start server:', err.message);
3543
+ }
3522
3544
  process.exit(1);
3523
3545
  });
3524
3546
  }