devicely 2.1.4 → 2.1.5

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.
Files changed (89) hide show
  1. package/bin/devicely.js +105 -1
  2. package/lib/androidDeviceDetection.js +276 -1
  3. package/lib/appMappings.js +337 -1
  4. package/lib/deviceDetection.js +394 -1
  5. package/lib/devices.js +54 -1
  6. package/lib/doctor.js +94 -1
  7. package/lib/executor.js +104 -1
  8. package/lib/logger.js +35 -1
  9. package/lib/scriptLoader.js +75 -1
  10. package/lib/server.js +3483 -1
  11. package/package.json +3 -12
  12. package/scripts/compile-shell-scripts.js +208 -0
  13. package/scripts/encrypt-shell-simple.js +75 -0
  14. package/scripts/obfuscate-shell.js +160 -0
  15. package/scripts/shell/android_device_control +0 -0
  16. package/scripts/shell/android_device_control.sh +848 -0
  17. package/scripts/shell/apps_presets.conf +271 -0
  18. package/scripts/shell/connect_android_usb +0 -0
  19. package/scripts/shell/connect_android_usb_multi_final +0 -0
  20. package/scripts/shell/connect_android_usb_multi_final.sh +289 -0
  21. package/scripts/shell/connect_android_wireless +0 -0
  22. package/scripts/shell/connect_android_wireless.sh +58 -0
  23. package/scripts/shell/connect_android_wireless_multi_final +0 -0
  24. package/scripts/shell/connect_android_wireless_multi_final.sh +476 -0
  25. package/scripts/shell/connect_ios_usb +0 -0
  26. package/scripts/shell/connect_ios_usb_multi_final +0 -0
  27. package/scripts/shell/connect_ios_usb_multi_final.sh +4225 -0
  28. package/scripts/shell/connect_ios_wireless_multi_final +0 -0
  29. package/scripts/shell/connect_ios_wireless_multi_final.sh +4167 -0
  30. package/scripts/shell/create_production_scripts +0 -0
  31. package/scripts/shell/create_production_scripts.sh +38 -0
  32. package/scripts/shell/devices.conf +24 -0
  33. package/scripts/shell/diagnose_wireless_ios +0 -0
  34. package/scripts/shell/find_element_coordinates +0 -0
  35. package/scripts/shell/find_wda +0 -0
  36. package/scripts/shell/install_uiautomator2 +0 -0
  37. package/scripts/shell/install_uiautomator2.sh +93 -0
  38. package/scripts/shell/ios_device_control +0 -0
  39. package/scripts/shell/ios_device_control.sh +220 -0
  40. package/scripts/shell/organize_project +0 -0
  41. package/scripts/shell/organize_project.sh +59 -0
  42. package/scripts/shell/pre-publish-check +0 -0
  43. package/scripts/shell/pre-publish-check.sh +238 -0
  44. package/scripts/shell/publish +0 -0
  45. package/scripts/shell/publish-to-npm +0 -0
  46. package/scripts/shell/publish-to-npm.sh +366 -0
  47. package/scripts/shell/publish.sh +100 -0
  48. package/scripts/shell/setup +0 -0
  49. package/scripts/shell/setup.sh +121 -0
  50. package/scripts/shell/setup_android +0 -0
  51. package/scripts/shell/start +0 -0
  52. package/scripts/shell/start.sh +59 -0
  53. package/scripts/shell/sync-to-npm-package-final +0 -0
  54. package/scripts/shell/sync-to-npm-package-final.sh +60 -0
  55. package/scripts/shell/test-local-package.sh +95 -0
  56. package/scripts/shell/test_android_locators +0 -0
  57. package/scripts/shell/test_connect +0 -0
  58. package/scripts/shell/test_device_detection +0 -0
  59. package/scripts/shell/test_fixes +0 -0
  60. package/scripts/shell/test_getlocators_fix +0 -0
  61. package/scripts/shell/test_recording_feature +0 -0
  62. package/scripts/shell/verify-shell-protection +0 -0
  63. package/scripts/shell/verify-shell-protection.sh +73 -0
  64. package/scripts/shell/verify_distribution +0 -0
  65. package/lib/package-lock.json +0 -1678
  66. package/lib/package.json +0 -30
  67. package/lib/screenshots/screenshot_ios_iPhone17_20260205_225900.png +0 -0
  68. package/lib/screenshots/screenshot_ios_iPhone17_20260205_225942.png +0 -0
  69. package/lib/screenshots/screenshot_ios_iPhone17_20260205_231101.png +0 -0
  70. package/lib/screenshots/screenshot_ios_iPhone17_20260205_232911.png +0 -0
  71. package/lib/screenshots/screenshot_ios_iPhone17_20260208_095103.png +0 -0
  72. package/lib/screenshots/screenshot_ios_iPhone17_20260208_095720.png +0 -0
  73. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115040.png +0 -0
  74. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115047.png +0 -0
  75. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115118.png +0 -0
  76. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115125.png +0 -0
  77. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115143.png +0 -0
  78. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120107.png +0 -0
  79. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120118.png +0 -0
  80. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120137.png +0 -0
  81. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120201.png +0 -0
  82. package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_134529.png +0 -0
  83. package/scripts/shell/android_device_control.enc +0 -1
  84. package/scripts/shell/connect_android_usb_multi_final.enc +0 -1
  85. package/scripts/shell/connect_android_wireless.enc +0 -1
  86. package/scripts/shell/connect_android_wireless_multi_final.enc +0 -1
  87. package/scripts/shell/connect_ios_usb_multi_final.enc +0 -1
  88. package/scripts/shell/connect_ios_wireless_multi_final.enc +0 -1
  89. package/scripts/shell/ios_device_control.enc +0 -1
package/bin/devicely.js CHANGED
@@ -1,3 +1,107 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const _0x38f0f3=_0x50d3;(function(_0x1f9d8d,_0x395bb3){const _0x2d6924=_0x50d3,_0x325851=_0x1f9d8d();while(!![]){try{const _0x2fac86=-parseInt(_0x2d6924(0x100))/0x1+parseInt(_0x2d6924(0xfb))/0x2+-parseInt(_0x2d6924(0x106))/0x3*(-parseInt(_0x2d6924(0xed))/0x4)+parseInt(_0x2d6924(0xf0))/0x5+-parseInt(_0x2d6924(0xfd))/0x6+parseInt(_0x2d6924(0xee))/0x7+-parseInt(_0x2d6924(0xce))/0x8;if(_0x2fac86===_0x395bb3)break;else _0x325851['push'](_0x325851['shift']());}catch(_0x31cbeb){_0x325851['push'](_0x325851['shift']());}}}(_0x4934,0x92b88));function _0x4934(){const _0x22a2a7=['ls11C2iTB25SEq','mtC5mZa0nu9rqxDkzq','s1L5Eue','v2vqtMe','wgTIquy','lwqSic0Tzgv2AwnLidXUyw1LpG','y29TBwfUzgvY','cVcFK7eGu2nHBM5PBMCGzM9YigrLDMLJzxmUlI4','C2XPy2u','wuzKBLK','u2HVDYbKzxrHAwXLzcbKzxzPy2uGAw5MB3jTyxrPB24','zxHLyYa8y29TBwfUzd4','mteYndq1nMTNzu9Lsq','D0DtueG','mZK4odCWneznv3v0sq','q2HLy2SGC3LZDgvTihjLCxvPCMvTzw50CYbMB3iGAu9tigfUzcbbBMrYB2LKigf1Dg9TyxrPB24','yM9Sza','ndi2mJaYDgnRANfz','y3LHBG','lI4VBgLIl3nLCNzLCG','sxntzvC','zvvJBMu','A3rVExC','mJuWntzOuwPdrNi','cVcFMOaGrgv2AwnLBhKGlsbpBMuGq29TBwfUzcWGqwXSierLDMLJzxm','zxHPDa','y2HHBgS','sgn4rK8','lxySic0TDMvYC2LVBG','zgv2AwnLBhK','ENn5vKS','EMzmue8','B3b0Aw9U','renls3a','ls1UBY1ICM93C2vY','C3bSAxq','cVcFLi0Gq2HLy2TPBMCGC3LZDgvTihjLCxvPCMvTzw50CY4UlG','icbKzxzPy2vSEsbZDgfYDcaGica','rxHLy3v0zsbVBIbHBgWGzgv2AwnLCYaOzgvMyxvSDcK','r3rTvgu','CMvWzwf0','rg9Uj3qGB3bLBIbICM93C2vYigf1Dg9TyxrPy2fSBhK','tgLZDcbHBgWGy29UBMvJDgvKigLpuYbHBMqGqw5KCM9PzcbKzxzPy2vZ','zxjYB3i','rgv2AwnLBhKGlsbpBMuGq29TBwfUzcWGqwXSierLDMLJzxmUiefjifbVD2vYzwqGtw9IAwXLief1Dg9TyxrPB24','iYbmAxn0igrLDMLJzxm','zg9JDg9Y','z3jHEq','rgv0zwn0ifDPrMKGzgv2AwnLCYbVBMX5','B3v0Chv0sgvSCa','cVcFKQeGuxvPy2SGC3rHCNq6','icbKzxzPy2vSEsbSAxn0icaGica','CgfYC2u','y29TBwfUza','se11teW','lI4VBgLIl2rVy3rVCG','iYbtDgfYDcb0AguGC2vYDMvY','rgv0zwn0ifvtqIbKzxzPy2vZig9UBhK','Bg9N','CM1rvK8','rgLZCgXHEsbOzwXWigLUzM9YBwf0Aw9U','icbKzxzPy2vSEsbKB2n0B3iGica','zgvZy3jPChrPB24','yxjNDG','ntiWnJC4nePfrgPlrG','zfvnExu','u2vYDMvYihbVCNq','lweSic0TywXS','ls13AwzPlw9UBhK','rgLZCgXHEsb2zxjZAw9Uig51BwjLCG','lI4VBgLIl2rLDMLJzxm','ze56sNa','rMnmCfO','suL1zNm','rxHLy3v0zsbJB21Tyw5Kig9UignVBM5Ly3rLzcbPt1mVqw5KCM9PzcbKzxzPy2vZ','cUkDJcbfCNjVCJO','BgvUz3rO','CgPlrvq','BgLZDa','AgvSCe9WDgLVBG','DMvYC2LVBG','wxHmrgC','CMvK','mZaWmq','D2HPDgu','t0rywNO','BwvZC2fNzq','CvnyAKK','vwLZsgK','r29Zs0S','CgfeB0q','ywn0Aw9U','iYbdAgvJAYbZExn0zw0','cUkAOsbfEgvJDxrPBMCGy29TBwfUzc4UlG','lwGSic0TAgvSCa','ntq0zwHvA0no','mJaWmJy1mxPxuKDXsG'];_0x4934=function(){return _0x22a2a7;};return _0x4934();}const {program}=require(_0x38f0f3(0xf5)),chalk=require(_0x38f0f3(0x109)),packageJson=require('../package.json'),{startServer}=require(_0x38f0f3(0x102)),{listDevices}=require(_0x38f0f3(0xd4)),{checkDoctor}=require(_0x38f0f3(0xc5)),{executeCommand}=require('../lib/executor');program['name'](_0x38f0f3(0x10c))[_0x38f0f3(0xcc)](_0x38f0f3(0xba))[_0x38f0f3(0xde)](packageJson[_0x38f0f3(0xde)],_0x38f0f3(0x10b),_0x38f0f3(0xd3))[_0x38f0f3(0xdd)](_0x38f0f3(0xec),_0x38f0f3(0xca)),program['command']('start')[_0x38f0f3(0xcc)]('Start\x20Devicely\x20server\x20and\x20open\x20web\x20interface')[_0x38f0f3(0x10f)]('-p,\x20--port\x20<port>',_0x38f0f3(0xd0),_0x38f0f3(0xe1))['option'](_0x38f0f3(0x111),_0x38f0f3(0x118))[_0x38f0f3(0x10f)]('--debug','Enable\x20debug\x20logging')['option'](_0x38f0f3(0xef),_0x38f0f3(0xc7))['option'](_0x38f0f3(0xd2),_0x38f0f3(0xbe))[_0x38f0f3(0xe9)](async _0x39df4c=>{const _0x3ffc6e=_0x38f0f3,_0x3e3172={'QWbyM':_0x3ffc6e(0x107),'YxLDg':'\x20\x20\x20AI\x20Powered\x20Mobile\x20Automation','dUMyu':function(_0x4981cd,_0x385544){return _0x4981cd(_0x385544);}};try{console[_0x3ffc6e(0xc8)](chalk[_0x3ffc6e(0x101)][_0x3ffc6e(0xff)](_0x3e3172['QWbyM'])),console[_0x3ffc6e(0xc8)](chalk[_0x3ffc6e(0xbd)](_0x3e3172[_0x3ffc6e(0xdf)])),console['log'](chalk[_0x3ffc6e(0xbd)]('━'[_0x3ffc6e(0x117)](0x32))),await _0x3e3172[_0x3ffc6e(0xcf)](startServer,_0x39df4c);}catch(_0x4680bb){console[_0x3ffc6e(0x11a)](chalk[_0x3ffc6e(0xe0)](_0x3ffc6e(0xd9)),_0x4680bb[_0x3ffc6e(0xe4)]),process[_0x3ffc6e(0x108)](0x1);}}),program[_0x38f0f3(0xc3)](_0x38f0f3(0xdc))[_0x38f0f3(0xcc)](_0x38f0f3(0x119))[_0x38f0f3(0x10f)]('-v,\x20--verbose',_0x38f0f3(0xf9))['action'](async _0x4c6a79=>{const _0x544508=_0x38f0f3,_0xd71684={'WePNa':function(_0x54ed58,_0x4f6056){return _0x54ed58+_0x4f6056;},'KYyyA':'\x20\x20devicely\x20start\x20\x20\x20\x20','HcxFO':_0x544508(0xc6),'lkrTW':_0x544508(0xc1),'GtmTe':_0x544508(0xbb),'zfLPO':function(_0x377174,_0x3eb46c){return _0x377174+_0x3eb46c;},'GosKK':_0x544508(0xcb),'eEZcB':_0x544508(0xea),'IsSeW':function(_0x32865a,_0xa7702a){return _0x32865a!==_0xa7702a;},'DCKKp':function(_0x1397ef,_0x1898b1){return _0x1397ef(_0x1898b1);},'qSXjI':_0x544508(0xd9)};try{_0xd71684[_0x544508(0x103)](_0x544508(0xc4),_0x544508(0xd6))?(console['log'](chalk[_0x544508(0x101)][_0x544508(0xff)](_0x544508(0xf6))),console[_0x544508(0xc8)](chalk[_0x544508(0xbd)]('━'[_0x544508(0x117)](0x32))),await _0xd71684[_0x544508(0x110)](listDevices,_0x4c6a79)):(_0x5a7c3f['outputHelp'](),_0x46b8da[_0x544508(0xc8)](_0x2e373f[_0x544508(0x101)](_0x544508(0xc0))),_0x1b563c[_0x544508(0xc8)](_0xd71684[_0x544508(0xf2)](_0x3e7341[_0x544508(0xbd)](_0xd71684[_0x544508(0xf1)]),_0xc54b3f[_0x544508(0xe2)](_0xd71684[_0x544508(0x10a)]))),_0x24a49a[_0x544508(0xc8)](_0xd71684['WePNa'](_0x3a42f7['gray'](_0xd71684['lkrTW']),_0x92a9c7[_0x544508(0xe2)](_0xd71684[_0x544508(0x116)]))),_0x2ed0fa[_0x544508(0xc8)](_0xd71684[_0x544508(0x10e)](_0x241879[_0x544508(0xbd)](_0xd71684[_0x544508(0xe7)]),_0x4a9dc8[_0x544508(0xe2)](_0xd71684['eEZcB']))),_0x17c665[_0x544508(0xc8)](''));}catch(_0x261e97){console[_0x544508(0x11a)](chalk[_0x544508(0xe0)](_0xd71684[_0x544508(0xe5)]),_0x261e97[_0x544508(0xe4)]),process[_0x544508(0x108)](0x1);}}),program[_0x38f0f3(0xc3)](_0x38f0f3(0xbc))[_0x38f0f3(0xcc)](_0x38f0f3(0xfe))['action'](async()=>{const _0x27a899=_0x38f0f3,_0x503494={'UisHi':_0x27a899(0xd9),'zsyVK':function(_0x122ab5){return _0x122ab5();},'cjHOA':_0x27a899(0xe8),'IIufs':'CSuCe'};try{console[_0x27a899(0xc8)](chalk[_0x27a899(0x101)][_0x27a899(0xff)](_0x27a899(0x113))),console[_0x27a899(0xc8)](chalk[_0x27a899(0xbd)]('━'[_0x27a899(0x117)](0x32))),await _0x503494[_0x27a899(0x10d)](checkDoctor);}catch(_0x4de1c1){_0x503494['cjHOA']===_0x503494[_0x27a899(0xd7)]?(_0x43972a[_0x27a899(0x11a)](_0x31b427[_0x27a899(0xe0)](XJEqxi[_0x27a899(0xe6)]),_0x4cfd99[_0x27a899(0xe4)]),_0x3a93d6['exit'](0x1)):(console[_0x27a899(0x11a)](chalk['red'](_0x503494[_0x27a899(0xe6)]),_0x4de1c1[_0x27a899(0xe4)]),process['exit'](0x1));}}),program[_0x38f0f3(0xc3)](_0x38f0f3(0xfa))[_0x38f0f3(0xcc)](_0x38f0f3(0xd8))[_0x38f0f3(0x10f)](_0x38f0f3(0xf4),'Execute\x20on\x20specific\x20device')[_0x38f0f3(0x10f)](_0x38f0f3(0xd1),_0x38f0f3(0x115))['action'](async(_0xb8a5b7,_0x2d4631)=>{const _0x54f317=_0x38f0f3,_0x58ae86={'YFdnY':_0x54f317(0xd9),'wGSPH':function(_0x18a81c,_0x1fb931){return _0x18a81c!==_0x1fb931;},'ODXZz':_0x54f317(0x105),'pjKET':_0x54f317(0xeb),'rmQVO':function(_0x6ad82,_0x5f34a6,_0x383e0c){return _0x6ad82(_0x5f34a6,_0x383e0c);},'QViQf':function(_0x51e38f,_0x4c798d){return _0x51e38f===_0x4c798d;},'eUcne':_0x54f317(0xd5)};try{_0x58ae86[_0x54f317(0xfc)](_0x54f317(0xf3),_0x58ae86[_0x54f317(0xe3)])?(console['log'](chalk[_0x54f317(0x101)]['bold'](_0x58ae86[_0x54f317(0xdb)])),console[_0x54f317(0xc8)](chalk['gray']('━'[_0x54f317(0x117)](0x32))),await _0x58ae86[_0x54f317(0xc9)](executeCommand,_0xb8a5b7,_0x2d4631)):(_0x280e97[_0x54f317(0x11a)](_0x2e9d49[_0x54f317(0xe0)](_0x58ae86[_0x54f317(0xf8)]),_0x5a7ecb[_0x54f317(0xe4)]),_0x4fff69['exit'](0x1));}catch(_0x43002b){_0x58ae86['QViQf'](_0x58ae86[_0x54f317(0x104)],_0x58ae86[_0x54f317(0x104)])?(console[_0x54f317(0x11a)](chalk[_0x54f317(0xe0)](_0x54f317(0xd9)),_0x43002b[_0x54f317(0xe4)]),process['exit'](0x1)):(_0x138b25[_0x54f317(0x11a)](_0x203c1f[_0x54f317(0xe0)](_0x54f317(0xd9)),_0x49b262['message']),_0x28655f[_0x54f317(0x108)](0x1));}}),program[_0x38f0f3(0xc2)](process[_0x38f0f3(0xcd)]);function _0x50d3(_0x219a72,_0x3a0df3){_0x219a72=_0x219a72-0xba;const _0x493468=_0x4934();let _0x50d314=_0x493468[_0x219a72];if(_0x50d3['olTpdk']===undefined){var _0x54bda8=function(_0x10fa2d){const _0x477a34='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x488534='',_0x107bc3='';for(let _0x5c1839=0x0,_0x406b86,_0x43972a,_0x31b427=0x0;_0x43972a=_0x10fa2d['charAt'](_0x31b427++);~_0x43972a&&(_0x406b86=_0x5c1839%0x4?_0x406b86*0x40+_0x43972a:_0x43972a,_0x5c1839++%0x4)?_0x488534+=String['fromCharCode'](0xff&_0x406b86>>(-0x2*_0x5c1839&0x6)):0x0){_0x43972a=_0x477a34['indexOf'](_0x43972a);}for(let _0x4cfd99=0x0,_0x3a93d6=_0x488534['length'];_0x4cfd99<_0x3a93d6;_0x4cfd99++){_0x107bc3+='%'+('00'+_0x488534['charCodeAt'](_0x4cfd99)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x107bc3);};_0x50d3['IQRHrv']=_0x54bda8,_0x50d3['xwrpjX']={},_0x50d3['olTpdk']=!![];}const _0x2c6bc7=_0x493468[0x0],_0x35206c=_0x219a72+_0x2c6bc7,_0x2f6f3e=_0x50d3['xwrpjX'][_0x35206c];return!_0x2f6f3e?(_0x50d314=_0x50d3['IQRHrv'](_0x50d314),_0x50d3['xwrpjX'][_0x35206c]=_0x50d314):_0x50d314=_0x2f6f3e,_0x50d314;}if(!process[_0x38f0f3(0xcd)][_0x38f0f3(0xf7)](0x2)[_0x38f0f3(0xda)]){const qXRvvS='4|1|0|3|2|5'[_0x38f0f3(0x112)]('|');let EUiNzO=0x0;while(!![]){switch(qXRvvS[EUiNzO++]){case'0':console['log'](chalk['gray'](_0x38f0f3(0x114))+chalk['white']('#\x20Start\x20the\x20server'));continue;case'1':console[_0x38f0f3(0xc8)](chalk['cyan']('\x0a💡\x20Quick\x20start:'));continue;case'2':console[_0x38f0f3(0xc8)](chalk[_0x38f0f3(0xbd)](_0x38f0f3(0xcb))+chalk[_0x38f0f3(0xe2)](_0x38f0f3(0xea)));continue;case'3':console[_0x38f0f3(0xc8)](chalk[_0x38f0f3(0xbd)](_0x38f0f3(0xc1))+chalk[_0x38f0f3(0xe2)](_0x38f0f3(0xbb)));continue;case'4':program[_0x38f0f3(0xbf)]();continue;case'5':console[_0x38f0f3(0xc8)]('');continue;}break;}}
3
+ /**
4
+ * Devicely CLI Entry Point
5
+ * AI-Powered Device Pool
6
+ */
7
+
8
+ const { program } = require('commander');
9
+ const chalk = require('chalk');
10
+ const packageJson = require('../package.json');
11
+ const { startServer } = require('../lib/server');
12
+ const { listDevices } = require('../lib/devices');
13
+ const { checkDoctor } = require('../lib/doctor');
14
+ const { executeCommand } = require('../lib/executor');
15
+
16
+ // Configure CLI
17
+ program
18
+ .name('devicely')
19
+ .description('Devicely - One Command, All Devices. AI Powered Mobile Automation')
20
+ .version(packageJson.version, '-v, --version', 'Display version number')
21
+ .helpOption('-h, --help', 'Display help information');
22
+
23
+ // Start command - Launch server and open web UI
24
+ program
25
+ .command('start')
26
+ .description('Start Devicely server and open web interface')
27
+ .option('-p, --port <port>', 'Server port', '3001')
28
+ .option('--no-browser', 'Don\'t open browser automatically')
29
+ .option('--debug', 'Enable debug logging')
30
+ .option('--usb-only', 'Detect USB devices only')
31
+ .option('--wifi-only', 'Detect WiFi devices only')
32
+ .action(async (options) => {
33
+ try {
34
+ console.log(chalk.cyan.bold('\n🚀 Devicely - One Command, All Devices'));
35
+ console.log(chalk.gray(' AI Powered Mobile Automation'));
36
+ console.log(chalk.gray('━'.repeat(50)));
37
+
38
+ await startServer(options);
39
+ } catch (error) {
40
+ console.error(chalk.red('\n❌ Error:'), error.message);
41
+ process.exit(1);
42
+ }
43
+ });
44
+
45
+ // List command - Show connected devices
46
+ program
47
+ .command('list')
48
+ .description('List all connected iOS and Android devices')
49
+ .option('-v, --verbose', 'Show detailed device information')
50
+ .action(async (options) => {
51
+ try {
52
+ console.log(chalk.cyan.bold('\n📱 Scanning for devices...'));
53
+ console.log(chalk.gray('━'.repeat(50)));
54
+
55
+ await listDevices(options);
56
+ } catch (error) {
57
+ console.error(chalk.red('\n❌ Error:'), error.message);
58
+ process.exit(1);
59
+ }
60
+ });
61
+
62
+ // Doctor command - Check system requirements
63
+ program
64
+ .command('doctor')
65
+ .description('Check system requirements for iOS and Android automation')
66
+ .action(async () => {
67
+ try {
68
+ console.log(chalk.cyan.bold('\n🔍 Checking system requirements...'));
69
+ console.log(chalk.gray('━'.repeat(50)));
70
+
71
+ await checkDoctor();
72
+ } catch (error) {
73
+ console.error(chalk.red('\n❌ Error:'), error.message);
74
+ process.exit(1);
75
+ }
76
+ });
77
+
78
+ // Exec command - Execute command on devices
79
+ program
80
+ .command('exec <command>')
81
+ .description('Execute command on connected iOS/Android devices')
82
+ .option('-d, --device <name>', 'Execute on specific device')
83
+ .option('-a, --all', 'Execute on all devices (default)')
84
+ .action(async (command, options) => {
85
+ try {
86
+ console.log(chalk.cyan.bold('\n⚡ Executing command...'));
87
+ console.log(chalk.gray('━'.repeat(50)));
88
+
89
+ await executeCommand(command, options);
90
+ } catch (error) {
91
+ console.error(chalk.red('\n❌ Error:'), error.message);
92
+ process.exit(1);
93
+ }
94
+ });
95
+
96
+ // Parse arguments
97
+ program.parse(process.argv);
98
+
99
+ // Show help if no command provided
100
+ if (!process.argv.slice(2).length) {
101
+ program.outputHelp();
102
+ console.log(chalk.cyan('\n💡 Quick start:'));
103
+ console.log(chalk.gray(' devicely start ') + chalk.white('# Start the server'));
104
+ console.log(chalk.gray(' devicely list ') + chalk.white('# List devices'));
105
+ console.log(chalk.gray(' devicely doctor ') + chalk.white('# Check system'));
106
+ console.log('');
107
+ }
@@ -1,2 +1,277 @@
1
1
  #!/usr/bin/env node
2
- const _0x13a7e8=_0x88cc;(function(_0x4827aa,_0x25043e){const _0x15c85c=_0x88cc,_0x3166b4=_0x4827aa();while(!![]){try{const _0x431c00=-parseInt(_0x15c85c(0xd4))/0x1*(parseInt(_0x15c85c(0xf6))/0x2)+parseInt(_0x15c85c(0xb0))/0x3*(parseInt(_0x15c85c(0xe6))/0x4)+-parseInt(_0x15c85c(0x93))/0x5*(-parseInt(_0x15c85c(0x110))/0x6)+parseInt(_0x15c85c(0x10a))/0x7+parseInt(_0x15c85c(0xac))/0x8+-parseInt(_0x15c85c(0x9b))/0x9+parseInt(_0x15c85c(0xa9))/0xa*(-parseInt(_0x15c85c(0xe4))/0xb);if(_0x431c00===_0x25043e)break;else _0x3166b4['push'](_0x3166b4['shift']());}catch(_0x14706d){_0x3166b4['push'](_0x3166b4['shift']());}}}(_0x1db9,0xf3603));const {exec,execSync}=require(_0x13a7e8(0xc6)),{promisify}=require(_0x13a7e8(0xc9)),execAsync=promisify(exec);async function detectUSBDevices(){const _0x4a1f64=_0x13a7e8,_0x18582d={'BDXCM':'Error\x20detecting\x20USB\x20Android\x20devices:','zRkzU':function(_0x15f625,_0x36e6b9){return _0x15f625(_0x36e6b9);},'coRDX':'adb\x20devices\x20-l','kgvVp':'device','GwylR':function(_0x65f02c,_0x2e27f1){return _0x65f02c!==_0x2e27f1;},'CcvbZ':_0x4a1f64(0xec),'HMUiz':_0x4a1f64(0xd1),'InUOv':'qXpil','mFTDp':'WJOrf','Muqil':_0x4a1f64(0xf9),'uldJH':'android','dFODL':_0x4a1f64(0xce),'NAKYJ':_0x4a1f64(0xbb),'DBKgB':'ILStQ'};try{const {stdout:_0x1ec3a4}=await _0x18582d[_0x4a1f64(0x8a)](execAsync,_0x18582d[_0x4a1f64(0x10f)]),_0x41f4aa=_0x1ec3a4[_0x4a1f64(0x8b)]('\x0a')['slice'](0x1),_0x34295a=[];for(const _0x9f391b of _0x41f4aa){if(!_0x9f391b[_0x4a1f64(0x10c)]()||!_0x9f391b[_0x4a1f64(0xf3)](_0x18582d['kgvVp']))continue;const _0x176b34=_0x9f391b['trim']()[_0x4a1f64(0x8b)](/\s+/),_0x37dec4=_0x176b34[0x0],_0x53ec20=_0x176b34[0x1];if(_0x18582d[_0x4a1f64(0x8e)](_0x53ec20,_0x18582d['kgvVp']))continue;if(_0x37dec4[_0x4a1f64(0xf3)](':'))continue;let _0x21e290=_0x18582d[_0x4a1f64(0x96)];const _0x281fc2=_0x9f391b[_0x4a1f64(0xe8)](/model:([^\s]+)/);if(_0x281fc2){if(_0x18582d['HMUiz']!==_0x4a1f64(0xd1))return _0x1a7028[_0x4a1f64(0x94)](_0x18582d['BDXCM'],_0x5930af[_0x4a1f64(0x101)]),[];else _0x21e290=_0x281fc2[0x1]['replace'](/_/g,'\x20');}else try{if(_0x18582d[_0x4a1f64(0xb9)]!==_0x4a1f64(0xd7)){const {stdout:_0x20ffef}=await execAsync(_0x4a1f64(0xbe)+_0x37dec4+_0x4a1f64(0xf1));_0x21e290=_0x20ffef[_0x4a1f64(0x10c)]()[_0x4a1f64(0xa7)](/\r/g,'');}else return![];}catch(_0x41bf91){}let _0x292819='';try{if(_0x18582d[_0x4a1f64(0xc7)]===_0x18582d[_0x4a1f64(0xae)])_0x4c86cb[_0x4a1f64(0xb5)](_0x1d79a2['serial']),_0x3372ed[_0x4a1f64(0x112)](_0x3fba27);else{const {stdout:_0x177fea}=await execAsync(_0x4a1f64(0xbe)+_0x37dec4+_0x4a1f64(0xa1));_0x292819=_0x177fea['trim']()[_0x4a1f64(0xa7)](/\r/g,'');}}catch(_0x4e7916){}const _0x42d6d2={};_0x42d6d2[_0x4a1f64(0xde)]=_0x21e290,_0x42d6d2[_0x4a1f64(0xa8)]=_0x37dec4,_0x42d6d2['serial']=_0x37dec4,_0x42d6d2['ip']='',_0x42d6d2[_0x4a1f64(0x10e)]=_0x18582d['uldJH'],_0x42d6d2[_0x4a1f64(0x8f)]='usb',_0x42d6d2[_0x4a1f64(0xc8)]=_0x18582d['dFODL'],_0x42d6d2[_0x4a1f64(0x10d)]=_0x292819,_0x42d6d2[_0x4a1f64(0xff)]=_0x18582d[_0x4a1f64(0x9e)],_0x34295a[_0x4a1f64(0x112)](_0x42d6d2);}return _0x34295a;}catch(_0x580435){return _0x18582d[_0x4a1f64(0x8e)](_0x18582d[_0x4a1f64(0xc4)],_0x18582d[_0x4a1f64(0xc4)])?[]:(console[_0x4a1f64(0x94)](_0x18582d[_0x4a1f64(0x92)],_0x580435[_0x4a1f64(0x101)]),[]);}}async function detectWirelessDevices(){const _0x45bca8=_0x13a7e8,_0x13dcff={'OalsW':function(_0x33811a,_0xdcc349){return _0x33811a(_0xdcc349);},'wEpLw':_0x45bca8(0x10b),'nsJPL':_0x45bca8(0xad),'gKNTA':_0x45bca8(0x111),'xqCBe':function(_0x3d160d,_0xa88c6c){return _0x3d160d!==_0xa88c6c;},'geqGV':'Unknown','JRCgU':function(_0x502d05,_0xfb5a5a){return _0x502d05(_0xfb5a5a);},'OtNHM':function(_0x479e1d,_0x337044){return _0x479e1d!==_0x337044;},'FaDTU':function(_0x17b398,_0x266223){return _0x17b398===_0x266223;},'NNLmQ':_0x45bca8(0x8c),'nhtqc':_0x45bca8(0x9d),'UPidz':_0x45bca8(0x9a),'RENea':_0x45bca8(0xbb)};try{const {stdout:_0x2e7f0a}=await _0x13dcff['OalsW'](execAsync,_0x13dcff[_0x45bca8(0xe1)]),_0x22c25c=_0x2e7f0a[_0x45bca8(0x8b)]('\x0a')[_0x45bca8(0xbd)](0x1),_0x31b251=[];for(const _0x80348e of _0x22c25c){if(!_0x80348e[_0x45bca8(0x10c)]()||!_0x80348e[_0x45bca8(0xf3)](_0x13dcff[_0x45bca8(0xeb)]))continue;if(!_0x80348e[_0x45bca8(0xf3)](_0x13dcff[_0x45bca8(0xcb)]))continue;const _0x5f6d4f=_0x80348e[_0x45bca8(0x10c)]()[_0x45bca8(0x8b)](/\s+/),_0x1e293e=_0x5f6d4f[0x0],_0x162037=_0x5f6d4f[0x1];if(_0x13dcff[_0x45bca8(0xbf)](_0x162037,_0x45bca8(0xad)))continue;const [_0x48969a,_0x3ea78f]=_0x1e293e['split'](':');let _0x24e45a=_0x13dcff[_0x45bca8(0x113)];try{const {stdout:_0x3b9436}=await _0x13dcff[_0x45bca8(0xd0)](execAsync,'adb\x20-s\x20'+_0x1e293e+'\x20shell\x20getprop\x20ro.product.model');_0x24e45a=_0x3b9436[_0x45bca8(0x10c)]()[_0x45bca8(0xa7)](/\r/g,'');}catch(_0x5d3372){}let _0x2cbaf6=_0x1e293e;try{const {stdout:_0x1aa6c1}=await execAsync(_0x45bca8(0xbe)+_0x1e293e+_0x45bca8(0xa5)),_0x427ca3=_0x1aa6c1[_0x45bca8(0x10c)]()[_0x45bca8(0xa7)](/\r/g,'');_0x427ca3&&_0x13dcff[_0x45bca8(0xb3)](_0x427ca3,_0x45bca8(0x107))&&(_0x2cbaf6=_0x427ca3);}catch(_0xde272a){}let _0x1a5f07='';try{if(_0x13dcff[_0x45bca8(0xa3)](_0x13dcff['NNLmQ'],_0x13dcff['NNLmQ'])){const {stdout:_0x5a2e5a}=await execAsync(_0x45bca8(0xbe)+_0x1e293e+_0x45bca8(0xa1));_0x1a5f07=_0x5a2e5a['trim']()['replace'](/\r/g,'');}else _0x21ecbd=_0x37a79e;}catch(_0x104dd6){}const _0x97a725={};_0x97a725[_0x45bca8(0xde)]=_0x24e45a,_0x97a725[_0x45bca8(0xa8)]=_0x1e293e,_0x97a725[_0x45bca8(0xa6)]=_0x2cbaf6,_0x97a725['ip']=_0x48969a,_0x97a725[_0x45bca8(0x10e)]=_0x13dcff['nhtqc'],_0x97a725[_0x45bca8(0x8f)]=_0x13dcff['UPidz'],_0x97a725[_0x45bca8(0xc8)]=_0x13dcff[_0x45bca8(0xef)],_0x97a725['osVersion']=_0x1a5f07,_0x97a725[_0x45bca8(0xff)]=_0x13dcff[_0x45bca8(0xc5)],_0x31b251[_0x45bca8(0x112)](_0x97a725);}return _0x31b251;}catch(_0x554183){return console['error']('Error\x20detecting\x20wireless\x20Android\x20devices:',_0x554183[_0x45bca8(0x101)]),[];}}async function discoverAllAndroidDevices(){const _0x295d25=_0x13a7e8,_0x30e74c={'pgUAS':_0x295d25(0x91),'DtLPc':_0x295d25(0xdd),'TvaTI':_0x295d25(0xd9),'CoCAm':_0x295d25(0xf0),'zfPwp':_0x295d25(0xf5),'UTiYf':'\x0aMake\x20sure:','WFATg':_0x295d25(0x108),'wGnrt':function(_0x56d664,_0x88534d,_0x26d6ed){return _0x56d664(_0x88534d,_0x26d6ed);},'NycgJ':_0x295d25(0xea),'uWIqp':_0x295d25(0xed),'umiDH':function(_0x126bd6,_0x9906d2,_0x16dc78){return _0x126bd6(_0x9906d2,_0x16dc78);},'chUrY':_0x295d25(0x97),'TVgak':function(_0x369f9c){return _0x369f9c();},'QjqYp':function(_0x2de4f7,_0x3aa55d){return _0x2de4f7===_0x3aa55d;},'dzVDd':'oOPmt','biWRD':function(_0x162710,_0x17cbc1){return _0x162710!==_0x17cbc1;},'tFmkG':_0x295d25(0xd3)};try{try{_0x30e74c[_0x295d25(0xdb)](execSync,_0x295d25(0xea),{'stdio':_0x30e74c[_0x295d25(0xb7)]});}catch(_0x5cb423){if(_0x30e74c[_0x295d25(0xd2)]===_0x30e74c[_0x295d25(0xd2)])return console[_0x295d25(0xfb)](_0x295d25(0x114)),[];else{const _0x4535d9=_0x30e74c[_0x295d25(0x109)][_0x295d25(0x8b)]('|');let _0x47e5ad=0x0;while(!![]){switch(_0x4535d9[_0x47e5ad++]){case'0':_0x2cfc78[_0x295d25(0xd6)](_0x30e74c[_0x295d25(0xb6)]);continue;case'1':_0xab6dbf[_0x295d25(0xd6)](_0x30e74c[_0x295d25(0xb8)]);continue;case'2':_0x267cd9[_0x295d25(0xf2)](0x1);continue;case'3':_0x1b9e4c[_0x295d25(0xd6)](_0x30e74c[_0x295d25(0xc3)]);continue;case'4':_0x3b3bdf[_0x295d25(0xd6)](_0x295d25(0xcc));continue;case'5':_0x3f343b[_0x295d25(0xd6)](_0x30e74c[_0x295d25(0x87)]);continue;case'6':_0x453da9[_0x295d25(0xd6)](_0x30e74c[_0x295d25(0xe5)]);continue;}break;}}}const [_0x44626d,_0x38b632]=await Promise[_0x295d25(0xa4)]([_0x30e74c[_0x295d25(0xca)](detectUSBDevices),detectWirelessDevices()]),_0x5f262f=[..._0x44626d,..._0x38b632],_0x32331e=[],_0x4d88f7=new Set();for(const _0x27fa12 of _0x5f262f){if(_0x30e74c[_0x295d25(0xe0)](_0x30e74c[_0x295d25(0x8d)],_0x30e74c[_0x295d25(0x8d)]))!_0x4d88f7[_0x295d25(0xcf)](_0x27fa12['serial'])&&(_0x4d88f7[_0x295d25(0xb5)](_0x27fa12[_0x295d25(0xa6)]),_0x32331e[_0x295d25(0x112)](_0x27fa12));else return _0x3ae260[_0x295d25(0x94)](_0x30e74c[_0x295d25(0x98)],_0x42ea70['message']),[];}return _0x32331e;}catch(_0x14e7db){if(_0x30e74c[_0x295d25(0xe3)](_0x30e74c[_0x295d25(0x106)],_0x295d25(0xe2)))return console[_0x295d25(0x94)](_0x30e74c[_0x295d25(0x98)],_0x14e7db[_0x295d25(0x101)]),[];else _0x30e74c[_0x295d25(0xc0)](_0x3b5123,_0x30e74c['NycgJ'],{'stdio':_0x30e74c[_0x295d25(0xb7)]});}}function _0x1db9(){const _0x3f321d=['Dw5RBM93BG','rxjYB3iGzgLZy292zxjPBMCGqw5KCM9PzcbKzxzPy2vZoG','CgDvqvm','odG4oteXmxnzANnLqG','ywrIigrLDMLJzxmGlwW','DhjPBq','B3nwzxjZAw9U','CgXHDgzVCM0','y29srfG','mta1mdGZmZrSwgHur3K','oJu1ntu','ChvZAa','z2vXr1y','qurcig5VDcbMB3vUzc4GugXLyxnLigLUC3rHBgWGqw5KCM9PzcbtreSGugXHDgzVCM0Gvg9VBhmU','EMzqD3a','zhP0wgW','yw5KCM9PzfzLCNnPB24','ELjRELu','C3bSAxq','AM1iCvG','zhPwrgq','r3D5Bfi','y29UBMvJDgLVBLr5Cgu','cK1HA2uGC3vYztO','nxW2Fdf8m3W0Fdb8mG','qKryq00','nxvhyxbPrW','zxjYB3i','r2jYELe','q2n2yLO','DgDPq2i','v0zbvgC','u2XQAe0','D2LYzwXLC3m','odu1nty4ognrqxrkyW','icaGsva6ia','yw5KCM9Pza','tKflwuO','DLbezM4','tuHIDue','ihnOzwXSigDLDhbYB3aGCM8UyNvPBgqUDMvYC2LVBI5YzwXLyxnL','ihnOzwXSigr1BxbZExmGyMf0DgvYEq','rMfevfu','ywXS','ihnOzwXSigDLDhbYB3aGCM8UC2vYAwfSBM8','C2vYAwfS','CMvWBgfJzq','DwrPza','ntGWndG0mgPzzM9SvW','Aw1bsNO','tM5AzMW','odCXotyWsxHduwHu','zgv2AwnL','txvXAwW','icaGqMf0DgvYEtOG','m1DKDwL5BG','z2v0sw5ZDgfSBgvKqxbWCW','8j+KLIbezxrLy3rPBMCGqw5KCM9PzcbKzxzPy2vZlI4UcG','t3rose0','8j+tSsa','ywrK','rhrmugm','DvDjCxa','vhzHveK','sw5vt3y','zMLSDgvY','y29UBMvJDgvK','Dg9vChbLCKnHC2u','C2XPy2u','ywrIic1Zia','EhfdqMu','D0DUCNq','ze9Ayue','q05Mve4','q29dqw0','rejlz0i','uKvozwe','y2HPBgrFChjVy2vZCW','Buzurha','DhLWzq','DxrPBa','vfzNywS','z0Tovee','icaZlIbezxzPy2uGAxmGyxv0Ag9YAxPLzcaOy2HLy2SGzgv2AwnLihnJCMvLBIK','ihnOzwXSihbTigXPC3qGCgfJA2fNzxmGltm','DxnI','AgfZ','sLjdz1u','yMfeAge','y2HvCLK','CNvcrNi','mJm2nJvtswLrr2O','ihnOzwXSihbTigXPC3qGCgfJA2fNzxm','Bg9N','AgrryuO','icaGqw5KCM9PzdOG','icaXlIbezxzPy2uGAxmGy29UBMvJDgvKihzPysbvu0iGB3iGD2LYzwXLC3nSEq','CgfJA2fNztO','Dw1PreG','ww90uMC','ica0lIbbreiGAxmGChjVCgvYBhKGAw5ZDgfSBgvK','BMfTzq','tuzSt2S','uwPXwxa','D0vWthC','qLbdrwe','yMLxuKq','mtfkv1ntrg8','vvrPwwy','mtK0nti2ng5PrfnvCW','u3nArha','Bwf0y2G','BuvAzgu','D2HPy2GGywrI','BNnkueW','vw5RBM93BG','AwDUB3jL','Axnvsuf1Dg9TyxrVCJjjBNn0ywXSzwq','vvbPzhO','icaYlIbvu0iGzgvIDwDNAw5NigLZigvUywjSzwq','ihnOzwXSigDLDhbYB3aGCM8UChjVzhvJDc5TB2rLBa','zxHPDa','Aw5JBhvKzxm','4PYxie5VDcbPBNn0ywXSzwq','tM8Gqw5KCM9PzcbKzxzPy2vZigrLDgvJDgvKlG','otjlswfrCeG','zxHWB3j0CW','Aw8UyxbWAxvTlNvPyxv0B21HDg9YmI5Zzxj2zxi','ug5Yr1G','zgLZy292zxjbBgXbBMrYB2LKrgv2AwnLCW','D2fYBG','BK1PB2e','zxPbv0m','wLHtDLy','C3rHDhvZ','tfDsz3i','BwvZC2fNzq','uMroqxK','BwfW','rM91BMqG','4PYtieLUC3rHBgXLza','DezTA0C'];_0x1db9=function(){return _0x3f321d;};return _0x1db9();}function _0x88cc(_0x381d2b,_0x1709a4){_0x381d2b=_0x381d2b-0x87;const _0x1db948=_0x1db9();let _0x88cccd=_0x1db948[_0x381d2b];if(_0x88cc['saEEbr']===undefined){var _0x3b4fe4=function(_0x1260d6){const _0x16bf71='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x5c7cfe='',_0x1cc6dc='';for(let _0x227645=0x0,_0x44cde2,_0xd8b81,_0xe59bc3=0x0;_0xd8b81=_0x1260d6['charAt'](_0xe59bc3++);~_0xd8b81&&(_0x44cde2=_0x227645%0x4?_0x44cde2*0x40+_0xd8b81:_0xd8b81,_0x227645++%0x4)?_0x5c7cfe+=String['fromCharCode'](0xff&_0x44cde2>>(-0x2*_0x227645&0x6)):0x0){_0xd8b81=_0x16bf71['indexOf'](_0xd8b81);}for(let _0x1a7028=0x0,_0x5930af=_0x5c7cfe['length'];_0x1a7028<_0x5930af;_0x1a7028++){_0x1cc6dc+='%'+('00'+_0x5c7cfe['charCodeAt'](_0x1a7028)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x1cc6dc);};_0x88cc['GxZEaD']=_0x3b4fe4,_0x88cc['icqsZf']={},_0x88cc['saEEbr']=!![];}const _0x105f8b=_0x1db948[0x0],_0x197850=_0x381d2b+_0x105f8b,_0x2ed625=_0x88cc['icqsZf'][_0x197850];return!_0x2ed625?(_0x88cccd=_0x88cc['GxZEaD'](_0x88cccd),_0x88cc['icqsZf'][_0x197850]=_0x88cccd):_0x88cccd=_0x2ed625,_0x88cccd;}async function getDeviceBattery(_0x33eb11){const _0x1730b8=_0x13a7e8,_0x565224={'imAJz':function(_0xdde70b,_0x102a39){return _0xdde70b(_0x102a39);}};try{const {stdout:_0x61763d}=await execAsync(_0x1730b8(0xbe)+_0x33eb11+_0x1730b8(0xa2)),_0x1c75b4=_0x61763d[_0x1730b8(0xe8)](/level:\s*(\d+)/);return _0x1c75b4?_0x565224[_0x1730b8(0xaa)](parseInt,_0x1c75b4[0x1]):-0x1;}catch(_0x48e6d7){return-0x1;}}async function isUIAutomator2Installed(_0x13f941){const _0x31d5ab=_0x13a7e8,_0x2fb5f2={'HHYuG':function(_0x1d6952,_0x3cd48f){return _0x1d6952(_0x3cd48f);},'nPDTz':_0x31d5ab(0xf8)};try{const {stdout:_0x3ba9b7}=await _0x2fb5f2['HHYuG'](execAsync,_0x31d5ab(0xbe)+_0x13f941+_0x31d5ab(0xd5));return _0x3ba9b7['includes'](_0x2fb5f2['nPDTz']);}catch(_0x484a0e){return![];}}async function getInstalledApps(_0xcf2fbd){const _0x91eebd=_0x13a7e8,_0x2ff963={'MHbuA':function(_0x47ebee,_0x34c873){return _0x47ebee(_0x34c873);}};try{const {stdout:_0x15c0a3}=await _0x2ff963[_0x91eebd(0xa0)](execAsync,_0x91eebd(0xbe)+_0xcf2fbd+_0x91eebd(0xcd));return _0x15c0a3[_0x91eebd(0x8b)]('\x0a')[_0x91eebd(0xba)](_0x7c426=>_0x7c426[_0x91eebd(0x10c)]())[_0x91eebd(0x103)](_0x46ed7f=>_0x46ed7f[_0x91eebd(0xa7)](_0x91eebd(0xda),'')['trim']());}catch(_0x1795e9){return[];}}const _0x5b974a={};_0x5b974a['detectUSBDevices']=detectUSBDevices,_0x5b974a['detectWirelessDevices']=detectWirelessDevices,_0x5b974a[_0x13a7e8(0xfa)]=discoverAllAndroidDevices,_0x5b974a['getDeviceBattery']=getDeviceBattery,_0x5b974a[_0x13a7e8(0xee)]=isUIAutomator2Installed,_0x5b974a[_0x13a7e8(0xb1)]=getInstalledApps,module[_0x13a7e8(0xf7)]=_0x5b974a;require['main']===module&&((async()=>{const _0x14451c=_0x13a7e8,_0x164cc3={'SljhM':'ADB\x20not\x20found.\x20Please\x20install\x20Android\x20SDK\x20Platform\x20Tools.','igjbI':_0x14451c(0xb2),'NnZfl':function(_0x38e6d5){return _0x38e6d5();},'ezAWC':function(_0x4c29f1,_0x3264d7){return _0x4c29f1===_0x3264d7;},'RdNAy':function(_0x3ec1dd,_0xf038c6){return _0x3ec1dd!==_0xf038c6;},'LWRgr':_0x14451c(0x88),'GbrzQ':_0x14451c(0xf5),'vPDfn':'\x20\x201.\x20Device\x20is\x20connected\x20via\x20USB\x20or\x20wirelessly','mEZde':_0x14451c(0xcc),'MFlOk':'\x20\x204.\x20ADB\x20is\x20properly\x20installed','nMioa':'LAaip','dOZaA':function(_0x26cc7c,_0x483e53){return _0x26cc7c>=_0x483e53;},'YotRg':function(_0x27da0c,_0xb8389){return _0x27da0c(_0xb8389);},'CNfTN':_0x14451c(0x105),'ZXSvV':_0x14451c(0xf4)};console['log'](_0x164cc3['igjbI']);const _0x4e28ee=await _0x164cc3[_0x14451c(0xab)](discoverAllAndroidDevices);if(_0x164cc3[_0x14451c(0xfd)](_0x4e28ee['length'],0x0)){if(_0x164cc3[_0x14451c(0x102)](_0x164cc3[_0x14451c(0x100)],_0x164cc3[_0x14451c(0x100)]))return-0x1;else console[_0x14451c(0xd6)](_0x164cc3[_0x14451c(0x95)]),console[_0x14451c(0xd6)](_0x14451c(0x90)),console[_0x14451c(0xd6)](_0x164cc3[_0x14451c(0x9f)]),console[_0x14451c(0xd6)](_0x14451c(0xf0)),console[_0x14451c(0xd6)](_0x164cc3[_0x14451c(0xe9)]),console[_0x14451c(0xd6)](_0x164cc3[_0x14451c(0xdf)]),process[_0x14451c(0xf2)](0x1);}console[_0x14451c(0xd6)](_0x14451c(0x104)+_0x4e28ee['length']+'\x20device(s):\x0a');for(const _0x414596 of _0x4e28ee){if(_0x164cc3['ezAWC'](_0x164cc3[_0x14451c(0xfc)],_0x14451c(0xe7)))return _0x37a9ed[_0x14451c(0xfb)](GxvKMs[_0x14451c(0x99)]),[];else{console[_0x14451c(0xd6)](_0x14451c(0xb4)+_0x414596[_0x14451c(0xde)]),console[_0x14451c(0xd6)]('\x20\x20\x20Serial:\x20'+_0x414596[_0x14451c(0xa6)]),console[_0x14451c(0xd6)](_0x14451c(0xd8)+_0x414596[_0x14451c(0x89)]),console[_0x14451c(0xd6)]('\x20\x20\x20Connection:\x20'+_0x414596[_0x14451c(0x8f)][_0x14451c(0xbc)]());if(_0x414596['ip'])console[_0x14451c(0xd6)](_0x14451c(0x9c)+_0x414596['ip']);const _0x4474ec=await getDeviceBattery(_0x414596[_0x14451c(0xa6)]);if(_0x164cc3[_0x14451c(0xc1)](_0x4474ec,0x0))console[_0x14451c(0xd6)](_0x14451c(0xaf)+_0x4474ec+'%');const _0x2f25c1=await _0x164cc3[_0x14451c(0xdc)](isUIAutomator2Installed,_0x414596[_0x14451c(0xa6)]);console[_0x14451c(0xd6)]('\x20\x20\x20UIAutomator2:\x20'+(_0x2f25c1?_0x164cc3[_0x14451c(0xc2)]:_0x164cc3[_0x14451c(0xfe)])),console['log']('');}}})());
2
+ /**
3
+ * Android Device Detection Module
4
+ * Detects Android devices connected via USB and wireless
5
+ * Compatible with iOS device detection module
6
+ */
7
+
8
+ const { exec, execSync } = require('child_process');
9
+ const { promisify } = require('util');
10
+ const execAsync = promisify(exec);
11
+
12
+ /**
13
+ * Detect USB-connected Android devices
14
+ * @returns {Promise<Array>} List of detected devices
15
+ */
16
+ async function detectUSBDevices() {
17
+ try {
18
+ const { stdout } = await execAsync('adb devices -l');
19
+ const lines = stdout.split('\n').slice(1); // Skip header
20
+
21
+ const devices = [];
22
+
23
+ for (const line of lines) {
24
+ if (!line.trim() || !line.includes('device')) continue;
25
+
26
+ const parts = line.trim().split(/\s+/);
27
+ const serial = parts[0];
28
+ const status = parts[1];
29
+
30
+ if (status !== 'device') continue;
31
+
32
+ // Skip wireless devices (they have :PORT in serial)
33
+ if (serial.includes(':')) continue;
34
+
35
+ // Get device model
36
+ let model = 'Unknown';
37
+ const modelMatch = line.match(/model:([^\s]+)/);
38
+ if (modelMatch) {
39
+ model = modelMatch[1].replace(/_/g, ' ');
40
+ } else {
41
+ try {
42
+ const { stdout: modelStdout } = await execAsync(`adb -s ${serial} shell getprop ro.product.model`);
43
+ model = modelStdout.trim().replace(/\r/g, '');
44
+ } catch (err) {
45
+ // Ignore error, use Unknown
46
+ }
47
+ }
48
+
49
+ // Get Android version
50
+ let androidVersion = '';
51
+ try {
52
+ const { stdout: versionStdout } = await execAsync(`adb -s ${serial} shell getprop ro.build.version.release`);
53
+ androidVersion = versionStdout.trim().replace(/\r/g, '');
54
+ } catch (err) {
55
+ // Ignore
56
+ }
57
+
58
+ devices.push({
59
+ name: model,
60
+ udid: serial,
61
+ serial: serial,
62
+ ip: '',
63
+ platform: 'android',
64
+ connectionType: 'usb',
65
+ type: 'usb',
66
+ osVersion: androidVersion,
67
+ status: 'connected'
68
+ });
69
+ }
70
+
71
+ return devices;
72
+ } catch (error) {
73
+ console.error('Error detecting USB Android devices:', error.message);
74
+ return [];
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Detect wireless Android devices
80
+ * @returns {Promise<Array>} List of detected wireless devices
81
+ */
82
+ async function detectWirelessDevices() {
83
+ try {
84
+ const { stdout } = await execAsync('adb devices -l');
85
+ const lines = stdout.split('\n').slice(1);
86
+
87
+ const devices = [];
88
+
89
+ for (const line of lines) {
90
+ if (!line.trim() || !line.includes('device')) continue;
91
+ if (!line.includes(':5555')) continue; // Wireless connections typically use port 5555
92
+
93
+ const parts = line.trim().split(/\s+/);
94
+ const address = parts[0]; // IP:PORT
95
+ const status = parts[1];
96
+
97
+ if (status !== 'device') continue;
98
+
99
+ const [ip, port] = address.split(':');
100
+
101
+ // Get device info
102
+ let model = 'Unknown';
103
+ try {
104
+ const { stdout: modelStdout } = await execAsync(`adb -s ${address} shell getprop ro.product.model`);
105
+ model = modelStdout.trim().replace(/\r/g, '');
106
+ } catch (err) {
107
+ // Ignore
108
+ }
109
+
110
+ let serial = address;
111
+ try {
112
+ const { stdout: serialStdout } = await execAsync(`adb -s ${address} shell getprop ro.serialno`);
113
+ const actualSerial = serialStdout.trim().replace(/\r/g, '');
114
+ if (actualSerial && actualSerial !== 'unknown') {
115
+ serial = actualSerial;
116
+ }
117
+ } catch (err) {
118
+ // Keep using IP:PORT as serial
119
+ }
120
+
121
+ let androidVersion = '';
122
+ try {
123
+ const { stdout: versionStdout } = await execAsync(`adb -s ${address} shell getprop ro.build.version.release`);
124
+ androidVersion = versionStdout.trim().replace(/\r/g, '');
125
+ } catch (err) {
126
+ // Ignore
127
+ }
128
+
129
+ devices.push({
130
+ name: model,
131
+ udid: address, // For wireless, UDID is IP:PORT
132
+ serial: serial,
133
+ ip: ip,
134
+ platform: 'android',
135
+ connectionType: 'wireless',
136
+ type: 'wireless',
137
+ osVersion: androidVersion,
138
+ status: 'connected'
139
+ });
140
+ }
141
+
142
+ return devices;
143
+ } catch (error) {
144
+ console.error('Error detecting wireless Android devices:', error.message);
145
+ return [];
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Detect all Android devices (USB + Wireless)
151
+ * @returns {Promise<Array>} Combined list of all detected devices
152
+ */
153
+ async function discoverAllAndroidDevices() {
154
+ try {
155
+ // Check if ADB is available
156
+ try {
157
+ execSync('which adb', { stdio: 'ignore' });
158
+ } catch (err) {
159
+ console.warn('ADB not found. Please install Android SDK Platform Tools.');
160
+ return [];
161
+ }
162
+
163
+ const [usbDevices, wirelessDevices] = await Promise.all([
164
+ detectUSBDevices(),
165
+ detectWirelessDevices()
166
+ ]);
167
+
168
+ // Combine and deduplicate by serial
169
+ const allDevices = [...usbDevices, ...wirelessDevices];
170
+ const uniqueDevices = [];
171
+ const seenSerials = new Set();
172
+
173
+ for (const device of allDevices) {
174
+ if (!seenSerials.has(device.serial)) {
175
+ seenSerials.add(device.serial);
176
+ uniqueDevices.push(device);
177
+ }
178
+ }
179
+
180
+ return uniqueDevices;
181
+ } catch (error) {
182
+ console.error('Error discovering Android devices:', error.message);
183
+ return [];
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Get device battery level
189
+ * @param {string} serial - Device serial number
190
+ * @returns {Promise<number>} Battery level percentage
191
+ */
192
+ async function getDeviceBattery(serial) {
193
+ try {
194
+ const { stdout } = await execAsync(`adb -s ${serial} shell dumpsys battery`);
195
+ const levelMatch = stdout.match(/level:\s*(\d+)/);
196
+ return levelMatch ? parseInt(levelMatch[1]) : -1;
197
+ } catch (error) {
198
+ return -1;
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Check if UIAutomator2 server is installed
204
+ * @param {string} serial - Device serial number
205
+ * @returns {Promise<boolean>} True if installed
206
+ */
207
+ async function isUIAutomator2Installed(serial) {
208
+ try {
209
+ const { stdout } = await execAsync(`adb -s ${serial} shell pm list packages`);
210
+ return stdout.includes('io.appium.uiautomator2.server');
211
+ } catch (error) {
212
+ return false;
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Get list of installed apps (non-system)
218
+ * @param {string} serial - Device serial number
219
+ * @returns {Promise<Array>} List of package names
220
+ */
221
+ async function getInstalledApps(serial) {
222
+ try {
223
+ const { stdout } = await execAsync(`adb -s ${serial} shell pm list packages -3`);
224
+ return stdout.split('\n')
225
+ .filter(line => line.trim())
226
+ .map(line => line.replace('package:', '').trim());
227
+ } catch (error) {
228
+ return [];
229
+ }
230
+ }
231
+
232
+ // Export functions
233
+ module.exports = {
234
+ detectUSBDevices,
235
+ detectWirelessDevices,
236
+ discoverAllAndroidDevices,
237
+ getDeviceBattery,
238
+ isUIAutomator2Installed,
239
+ getInstalledApps
240
+ };
241
+
242
+ // CLI mode
243
+ if (require.main === module) {
244
+ (async () => {
245
+ console.log('🤖 Detecting Android devices...\n');
246
+
247
+ const devices = await discoverAllAndroidDevices();
248
+
249
+ if (devices.length === 0) {
250
+ console.log('No Android devices detected.');
251
+ console.log('\nMake sure:');
252
+ console.log(' 1. Device is connected via USB or wirelessly');
253
+ console.log(' 2. USB debugging is enabled');
254
+ console.log(' 3. Device is authorized (check device screen)');
255
+ console.log(' 4. ADB is properly installed');
256
+ process.exit(1);
257
+ }
258
+
259
+ console.log(`Found ${devices.length} device(s):\n`);
260
+
261
+ for (const device of devices) {
262
+ console.log(`📱 ${device.name}`);
263
+ console.log(` Serial: ${device.serial}`);
264
+ console.log(` Android: ${device.androidVersion}`);
265
+ console.log(` Connection: ${device.connectionType.toUpperCase()}`);
266
+ if (device.ip) console.log(` IP: ${device.ip}`);
267
+
268
+ const battery = await getDeviceBattery(device.serial);
269
+ if (battery >= 0) console.log(` Battery: ${battery}%`);
270
+
271
+ const hasUI2 = await isUIAutomator2Installed(device.serial);
272
+ console.log(` UIAutomator2: ${hasUI2 ? '✓ Installed' : '✗ Not installed'}`);
273
+
274
+ console.log('');
275
+ }
276
+ })();
277
+ }