react-native-ai-debugger 2.4.0 → 2.6.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.
Files changed (594) hide show
  1. package/README.md +2 -0
  2. package/build/__tests__/helpers/fake-cdp-server.d.ts +0 -12
  3. package/build/__tests__/helpers/fake-cdp-server.d.ts.map +1 -1
  4. package/build/__tests__/helpers/fake-cdp-server.js +0 -22
  5. package/build/__tests__/helpers/fake-cdp-server.js.map +1 -1
  6. package/build/__tests__/helpers/tap-test-helpers.d.ts +0 -23
  7. package/build/__tests__/helpers/tap-test-helpers.d.ts.map +1 -1
  8. package/build/__tests__/helpers/tap-test-helpers.js +2 -29
  9. package/build/__tests__/helpers/tap-test-helpers.js.map +1 -1
  10. package/build/__tests__/integration/auto-reconnect.test.js +4 -14
  11. package/build/__tests__/integration/auto-reconnect.test.js.map +1 -1
  12. package/build/__tests__/integration/connection-health.test.js +1 -10
  13. package/build/__tests__/integration/connection-health.test.js.map +1 -1
  14. package/build/__tests__/integration/execute-in-app.test.js +1 -11
  15. package/build/__tests__/integration/execute-in-app.test.js.map +1 -1
  16. package/build/__tests__/integration/native-logs.test.js +0 -5
  17. package/build/__tests__/integration/native-logs.test.js.map +1 -1
  18. package/build/__tests__/integration/per-call-timeout.test.js +1 -5
  19. package/build/__tests__/integration/per-call-timeout.test.js.map +1 -1
  20. package/build/__tests__/integration/socket-close-midflight.test.js +2 -12
  21. package/build/__tests__/integration/socket-close-midflight.test.js.map +1 -1
  22. package/build/__tests__/integration/stale-target-probe.test.js +2 -17
  23. package/build/__tests__/integration/stale-target-probe.test.js.map +1 -1
  24. package/build/__tests__/integration/tap-strategies.test.js +2 -36
  25. package/build/__tests__/integration/tap-strategies.test.js.map +1 -1
  26. package/build/__tests__/integration/text-input.test.js +0 -39
  27. package/build/__tests__/integration/text-input.test.js.map +1 -1
  28. package/build/__tests__/integration/tools.test.js +1 -7
  29. package/build/__tests__/integration/tools.test.js.map +1 -1
  30. package/build/__tests__/setup.js +0 -2
  31. package/build/__tests__/setup.js.map +1 -1
  32. package/build/__tests__/unit/androidEmulatorAvds.test.js +0 -10
  33. package/build/__tests__/unit/androidEmulatorAvds.test.js.map +1 -1
  34. package/build/__tests__/unit/androidPinch.test.d.ts +2 -0
  35. package/build/__tests__/unit/androidPinch.test.d.ts.map +1 -0
  36. package/build/__tests__/unit/androidPinch.test.js +119 -0
  37. package/build/__tests__/unit/androidPinch.test.js.map +1 -0
  38. package/build/__tests__/unit/appContext.test.js +0 -2
  39. package/build/__tests__/unit/appContext.test.js.map +1 -1
  40. package/build/__tests__/unit/appRequest.test.js +0 -3
  41. package/build/__tests__/unit/appRequest.test.js.map +1 -1
  42. package/build/__tests__/unit/buildToken.test.js +0 -6
  43. package/build/__tests__/unit/buildToken.test.js.map +1 -1
  44. package/build/__tests__/unit/burst.test.js +0 -1
  45. package/build/__tests__/unit/burst.test.js.map +1 -1
  46. package/build/__tests__/unit/clearLogsNative.test.js +0 -8
  47. package/build/__tests__/unit/clearLogsNative.test.js.map +1 -1
  48. package/build/__tests__/unit/componentFormatNaming.test.js +0 -13
  49. package/build/__tests__/unit/componentFormatNaming.test.js.map +1 -1
  50. package/build/__tests__/unit/componentSource.test.js +0 -4
  51. package/build/__tests__/unit/componentSource.test.js.map +1 -1
  52. package/build/__tests__/unit/componentSourceResolve.test.js +0 -1
  53. package/build/__tests__/unit/componentSourceResolve.test.js.map +1 -1
  54. package/build/__tests__/unit/contextWiring.test.js +0 -3
  55. package/build/__tests__/unit/contextWiring.test.js.map +1 -1
  56. package/build/__tests__/unit/coordinateMiss.test.js +0 -16
  57. package/build/__tests__/unit/coordinateMiss.test.js.map +1 -1
  58. package/build/__tests__/unit/deviceDiscovery.test.js +0 -4
  59. package/build/__tests__/unit/deviceDiscovery.test.js.map +1 -1
  60. package/build/__tests__/unit/deviceResolution.test.js +0 -2
  61. package/build/__tests__/unit/deviceResolution.test.js.map +1 -1
  62. package/build/__tests__/unit/deviceResolver.test.js +0 -1
  63. package/build/__tests__/unit/deviceResolver.test.js.map +1 -1
  64. package/build/__tests__/unit/deviceResolverStaleRetry.test.js +0 -8
  65. package/build/__tests__/unit/deviceResolverStaleRetry.test.js.map +1 -1
  66. package/build/__tests__/unit/emulatorBridge.test.d.ts +2 -0
  67. package/build/__tests__/unit/emulatorBridge.test.d.ts.map +1 -0
  68. package/build/__tests__/unit/emulatorBridge.test.js +76 -0
  69. package/build/__tests__/unit/emulatorBridge.test.js.map +1 -0
  70. package/build/__tests__/unit/emulatorGrpc.test.d.ts +2 -0
  71. package/build/__tests__/unit/emulatorGrpc.test.d.ts.map +1 -0
  72. package/build/__tests__/unit/emulatorGrpc.test.js +33 -0
  73. package/build/__tests__/unit/emulatorGrpc.test.js.map +1 -0
  74. package/build/__tests__/unit/epochRender.test.js +0 -3
  75. package/build/__tests__/unit/epochRender.test.js.map +1 -1
  76. package/build/__tests__/unit/errorCategorization.test.js +0 -18
  77. package/build/__tests__/unit/errorCategorization.test.js.map +1 -1
  78. package/build/__tests__/unit/exec.test.js +0 -1
  79. package/build/__tests__/unit/exec.test.js.map +1 -1
  80. package/build/__tests__/unit/executor.test.js +0 -15
  81. package/build/__tests__/unit/executor.test.js.map +1 -1
  82. package/build/__tests__/unit/findElementTreeReuse.test.js +0 -12
  83. package/build/__tests__/unit/findElementTreeReuse.test.js.map +1 -1
  84. package/build/__tests__/unit/fingerprint.test.js +0 -4
  85. package/build/__tests__/unit/fingerprint.test.js.map +1 -1
  86. package/build/__tests__/unit/focusedInputTools.test.js +0 -4
  87. package/build/__tests__/unit/focusedInputTools.test.js.map +1 -1
  88. package/build/__tests__/unit/getLogsEmptyContract.test.js +0 -30
  89. package/build/__tests__/unit/getLogsEmptyContract.test.js.map +1 -1
  90. package/build/__tests__/unit/getLogsNativeSource.test.js +0 -22
  91. package/build/__tests__/unit/getLogsNativeSource.test.js.map +1 -1
  92. package/build/__tests__/unit/graphqlOperation.test.d.ts +2 -0
  93. package/build/__tests__/unit/graphqlOperation.test.d.ts.map +1 -0
  94. package/build/__tests__/unit/graphqlOperation.test.js +107 -0
  95. package/build/__tests__/unit/graphqlOperation.test.js.map +1 -0
  96. package/build/__tests__/unit/inputTarget.test.js +0 -16
  97. package/build/__tests__/unit/inputTarget.test.js.map +1 -1
  98. package/build/__tests__/unit/inputTextTool.test.js +0 -3
  99. package/build/__tests__/unit/inputTextTool.test.js.map +1 -1
  100. package/build/__tests__/unit/jsLogEvents.test.js +0 -3
  101. package/build/__tests__/unit/jsLogEvents.test.js.map +1 -1
  102. package/build/__tests__/unit/keyboardMetrics.test.js +0 -2
  103. package/build/__tests__/unit/keyboardMetrics.test.js.map +1 -1
  104. package/build/__tests__/unit/keyboardRaise.test.js +0 -2
  105. package/build/__tests__/unit/keyboardRaise.test.js.map +1 -1
  106. package/build/__tests__/unit/licenseGrace.test.js +1 -4
  107. package/build/__tests__/unit/licenseGrace.test.js.map +1 -1
  108. package/build/__tests__/unit/logEventFormat.test.js +0 -27
  109. package/build/__tests__/unit/logEventFormat.test.js.map +1 -1
  110. package/build/__tests__/unit/logEvents.test.js +1 -5
  111. package/build/__tests__/unit/logEvents.test.js.map +1 -1
  112. package/build/__tests__/unit/logGrouping.test.js +0 -2
  113. package/build/__tests__/unit/logGrouping.test.js.map +1 -1
  114. package/build/__tests__/unit/logOwnership.test.js +0 -11
  115. package/build/__tests__/unit/logOwnership.test.js.map +1 -1
  116. package/build/__tests__/unit/logRelevance.test.js +0 -6
  117. package/build/__tests__/unit/logRelevance.test.js.map +1 -1
  118. package/build/__tests__/unit/logSourceAndroid.test.js +0 -4
  119. package/build/__tests__/unit/logSourceAndroid.test.js.map +1 -1
  120. package/build/__tests__/unit/logSourceIos.test.js +0 -5
  121. package/build/__tests__/unit/logSourceIos.test.js.map +1 -1
  122. package/build/__tests__/unit/logs.test.js +0 -1
  123. package/build/__tests__/unit/logs.test.js.map +1 -1
  124. package/build/__tests__/unit/measureComponentTools.test.js +0 -1
  125. package/build/__tests__/unit/measureComponentTools.test.js.map +1 -1
  126. package/build/__tests__/unit/metro.test.js +0 -2
  127. package/build/__tests__/unit/metro.test.js.map +1 -1
  128. package/build/__tests__/unit/nativeInputValue.test.js +0 -4
  129. package/build/__tests__/unit/nativeInputValue.test.js.map +1 -1
  130. package/build/__tests__/unit/nativeLogs.test.js +1 -23
  131. package/build/__tests__/unit/nativeLogs.test.js.map +1 -1
  132. package/build/__tests__/unit/navigateVerify.test.js +0 -6
  133. package/build/__tests__/unit/navigateVerify.test.js.map +1 -1
  134. package/build/__tests__/unit/navigation.test.js +0 -5
  135. package/build/__tests__/unit/navigation.test.js.map +1 -1
  136. package/build/__tests__/unit/networkInterceptor.test.js +0 -2
  137. package/build/__tests__/unit/networkInterceptor.test.js.map +1 -1
  138. package/build/__tests__/unit/overlayGuard.test.js +0 -17
  139. package/build/__tests__/unit/overlayGuard.test.js.map +1 -1
  140. package/build/__tests__/unit/pendingExecutions.test.js +0 -6
  141. package/build/__tests__/unit/pendingExecutions.test.js.map +1 -1
  142. package/build/__tests__/unit/pinchGeometry.test.d.ts +2 -0
  143. package/build/__tests__/unit/pinchGeometry.test.d.ts.map +1 -0
  144. package/build/__tests__/unit/pinchGeometry.test.js +139 -0
  145. package/build/__tests__/unit/pinchGeometry.test.js.map +1 -0
  146. package/build/__tests__/unit/pinchTool.test.d.ts +2 -0
  147. package/build/__tests__/unit/pinchTool.test.d.ts.map +1 -0
  148. package/build/__tests__/unit/pinchTool.test.js +39 -0
  149. package/build/__tests__/unit/pinchTool.test.js.map +1 -0
  150. package/build/__tests__/unit/probe.test.js +0 -1
  151. package/build/__tests__/unit/probe.test.js.map +1 -1
  152. package/build/__tests__/unit/projectMemory.test.js +6 -7
  153. package/build/__tests__/unit/projectMemory.test.js.map +1 -1
  154. package/build/__tests__/unit/projectStore.test.js +2 -2
  155. package/build/__tests__/unit/projectStore.test.js.map +1 -1
  156. package/build/__tests__/unit/reloadAppAutoConnect.test.js +0 -9
  157. package/build/__tests__/unit/reloadAppAutoConnect.test.js.map +1 -1
  158. package/build/__tests__/unit/rnGlobalsBootstrap.test.js +3 -3
  159. package/build/__tests__/unit/rnGlobalsBootstrap.test.js.map +1 -1
  160. package/build/__tests__/unit/routeHistory.test.d.ts +2 -0
  161. package/build/__tests__/unit/routeHistory.test.d.ts.map +1 -0
  162. package/build/__tests__/unit/routeHistory.test.js +136 -0
  163. package/build/__tests__/unit/routeHistory.test.js.map +1 -0
  164. package/build/__tests__/unit/screenSpace.test.js +0 -16
  165. package/build/__tests__/unit/screenSpace.test.js.map +1 -1
  166. package/build/__tests__/unit/screenState.test.js +3 -6
  167. package/build/__tests__/unit/screenState.test.js.map +1 -1
  168. package/build/__tests__/unit/screenStateInputValue.test.js +0 -7
  169. package/build/__tests__/unit/screenStateInputValue.test.js.map +1 -1
  170. package/build/__tests__/unit/screenStateKeyboard.test.js +0 -1
  171. package/build/__tests__/unit/screenStateKeyboard.test.js.map +1 -1
  172. package/build/__tests__/unit/screenshot-diff.test.js +0 -6
  173. package/build/__tests__/unit/screenshot-diff.test.js.map +1 -1
  174. package/build/__tests__/unit/sdkMirrorPoller.test.js +0 -8
  175. package/build/__tests__/unit/sdkMirrorPoller.test.js.map +1 -1
  176. package/build/__tests__/unit/settleAndDiff.test.js +0 -11
  177. package/build/__tests__/unit/settleAndDiff.test.js.map +1 -1
  178. package/build/__tests__/unit/signedVerdict.test.js +0 -5
  179. package/build/__tests__/unit/signedVerdict.test.js.map +1 -1
  180. package/build/__tests__/unit/swipeDirection.test.js +6 -9
  181. package/build/__tests__/unit/swipeDirection.test.js.map +1 -1
  182. package/build/__tests__/unit/symbolicate.test.js +0 -1
  183. package/build/__tests__/unit/symbolicate.test.js.map +1 -1
  184. package/build/__tests__/unit/tap.test.js +0 -38
  185. package/build/__tests__/unit/tap.test.js.map +1 -1
  186. package/build/__tests__/unit/textEntry.test.js +0 -27
  187. package/build/__tests__/unit/textEntry.test.js.map +1 -1
  188. package/build/__tests__/unit/toolDescriptions.test.js +0 -40
  189. package/build/__tests__/unit/toolDescriptions.test.js.map +1 -1
  190. package/build/__tests__/unit/toolsJson.test.js +0 -10
  191. package/build/__tests__/unit/toolsJson.test.js.map +1 -1
  192. package/build/__tests__/unit/transportClassify.test.js +0 -20
  193. package/build/__tests__/unit/transportClassify.test.js.map +1 -1
  194. package/build/__tests__/unit/truncate.test.js +0 -5
  195. package/build/__tests__/unit/truncate.test.js.map +1 -1
  196. package/build/__tests__/unit/usageCache.test.js +0 -3
  197. package/build/__tests__/unit/usageCache.test.js.map +1 -1
  198. package/build/__tests__/unit/usageGate.test.js +1 -1
  199. package/build/__tests__/unit/usageGate.test.js.map +1 -1
  200. package/build/__tests__/unit/visibility.test.js +0 -8
  201. package/build/__tests__/unit/visibility.test.js.map +1 -1
  202. package/build/__tests__/unit/waitForMeasurements.test.js +2 -7
  203. package/build/__tests__/unit/waitForMeasurements.test.js.map +1 -1
  204. package/build/bin.js +0 -18
  205. package/build/bin.js.map +1 -1
  206. package/build/core/android.d.ts +0 -120
  207. package/build/core/android.d.ts.map +1 -1
  208. package/build/core/android.js +4 -259
  209. package/build/core/android.js.map +1 -1
  210. package/build/core/androidPinch.d.ts +21 -0
  211. package/build/core/androidPinch.d.ts.map +1 -0
  212. package/build/core/androidPinch.js +72 -0
  213. package/build/core/androidPinch.js.map +1 -0
  214. package/build/core/androidSystemBars.d.ts +7 -0
  215. package/build/core/androidSystemBars.d.ts.map +1 -0
  216. package/build/core/androidSystemBars.js +21 -0
  217. package/build/core/androidSystemBars.js.map +1 -0
  218. package/build/core/appContext.d.ts +0 -50
  219. package/build/core/appContext.d.ts.map +1 -1
  220. package/build/core/appContext.js +0 -50
  221. package/build/core/appContext.js.map +1 -1
  222. package/build/core/appDetection.d.ts +0 -16
  223. package/build/core/appDetection.d.ts.map +1 -1
  224. package/build/core/appDetection.js +0 -36
  225. package/build/core/appDetection.js.map +1 -1
  226. package/build/core/appRequest.d.ts +0 -12
  227. package/build/core/appRequest.d.ts.map +1 -1
  228. package/build/core/appRequest.js +0 -15
  229. package/build/core/appRequest.js.map +1 -1
  230. package/build/core/bufferConfig.d.ts +0 -2
  231. package/build/core/bufferConfig.d.ts.map +1 -1
  232. package/build/core/bufferConfig.js +0 -2
  233. package/build/core/bufferConfig.js.map +1 -1
  234. package/build/core/bundle.js +0 -40
  235. package/build/core/bundle.js.map +1 -1
  236. package/build/core/componentSearch.d.ts +0 -19
  237. package/build/core/componentSearch.d.ts.map +1 -1
  238. package/build/core/componentSearch.js +1 -22
  239. package/build/core/componentSearch.js.map +1 -1
  240. package/build/core/componentSource.d.ts +0 -21
  241. package/build/core/componentSource.d.ts.map +1 -1
  242. package/build/core/componentSource.js +0 -27
  243. package/build/core/componentSource.js.map +1 -1
  244. package/build/core/componentTree.js +0 -12
  245. package/build/core/componentTree.js.map +1 -1
  246. package/build/core/config.d.ts +0 -8
  247. package/build/core/config.d.ts.map +1 -1
  248. package/build/core/config.js +0 -10
  249. package/build/core/config.js.map +1 -1
  250. package/build/core/connection.d.ts +0 -76
  251. package/build/core/connection.d.ts.map +1 -1
  252. package/build/core/connection.js +15 -340
  253. package/build/core/connection.js.map +1 -1
  254. package/build/core/connectionState.d.ts +0 -78
  255. package/build/core/connectionState.d.ts.map +1 -1
  256. package/build/core/connectionState.js +4 -92
  257. package/build/core/connectionState.js.map +1 -1
  258. package/build/core/debugGlobals.js +0 -68
  259. package/build/core/debugGlobals.js.map +1 -1
  260. package/build/core/deviceDiscovery.d.ts +0 -5
  261. package/build/core/deviceDiscovery.d.ts.map +1 -1
  262. package/build/core/deviceDiscovery.js +0 -12
  263. package/build/core/deviceDiscovery.js.map +1 -1
  264. package/build/core/deviceResolver.d.ts +0 -10
  265. package/build/core/deviceResolver.d.ts.map +1 -1
  266. package/build/core/deviceResolver.js +0 -54
  267. package/build/core/deviceResolver.js.map +1 -1
  268. package/build/core/emulatorBridge.d.ts +17 -0
  269. package/build/core/emulatorBridge.d.ts.map +1 -0
  270. package/build/core/emulatorBridge.js +78 -0
  271. package/build/core/emulatorBridge.js.map +1 -0
  272. package/build/core/emulatorGrpc.d.ts +14 -0
  273. package/build/core/emulatorGrpc.d.ts.map +1 -0
  274. package/build/core/emulatorGrpc.js +93 -0
  275. package/build/core/emulatorGrpc.js.map +1 -0
  276. package/build/core/epochRender.d.ts +0 -12
  277. package/build/core/epochRender.d.ts.map +1 -1
  278. package/build/core/epochRender.js +0 -12
  279. package/build/core/epochRender.js.map +1 -1
  280. package/build/core/errorScreenParser.d.ts +0 -21
  281. package/build/core/errorScreenParser.d.ts.map +1 -1
  282. package/build/core/errorScreenParser.js +0 -50
  283. package/build/core/errorScreenParser.js.map +1 -1
  284. package/build/core/errors.d.ts +0 -15
  285. package/build/core/errors.d.ts.map +1 -1
  286. package/build/core/errors.js +0 -15
  287. package/build/core/errors.js.map +1 -1
  288. package/build/core/escapeNonAscii.d.ts +0 -9
  289. package/build/core/escapeNonAscii.d.ts.map +1 -1
  290. package/build/core/escapeNonAscii.js +1 -43
  291. package/build/core/escapeNonAscii.js.map +1 -1
  292. package/build/core/exec.d.ts +0 -12
  293. package/build/core/exec.d.ts.map +1 -1
  294. package/build/core/exec.js +2 -14
  295. package/build/core/exec.js.map +1 -1
  296. package/build/core/executor.js +0 -3
  297. package/build/core/executor.js.map +1 -1
  298. package/build/core/fastRefreshRecorder.js +0 -4
  299. package/build/core/fastRefreshRecorder.js.map +1 -1
  300. package/build/core/fastRefreshTools.js +0 -3
  301. package/build/core/fastRefreshTools.js.map +1 -1
  302. package/build/core/feedback.js +0 -4
  303. package/build/core/feedback.js.map +1 -1
  304. package/build/core/graphqlOperation.d.ts +13 -0
  305. package/build/core/graphqlOperation.d.ts.map +1 -0
  306. package/build/core/graphqlOperation.js +80 -0
  307. package/build/core/graphqlOperation.js.map +1 -0
  308. package/build/core/guides.d.ts +0 -10
  309. package/build/core/guides.d.ts.map +1 -1
  310. package/build/core/guides.js +18 -12
  311. package/build/core/guides.js.map +1 -1
  312. package/build/core/iconSemantics.d.ts +0 -15
  313. package/build/core/iconSemantics.d.ts.map +1 -1
  314. package/build/core/iconSemantics.js +0 -31
  315. package/build/core/iconSemantics.js.map +1 -1
  316. package/build/core/index.d.ts +2 -0
  317. package/build/core/index.d.ts.map +1 -1
  318. package/build/core/index.js +5 -47
  319. package/build/core/index.js.map +1 -1
  320. package/build/core/injected/visibility.d.ts +0 -30
  321. package/build/core/injected/visibility.d.ts.map +1 -1
  322. package/build/core/injected/visibility.js +0 -33
  323. package/build/core/injected/visibility.js.map +1 -1
  324. package/build/core/injectedFilters.d.ts +0 -28
  325. package/build/core/injectedFilters.d.ts.map +1 -1
  326. package/build/core/injectedFilters.js +0 -28
  327. package/build/core/injectedFilters.js.map +1 -1
  328. package/build/core/inputTarget.d.ts +1 -34
  329. package/build/core/inputTarget.d.ts.map +1 -1
  330. package/build/core/inputTarget.js +0 -26
  331. package/build/core/inputTarget.js.map +1 -1
  332. package/build/core/inputTargetTools.d.ts +0 -7
  333. package/build/core/inputTargetTools.d.ts.map +1 -1
  334. package/build/core/inputTargetTools.js +0 -7
  335. package/build/core/inputTargetTools.js.map +1 -1
  336. package/build/core/inspector.d.ts +0 -33
  337. package/build/core/inspector.d.ts.map +1 -1
  338. package/build/core/inspector.js +0 -36
  339. package/build/core/inspector.js.map +1 -1
  340. package/build/core/ios.d.ts +0 -127
  341. package/build/core/ios.d.ts.map +1 -1
  342. package/build/core/ios.js +2 -313
  343. package/build/core/ios.js.map +1 -1
  344. package/build/core/jsExecute.d.ts +0 -100
  345. package/build/core/jsExecute.d.ts.map +1 -1
  346. package/build/core/jsExecute.js +0 -261
  347. package/build/core/jsExecute.js.map +1 -1
  348. package/build/core/jsLogEvents.d.ts +0 -8
  349. package/build/core/jsLogEvents.d.ts.map +1 -1
  350. package/build/core/jsLogEvents.js +0 -8
  351. package/build/core/jsLogEvents.js.map +1 -1
  352. package/build/core/keyboardMetrics.js +0 -8
  353. package/build/core/keyboardMetrics.js.map +1 -1
  354. package/build/core/keyboardRaise.d.ts +0 -8
  355. package/build/core/keyboardRaise.d.ts.map +1 -1
  356. package/build/core/keyboardRaise.js +0 -23
  357. package/build/core/keyboardRaise.js.map +1 -1
  358. package/build/core/license.d.ts +0 -4
  359. package/build/core/license.d.ts.map +1 -1
  360. package/build/core/license.js +2 -55
  361. package/build/core/license.js.map +1 -1
  362. package/build/core/logDiagnosis.d.ts +0 -34
  363. package/build/core/logDiagnosis.d.ts.map +1 -1
  364. package/build/core/logDiagnosis.js +0 -15
  365. package/build/core/logDiagnosis.js.map +1 -1
  366. package/build/core/logEventFormat.d.ts +0 -1
  367. package/build/core/logEventFormat.d.ts.map +1 -1
  368. package/build/core/logEventFormat.js +0 -30
  369. package/build/core/logEventFormat.js.map +1 -1
  370. package/build/core/logEvents.d.ts +0 -54
  371. package/build/core/logEvents.d.ts.map +1 -1
  372. package/build/core/logEvents.js +0 -37
  373. package/build/core/logEvents.js.map +1 -1
  374. package/build/core/logGrouping.d.ts +0 -9
  375. package/build/core/logGrouping.d.ts.map +1 -1
  376. package/build/core/logGrouping.js +0 -17
  377. package/build/core/logGrouping.js.map +1 -1
  378. package/build/core/logOwnership.d.ts +0 -17
  379. package/build/core/logOwnership.d.ts.map +1 -1
  380. package/build/core/logOwnership.js +0 -34
  381. package/build/core/logOwnership.js.map +1 -1
  382. package/build/core/logRelevance.d.ts +0 -8
  383. package/build/core/logRelevance.d.ts.map +1 -1
  384. package/build/core/logRelevance.js +0 -15
  385. package/build/core/logRelevance.js.map +1 -1
  386. package/build/core/logSourceAndroid.d.ts +0 -8
  387. package/build/core/logSourceAndroid.d.ts.map +1 -1
  388. package/build/core/logSourceAndroid.js +0 -11
  389. package/build/core/logSourceAndroid.js.map +1 -1
  390. package/build/core/logSourceIos.d.ts +0 -8
  391. package/build/core/logSourceIos.d.ts.map +1 -1
  392. package/build/core/logSourceIos.js +1 -24
  393. package/build/core/logSourceIos.js.map +1 -1
  394. package/build/core/logbox.d.ts +0 -30
  395. package/build/core/logbox.d.ts.map +1 -1
  396. package/build/core/logbox.js +0 -43
  397. package/build/core/logbox.js.map +1 -1
  398. package/build/core/logs.d.ts +0 -6
  399. package/build/core/logs.d.ts.map +1 -1
  400. package/build/core/logs.js +0 -19
  401. package/build/core/logs.js.map +1 -1
  402. package/build/core/metro.d.ts +0 -14
  403. package/build/core/metro.d.ts.map +1 -1
  404. package/build/core/metro.js +1 -32
  405. package/build/core/metro.js.map +1 -1
  406. package/build/core/moduleRegistry.d.ts +0 -17
  407. package/build/core/moduleRegistry.d.ts.map +1 -1
  408. package/build/core/moduleRegistry.js +0 -17
  409. package/build/core/moduleRegistry.js.map +1 -1
  410. package/build/core/nativeInputValue.d.ts +0 -29
  411. package/build/core/nativeInputValue.d.ts.map +1 -1
  412. package/build/core/nativeInputValue.js +0 -18
  413. package/build/core/nativeInputValue.js.map +1 -1
  414. package/build/core/nativeLogs.d.ts +0 -47
  415. package/build/core/nativeLogs.d.ts.map +1 -1
  416. package/build/core/nativeLogs.js +0 -82
  417. package/build/core/nativeLogs.js.map +1 -1
  418. package/build/core/nativeOnlyHints.js +0 -4
  419. package/build/core/nativeOnlyHints.js.map +1 -1
  420. package/build/core/navigate.d.ts +0 -15
  421. package/build/core/navigate.d.ts.map +1 -1
  422. package/build/core/navigate.js +0 -22
  423. package/build/core/navigate.js.map +1 -1
  424. package/build/core/navigation.d.ts +0 -60
  425. package/build/core/navigation.d.ts.map +1 -1
  426. package/build/core/navigation.js +0 -60
  427. package/build/core/navigation.js.map +1 -1
  428. package/build/core/network.d.ts +0 -5
  429. package/build/core/network.d.ts.map +1 -1
  430. package/build/core/network.js +10 -31
  431. package/build/core/network.js.map +1 -1
  432. package/build/core/networkInterceptor.d.ts +0 -19
  433. package/build/core/networkInterceptor.d.ts.map +1 -1
  434. package/build/core/networkInterceptor.js +3 -27
  435. package/build/core/networkInterceptor.js.map +1 -1
  436. package/build/core/ocr.d.ts +0 -31
  437. package/build/core/ocr.d.ts.map +1 -1
  438. package/build/core/ocr.js +1 -71
  439. package/build/core/ocr.js.map +1 -1
  440. package/build/core/paths.js +0 -1
  441. package/build/core/paths.js.map +1 -1
  442. package/build/core/pinchGeometry.d.ts +28 -0
  443. package/build/core/pinchGeometry.d.ts.map +1 -0
  444. package/build/core/pinchGeometry.js +97 -0
  445. package/build/core/pinchGeometry.js.map +1 -0
  446. package/build/core/pinchThresholds.d.ts +14 -0
  447. package/build/core/pinchThresholds.d.ts.map +1 -0
  448. package/build/core/pinchThresholds.js +9 -0
  449. package/build/core/pinchThresholds.js.map +1 -0
  450. package/build/core/posthog.js +0 -7
  451. package/build/core/posthog.js.map +1 -1
  452. package/build/core/pressables.d.ts +0 -25
  453. package/build/core/pressables.d.ts.map +1 -1
  454. package/build/core/pressables.js +0 -37
  455. package/build/core/pressables.js.map +1 -1
  456. package/build/core/probe.d.ts +0 -9
  457. package/build/core/probe.d.ts.map +1 -1
  458. package/build/core/probe.js +0 -9
  459. package/build/core/probe.js.map +1 -1
  460. package/build/core/projectMemory.d.ts +0 -2
  461. package/build/core/projectMemory.d.ts.map +1 -1
  462. package/build/core/projectMemory.js +2 -7
  463. package/build/core/projectMemory.js.map +1 -1
  464. package/build/core/projectStore.d.ts +0 -18
  465. package/build/core/projectStore.d.ts.map +1 -1
  466. package/build/core/projectStore.js +0 -19
  467. package/build/core/projectStore.js.map +1 -1
  468. package/build/core/promiseHandles.d.ts +0 -13
  469. package/build/core/promiseHandles.d.ts.map +1 -1
  470. package/build/core/promiseHandles.js +0 -25
  471. package/build/core/promiseHandles.js.map +1 -1
  472. package/build/core/register.js +0 -44
  473. package/build/core/register.js.map +1 -1
  474. package/build/core/rnGlobalsBootstrap.d.ts +0 -13
  475. package/build/core/rnGlobalsBootstrap.d.ts.map +1 -1
  476. package/build/core/rnGlobalsBootstrap.js +0 -22
  477. package/build/core/rnGlobalsBootstrap.js.map +1 -1
  478. package/build/core/routeHistory.d.ts +24 -0
  479. package/build/core/routeHistory.d.ts.map +1 -0
  480. package/build/core/routeHistory.js +186 -0
  481. package/build/core/routeHistory.js.map +1 -0
  482. package/build/core/screenLayout.d.ts +0 -11
  483. package/build/core/screenLayout.d.ts.map +1 -1
  484. package/build/core/screenLayout.js +1 -60
  485. package/build/core/screenLayout.js.map +1 -1
  486. package/build/core/screenSpace.d.ts +0 -107
  487. package/build/core/screenSpace.d.ts.map +1 -1
  488. package/build/core/screenSpace.js +0 -103
  489. package/build/core/screenSpace.js.map +1 -1
  490. package/build/core/screenSpaceDevice.d.ts +0 -8
  491. package/build/core/screenSpaceDevice.d.ts.map +1 -1
  492. package/build/core/screenSpaceDevice.js +0 -23
  493. package/build/core/screenSpaceDevice.js.map +1 -1
  494. package/build/core/screenState.d.ts +0 -73
  495. package/build/core/screenState.d.ts.map +1 -1
  496. package/build/core/screenState.js +6 -115
  497. package/build/core/screenState.js.map +1 -1
  498. package/build/core/sdkBridge.js +0 -8
  499. package/build/core/sdkBridge.js.map +1 -1
  500. package/build/core/sdkMirrorPoller.d.ts +0 -18
  501. package/build/core/sdkMirrorPoller.d.ts.map +1 -1
  502. package/build/core/sdkMirrorPoller.js +0 -47
  503. package/build/core/sdkMirrorPoller.js.map +1 -1
  504. package/build/core/selectionBuffer.d.ts +0 -6
  505. package/build/core/selectionBuffer.d.ts.map +1 -1
  506. package/build/core/selectionBuffer.js +0 -5
  507. package/build/core/selectionBuffer.js.map +1 -1
  508. package/build/core/signedVerdict.js +0 -6
  509. package/build/core/signedVerdict.js.map +1 -1
  510. package/build/core/state.d.ts +0 -31
  511. package/build/core/state.d.ts.map +1 -1
  512. package/build/core/state.js +0 -57
  513. package/build/core/state.js.map +1 -1
  514. package/build/core/symbolicate.js +0 -11
  515. package/build/core/symbolicate.js.map +1 -1
  516. package/build/core/telemetry.d.ts +0 -47
  517. package/build/core/telemetry.d.ts.map +1 -1
  518. package/build/core/telemetry.js +1 -173
  519. package/build/core/telemetry.js.map +1 -1
  520. package/build/core/textEntry.d.ts +0 -34
  521. package/build/core/textEntry.d.ts.map +1 -1
  522. package/build/core/textEntry.js +0 -73
  523. package/build/core/textEntry.js.map +1 -1
  524. package/build/core/toolHelpers.d.ts +0 -12
  525. package/build/core/toolHelpers.d.ts.map +1 -1
  526. package/build/core/toolHelpers.js +2 -47
  527. package/build/core/toolHelpers.js.map +1 -1
  528. package/build/core/truncate.d.ts +0 -17
  529. package/build/core/truncate.d.ts.map +1 -1
  530. package/build/core/truncate.js +0 -32
  531. package/build/core/truncate.js.map +1 -1
  532. package/build/core/types.d.ts +0 -6
  533. package/build/core/types.d.ts.map +1 -1
  534. package/build/core/usageCache.js +0 -12
  535. package/build/core/usageCache.js.map +1 -1
  536. package/build/index.js +0 -18
  537. package/build/index.js.map +1 -1
  538. package/build/pro/coordinateMiss.d.ts +0 -30
  539. package/build/pro/coordinateMiss.d.ts.map +1 -1
  540. package/build/pro/coordinateMiss.js +0 -17
  541. package/build/pro/coordinateMiss.js.map +1 -1
  542. package/build/pro/overlayGuard.d.ts +2 -40
  543. package/build/pro/overlayGuard.d.ts.map +1 -1
  544. package/build/pro/overlayGuard.js +0 -63
  545. package/build/pro/overlayGuard.js.map +1 -1
  546. package/build/pro/screenshot-diff.js +4 -6
  547. package/build/pro/screenshot-diff.js.map +1 -1
  548. package/build/pro/tap.d.ts +0 -55
  549. package/build/pro/tap.d.ts.map +1 -1
  550. package/build/pro/tap.js +7 -330
  551. package/build/pro/tap.js.map +1 -1
  552. package/build/pro/usageGate.js +0 -9
  553. package/build/pro/usageGate.js.map +1 -1
  554. package/build/pro/usageNotifications.js +1 -13
  555. package/build/pro/usageNotifications.js.map +1 -1
  556. package/build/pro/verifyAction.d.ts +0 -13
  557. package/build/pro/verifyAction.d.ts.map +1 -1
  558. package/build/pro/verifyAction.js +0 -45
  559. package/build/pro/verifyAction.js.map +1 -1
  560. package/build/tools/_deviceArg.d.ts +0 -35
  561. package/build/tools/_deviceArg.d.ts.map +1 -1
  562. package/build/tools/_deviceArg.js +0 -35
  563. package/build/tools/_deviceArg.js.map +1 -1
  564. package/build/tools/accountTools.js +2 -2
  565. package/build/tools/accountTools.js.map +1 -1
  566. package/build/tools/bundleTools.js +0 -16
  567. package/build/tools/bundleTools.js.map +1 -1
  568. package/build/tools/componentTools.d.ts.map +1 -1
  569. package/build/tools/componentTools.js +17 -45
  570. package/build/tools/componentTools.js.map +1 -1
  571. package/build/tools/connectionTools.js +1 -59
  572. package/build/tools/connectionTools.js.map +1 -1
  573. package/build/tools/deviceTools.js +0 -11
  574. package/build/tools/deviceTools.js.map +1 -1
  575. package/build/tools/executionTools.js +1 -18
  576. package/build/tools/executionTools.js.map +1 -1
  577. package/build/tools/interactionTools.d.ts +0 -10
  578. package/build/tools/interactionTools.d.ts.map +1 -1
  579. package/build/tools/interactionTools.js +190 -59
  580. package/build/tools/interactionTools.js.map +1 -1
  581. package/build/tools/logTools.d.ts +0 -13
  582. package/build/tools/logTools.d.ts.map +1 -1
  583. package/build/tools/logTools.js +2 -126
  584. package/build/tools/logTools.js.map +1 -1
  585. package/build/tools/metaTools.js +0 -10
  586. package/build/tools/metaTools.js.map +1 -1
  587. package/build/tools/networkTools.js +4 -43
  588. package/build/tools/networkTools.js.map +1 -1
  589. package/build/tools/requestTools.js +0 -5
  590. package/build/tools/requestTools.js.map +1 -1
  591. package/build/tools/screenshotTools.js +5 -111
  592. package/build/tools/screenshotTools.js.map +1 -1
  593. package/package.json +2 -2
  594. package/tools.json +16 -1
package/build/core/ios.js CHANGED
@@ -8,13 +8,9 @@ import { getActiveSimulatorUdid } from "./state.js";
8
8
  import { notifyDriverMissing } from "./logbox.js";
9
9
  import { execAsync } from "./exec.js";
10
10
  const execFileAsync = promisify(execFile);
11
- // simctl command timeout in milliseconds
12
11
  const SIMCTL_TIMEOUT = 30000;
13
- // IDB command timeout in milliseconds
14
12
  const IDB_TIMEOUT = 30000;
15
- // AXe command timeout in milliseconds
16
13
  const AXE_TIMEOUT = 30000;
17
- // Valid button types for IDB ui button command
18
14
  export const IOS_BUTTON_TYPES = [
19
15
  "HOME",
20
16
  "LOCK",
@@ -22,35 +18,19 @@ export const IOS_BUTTON_TYPES = [
22
18
  "SIRI",
23
19
  "APPLE_PAY",
24
20
  ];
25
- // Track connected IDB simulators to avoid redundant connect calls
26
21
  const connectedIdbSimulators = new Set();
27
- /**
28
- * Get the IDB executable path
29
- * Supports IDB_PATH environment variable for custom installations
30
- */
31
22
  function getIdbPath() {
32
23
  return process.env.IDB_PATH || "idb";
33
24
  }
34
- /**
35
- * Get the active iOS UI driver.
36
- * Defaults to AXe; set IOS_DRIVER=idb in MCP server env to use IDB instead.
37
- */
38
25
  function getIosDriver() {
39
26
  const driver = process.env.IOS_DRIVER?.toLowerCase();
40
27
  if (driver === "idb")
41
28
  return "idb";
42
29
  return "axe";
43
30
  }
44
- /**
45
- * Get the AXe executable path.
46
- * Supports AXE_PATH environment variable for custom installations.
47
- */
48
31
  function getAxePath() {
49
32
  return process.env.AXE_PATH || "axe";
50
33
  }
51
- /**
52
- * Run AXe command with execFile (no shell) for proper argument handling.
53
- */
54
34
  async function runAxe(...args) {
55
35
  const axePath = getAxePath();
56
36
  const { stdout, stderr } = await execFileAsync(axePath, args, {
@@ -61,10 +41,6 @@ async function runAxe(...args) {
61
41
  stderr: stderr.trim(),
62
42
  };
63
43
  }
64
- /**
65
- * Run IDB command with execFile (no shell) for proper argument handling
66
- * This matches the original ios-simulator-mcp implementation
67
- */
68
44
  async function runIdb(...args) {
69
45
  const idbPath = getIdbPath();
70
46
  const { stdout, stderr } = await execFileAsync(idbPath, args, {
@@ -75,9 +51,6 @@ async function runIdb(...args) {
75
51
  stderr: stderr.trim(),
76
52
  };
77
53
  }
78
- /**
79
- * Check if IDB is available
80
- */
81
54
  export async function isIdbAvailable() {
82
55
  try {
83
56
  await runIdb("--help");
@@ -87,9 +60,6 @@ export async function isIdbAvailable() {
87
60
  return false;
88
61
  }
89
62
  }
90
- /**
91
- * Check if AXe CLI is available
92
- */
93
63
  export async function isAxeAvailable() {
94
64
  try {
95
65
  await runAxe("--version");
@@ -99,17 +69,10 @@ export async function isAxeAvailable() {
99
69
  return false;
100
70
  }
101
71
  }
102
- /**
103
- * Check if the active iOS UI driver is available.
104
- * Used by tap.ts for early fail-fast checks.
105
- */
106
72
  export async function isUiDriverAvailable() {
107
73
  const driver = getIosDriver();
108
74
  return driver === "axe" ? isAxeAvailable() : isIdbAvailable();
109
75
  }
110
- /**
111
- * Get install instructions for the active iOS UI driver.
112
- */
113
76
  export function getUiDriverInstallHint() {
114
77
  const driver = getIosDriver();
115
78
  if (driver === "axe") {
@@ -117,9 +80,6 @@ export function getUiDriverInstallHint() {
117
80
  }
118
81
  return "IDB is not installed. Install with: brew install idb-companion\nTip: Consider switching to AXe (recommended) — brew install cameroncooke/axe/axe and set IOS_DRIVER=axe";
119
82
  }
120
- /**
121
- * Map IDB button names (uppercase/underscores) to AXe button names (lowercase/hyphens).
122
- */
123
83
  function toAxeButtonName(idbButton) {
124
84
  const map = {
125
85
  HOME: "home",
@@ -130,12 +90,7 @@ function toAxeButtonName(idbButton) {
130
90
  };
131
91
  return map[idbButton];
132
92
  }
133
- /**
134
- * Ensure IDB is connected to the specified simulator
135
- * IDB requires `idb connect <UDID>` before any UI commands work
136
- */
137
93
  async function ensureIdbConnected(udid) {
138
- // Skip if already connected in this session
139
94
  if (connectedIdbSimulators.has(udid)) {
140
95
  return { success: true };
141
96
  }
@@ -146,7 +101,6 @@ async function ensureIdbConnected(udid) {
146
101
  }
147
102
  catch (error) {
148
103
  const errorMessage = error instanceof Error ? error.message : String(error);
149
- // "Already connected" is not an error
150
104
  if (errorMessage.includes("already connected") ||
151
105
  errorMessage.includes("Connected")) {
152
106
  connectedIdbSimulators.add(udid);
@@ -158,12 +112,6 @@ async function ensureIdbConnected(udid) {
158
112
  };
159
113
  }
160
114
  }
161
- /**
162
- * Shared pre-flight check for all UI driver functions:
163
- * 1. Check driver availability
164
- * 2. Resolve target simulator UDID
165
- * 3. Ensure IDB connection (IDB only)
166
- */
167
115
  async function ensureUiDriverReady(udid) {
168
116
  const driver = getIosDriver();
169
117
  if (driver === "axe") {
@@ -205,19 +153,11 @@ async function ensureUiDriverReady(udid) {
205
153
  }
206
154
  return { ready: true, driver, targetUdid };
207
155
  }
208
- // Shared message for callers that hit a missing-Xcode preflight. Includes
209
- // the actual install command so the agent (or user) can act without guessing.
210
156
  export const XCODE_MISSING_ERROR = "Xcode command line tools are not installed or not selected. " +
211
157
  "Run `xcode-select --install` for the CLT, or install full Xcode from the App Store " +
212
158
  "and run `sudo xcode-select -s /Applications/Xcode.app/Contents/Developer`. " +
213
159
  "simctl ships with full Xcode (the standalone CLT does not include it).";
214
- // Memoized result — Xcode CLT presence does not change mid-session in
215
- // practice, and `xcrun simctl help` adds 50–200 ms per ios_* call without
216
- // caching. Re-resolve once per process; restart the MCP server after install.
217
160
  let simctlAvailableCache = null;
218
- /**
219
- * Check if simctl is available (cached for the lifetime of the process).
220
- */
221
161
  export async function isSimctlAvailable() {
222
162
  if (simctlAvailableCache)
223
163
  return simctlAvailableCache;
@@ -232,15 +172,9 @@ export async function isSimctlAvailable() {
232
172
  })();
233
173
  return simctlAvailableCache;
234
174
  }
235
- /**
236
- * Reset the cached simctl availability check. Test-only.
237
- */
238
175
  export function resetSimctlAvailableCache() {
239
176
  simctlAvailableCache = null;
240
177
  }
241
- /**
242
- * List iOS simulators
243
- */
244
178
  export async function listIOSSimulators(onlyBooted = false) {
245
179
  try {
246
180
  const simctlAvailable = await isSimctlAvailable();
@@ -255,7 +189,6 @@ export async function listIOSSimulators(onlyBooted = false) {
255
189
  });
256
190
  const data = JSON.parse(stdout);
257
191
  const simulators = [];
258
- // Parse devices from each runtime
259
192
  for (const [runtime, devices] of Object.entries(data.devices)) {
260
193
  if (!Array.isArray(devices))
261
194
  continue;
@@ -264,7 +197,6 @@ export async function listIOSSimulators(onlyBooted = false) {
264
197
  continue;
265
198
  if (onlyBooted && device.state !== "Booted")
266
199
  continue;
267
- // Extract iOS version from runtime string
268
200
  const runtimeMatch = runtime.match(/iOS[- ](\d+[.-]\d+)/i);
269
201
  const runtimeVersion = runtimeMatch
270
202
  ? `iOS ${runtimeMatch[1].replace("-", ".")}`
@@ -288,7 +220,6 @@ export async function listIOSSimulators(onlyBooted = false) {
288
220
  simulators: [],
289
221
  };
290
222
  }
291
- // Sort: Booted first, then by name
292
223
  simulators.sort((a, b) => {
293
224
  if (a.state === "Booted" && b.state !== "Booted")
294
225
  return -1;
@@ -315,11 +246,6 @@ export async function listIOSSimulators(onlyBooted = false) {
315
246
  };
316
247
  }
317
248
  }
318
- /**
319
- * Build the actionable "no booted simulator" error message. Lists up to 6
320
- * recently-available shutdown simulators by name+UDID and points the agent
321
- * at `ios_boot_simulator`, so it can recover instead of giving up.
322
- */
323
249
  export async function buildNoSimulatorError() {
324
250
  const base = "No iOS simulator is currently running. " +
325
251
  "Boot one with `ios_boot_simulator` (pass udid or name), " +
@@ -350,9 +276,6 @@ export async function buildNoSimulatorError() {
350
276
  return base;
351
277
  }
352
278
  }
353
- /**
354
- * Get the booted simulator UDID
355
- */
356
279
  export async function getBootedSimulatorUdid() {
357
280
  try {
358
281
  const { stdout } = await execAsync("xcrun simctl list devices booted -j", {
@@ -374,10 +297,6 @@ export async function getBootedSimulatorUdid() {
374
297
  return null;
375
298
  }
376
299
  }
377
- /**
378
- * Find a booted simulator's UDID by its device name
379
- * Matches Metro's deviceName against simulator names from simctl
380
- */
381
300
  export async function findSimulatorByName(deviceName) {
382
301
  try {
383
302
  const { stdout } = await execAsync("xcrun simctl list devices booted -j", {
@@ -392,11 +311,9 @@ export async function findSimulatorByName(deviceName) {
392
311
  if (device.state !== "Booted")
393
312
  continue;
394
313
  const normalizedSimName = device.name.toLowerCase().trim();
395
- // Exact match
396
314
  if (normalizedSimName === normalizedDeviceName) {
397
315
  return device.udid;
398
316
  }
399
- // Partial match (deviceName contains simulator name or vice versa)
400
317
  if (normalizedSimName.includes(normalizedDeviceName) ||
401
318
  normalizedDeviceName.includes(normalizedSimName)) {
402
319
  return device.udid;
@@ -409,28 +326,16 @@ export async function findSimulatorByName(deviceName) {
409
326
  return null;
410
327
  }
411
328
  }
412
- /**
413
- * Get the active simulator UDID (Metro-connected) or fall back to first booted simulator
414
- * This enables automatic device scoping based on Metro connection
415
- */
416
329
  export async function getActiveOrBootedSimulatorUdid() {
417
- // First, check if there's an active Metro-connected simulator
418
330
  const activeUdid = getActiveSimulatorUdid();
419
331
  if (activeUdid) {
420
332
  return activeUdid;
421
333
  }
422
- // Fall back to first booted simulator
423
334
  return getBootedSimulatorUdid();
424
335
  }
425
- /**
426
- * Build device selector for simctl command
427
- */
428
336
  function buildDeviceArg(udid) {
429
337
  return udid || "booted";
430
338
  }
431
- /**
432
- * Take a screenshot from an iOS simulator
433
- */
434
339
  export async function iosScreenshot(outputPath, udid) {
435
340
  try {
436
341
  const simctlAvailable = await isSimctlAvailable();
@@ -440,7 +345,6 @@ export async function iosScreenshot(outputPath, udid) {
440
345
  error: XCODE_MISSING_ERROR,
441
346
  };
442
347
  }
443
- // Resolve target UDID (prefer Metro-connected simulator)
444
348
  const targetUdid = udid || (await getActiveOrBootedSimulatorUdid());
445
349
  if (!targetUdid) {
446
350
  return {
@@ -448,14 +352,11 @@ export async function iosScreenshot(outputPath, udid) {
448
352
  error: await buildNoSimulatorError(),
449
353
  };
450
354
  }
451
- // Generate output path if not provided
452
355
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
453
356
  const finalOutputPath = outputPath || path.join(os.tmpdir(), `ios-screenshot-${timestamp}.png`);
454
357
  await execAsync(`xcrun simctl io ${targetUdid} screenshot "${finalOutputPath}"`, {
455
358
  timeout: SIMCTL_TIMEOUT,
456
359
  });
457
- // Resize image if needed (API limit: 2000px max for multi-image requests)
458
- // Return scale factor so AI can convert image coords to device coords
459
360
  const MAX_DIMENSION = 2000;
460
361
  const image = sharp(finalOutputPath);
461
362
  const metadata = await image.metadata();
@@ -464,7 +365,6 @@ export async function iosScreenshot(outputPath, udid) {
464
365
  let imageData;
465
366
  let scaleFactor = 1;
466
367
  if (originalWidth > MAX_DIMENSION || originalHeight > MAX_DIMENSION) {
467
- // Calculate scale to fit within MAX_DIMENSION
468
368
  scaleFactor = Math.max(originalWidth, originalHeight) / MAX_DIMENSION;
469
369
  imageData = await image
470
370
  .resize(MAX_DIMENSION, MAX_DIMENSION, {
@@ -493,9 +393,6 @@ export async function iosScreenshot(outputPath, udid) {
493
393
  };
494
394
  }
495
395
  }
496
- /**
497
- * Install an app on an iOS simulator
498
- */
499
396
  export async function iosInstallApp(appPath, udid) {
500
397
  try {
501
398
  const simctlAvailable = await isSimctlAvailable();
@@ -505,14 +402,12 @@ export async function iosInstallApp(appPath, udid) {
505
402
  error: XCODE_MISSING_ERROR,
506
403
  };
507
404
  }
508
- // Verify app exists
509
405
  if (!existsSync(appPath)) {
510
406
  return {
511
407
  success: false,
512
408
  error: `App bundle not found: ${appPath}`,
513
409
  };
514
410
  }
515
- // Resolve target UDID (prefer Metro-connected simulator)
516
411
  const targetUdid = udid || (await getActiveOrBootedSimulatorUdid());
517
412
  if (!targetUdid) {
518
413
  return {
@@ -521,7 +416,7 @@ export async function iosInstallApp(appPath, udid) {
521
416
  };
522
417
  }
523
418
  await execAsync(`xcrun simctl install ${targetUdid} "${appPath}"`, {
524
- timeout: 120000, // 2 minute timeout for install
419
+ timeout: 120000,
525
420
  });
526
421
  return {
527
422
  success: true,
@@ -535,9 +430,6 @@ export async function iosInstallApp(appPath, udid) {
535
430
  };
536
431
  }
537
432
  }
538
- /**
539
- * Launch an app on an iOS simulator
540
- */
541
433
  export async function iosLaunchApp(bundleId, udid) {
542
434
  try {
543
435
  const simctlAvailable = await isSimctlAvailable();
@@ -547,7 +439,6 @@ export async function iosLaunchApp(bundleId, udid) {
547
439
  error: XCODE_MISSING_ERROR,
548
440
  };
549
441
  }
550
- // Resolve target UDID (prefer Metro-connected simulator)
551
442
  const targetUdid = udid || (await getActiveOrBootedSimulatorUdid());
552
443
  if (!targetUdid) {
553
444
  return {
@@ -576,9 +467,6 @@ export async function iosLaunchApp(bundleId, udid) {
576
467
  };
577
468
  }
578
469
  }
579
- /**
580
- * Open a URL in the iOS simulator
581
- */
582
470
  export async function iosOpenUrl(url, udid) {
583
471
  try {
584
472
  const simctlAvailable = await isSimctlAvailable();
@@ -588,7 +476,6 @@ export async function iosOpenUrl(url, udid) {
588
476
  error: XCODE_MISSING_ERROR,
589
477
  };
590
478
  }
591
- // Resolve target UDID (prefer Metro-connected simulator)
592
479
  const targetUdid = udid || (await getActiveOrBootedSimulatorUdid());
593
480
  if (!targetUdid) {
594
481
  return {
@@ -618,9 +505,6 @@ export async function iosOpenUrl(url, udid) {
618
505
  };
619
506
  }
620
507
  }
621
- /**
622
- * Terminate an app on an iOS simulator
623
- */
624
508
  export async function iosTerminateApp(bundleId, udid) {
625
509
  try {
626
510
  const simctlAvailable = await isSimctlAvailable();
@@ -630,7 +514,6 @@ export async function iosTerminateApp(bundleId, udid) {
630
514
  error: XCODE_MISSING_ERROR,
631
515
  };
632
516
  }
633
- // Resolve target UDID (prefer Metro-connected simulator)
634
517
  const targetUdid = udid || (await getActiveOrBootedSimulatorUdid());
635
518
  if (!targetUdid) {
636
519
  return {
@@ -653,9 +536,6 @@ export async function iosTerminateApp(bundleId, udid) {
653
536
  };
654
537
  }
655
538
  }
656
- /**
657
- * Boot an iOS simulator
658
- */
659
539
  export async function iosBootSimulator(udid) {
660
540
  try {
661
541
  const simctlAvailable = await isSimctlAvailable();
@@ -666,14 +546,10 @@ export async function iosBootSimulator(udid) {
666
546
  };
667
547
  }
668
548
  await execAsync(`xcrun simctl boot ${udid}`, {
669
- timeout: 60000, // 1 minute timeout for boot
549
+ timeout: 60000,
670
550
  });
671
- // Open Simulator app
672
551
  await execAsync("open -a Simulator", { timeout: 10000 }).catch(() => {
673
- // Ignore if Simulator app doesn't open
674
552
  });
675
- // The device inventory just changed — drop the cached copy so the next
676
- // resolve/tap sees this simulator as booted without waiting out the TTL.
677
553
  const { resetDeviceDiscoveryCache } = await import("./deviceDiscovery.js");
678
554
  resetDeviceDiscoveryCache();
679
555
  return {
@@ -683,7 +559,6 @@ export async function iosBootSimulator(udid) {
683
559
  }
684
560
  catch (error) {
685
561
  const errorMessage = error instanceof Error ? error.message : String(error);
686
- // Already booted is not an error
687
562
  if (errorMessage.includes("Unable to boot device in current state: Booted")) {
688
563
  return {
689
564
  success: true,
@@ -696,16 +571,6 @@ export async function iosBootSimulator(udid) {
696
571
  };
697
572
  }
698
573
  }
699
- // ============================================================================
700
- // iOS UI Interaction Tools
701
- // These tools require an iOS UI driver to be installed:
702
- // Recommended: AXe — brew install cameroncooke/axe/axe
703
- // Alternative: IDB — brew install idb-companion
704
- // AXe is the default driver. Set IOS_DRIVER=idb to fall back to IDB.
705
- // ============================================================================
706
- /**
707
- * Tap at coordinates on an iOS simulator using IDB
708
- */
709
574
  export async function iosTap(x, y, options) {
710
575
  try {
711
576
  const preflight = await ensureUiDriverReady(options?.udid);
@@ -716,7 +581,6 @@ export async function iosTap(x, y, options) {
716
581
  const yRounded = Math.round(y);
717
582
  if (driver === "axe") {
718
583
  if (options?.duration !== undefined) {
719
- // Long press: use axe touch with delay (convert ms to seconds)
720
584
  const delaySecs = String(options.duration / 1000);
721
585
  await runAxe("touch", "-x", String(xRounded), "-y", String(yRounded), "--down", "--up", "--delay", delaySecs, "--udid", targetUdid);
722
586
  }
@@ -746,9 +610,6 @@ export async function iosTap(x, y, options) {
746
610
  };
747
611
  }
748
612
  }
749
- /**
750
- * Swipe gesture on an iOS simulator
751
- */
752
613
  export async function iosSwipe(startX, startY, endX, endY, options) {
753
614
  try {
754
615
  const preflight = await ensureUiDriverReady(options?.udid);
@@ -772,7 +633,6 @@ export async function iosSwipe(startX, startY, endX, endY, options) {
772
633
  String(y2),
773
634
  ];
774
635
  if (options?.duration !== undefined) {
775
- // Both axe and idb expect duration in seconds (matches the MCP tool schema).
776
636
  args.push("--duration", String(options.duration));
777
637
  }
778
638
  if (options?.delta !== undefined) {
@@ -806,9 +666,6 @@ export async function iosSwipe(startX, startY, endX, endY, options) {
806
666
  };
807
667
  }
808
668
  }
809
- /**
810
- * Input text into the active field on an iOS simulator
811
- */
812
669
  export async function iosInputText(text, udid) {
813
670
  try {
814
671
  const preflight = await ensureUiDriverReady(udid);
@@ -816,12 +673,6 @@ export async function iosInputText(text, udid) {
816
673
  return preflight.error;
817
674
  const { driver, targetUdid } = preflight;
818
675
  if (driver === "axe") {
819
- // Submit one HID event per chunk instead of AXe's default 200. Text
820
- // arriving out of order has been observed on device ("Alice" landing as
821
- // "Aicel", "CASEB" as "CSEBA" — in both cases the second keystroke last),
822
- // and a single large submission is the plausible cause. Measured at the
823
- // same latency as plain `axe type` (1432ms vs 1519ms for 19 chars), so
824
- // the serialisation is free.
825
676
  await runAxe("batch", "--udid", targetUdid, "--type-chunk-size", "1", "--step", `type '${text.replace(/'/g, "'\\''")}'`);
826
677
  }
827
678
  else {
@@ -841,12 +692,8 @@ export async function iosInputText(text, udid) {
841
692
  };
842
693
  }
843
694
  }
844
- /**
845
- * Press a hardware button on an iOS simulator
846
- */
847
695
  export async function iosButton(button, options) {
848
696
  try {
849
- // Validate button type
850
697
  if (!IOS_BUTTON_TYPES.includes(button)) {
851
698
  return {
852
699
  success: false,
@@ -887,9 +734,6 @@ export async function iosButton(button, options) {
887
734
  };
888
735
  }
889
736
  }
890
- /**
891
- * Send a key event to an iOS simulator
892
- */
893
737
  export async function iosKeyEvent(keycode, options) {
894
738
  try {
895
739
  const preflight = await ensureUiDriverReady(options?.udid);
@@ -926,9 +770,6 @@ export async function iosKeyEvent(keycode, options) {
926
770
  };
927
771
  }
928
772
  }
929
- /**
930
- * Send a sequence of key events to an iOS simulator
931
- */
932
773
  export async function iosKeySequence(keycodes, udid) {
933
774
  try {
934
775
  if (!keycodes || keycodes.length === 0) {
@@ -968,9 +809,6 @@ export async function iosKeySequence(keycodes, udid) {
968
809
  };
969
810
  }
970
811
  }
971
- /**
972
- * Format accessibility tree for human-readable output
973
- */
974
812
  function formatAccessibilityTree(elements, depth = 0) {
975
813
  const lines = [];
976
814
  const indent = " ".repeat(depth);
@@ -997,25 +835,8 @@ function formatAccessibilityTree(elements, depth = 0) {
997
835
  }
998
836
  return lines.join("\n");
999
837
  }
1000
- /**
1001
- * Probe the iOS root accessibility element for the top safe-area inset in points.
1002
- * React-native-screens modal/sheet presentations cause measureInWindow to return y
1003
- * relative to the content origin (below the inset) instead of the window. Knowing
1004
- * the inset lets us detect and correct the shifted coordinate space.
1005
- *
1006
- * Cached so repeated taps don't each incur a describe-ui call. The probe costs
1007
- * ~200ms and ran on essentially every fiber+native tap under the old 5s TTL;
1008
- * the inset itself only changes on rotation, so a longer TTL is safe (a rotation
1009
- * mid-session costs at most one stale correction until the entry expires).
1010
- */
1011
838
  const SAFE_AREA_CACHE_TTL_MS = 30_000;
1012
839
  const safeAreaTopCache = new Map();
1013
- /**
1014
- * The root element's frame carries both the inset and the screen's point size, so the
1015
- * one describe-ui call answers both. Splitting them into two probes would double the
1016
- * ~200ms cost for callers (the layout tools) that need the size to derive the
1017
- * point -> delivered-pixel scale.
1018
- */
1019
840
  async function probeIOSRootFrame(udid) {
1020
841
  const cacheKey = udid || "__default__";
1021
842
  const cached = safeAreaTopCache.get(cacheKey);
@@ -1048,7 +869,6 @@ async function probeIOSRootFrame(udid) {
1048
869
  }
1049
870
  }
1050
871
  catch {
1051
- // Fall through: value stays 0 (no correction)
1052
872
  }
1053
873
  const entry = { value, screen, expires: Date.now() + SAFE_AREA_CACHE_TTL_MS };
1054
874
  safeAreaTopCache.set(cacheKey, entry);
@@ -1057,13 +877,9 @@ async function probeIOSRootFrame(udid) {
1057
877
  export async function getIOSSafeAreaTop(udid) {
1058
878
  return (await probeIOSRootFrame(udid)).value;
1059
879
  }
1060
- /** Screen size in points, or null when the UI driver could not be reached. */
1061
880
  export async function getIOSScreenPointSize(udid) {
1062
881
  return (await probeIOSRootFrame(udid)).screen;
1063
882
  }
1064
- /**
1065
- * Get accessibility info for the entire screen
1066
- */
1067
883
  export async function iosDescribeAll(udid) {
1068
884
  try {
1069
885
  const preflight = await ensureUiDriverReady(udid);
@@ -1081,9 +897,7 @@ export async function iosDescribeAll(udid) {
1081
897
  throw new Error(result.stderr);
1082
898
  stdout = result.stdout;
1083
899
  }
1084
- // Parse JSON response
1085
900
  const elements = JSON.parse(stdout);
1086
- // Format for human-readable output
1087
901
  const formatted = formatAccessibilityTree(elements);
1088
902
  const header = 'Note: All coordinates are in iOS points. Use tap(text="...") for tapping — do not pass these coordinates to tap(x, y) directly.\n\n';
1089
903
  return {
@@ -1099,27 +913,8 @@ export async function iosDescribeAll(udid) {
1099
913
  };
1100
914
  }
1101
915
  }
1102
- /**
1103
- * I1 (2026-05-16): when a native iOS system sheet (auth prompt, permission request,
1104
- * Safari sign-in sheet) is on screen, the RN app's fiber tree still describes the
1105
- * underlying screen — but those pressables aren't interactable until the sheet is
1106
- * dismissed. Detect the overlay so the screenshot output can warn the agent and
1107
- * point it at tap(x, y, native=true) for the overlay's actual buttons.
1108
- *
1109
- * Heuristic: scan the top three levels of the AXe accessibility tree for an
1110
- * element whose type matches an iOS sheet/alert role, OR whose AXLabel matches a
1111
- * well-known system-overlay phrase. False positives are rare because the patterns
1112
- * are specific to system-presented sheets — RN content rarely uses these labels.
1113
- */
1114
916
  const IOS_SYSTEM_OVERLAY_TYPES = /^(Alert|ActionSheet|Sheet|Dialog|SystemDialog)$/i;
1115
917
  const IOS_SYSTEM_OVERLAY_LABEL_PATTERNS = /Wants to Use|Sign in to|Sign In to|Allow .* to (use|access)|Open in Safari|Continue with|Use Face ID|Use Touch ID|Use Passcode/i;
1116
- /**
1117
- * Telltale of an RN accessibilityLabel rollup vs a system-presented sheet:
1118
- * a rollup concatenates multiple child labels with commas / newlines (3+ separators),
1119
- * while a system sheet's label is a single sentence. Without this guard the label
1120
- * patterns above false-positive on screens like gifted.co's login wrapper whose
1121
- * rollup happens to contain "Continue with" amongst many other phrases.
1122
- */
1123
918
  function looksLikeRNLabelRollup(label) {
1124
919
  const commas = (label.match(/,/g) ?? []).length;
1125
920
  const newlines = (label.match(/\n/g) ?? []).length;
@@ -1166,9 +961,6 @@ export function formatIOSSystemOverlayWarning(detection) {
1166
961
  `React Native screen UNDERNEATH and may be stale. For overlay buttons, take the coordinates ` +
1167
962
  `from the screenshot and call tap(x, y, native=true, platform="ios").`);
1168
963
  }
1169
- /**
1170
- * Get accessibility info at a specific point
1171
- */
1172
964
  export async function iosDescribePoint(x, y, udid) {
1173
965
  try {
1174
966
  const preflight = await ensureUiDriverReady(udid);
@@ -1188,7 +980,6 @@ export async function iosDescribePoint(x, y, udid) {
1188
980
  throw new Error(result.stderr);
1189
981
  stdout = result.stdout;
1190
982
  }
1191
- // Parse JSON response - may be single element or array
1192
983
  let element;
1193
984
  try {
1194
985
  const parsed = JSON.parse(stdout);
@@ -1201,7 +992,6 @@ export async function iosDescribePoint(x, y, udid) {
1201
992
  elements: [],
1202
993
  };
1203
994
  }
1204
- // Format for human-readable output
1205
995
  const parts = [];
1206
996
  if (element.type)
1207
997
  parts.push(`Type: ${element.type}`);
@@ -1231,9 +1021,6 @@ export async function iosDescribePoint(x, y, udid) {
1231
1021
  };
1232
1022
  }
1233
1023
  }
1234
- /**
1235
- * Helper to flatten nested accessibility elements
1236
- */
1237
1024
  function flattenElements(elements) {
1238
1025
  const result = [];
1239
1026
  for (const el of elements) {
@@ -1244,10 +1031,6 @@ function flattenElements(elements) {
1244
1031
  }
1245
1032
  return result;
1246
1033
  }
1247
- /**
1248
- * Tap an element by its accessibility label using IDB
1249
- * This simplifies the workflow: no need to manually find coordinates
1250
- */
1251
1034
  export async function iosTapElement(options) {
1252
1035
  try {
1253
1036
  const { label, labelContains, index = 0, duration, udid } = options;
@@ -1257,7 +1040,6 @@ export async function iosTapElement(options) {
1257
1040
  error: "Either 'label' (exact match) or 'labelContains' (partial match) is required",
1258
1041
  };
1259
1042
  }
1260
- // Get all accessibility elements
1261
1043
  const describeResult = await iosDescribeAll(udid);
1262
1044
  if (!describeResult.success || !describeResult.elements) {
1263
1045
  return {
@@ -1265,7 +1047,6 @@ export async function iosTapElement(options) {
1265
1047
  error: describeResult.error || "Failed to get accessibility elements",
1266
1048
  };
1267
1049
  }
1268
- // Flatten the tree and find matching elements
1269
1050
  const allElements = flattenElements(describeResult.elements);
1270
1051
  const matches = allElements.filter((el) => {
1271
1052
  if (!el.AXLabel)
@@ -1285,7 +1066,6 @@ export async function iosTapElement(options) {
1285
1066
  error: `No element found with ${searchTerm}`,
1286
1067
  };
1287
1068
  }
1288
- // Select element by index (default 0 = first match)
1289
1069
  if (index >= matches.length) {
1290
1070
  return {
1291
1071
  success: false,
@@ -1293,17 +1073,14 @@ export async function iosTapElement(options) {
1293
1073
  };
1294
1074
  }
1295
1075
  const element = matches[index];
1296
- // Check if element has frame coordinates
1297
1076
  if (!element.frame) {
1298
1077
  return {
1299
1078
  success: false,
1300
1079
  error: `Element "${element.AXLabel}" has no frame coordinates`,
1301
1080
  };
1302
1081
  }
1303
- // Calculate center
1304
1082
  const centerX = Math.round(element.frame.x + element.frame.width / 2);
1305
1083
  const centerY = Math.round(element.frame.y + element.frame.height / 2);
1306
- // Tap at center
1307
1084
  const tapResult = await iosTap(centerX, centerY, { duration, udid });
1308
1085
  if (tapResult.success) {
1309
1086
  return {
@@ -1320,9 +1097,6 @@ export async function iosTapElement(options) {
1320
1097
  };
1321
1098
  }
1322
1099
  }
1323
- /**
1324
- * Parse IDB accessibility output into simplified element array
1325
- */
1326
1100
  function parseIdbAccessibilityForFindElement(output) {
1327
1101
  const elements = [];
1328
1102
  try {
@@ -1375,14 +1149,9 @@ function parseIdbAccessibilityForFindElement(output) {
1375
1149
  }
1376
1150
  }
1377
1151
  catch {
1378
- // If JSON parsing fails, return empty array
1379
1152
  }
1380
1153
  return elements;
1381
1154
  }
1382
- /**
1383
- * Check if an element's center is within the screen viewport.
1384
- * Filters out off-screen elements in scroll views, horizontal pagers, etc.
1385
- */
1386
1155
  function isIOSElementInViewport(element, screenWidth, screenHeight) {
1387
1156
  const { center } = element;
1388
1157
  return (center.x >= 0 &&
@@ -1390,10 +1159,6 @@ function isIOSElementInViewport(element, screenWidth, screenHeight) {
1390
1159
  center.y >= 0 &&
1391
1160
  center.y <= screenHeight);
1392
1161
  }
1393
- /**
1394
- * Extract screen dimensions from the parsed UI tree.
1395
- * The root Application element's frame represents the screen size.
1396
- */
1397
1162
  function extractIOSScreenSize(rawOutput) {
1398
1163
  try {
1399
1164
  const data = JSON.parse(rawOutput);
@@ -1404,13 +1169,9 @@ function extractIOSScreenSize(rawOutput) {
1404
1169
  }
1405
1170
  }
1406
1171
  catch {
1407
- // Fall through
1408
1172
  }
1409
1173
  return null;
1410
1174
  }
1411
- /**
1412
- * Match iOS element against find options
1413
- */
1414
1175
  function matchesIOSFindElement(element, options) {
1415
1176
  if (options.label !== undefined) {
1416
1177
  if (element.label !== options.label)
@@ -1444,9 +1205,6 @@ function matchesIOSFindElement(element, options) {
1444
1205
  }
1445
1206
  return true;
1446
1207
  }
1447
- /**
1448
- * Get UI accessibility tree from iOS simulator using IDB (for find_element)
1449
- */
1450
1208
  export async function iosGetUITree(udid) {
1451
1209
  try {
1452
1210
  const preflight = await ensureUiDriverReady(udid);
@@ -1476,20 +1234,6 @@ export async function iosGetUITree(udid) {
1476
1234
  };
1477
1235
  }
1478
1236
  }
1479
- /**
1480
- * Bug 3 (2026-05-16): RN rolls up child Text labels into a parent View's
1481
- * accessibilityLabel when the parent is marked `accessible`. Result: a screen-root
1482
- * View whose label is a 200+ char concatenation of every visible text. `labelContains`
1483
- * matches it, frame is the whole screen, centroid happens to land on whatever button
1484
- * sits near the middle — and the tap silently lands on the wrong target.
1485
- *
1486
- * Heuristic filter: an element is an aggregator wrapper when EITHER
1487
- * (a) its label is much longer than the query AND contains concatenation hints
1488
- * (newlines, commas, semicolons — RN rollup typically joins with `, ` or `\n`)
1489
- * (b) its frame covers >50% of the viewport (a real button never does this)
1490
- *
1491
- * Both heuristics together catch the gifted.co LoginScreen wrapper case the doc cites.
1492
- */
1493
1237
  function isAggregatorWrapper(element, query, screenSize) {
1494
1238
  const labelLen = element.label?.length ?? 0;
1495
1239
  const queryLen = query.length;
@@ -1507,15 +1251,6 @@ function isAggregatorWrapper(element, query, screenSize) {
1507
1251
  }
1508
1252
  return isLongConcatenatedLabel || isFullScreenFrame;
1509
1253
  }
1510
- /**
1511
- * Find element(s) in the iOS UI tree matching the given criteria.
1512
- *
1513
- * `tree` lets a caller reuse an accessibility dump it already has. Each fetch
1514
- * shells out to `axe describe-ui` (~210ms measured 2026-08-01) and the tap
1515
- * strategy runs two or three passes with different predicates, so re-fetching
1516
- * per pass was costing 400-600ms per accessibility tap for a tree that cannot
1517
- * change between passes.
1518
- */
1519
1254
  export async function iosFindElement(options, udid, tree) {
1520
1255
  try {
1521
1256
  if (!options.label &&
@@ -1539,8 +1274,6 @@ export async function iosFindElement(options, udid, tree) {
1539
1274
  error: treeResult.error,
1540
1275
  };
1541
1276
  }
1542
- // Filter to viewport-visible elements first, then match criteria.
1543
- // This prevents selecting off-screen duplicates in scroll views / pagers.
1544
1277
  const screenSize = treeResult.rawOutput
1545
1278
  ? extractIOSScreenSize(treeResult.rawOutput)
1546
1279
  : null;
@@ -1548,21 +1281,9 @@ export async function iosFindElement(options, udid, tree) {
1548
1281
  ? treeResult.elements.filter((el) => isIOSElementInViewport(el, screenSize.width, screenSize.height))
1549
1282
  : treeResult.elements;
1550
1283
  let matches = visibleElements.filter((el) => matchesIOSFindElement(el, options));
1551
- // If no visible matches, fall back to all elements (element may be partially visible
1552
- // or the screen size extraction failed)
1553
1284
  if (matches.length === 0) {
1554
1285
  matches = treeResult.elements.filter((el) => matchesIOSFindElement(el, options));
1555
1286
  }
1556
- // Bug 3 (2026-05-16): when matching by partial string (labelContains / identifierContains),
1557
- // drop aggregator-wrapper elements that match only because their label rolls up every
1558
- // visible child's text. Without this filter, tapping such a wrapper's centroid
1559
- // silently lands on the wrong on-screen element.
1560
- //
1561
- // When ALL matches are aggregator wrappers (the common case — RN often rolls labels
1562
- // up to a single accessible wrapper, leaving no individual element with a matching
1563
- // label), refuse with a clear error pointing the agent at component= or coordinates.
1564
- // This is safer than silently tapping the wrapper centroid (which lands wherever the
1565
- // wrapper's geometric center happens to be — usually NOT on the requested button).
1566
1287
  if (options.labelContains !== undefined && matches.length > 0) {
1567
1288
  const filtered = matches.filter((el) => !isAggregatorWrapper(el, options.labelContains, screenSize));
1568
1289
  if (filtered.length > 0) {
@@ -1628,26 +1349,11 @@ export async function iosFindElement(options, udid, tree) {
1628
1349
  };
1629
1350
  }
1630
1351
  }
1631
- // DPR cache: UDID → device pixel ratio (never changes during session)
1632
1352
  const dprCache = new Map();
1633
- /**
1634
- * Screen size in device pixels, recorded on the same cold pass that resolves the DPR.
1635
- * The layout tools need it to predict the delivery downscale, and re-deriving it later
1636
- * would mean a second screenshot for a number this call already had in hand.
1637
- */
1638
1353
  const pixelSizeCache = new Map();
1639
- /**
1640
- * Pure calculation: DPR = screenshotPixelWidth / screenPointWidth.
1641
- * Exported for unit testing.
1642
- */
1643
1354
  export function calculateDPR(screenshotPixelWidth, screenPointWidth) {
1644
1355
  return Math.round(screenshotPixelWidth / screenPointWidth);
1645
1356
  }
1646
- /**
1647
- * Query the actual device pixel ratio for an iOS simulator.
1648
- * Uses screenshot pixel width vs accessibility root frame width.
1649
- * Result is cached per UDID for the session.
1650
- */
1651
1357
  export async function getDevicePixelRatio(udid, pixelDims) {
1652
1358
  const cacheKey = udid || "__default__";
1653
1359
  const cached = dprCache.get(cacheKey);
@@ -1660,14 +1366,10 @@ export async function getDevicePixelRatio(udid, pixelDims) {
1660
1366
  let pixelWidth;
1661
1367
  let pixelHeight;
1662
1368
  if (pixelDims && pixelDims.width > 0 && pixelDims.height > 0) {
1663
- // The caller already captured a frame this turn (tap always does) — reuse
1664
- // its dimensions instead of shelling out for a screenshot of our own, which
1665
- // measured ~230ms of the ~470ms first-call cost.
1666
1369
  pixelWidth = pixelDims.width;
1667
1370
  pixelHeight = pixelDims.height;
1668
1371
  }
1669
1372
  else {
1670
- // Take screenshot to get pixel dimensions
1671
1373
  const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
1672
1374
  const screenshotPath = path.join(os.tmpdir(), `ios-dpr-screenshot-${timestamp}.png`);
1673
1375
  await execAsync(`xcrun simctl io ${resolvedUdid} screenshot "${screenshotPath}"`, {
@@ -1680,7 +1382,6 @@ export async function getDevicePixelRatio(udid, pixelDims) {
1680
1382
  if (pixelWidth > 0 && pixelHeight > 0) {
1681
1383
  pixelSizeCache.set(cacheKey, { width: pixelWidth, height: pixelHeight });
1682
1384
  }
1683
- // Try accessibility tree for exact DPR, fall back to inference
1684
1385
  const driver = getIosDriver();
1685
1386
  const driverOk = driver === "axe" ? await isAxeAvailable() : await isIdbAvailable();
1686
1387
  if (driverOk) {
@@ -1703,37 +1404,25 @@ export async function getDevicePixelRatio(udid, pixelDims) {
1703
1404
  }
1704
1405
  }
1705
1406
  catch {
1706
- // driver failed — fall through to inference
1707
1407
  }
1708
1408
  }
1709
- // Fallback: infer DPR from screenshot pixel dimensions
1710
1409
  const { inferIOSDevicePixelRatio } = await import("./ocr.js");
1711
1410
  const dpr = inferIOSDevicePixelRatio(pixelWidth, pixelHeight);
1712
1411
  dprCache.set(cacheKey, dpr);
1713
1412
  return dpr;
1714
1413
  }
1715
- /**
1716
- * Screen size in device pixels, or null when no simulator could be measured.
1717
- * Piggybacks on the DPR probe's cache, so this is free once either has run.
1718
- */
1719
1414
  export async function getIOSScreenPixelSize(udid, pixelDims) {
1720
1415
  const cacheKey = udid || "__default__";
1721
1416
  const cached = pixelSizeCache.get(cacheKey);
1722
1417
  if (cached)
1723
1418
  return cached;
1724
- // Resolving the DPR is what populates the size cache; its own failure modes
1725
- // (no simulator, no UI driver) are not this caller's problem — it degrades to null.
1726
1419
  await getDevicePixelRatio(udid, pixelDims).catch(() => undefined);
1727
1420
  return pixelSizeCache.get(cacheKey) ?? null;
1728
1421
  }
1729
- /** Clear DPR cache (for testing or when devices change) */
1730
1422
  export function clearDPRCache() {
1731
1423
  dprCache.clear();
1732
1424
  pixelSizeCache.clear();
1733
1425
  }
1734
- /**
1735
- * Wait for element to appear on iOS screen with polling
1736
- */
1737
1426
  export async function iosWaitForElement(options, udid) {
1738
1427
  const timeoutMs = options.timeoutMs ?? 10000;
1739
1428
  const pollIntervalMs = options.pollIntervalMs ?? 500;