devicely 2.1.9 → 2.2.0

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/logger.js CHANGED
@@ -1,7 +1,9 @@
1
1
  // Centralized Logger for Production
2
- // Use environment variable to control debug output
2
+ // Use environment variable or --debug flag to control debug output
3
3
 
4
- const DEBUG_MODE = process.env.DEBUG === 'true' || process.env.NODE_ENV === 'development';
4
+ const DEBUG_MODE = process.argv.includes('--debug') ||
5
+ process.env.DEBUG === 'true' ||
6
+ process.env.NODE_ENV === 'development';
5
7
 
6
8
  class Logger {
7
9
  constructor(module) {
@@ -28,8 +30,18 @@ class Logger {
28
30
 
29
31
  // Keep critical startup/connection messages
30
32
  startup(...args) {
31
- console.log(`[STARTUP][${this.module}]`, ...args);
33
+ console.log(`✅ [${this.module}]`, ...args);
32
34
  }
35
+
36
+ // Show execution results (always visible)
37
+ result(...args) {
38
+ console.log(`📝 [${this.module}]`, ...args);
39
+ }
40
+ }
41
+
42
+ // Show debug mode status on startup
43
+ if (DEBUG_MODE) {
44
+ console.log('🔧 DEBUG MODE ENABLED - Use devicely without --debug flag for quiet mode\n');
33
45
  }
34
46
 
35
47
  module.exports = Logger;
package/lib/server.js CHANGED
@@ -9,6 +9,10 @@ const { spawn } = require('child_process');
9
9
  const WebSocket = require('ws');
10
10
  const fs = require('fs').promises;
11
11
  const AIProviderManager = require('./aiProviders');
12
+ const Logger = require('./logger');
13
+
14
+ // Initialize logger
15
+ const logger = new Logger('Server');
12
16
 
13
17
  // Import scriptLoader for encrypted scripts
14
18
  let scriptLoader;
@@ -643,12 +647,11 @@ function executeCommand(deviceNames, command, wsClient) {
643
647
 
644
648
  function executeWithScript(scriptPath, deviceNames, command, wsClient) {
645
649
  return new Promise((resolve, reject) => {
646
- console.log(`\n${'='.repeat(60)}`);
647
- console.log(`Script: ${path.basename(scriptPath)}`);
648
- console.log(`Devices: [${deviceNames.join(', ')}]`);
649
- console.log(`Command: "${command}"`);
650
-
651
- console.log(`${'='.repeat(60)}\n`);
650
+ logger.debug(`\n${'='.repeat(60)}`);
651
+ logger.debug(`Script: ${path.basename(scriptPath)}`);
652
+ logger.debug(`Devices: [${deviceNames.join(', ')}]`);
653
+ logger.debug(`Command: "${command}"`);
654
+ logger.debug(`${'='.repeat(60)}\n`);
652
655
 
653
656
  // Execute command on each device in parallel
654
657
  const devicePromises = deviceNames.map((deviceName, index) => {
@@ -657,6 +660,8 @@ function executeWithScript(scriptPath, deviceNames, command, wsClient) {
657
660
  // Use -d flag for each device
658
661
  const args = ['-d', deviceName, command];
659
662
 
663
+ logger.debug(`[${index + 1}/${deviceNames.length}] Executing on: ${deviceName}`);
664
+
660
665
 
661
666
  const child = spawn(scriptPath, args, {
662
667
  cwd: path.dirname(scriptPath)
@@ -669,7 +674,7 @@ function executeWithScript(scriptPath, deviceNames, command, wsClient) {
669
674
  child.stdout.on('data', (data) => {
670
675
  const text = data.toString();
671
676
  output += text;
672
- console.log(`[${deviceName}] STDOUT: ${text.trim()}`);
677
+ logger.debug(`[${deviceName}] STDOUT: ${text.trim()}`);
673
678
  if (wsClient) {
674
679
  wsClient.send(JSON.stringify({
675
680
  type: 'command_output',
@@ -728,15 +733,15 @@ function executeWithScript(scriptPath, deviceNames, command, wsClient) {
728
733
  // Execute Android commands (uses device UDID instead of name)
729
734
  function executeAndroidDevices(scriptPath, devices, command, wsClient) {
730
735
  return new Promise((resolve, reject) => {
731
- console.log(`\n${'='.repeat(60)}`);
732
- console.log(`Script: ${path.basename(scriptPath)}`);
733
- console.log(`Devices: [${devices.map(d => d.name).join(', ')}]`);
734
- console.log(`Command: "${command}"`);
735
- console.log(`${'='.repeat(60)}\n`);
736
+ logger.debug(`\n${'='.repeat(60)}`);
737
+ logger.debug(`Script: ${path.basename(scriptPath)}`);
738
+ logger.debug(`Devices: [${devices.map(d => d.name).join(', ')}]`);
739
+ logger.debug(`Command: "${command}"`);
740
+ logger.debug(`${'='.repeat(60)}\n`);
736
741
 
737
742
  // Execute command on each device in parallel
738
743
  const devicePromises = devices.map((device, index) => {
739
- console.log(`[${index + 1}/${devices.length}] Creating execution promise for: ${device.name} (${device.udid})`);
744
+ logger.debug(`[${index + 1}/${devices.length}] Creating execution promise for: ${device.name} (${device.udid}`);
740
745
 
741
746
  return new Promise((resolveDevice, rejectDevice) => {
742
747
  // Android script expects: <device_serial> <command> [args...]
@@ -754,7 +759,7 @@ function executeAndroidDevices(scriptPath, devices, command, wsClient) {
754
759
  child.stdout.on('data', (data) => {
755
760
  const text = data.toString();
756
761
  output += text;
757
- console.log(`[${device.name}] STDOUT: ${text.trim()}`);
762
+ logger.debug(`[${device.name}] STDOUT: ${text.trim()}`);
758
763
  if (wsClient) {
759
764
  wsClient.send(JSON.stringify({
760
765
  type: 'output',
@@ -767,7 +772,7 @@ function executeAndroidDevices(scriptPath, devices, command, wsClient) {
767
772
  child.stderr.on('data', (data) => {
768
773
  const text = data.toString();
769
774
  error += text;
770
- console.log(`[${device.name}] STDERR: ${text.trim()}`);
775
+ logger.debug(`[${device.name}] STDERR: ${text.trim()}`);
771
776
  });
772
777
 
773
778
  child.on('close', (code) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devicely",
3
- "version": "2.1.9",
3
+ "version": "2.2.0",
4
4
  "description": "Devicely - One Command, All Devices. AI Powered Mobile Automation for iOS and Android",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"static/css/main.23bd35c0.css","mappings":"AAGA,kBACE,GACE,SAAU,CACV,0BACF,CACA,GACE,SAAU,CACV,uBACF,CACF,CAGA,wBACE,GACE,SAAU,CACV,0BACF,CACA,GACE,SAAU,CACV,uBACF,CACF,CAGA,uBACE,GACE,SAAU,CACV,2BACF,CACA,GACE,SAAU,CACV,uBACF,CACF,CAGA,mBACE,GACE,SAAU,CACV,mBACF,CACA,GACE,SAAU,CACV,kBACF,CACF,CAGA,iBACE,MACE,SAAU,CACV,kBACF,CACA,IACE,UAAY,CACZ,qBACF,CACF,CAGA,gBACE,OAEE,SAAU,CADV,kBAEF,CACF,CAGA,kBACE,MACE,uBACF,CACA,IACE,2BACF,CACF,CAGA,mBACE,GACE,6BACF,CACA,GACE,4BACF,CACF,CAGA,kBACE,GACE,sBACF,CACA,GACE,uBACF,CACF,CAGA,iBACE,MACE,uBACF,CACA,IACE,0BACF,CACF,CAGA,gBACE,MACE,4BACF,CACA,IACE,gDACF,CACF,CAGA,SACE,6BACF,CAEA,gBACE,mCACF,CAEA,eACE,kCACF,CAEA,UACE,kDACF,CAEA,OACE,mDACF,CAEA,MACE,iDACF,CAEA,QACE,wCACF,CAEA,OACE,uCACF,CAEA,SAQE,6BAA8B,CAP9B,6DAKC,CACD,2BAEF,CAEA,QACE,0BACF,CAEA,MACE,sCACF,CAGA,EACE,uCACF,CAEA,mBACE,0CACF,CAEA,oBAEE,gCAA2C,CAD3C,0BAEF,CAGA,OACE,oBAAoC,CAGpC,sBACF,CAEA,mBALE,yCAA0C,CAC1C,iDASF,CALA,YACE,gBAA8B,CAG9B,0BACF,CAGA,YACE,0CACF,CAEA,kBAEE,4BAA0C,CAD1C,sCAEF,CAGA,QAEE,eAAgB,CADhB,iBAEF,CAEA,cAQE,oBAAoC,CADpC,iBAAkB,CANlB,UAAW,CAKX,QAAS,CAFT,QAAS,CAFT,iBAAkB,CAClB,OAAQ,CAMR,8BAAgC,CAChC,+BAAmC,CALnC,OAMF,CAEA,qBAEE,YAAa,CADb,WAEF,CAGA,oBAEE,WAAY,CADZ,UAEF,CAEA,0BACE,oBAA+B,CAC/B,kBACF,CAEA,0BACE,oBAA8B,CAC9B,kBAAmB,CACnB,+BAAyB,CAAzB,uBACF,CAEA,gCACE,oBACF,CAGA,UAQE,+BAAgC,CAPhC,2EAKC,CACD,yBAA0B,CAE1B,iBACF,CAGA,eAGE,iBAAkB,CAFlB,2BAA0C,CAC1C,kBAEF,CAGA,WACE,wBAAyB,CAGzB,gBACF,CAGA,eAGE,6BAAoC,CAFpC,kDAA6D,CAC7D,4BAA6B,CAE7B,oBACF,CAGA,aACE,mDACF,CAEA,eACE,oDACF,CAEA,eACE,qDACF,CAGA,cAEE,sCAAwC,CADxC,SAEF,CAEA,0BAA6B,oBAAwB,CACrD,2BAA6B,mBAAuB,CACpD,2BAA6B,oBAAwB,CACrD,2BAA6B,mBAAuB,CACpD,2BAA6B,oBAAwB,CACrD,2BAA6B,mBAAuB,CACpD,2BAA6B,oBAAwB,CACrD,2BAA6B,mBAAuB,CAGpD,oBACE,yBACF,CAEA,oBACE,yBACF,CAGA,uCACE,iBAGE,kCAAqC,CACrC,qCAAuC,CACvC,mCACF,CACF","sources":["animations.css"],"sourcesContent":["/* Enhanced UI Animations and Effects */\n\n/* Smooth Fade In */\n@keyframes fadeIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n/* Slide In From Right */\n@keyframes slideInRight {\n from {\n opacity: 0;\n transform: translateX(30px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n/* Slide In From Left */\n@keyframes slideInLeft {\n from {\n opacity: 0;\n transform: translateX(-30px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n/* Scale In */\n@keyframes scaleIn {\n from {\n opacity: 0;\n transform: scale(0.9);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n/* Pulse Effect */\n@keyframes pulse {\n 0%, 100% {\n opacity: 1;\n transform: scale(1);\n }\n 50% {\n opacity: 0.6;\n transform: scale(1.15);\n }\n}\n\n/* Ping Effect (Ripple) */\n@keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n/* Bounce */\n@keyframes bounce {\n 0%, 100% {\n transform: translateY(0);\n }\n 50% {\n transform: translateY(-10px);\n }\n}\n\n/* Shimmer Loading */\n@keyframes shimmer {\n 0% {\n background-position: -1000px 0;\n }\n 100% {\n background-position: 1000px 0;\n }\n}\n\n/* Rotate */\n@keyframes rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Float */\n@keyframes float {\n 0%, 100% {\n transform: translateY(0px);\n }\n 50% {\n transform: translateY(-8px);\n }\n}\n\n/* Glow */\n@keyframes glow {\n 0%, 100% {\n box-shadow: 0 0 5px rgba(24, 144, 255, 0.5);\n }\n 50% {\n box-shadow: 0 0 20px rgba(24, 144, 255, 0.8), 0 0 30px rgba(24, 144, 255, 0.6);\n }\n}\n\n/* Apply Animations */\n.fade-in {\n animation: fadeIn 0.5s ease-out;\n}\n\n.slide-in-right {\n animation: slideInRight 0.5s ease-out;\n}\n\n.slide-in-left {\n animation: slideInLeft 0.5s ease-out;\n}\n\n.scale-in {\n animation: scaleIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);\n}\n\n.pulse {\n animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n\n.ping {\n animation: ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n\n.bounce {\n animation: bounce 1s ease-in-out infinite;\n}\n\n.float {\n animation: float 3s ease-in-out infinite;\n}\n\n.shimmer {\n background: linear-gradient(\n to right,\n rgba(255, 255, 255, 0) 0%,\n rgba(255, 255, 255, 0.3) 50%,\n rgba(255, 255, 255, 0) 100%\n );\n background-size: 1000px 100%;\n animation: shimmer 2s infinite;\n}\n\n.rotate {\n animation: rotate 1s linear;\n}\n\n.glow {\n animation: glow 2s ease-in-out infinite;\n}\n\n/* Smooth Transitions */\n* {\n -webkit-tap-highlight-color: transparent;\n}\n\n.smooth-transition {\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.smooth-hover:hover {\n transform: translateY(-2px);\n box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);\n}\n\n/* Glass Morphism */\n.glass {\n background: rgba(255, 255, 255, 0.1);\n backdrop-filter: blur(10px) saturate(180%);\n -webkit-backdrop-filter: blur(10px) saturate(180%);\n border: 1px solid rgba(255, 255, 255, 0.2);\n}\n\n.glass-dark {\n background: rgba(0, 0, 0, 0.2);\n backdrop-filter: blur(10px) saturate(180%);\n -webkit-backdrop-filter: blur(10px) saturate(180%);\n border: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n/* Card Hover Effects */\n.card-hover {\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.card-hover:hover {\n transform: translateY(-4px) scale(1.02);\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);\n}\n\n/* Button Ripple Effect */\n.ripple {\n position: relative;\n overflow: hidden;\n}\n\n.ripple::after {\n content: \"\";\n position: absolute;\n top: 50%;\n left: 50%;\n width: 0;\n height: 0;\n border-radius: 50%;\n background: rgba(255, 255, 255, 0.5);\n transform: translate(-50%, -50%);\n transition: width 0.6s, height 0.6s;\n}\n\n.ripple:active::after {\n width: 300px;\n height: 300px;\n}\n\n/* Smooth Scrollbar */\n::-webkit-scrollbar {\n width: 10px;\n height: 10px;\n}\n\n::-webkit-scrollbar-track {\n background: rgba(0, 0, 0, 0.05);\n border-radius: 10px;\n}\n\n::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.3);\n border-radius: 10px;\n transition: all 0.3s ease;\n}\n\n::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.5);\n}\n\n/* Loading Skeleton */\n.skeleton {\n background: linear-gradient(\n 90deg,\n rgba(200, 200, 200, 0.3) 25%,\n rgba(200, 200, 200, 0.5) 50%,\n rgba(200, 200, 200, 0.3) 75%\n );\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n border-radius: 8px;\n}\n\n/* Focus Visible for Accessibility */\n*:focus-visible {\n outline: 2px solid rgba(24, 144, 255, 0.6);\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n/* Prevent Text Selection on Interactive Elements */\n.no-select {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n/* Gradient Text */\n.gradient-text {\n background: linear-gradient(135deg, #1890FF 0%, #9254DE 100%);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n background-clip: text;\n}\n\n/* Enhanced Shadow */\n.shadow-soft {\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 4px 16px rgba(0, 0, 0, 0.08);\n}\n\n.shadow-medium {\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1), 0 8px 24px rgba(0, 0, 0, 0.1);\n}\n\n.shadow-strong {\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15), 0 16px 48px rgba(0, 0, 0, 0.15);\n}\n\n/* Stagger Animation for Lists */\n.stagger-item {\n opacity: 0;\n animation: fadeIn 0.5s ease-out forwards;\n}\n\n.stagger-item:nth-child(1) { animation-delay: 0.05s; }\n.stagger-item:nth-child(2) { animation-delay: 0.1s; }\n.stagger-item:nth-child(3) { animation-delay: 0.15s; }\n.stagger-item:nth-child(4) { animation-delay: 0.2s; }\n.stagger-item:nth-child(5) { animation-delay: 0.25s; }\n.stagger-item:nth-child(6) { animation-delay: 0.3s; }\n.stagger-item:nth-child(7) { animation-delay: 0.35s; }\n.stagger-item:nth-child(8) { animation-delay: 0.4s; }\n\n/* Micro-interactions */\n.micro-bounce:hover {\n animation: bounce 0.5s ease;\n}\n\n.micro-rotate:hover {\n animation: rotate 0.5s ease;\n}\n\n/* Accessibility */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n"],"names":[],"ignoreList":[],"sourceRoot":""}