react-native-mcp-kit 4.2.0 → 4.3.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 (239) hide show
  1. package/dist/babel/testIdPlugin/collectHooks.d.ts +13 -0
  2. package/dist/babel/testIdPlugin/collectHooks.d.ts.map +1 -0
  3. package/dist/babel/testIdPlugin/collectHooks.js +112 -0
  4. package/dist/babel/testIdPlugin/collectHooks.js.map +1 -0
  5. package/dist/babel/testIdPlugin/constants.d.ts +6 -0
  6. package/dist/babel/testIdPlugin/constants.d.ts.map +1 -0
  7. package/dist/babel/testIdPlugin/constants.js +49 -0
  8. package/dist/babel/testIdPlugin/constants.js.map +1 -0
  9. package/dist/babel/testIdPlugin/helpers.d.ts +7 -0
  10. package/dist/babel/testIdPlugin/helpers.d.ts.map +1 -0
  11. package/dist/babel/testIdPlugin/helpers.js +77 -0
  12. package/dist/babel/testIdPlugin/helpers.js.map +1 -0
  13. package/dist/babel/testIdPlugin/hocUnwrap.d.ts +4 -0
  14. package/dist/babel/testIdPlugin/hocUnwrap.d.ts.map +1 -0
  15. package/dist/babel/testIdPlugin/hocUnwrap.js +94 -0
  16. package/dist/babel/testIdPlugin/hocUnwrap.js.map +1 -0
  17. package/dist/babel/{testIdPlugin.d.ts → testIdPlugin/index.d.ts} +1 -1
  18. package/dist/babel/testIdPlugin/index.d.ts.map +1 -0
  19. package/dist/babel/testIdPlugin/index.js +205 -0
  20. package/dist/babel/testIdPlugin/index.js.map +1 -0
  21. package/dist/babel/testIdPlugin/inject.d.ts +7 -0
  22. package/dist/babel/testIdPlugin/inject.d.ts.map +1 -0
  23. package/dist/babel/testIdPlugin/inject.js +86 -0
  24. package/dist/babel/testIdPlugin/inject.js.map +1 -0
  25. package/dist/babel/testIdPlugin/types.d.ts +59 -0
  26. package/dist/babel/testIdPlugin/types.d.ts.map +1 -0
  27. package/dist/babel/testIdPlugin/types.js +3 -0
  28. package/dist/babel/testIdPlugin/types.js.map +1 -0
  29. package/dist/bin/ios-hid +0 -0
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/modules/fiberTree/hooks/extract.d.ts +6 -0
  35. package/dist/modules/fiberTree/hooks/extract.d.ts.map +1 -0
  36. package/dist/modules/fiberTree/hooks/extract.js +187 -0
  37. package/dist/modules/fiberTree/hooks/extract.js.map +1 -0
  38. package/dist/modules/fiberTree/hooks/flatten.d.ts +4 -0
  39. package/dist/modules/fiberTree/hooks/flatten.d.ts.map +1 -0
  40. package/dist/modules/fiberTree/hooks/flatten.js +81 -0
  41. package/dist/modules/fiberTree/hooks/flatten.js.map +1 -0
  42. package/dist/modules/fiberTree/hooks/index.d.ts +5 -0
  43. package/dist/modules/fiberTree/hooks/index.d.ts.map +1 -0
  44. package/dist/modules/fiberTree/hooks/index.js +10 -0
  45. package/dist/modules/fiberTree/hooks/index.js.map +1 -0
  46. package/dist/modules/fiberTree/hooks/options.d.ts +9 -0
  47. package/dist/modules/fiberTree/hooks/options.d.ts.map +1 -0
  48. package/dist/modules/fiberTree/hooks/options.js +27 -0
  49. package/dist/modules/fiberTree/hooks/options.js.map +1 -0
  50. package/dist/modules/fiberTree/hooks/patterns.d.ts +2 -0
  51. package/dist/modules/fiberTree/hooks/patterns.d.ts.map +1 -0
  52. package/dist/modules/fiberTree/hooks/patterns.js +26 -0
  53. package/dist/modules/fiberTree/hooks/patterns.js.map +1 -0
  54. package/dist/modules/fiberTree/hooks/shape.d.ts +3 -0
  55. package/dist/modules/fiberTree/hooks/shape.d.ts.map +1 -0
  56. package/dist/modules/fiberTree/hooks/shape.js +66 -0
  57. package/dist/modules/fiberTree/hooks/shape.js.map +1 -0
  58. package/dist/modules/fiberTree/hooks/slotCount.d.ts +2 -0
  59. package/dist/modules/fiberTree/hooks/slotCount.d.ts.map +1 -0
  60. package/dist/modules/fiberTree/hooks/slotCount.js +93 -0
  61. package/dist/modules/fiberTree/hooks/slotCount.js.map +1 -0
  62. package/dist/modules/fiberTree/{hooks.d.ts → hooks/types.d.ts} +1 -34
  63. package/dist/modules/fiberTree/hooks/types.d.ts.map +1 -0
  64. package/dist/modules/fiberTree/hooks/types.js +3 -0
  65. package/dist/modules/fiberTree/hooks/types.js.map +1 -0
  66. package/dist/modules/fiberTree/hooks/value.d.ts +2 -0
  67. package/dist/modules/fiberTree/hooks/value.d.ts.map +1 -0
  68. package/dist/modules/fiberTree/hooks/value.js +89 -0
  69. package/dist/modules/fiberTree/hooks/value.js.map +1 -0
  70. package/dist/modules/fiberTree/utils/constants.d.ts +8 -0
  71. package/dist/modules/fiberTree/utils/constants.d.ts.map +1 -0
  72. package/dist/modules/fiberTree/utils/constants.js +15 -0
  73. package/dist/modules/fiberTree/utils/constants.js.map +1 -0
  74. package/dist/modules/fiberTree/utils/index.d.ts +9 -0
  75. package/dist/modules/fiberTree/utils/index.d.ts.map +1 -0
  76. package/dist/modules/fiberTree/utils/index.js +34 -0
  77. package/dist/modules/fiberTree/utils/index.js.map +1 -0
  78. package/dist/modules/fiberTree/utils/match.d.ts +4 -0
  79. package/dist/modules/fiberTree/utils/match.d.ts.map +1 -0
  80. package/dist/modules/fiberTree/utils/match.js +169 -0
  81. package/dist/modules/fiberTree/utils/match.js.map +1 -0
  82. package/dist/modules/fiberTree/utils/naming.d.ts +4 -0
  83. package/dist/modules/fiberTree/utils/naming.d.ts.map +1 -0
  84. package/dist/modules/fiberTree/utils/naming.js +52 -0
  85. package/dist/modules/fiberTree/utils/naming.js.map +1 -0
  86. package/dist/modules/fiberTree/utils/native.d.ts +5 -0
  87. package/dist/modules/fiberTree/utils/native.d.ts.map +1 -0
  88. package/dist/modules/fiberTree/utils/native.js +101 -0
  89. package/dist/modules/fiberTree/utils/native.js.map +1 -0
  90. package/dist/modules/fiberTree/utils/projection.d.ts +9 -0
  91. package/dist/modules/fiberTree/utils/projection.d.ts.map +1 -0
  92. package/dist/modules/fiberTree/utils/projection.js +75 -0
  93. package/dist/modules/fiberTree/utils/projection.js.map +1 -0
  94. package/dist/modules/fiberTree/utils/root.d.ts +4 -0
  95. package/dist/modules/fiberTree/utils/root.d.ts.map +1 -0
  96. package/dist/modules/fiberTree/utils/root.js +30 -0
  97. package/dist/modules/fiberTree/utils/root.js.map +1 -0
  98. package/dist/modules/fiberTree/utils/screen.d.ts +10 -0
  99. package/dist/modules/fiberTree/utils/screen.d.ts.map +1 -0
  100. package/dist/modules/fiberTree/utils/screen.js +39 -0
  101. package/dist/modules/fiberTree/utils/screen.js.map +1 -0
  102. package/dist/modules/fiberTree/utils/serialize.d.ts +4 -0
  103. package/dist/modules/fiberTree/utils/serialize.d.ts.map +1 -0
  104. package/dist/modules/fiberTree/utils/serialize.js +102 -0
  105. package/dist/modules/fiberTree/utils/serialize.js.map +1 -0
  106. package/dist/modules/fiberTree/utils/traverse.d.ts +12 -0
  107. package/dist/modules/fiberTree/utils/traverse.d.ts.map +1 -0
  108. package/dist/modules/fiberTree/utils/traverse.js +107 -0
  109. package/dist/modules/fiberTree/utils/traverse.js.map +1 -0
  110. package/dist/server/dispatch.d.ts +15 -0
  111. package/dist/server/dispatch.d.ts.map +1 -0
  112. package/dist/server/dispatch.js +121 -0
  113. package/dist/server/dispatch.js.map +1 -0
  114. package/dist/server/helpers.d.ts +129 -0
  115. package/dist/server/helpers.d.ts.map +1 -0
  116. package/dist/server/helpers.js +250 -0
  117. package/dist/server/helpers.js.map +1 -0
  118. package/dist/server/host/deviceResolver/byClient.d.ts +5 -0
  119. package/dist/server/host/deviceResolver/byClient.d.ts.map +1 -0
  120. package/dist/server/host/deviceResolver/byClient.js +171 -0
  121. package/dist/server/host/deviceResolver/byClient.js.map +1 -0
  122. package/dist/server/host/deviceResolver/byId.d.ts +5 -0
  123. package/dist/server/host/deviceResolver/byId.d.ts.map +1 -0
  124. package/dist/server/host/deviceResolver/byId.js +81 -0
  125. package/dist/server/host/deviceResolver/byId.js.map +1 -0
  126. package/dist/server/host/deviceResolver/enrich.d.ts +5 -0
  127. package/dist/server/host/deviceResolver/enrich.d.ts.map +1 -0
  128. package/dist/server/host/deviceResolver/enrich.js +123 -0
  129. package/dist/server/host/deviceResolver/enrich.js.map +1 -0
  130. package/dist/server/host/deviceResolver/index.d.ts +13 -0
  131. package/dist/server/host/deviceResolver/index.d.ts.map +1 -0
  132. package/dist/server/host/deviceResolver/index.js +65 -0
  133. package/dist/server/host/deviceResolver/index.js.map +1 -0
  134. package/dist/server/host/deviceResolver/list.d.ts +10 -0
  135. package/dist/server/host/deviceResolver/list.d.ts.map +1 -0
  136. package/dist/server/host/deviceResolver/list.js +119 -0
  137. package/dist/server/host/deviceResolver/list.js.map +1 -0
  138. package/dist/server/host/deviceResolver/scan.d.ts +4 -0
  139. package/dist/server/host/deviceResolver/scan.d.ts.map +1 -0
  140. package/dist/server/host/deviceResolver/scan.js +102 -0
  141. package/dist/server/host/deviceResolver/scan.js.map +1 -0
  142. package/dist/server/host/{deviceResolver.d.ts → deviceResolver/types.d.ts} +1 -16
  143. package/dist/server/host/deviceResolver/types.d.ts.map +1 -0
  144. package/dist/server/host/deviceResolver/types.js +3 -0
  145. package/dist/server/host/deviceResolver/types.js.map +1 -0
  146. package/dist/server/host/tools/input/android.d.ts +15 -0
  147. package/dist/server/host/tools/input/android.d.ts.map +1 -0
  148. package/dist/server/host/tools/input/android.js +88 -0
  149. package/dist/server/host/tools/input/android.js.map +1 -0
  150. package/dist/server/host/tools/input/constants.d.ts +14 -0
  151. package/dist/server/host/tools/input/constants.d.ts.map +1 -0
  152. package/dist/server/host/tools/input/constants.js +41 -0
  153. package/dist/server/host/tools/input/constants.js.map +1 -0
  154. package/dist/server/host/tools/input/drag.d.ts +4 -0
  155. package/dist/server/host/tools/input/drag.d.ts.map +1 -0
  156. package/dist/server/host/tools/input/drag.js +76 -0
  157. package/dist/server/host/tools/input/drag.js.map +1 -0
  158. package/dist/server/host/tools/input/index.d.ts +8 -0
  159. package/dist/server/host/tools/input/index.d.ts.map +1 -0
  160. package/dist/server/host/tools/input/index.js +18 -0
  161. package/dist/server/host/tools/input/index.js.map +1 -0
  162. package/dist/server/host/tools/input/longPress.d.ts +4 -0
  163. package/dist/server/host/tools/input/longPress.d.ts.map +1 -0
  164. package/dist/server/host/tools/input/longPress.js +49 -0
  165. package/dist/server/host/tools/input/longPress.js.map +1 -0
  166. package/dist/server/host/tools/input/pressKey.d.ts +4 -0
  167. package/dist/server/host/tools/input/pressKey.d.ts.map +1 -0
  168. package/dist/server/host/tools/input/pressKey.js +42 -0
  169. package/dist/server/host/tools/input/pressKey.js.map +1 -0
  170. package/dist/server/host/tools/input/swipe.d.ts +4 -0
  171. package/dist/server/host/tools/input/swipe.d.ts.map +1 -0
  172. package/dist/server/host/tools/input/swipe.js +71 -0
  173. package/dist/server/host/tools/input/swipe.js.map +1 -0
  174. package/dist/server/host/tools/input/tap.d.ts +4 -0
  175. package/dist/server/host/tools/input/tap.d.ts.map +1 -0
  176. package/dist/server/host/tools/input/tap.js +49 -0
  177. package/dist/server/host/tools/input/tap.js.map +1 -0
  178. package/dist/server/host/tools/input/typeText.d.ts +4 -0
  179. package/dist/server/host/tools/input/typeText.d.ts.map +1 -0
  180. package/dist/server/host/tools/input/typeText.js +52 -0
  181. package/dist/server/host/tools/input/typeText.js.map +1 -0
  182. package/dist/server/host/tools/input/typeTextBatch.d.ts +4 -0
  183. package/dist/server/host/tools/input/typeTextBatch.d.ts.map +1 -0
  184. package/dist/server/host/tools/input/typeTextBatch.js +106 -0
  185. package/dist/server/host/tools/input/typeTextBatch.js.map +1 -0
  186. package/dist/server/instructions.d.ts +2 -0
  187. package/dist/server/instructions.d.ts.map +1 -0
  188. package/dist/server/instructions.js +89 -0
  189. package/dist/server/instructions.js.map +1 -0
  190. package/dist/server/mcpServer.d.ts +0 -12
  191. package/dist/server/mcpServer.d.ts.map +1 -1
  192. package/dist/server/mcpServer.js +26 -877
  193. package/dist/server/mcpServer.js.map +1 -1
  194. package/dist/server/predicate.d.ts +31 -0
  195. package/dist/server/predicate.d.ts.map +1 -0
  196. package/dist/server/predicate.js +104 -0
  197. package/dist/server/predicate.js.map +1 -0
  198. package/dist/server/tools/assert.d.ts +4 -0
  199. package/dist/server/tools/assert.d.ts.map +1 -0
  200. package/dist/server/tools/assert.js +103 -0
  201. package/dist/server/tools/assert.js.map +1 -0
  202. package/dist/server/tools/call.d.ts +4 -0
  203. package/dist/server/tools/call.d.ts.map +1 -0
  204. package/dist/server/tools/call.js +48 -0
  205. package/dist/server/tools/call.js.map +1 -0
  206. package/dist/server/tools/connectionStatus.d.ts +4 -0
  207. package/dist/server/tools/connectionStatus.d.ts.map +1 -0
  208. package/dist/server/tools/connectionStatus.js +41 -0
  209. package/dist/server/tools/connectionStatus.js.map +1 -0
  210. package/dist/server/tools/describeTool.d.ts +4 -0
  211. package/dist/server/tools/describeTool.d.ts.map +1 -0
  212. package/dist/server/tools/describeTool.js +149 -0
  213. package/dist/server/tools/describeTool.js.map +1 -0
  214. package/dist/server/tools/listTools.d.ts +4 -0
  215. package/dist/server/tools/listTools.d.ts.map +1 -0
  216. package/dist/server/tools/listTools.js +116 -0
  217. package/dist/server/tools/listTools.js.map +1 -0
  218. package/dist/server/tools/waitUntil.d.ts +4 -0
  219. package/dist/server/tools/waitUntil.d.ts.map +1 -0
  220. package/dist/server/tools/waitUntil.js +169 -0
  221. package/dist/server/tools/waitUntil.js.map +1 -0
  222. package/package.json +2 -2
  223. package/dist/babel/testIdPlugin.d.ts.map +0 -1
  224. package/dist/babel/testIdPlugin.js +0 -585
  225. package/dist/babel/testIdPlugin.js.map +0 -1
  226. package/dist/modules/fiberTree/hooks.d.ts.map +0 -1
  227. package/dist/modules/fiberTree/hooks.js +0 -550
  228. package/dist/modules/fiberTree/hooks.js.map +0 -1
  229. package/dist/modules/fiberTree/utils.d.ts +0 -39
  230. package/dist/modules/fiberTree/utils.d.ts.map +0 -1
  231. package/dist/modules/fiberTree/utils.js +0 -641
  232. package/dist/modules/fiberTree/utils.js.map +0 -1
  233. package/dist/server/host/deviceResolver.d.ts.map +0 -1
  234. package/dist/server/host/deviceResolver.js +0 -621
  235. package/dist/server/host/deviceResolver.js.map +0 -1
  236. package/dist/server/host/tools/input.d.ts +0 -10
  237. package/dist/server/host/tools/input.d.ts.map +0 -1
  238. package/dist/server/host/tools/input.js +0 -503
  239. package/dist/server/host/tools/input.js.map +0 -1
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enrichDevicesWithClientStatus = void 0;
4
+ const processRunner_1 = require("../../../server/host/processRunner");
5
+ const list_1 = require("./list");
6
+ const enrichDevicesWithClientStatus = async (bridge, runner) => {
7
+ const iosPromise = (0, list_1.listIosSimulators)(runner)
8
+ .then((sims) => {
9
+ return { ok: true, sims };
10
+ })
11
+ .catch((err) => {
12
+ if (err instanceof processRunner_1.ProcessNotFoundError) {
13
+ return { error: 'xcrun not found', ok: false };
14
+ }
15
+ return { error: err.message, ok: false };
16
+ });
17
+ const androidPromise = (0, list_1.listAndroidDevices)(runner)
18
+ .then((devices) => {
19
+ return { devices, ok: true };
20
+ })
21
+ .catch((err) => {
22
+ if (err instanceof processRunner_1.ProcessNotFoundError) {
23
+ return { error: 'adb not found', ok: false };
24
+ }
25
+ return { error: err.message, ok: false };
26
+ });
27
+ const [iosRaw, androidRaw] = await Promise.all([iosPromise, androidPromise]);
28
+ const clients = bridge.listClients();
29
+ const iosClients = clients.filter((c) => {
30
+ return c.platform === 'ios';
31
+ });
32
+ const androidClients = clients.filter((c) => {
33
+ return c.platform === 'android';
34
+ });
35
+ let iosOut;
36
+ if (iosRaw.ok) {
37
+ const enriched = iosRaw.sims.map((sim) => {
38
+ return { ...sim, connected: false };
39
+ });
40
+ for (const client of iosClients) {
41
+ if (!client.label) {
42
+ continue;
43
+ }
44
+ const label = client.label;
45
+ const exact = enriched.filter((s) => {
46
+ return s.state === 'Booted' && !s.connected && s.name === label;
47
+ });
48
+ if (exact.length === 1) {
49
+ exact[0].connected = true;
50
+ exact[0].clientId = client.id;
51
+ continue;
52
+ }
53
+ const substring = enriched.filter((s) => {
54
+ return s.state === 'Booted' && !s.connected && s.name.includes(label);
55
+ });
56
+ if (substring.length === 1) {
57
+ substring[0].connected = true;
58
+ substring[0].clientId = client.id;
59
+ }
60
+ }
61
+ enriched.sort((a, b) => {
62
+ const rank = (item) => {
63
+ if (item.connected) {
64
+ return 0;
65
+ }
66
+ return item.state === 'Booted' ? 1 : 2;
67
+ };
68
+ const aRank = rank(a);
69
+ const bRank = rank(b);
70
+ if (aRank !== bRank) {
71
+ return aRank - bRank;
72
+ }
73
+ if (a.connected && b.connected) {
74
+ return (a.clientId ?? '').localeCompare(b.clientId ?? '');
75
+ }
76
+ return a.name.localeCompare(b.name);
77
+ });
78
+ iosOut = enriched;
79
+ }
80
+ else {
81
+ iosOut = { error: iosRaw.error };
82
+ }
83
+ let androidOut;
84
+ if (androidRaw.ok) {
85
+ const enriched = androidRaw.devices.map((d) => {
86
+ return { ...d, connected: false };
87
+ });
88
+ const onlineIdx = enriched.findIndex((d) => {
89
+ return d.state === 'device';
90
+ });
91
+ const onlineCount = enriched.filter((d) => {
92
+ return d.state === 'device';
93
+ }).length;
94
+ if (onlineCount === 1 && androidClients.length === 1 && onlineIdx >= 0) {
95
+ enriched[onlineIdx].connected = true;
96
+ enriched[onlineIdx].clientId = androidClients[0].id;
97
+ }
98
+ enriched.sort((a, b) => {
99
+ const rank = (item) => {
100
+ if (item.connected) {
101
+ return 0;
102
+ }
103
+ return item.state === 'device' ? 1 : 2;
104
+ };
105
+ const aRank = rank(a);
106
+ const bRank = rank(b);
107
+ if (aRank !== bRank) {
108
+ return aRank - bRank;
109
+ }
110
+ if (a.connected && b.connected) {
111
+ return (a.clientId ?? '').localeCompare(b.clientId ?? '');
112
+ }
113
+ return a.serial.localeCompare(b.serial);
114
+ });
115
+ androidOut = enriched;
116
+ }
117
+ else {
118
+ androidOut = { error: androidRaw.error };
119
+ }
120
+ return { android: androidOut, ios: iosOut };
121
+ };
122
+ exports.enrichDevicesWithClientStatus = enrichDevicesWithClientStatus;
123
+ //# sourceMappingURL=enrich.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrich.js","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/enrich.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type ProcessRunner } from '../../../server/host/processRunner';
2
+ import { type HostContext } from '../../../server/host/types';
3
+ import { type DeviceResolution } from './types';
4
+ interface ResolveOptions {
5
+ platform?: 'android' | 'ios';
6
+ serial?: string;
7
+ udid?: string;
8
+ }
9
+ export declare const resolveDevice: (ctx: HostContext, options: ResolveOptions, runner: ProcessRunner) => Promise<DeviceResolution>;
10
+ export { clearDeviceCache, listAndroidDevices, listIosRealDevices, listIosSimulators, } from './list';
11
+ export { enrichDevicesWithClientStatus } from './enrich';
12
+ export { type AndroidDevice, type DeviceKind, type DeviceResolution, type EnrichedAndroidDevice, type EnrichedDeviceList, type EnrichedIosSim, type IosRealDevice, type IosSimulator, type ResolvedDevice, } from './types';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAKvD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,UAAU,cAAc;IACtB,QAAQ,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,aAAa,QACnB,WAAW,WACP,cAAc,UACf,aAAa,KACpB,OAAO,CAAC,gBAAgB,CAuD1B,CAAC;AAEF,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,QAAQ,CAAC;AAChB,OAAO,EAAE,6BAA6B,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enrichDevicesWithClientStatus = exports.listIosSimulators = exports.listIosRealDevices = exports.listAndroidDevices = exports.clearDeviceCache = exports.resolveDevice = void 0;
4
+ const byClient_1 = require("./byClient");
5
+ const byId_1 = require("./byId");
6
+ const scan_1 = require("./scan");
7
+ const resolveDevice = async (ctx, options, runner) => {
8
+ // Step 0: explicit native identifier — highest priority, bypasses everything else
9
+ if (options.udid) {
10
+ return (0, byId_1.resolveIosByUdid)(options.udid, runner);
11
+ }
12
+ if (options.serial) {
13
+ return (0, byId_1.resolveAndroidBySerial)(options.serial, runner);
14
+ }
15
+ // Step 1: explicit clientId — resolve it, no bare-scan fallback
16
+ if (ctx.requestedClientId) {
17
+ const client = ctx.bridge.getClient(ctx.requestedClientId);
18
+ if (!client) {
19
+ const available = ctx.bridge
20
+ .listClients()
21
+ .map((c) => {
22
+ return c.id;
23
+ })
24
+ .join(', ') || '(none)';
25
+ return {
26
+ error: `Client '${ctx.requestedClientId}' not connected. Available: ${available}`,
27
+ ok: false,
28
+ };
29
+ }
30
+ return (0, byClient_1.resolveClientToDevice)(client, runner);
31
+ }
32
+ // Step 2: exactly one connected client matching the platform filter → auto-pick
33
+ const clients = ctx.bridge.listClients();
34
+ const filtered = options.platform
35
+ ? clients.filter((c) => {
36
+ return c.platform === options.platform;
37
+ })
38
+ : clients;
39
+ if (filtered.length === 1) {
40
+ return (0, byClient_1.resolveClientToDevice)(filtered[0], runner);
41
+ }
42
+ // Step 3: multiple matching clients → ambiguous, error
43
+ if (filtered.length > 1) {
44
+ const labels = filtered
45
+ .map((c) => {
46
+ return c.label ? `${c.id} (${c.label})` : c.id;
47
+ })
48
+ .join(', ');
49
+ return {
50
+ error: `Multiple clients connected: ${labels}. Specify clientId.`,
51
+ ok: false,
52
+ };
53
+ }
54
+ // Step 4: no clients matched — fall through to bare platform scan
55
+ return (0, scan_1.scanForDevice)(options.platform, runner);
56
+ };
57
+ exports.resolveDevice = resolveDevice;
58
+ var list_1 = require("./list");
59
+ Object.defineProperty(exports, "clearDeviceCache", { enumerable: true, get: function () { return list_1.clearDeviceCache; } });
60
+ Object.defineProperty(exports, "listAndroidDevices", { enumerable: true, get: function () { return list_1.listAndroidDevices; } });
61
+ Object.defineProperty(exports, "listIosRealDevices", { enumerable: true, get: function () { return list_1.listIosRealDevices; } });
62
+ Object.defineProperty(exports, "listIosSimulators", { enumerable: true, get: function () { return list_1.listIosSimulators; } });
63
+ var enrich_1 = require("./enrich");
64
+ Object.defineProperty(exports, "enrichDevicesWithClientStatus", { enumerable: true, get: function () { return enrich_1.enrichDevicesWithClientStatus; } });
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/index.ts"],"names":[],"mappings":";;;AAGA,yCAAmD;AACnD,iCAAkE;AAClE,iCAAuC;AAShC,MAAM,aAAa,GAAG,KAAK,EAChC,GAAgB,EAChB,OAAuB,EACvB,MAAqB,EACM,EAAE;IAC7B,kFAAkF;IAClF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,IAAA,uBAAgB,EAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,IAAA,6BAAsB,EAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC;IAED,gEAAgE;IAChE,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,SAAS,GACb,GAAG,CAAC,MAAM;iBACP,WAAW,EAAE;iBACb,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACT,OAAO,CAAC,CAAC,EAAE,CAAC;YACd,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;YAC5B,OAAO;gBACL,KAAK,EAAE,WAAW,GAAG,CAAC,iBAAiB,+BAA+B,SAAS,EAAE;gBACjF,EAAE,EAAE,KAAK;aACV,CAAC;QACJ,CAAC;QACD,OAAO,IAAA,gCAAqB,EAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,gFAAgF;IAChF,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ;QAC/B,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACnB,OAAO,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC;QACzC,CAAC,CAAC;QACJ,CAAC,CAAC,OAAO,CAAC;IAEZ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAA,gCAAqB,EAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,uDAAuD;IACvD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,QAAQ;aACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO;YACL,KAAK,EAAE,+BAA+B,MAAM,qBAAqB;YACjE,EAAE,EAAE,KAAK;SACV,CAAC;IACJ,CAAC;IAED,kEAAkE;IAClE,OAAO,IAAA,oBAAa,EAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC,CAAC;AA3DW,QAAA,aAAa,iBA2DxB;AAEF,+BAKgB;AAJd,wGAAA,gBAAgB,OAAA;AAChB,0GAAA,kBAAkB,OAAA;AAClB,0GAAA,kBAAkB,OAAA;AAClB,yGAAA,iBAAiB,OAAA;AAEnB,mCAAyD;AAAhD,uHAAA,6BAA6B,OAAA"}
@@ -0,0 +1,10 @@
1
+ import { type ProcessRunner } from '../../../server/host/processRunner';
2
+ import { type AndroidDevice, type DeviceResolution, type IosRealDevice, type IosSimulator } from './types';
3
+ export declare const clearDeviceCache: () => void;
4
+ export declare const XCRUN_MISSING_ERROR = "xcrun not found. iOS host tools require Xcode command line tools (macOS only).";
5
+ export declare const ADB_MISSING_ERROR = "adb not found. Android host tools require Android platform-tools on PATH.";
6
+ export declare const toDeviceError: (err: unknown, context: string, toolMissing: string) => DeviceResolution;
7
+ export declare const listIosSimulators: (runner: ProcessRunner) => Promise<IosSimulator[]>;
8
+ export declare const listIosRealDevices: (runner: ProcessRunner) => Promise<IosRealDevice[]>;
9
+ export declare const listAndroidDevices: (runner: ProcessRunner) => Promise<AndroidDevice[]>;
10
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/list.ts"],"names":[],"mappings":"AAMA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEvF,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,SAAS,CAAC;AAcjB,eAAO,MAAM,gBAAgB,QAAO,IAInC,CAAC;AAEF,eAAO,MAAM,mBAAmB,mFACkD,CAAC;AACnF,eAAO,MAAM,iBAAiB,8EAC+C,CAAC;AAK9E,eAAO,MAAM,aAAa,QACnB,OAAO,WACH,MAAM,eACF,MAAM,KAClB,gBAKF,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAkB,aAAa,KAAG,OAAO,CAAC,YAAY,EAAE,CAyBrF,CAAC;AAKF,eAAO,MAAM,kBAAkB,WAAkB,aAAa,KAAG,OAAO,CAAC,aAAa,EAAE,CA2CvF,CAAC;AAEF,eAAO,MAAM,kBAAkB,WAAkB,aAAa,KAAG,OAAO,CAAC,aAAa,EAAE,CAwBvF,CAAC"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listAndroidDevices = exports.listIosRealDevices = exports.listIosSimulators = exports.toDeviceError = exports.ADB_MISSING_ERROR = exports.XCRUN_MISSING_ERROR = exports.clearDeviceCache = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const node_fs_1 = require("node:fs");
6
+ const promises_1 = require("node:fs/promises");
7
+ const node_os_1 = require("node:os");
8
+ const node_path_1 = require("node:path");
9
+ const processRunner_1 = require("../../../server/host/processRunner");
10
+ const CACHE_TTL_MS = 5_000;
11
+ const LIST_TIMEOUT_MS = 5_000;
12
+ let iosCache = null;
13
+ let iosRealCache = null;
14
+ let androidCache = null;
15
+ const clearDeviceCache = () => {
16
+ iosCache = null;
17
+ iosRealCache = null;
18
+ androidCache = null;
19
+ };
20
+ exports.clearDeviceCache = clearDeviceCache;
21
+ exports.XCRUN_MISSING_ERROR = 'xcrun not found. iOS host tools require Xcode command line tools (macOS only).';
22
+ exports.ADB_MISSING_ERROR = 'adb not found. Android host tools require Android platform-tools on PATH.';
23
+ // Map a thrown error to a user-facing DeviceResolution error. Handles the
24
+ // common ProcessNotFoundError → "install the toolchain" message; everything
25
+ // else gets wrapped as a context-prefixed message.
26
+ const toDeviceError = (err, context, toolMissing) => {
27
+ if (err instanceof processRunner_1.ProcessNotFoundError) {
28
+ return { error: toolMissing, ok: false };
29
+ }
30
+ return { error: `${context}: ${err.message}`, ok: false };
31
+ };
32
+ exports.toDeviceError = toDeviceError;
33
+ const listIosSimulators = async (runner) => {
34
+ if (iosCache && Date.now() - iosCache.timestamp < CACHE_TTL_MS) {
35
+ return iosCache.result;
36
+ }
37
+ const proc = await runner('xcrun', ['simctl', 'list', 'devices', '--json'], {
38
+ timeoutMs: LIST_TIMEOUT_MS,
39
+ });
40
+ if (proc.exitCode !== 0) {
41
+ throw new Error(`xcrun simctl list failed (exit ${proc.exitCode}): ${proc.stderr.toString('utf8').trim().slice(0, 500)}`);
42
+ }
43
+ const parsed = JSON.parse(proc.stdout.toString('utf8'));
44
+ const out = [];
45
+ for (const runtime of Object.values(parsed.devices ?? {})) {
46
+ for (const d of runtime) {
47
+ if (typeof d.udid === 'string' && typeof d.name === 'string' && typeof d.state === 'string') {
48
+ out.push({ name: d.name, state: d.state, udid: d.udid });
49
+ }
50
+ }
51
+ }
52
+ iosCache = { result: out, timestamp: Date.now() };
53
+ return out;
54
+ };
55
+ exports.listIosSimulators = listIosSimulators;
56
+ // Paired physical iOS devices come from `xcrun devicectl` — simctl knows
57
+ // nothing about them. The JSON output of `list devices` is the only stable
58
+ // integration surface (its stdout has a human-readable header first).
59
+ const listIosRealDevices = async (runner) => {
60
+ if (iosRealCache && Date.now() - iosRealCache.timestamp < CACHE_TTL_MS) {
61
+ return iosRealCache.result;
62
+ }
63
+ const tmpPath = (0, node_path_1.join)((0, node_os_1.tmpdir)(), `rnmcp-devicectl-${(0, node_crypto_1.randomUUID)()}.json`);
64
+ try {
65
+ const proc = await runner('xcrun', ['devicectl', 'list', 'devices', '--json-output', tmpPath], {
66
+ timeoutMs: LIST_TIMEOUT_MS,
67
+ });
68
+ if (proc.exitCode !== 0) {
69
+ throw new Error(`xcrun devicectl list failed (exit ${proc.exitCode}): ${proc.stderr.toString('utf8').trim().slice(0, 500)}`);
70
+ }
71
+ const raw = (0, node_fs_1.readFileSync)(tmpPath, 'utf8');
72
+ const parsed = JSON.parse(raw);
73
+ const devices = parsed.result?.devices ?? [];
74
+ const out = [];
75
+ for (const d of devices) {
76
+ if (d.hardwareProperties?.platform !== 'iOS')
77
+ continue;
78
+ const id = d.identifier;
79
+ const name = d.deviceProperties?.name;
80
+ const pairingState = d.connectionProperties?.pairingState;
81
+ if (typeof id === 'string' && typeof name === 'string' && typeof pairingState === 'string') {
82
+ out.push({ coreDeviceIdentifier: id, name, pairingState });
83
+ }
84
+ }
85
+ iosRealCache = { result: out, timestamp: Date.now() };
86
+ return out;
87
+ }
88
+ finally {
89
+ (0, promises_1.rm)(tmpPath, { force: true }).catch(() => {
90
+ // best-effort
91
+ });
92
+ }
93
+ };
94
+ exports.listIosRealDevices = listIosRealDevices;
95
+ const listAndroidDevices = async (runner) => {
96
+ if (androidCache && Date.now() - androidCache.timestamp < CACHE_TTL_MS) {
97
+ return androidCache.result;
98
+ }
99
+ const proc = await runner('adb', ['devices'], { timeoutMs: LIST_TIMEOUT_MS });
100
+ if (proc.exitCode !== 0) {
101
+ throw new Error(`adb devices failed (exit ${proc.exitCode}): ${proc.stderr.toString('utf8').trim().slice(0, 500)}`);
102
+ }
103
+ const lines = proc.stdout.toString('utf8').split('\n');
104
+ const out = [];
105
+ for (const raw of lines.slice(1)) {
106
+ const line = raw.trim();
107
+ if (!line) {
108
+ continue;
109
+ }
110
+ const match = line.match(/^(\S+)\s+(\S+)\s*$/);
111
+ if (match?.[1] && match[2]) {
112
+ out.push({ serial: match[1], state: match[2] });
113
+ }
114
+ }
115
+ androidCache = { result: out, timestamp: Date.now() };
116
+ return out;
117
+ };
118
+ exports.listAndroidDevices = listAndroidDevices;
119
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type ProcessRunner } from '../../../server/host/processRunner';
2
+ import { type DeviceResolution } from './types';
3
+ export declare const scanForDevice: (platform: "android" | "ios" | undefined, runner: ProcessRunner) => Promise<DeviceResolution>;
4
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AASjE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA+EhD,eAAO,MAAM,aAAa,aACd,SAAS,GAAG,KAAK,GAAG,SAAS,UAC/B,aAAa,KACpB,OAAO,CAAC,gBAAgB,CAmB1B,CAAC"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scanForDevice = void 0;
4
+ const list_1 = require("./list");
5
+ const scanIosDevices = async (runner) => {
6
+ try {
7
+ const sims = await (0, list_1.listIosSimulators)(runner);
8
+ const booted = sims.filter((s) => {
9
+ return s.state === 'Booted';
10
+ });
11
+ if (booted.length === 0) {
12
+ return {
13
+ error: 'No booted iOS simulator found. Boot one via Simulator.app or `xcrun simctl boot <udid>`.',
14
+ ok: false,
15
+ };
16
+ }
17
+ if (booted.length === 1) {
18
+ const only = booted[0];
19
+ return {
20
+ device: {
21
+ displayName: only.name,
22
+ kind: 'simulator',
23
+ nativeId: only.udid,
24
+ platform: 'ios',
25
+ },
26
+ ok: true,
27
+ };
28
+ }
29
+ const list = booted
30
+ .map((s) => {
31
+ return `${s.name} (${s.udid})`;
32
+ })
33
+ .join(', ');
34
+ return {
35
+ error: `Multiple iOS simulators booted: ${list}. Specify clientId or a more precise target.`,
36
+ ok: false,
37
+ };
38
+ }
39
+ catch (err) {
40
+ return (0, list_1.toDeviceError)(err, 'Failed to list iOS simulators', list_1.XCRUN_MISSING_ERROR);
41
+ }
42
+ };
43
+ const scanAndroidDevices = async (runner) => {
44
+ try {
45
+ const devices = await (0, list_1.listAndroidDevices)(runner);
46
+ const online = devices.filter((d) => {
47
+ return d.state === 'device';
48
+ });
49
+ if (online.length === 0) {
50
+ return {
51
+ error: 'No online Android device found. Start an emulator or connect a device.',
52
+ ok: false,
53
+ };
54
+ }
55
+ if (online.length === 1) {
56
+ const only = online[0];
57
+ return {
58
+ device: {
59
+ displayName: only.serial,
60
+ kind: 'real-device',
61
+ nativeId: only.serial,
62
+ platform: 'android',
63
+ },
64
+ ok: true,
65
+ };
66
+ }
67
+ const list = online
68
+ .map((d) => {
69
+ return d.serial;
70
+ })
71
+ .join(', ');
72
+ return {
73
+ error: `Multiple Android devices online: ${list}. Specify clientId.`,
74
+ ok: false,
75
+ };
76
+ }
77
+ catch (err) {
78
+ return (0, list_1.toDeviceError)(err, 'Failed to list Android devices', list_1.ADB_MISSING_ERROR);
79
+ }
80
+ };
81
+ const scanForDevice = async (platform, runner) => {
82
+ if (platform === 'ios') {
83
+ return scanIosDevices(runner);
84
+ }
85
+ if (platform === 'android') {
86
+ return scanAndroidDevices(runner);
87
+ }
88
+ const iosResult = await scanIosDevices(runner);
89
+ if (iosResult.ok) {
90
+ return iosResult;
91
+ }
92
+ const androidResult = await scanAndroidDevices(runner);
93
+ if (androidResult.ok) {
94
+ return androidResult;
95
+ }
96
+ return {
97
+ error: `No device available. iOS: ${iosResult.error} Android: ${androidResult.error}`,
98
+ ok: false,
99
+ };
100
+ };
101
+ exports.scanForDevice = scanForDevice;
102
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/scan.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,3 @@
1
- import { type Bridge } from '../../server/bridge';
2
- import { type ProcessRunner } from './processRunner';
3
- import { type HostContext } from './types';
4
1
  export interface IosSimulator {
5
2
  name: string;
6
3
  state: string;
@@ -46,16 +43,4 @@ export type DeviceResolution = {
46
43
  error: string;
47
44
  ok: false;
48
45
  };
49
- interface ResolveOptions {
50
- platform?: 'android' | 'ios';
51
- serial?: string;
52
- udid?: string;
53
- }
54
- export declare const clearDeviceCache: () => void;
55
- export declare const listIosSimulators: (runner: ProcessRunner) => Promise<IosSimulator[]>;
56
- export declare const listIosRealDevices: (runner: ProcessRunner) => Promise<IosRealDevice[]>;
57
- export declare const listAndroidDevices: (runner: ProcessRunner) => Promise<AndroidDevice[]>;
58
- export declare const resolveDevice: (ctx: HostContext, options: ResolveOptions, runner: ProcessRunner) => Promise<DeviceResolution>;
59
- export declare const enrichDevicesWithClientStatus: (bridge: Bridge, runner: ProcessRunner) => Promise<EnrichedDeviceList>;
60
- export {};
61
- //# sourceMappingURL=deviceResolver.d.ts.map
46
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,WAAW,CAAC;AAErD,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,SAAS,GAAG,KAAK,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,qBAAqB,EAAE,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,GAAG,EAAE,cAAc,EAAE,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C;AAED,MAAM,MAAM,gBAAgB,GAAG;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/server/host/deviceResolver/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import { type AppTargetError } from '../../../../server/host/helpers';
2
+ import { type ProcessRunner } from '../../../../server/host/processRunner';
3
+ export declare const tapAndroid: (serial: string, x: number, y: number, runner: ProcessRunner) => Promise<{
4
+ ok: true;
5
+ } | AppTargetError>;
6
+ export declare const swipeAndroid: (serial: string, x1: number, y1: number, x2: number, y2: number, durationMs: number, runner: ProcessRunner) => Promise<{
7
+ ok: true;
8
+ } | AppTargetError>;
9
+ export declare const typeTextAndroid: (serial: string, text: string, submit: boolean, runner: ProcessRunner) => Promise<{
10
+ ok: true;
11
+ } | AppTargetError>;
12
+ export declare const pressKeyAndroid: (serial: string, key: string, runner: ProcessRunner) => Promise<{
13
+ ok: true;
14
+ } | AppTargetError>;
15
+ //# sourceMappingURL=android.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../../../../../src/server/host/tools/input/android.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AA6CvF,eAAO,MAAM,UAAU,WACb,MAAM,KACX,MAAM,KACN,MAAM,UACD,aAAa,KACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,cAAc,CAEvC,CAAC;AAEF,eAAO,MAAM,YAAY,WACf,MAAM,MACV,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,cACE,MAAM,UACV,aAAa,KACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,cAAc,CAOvC,CAAC;AAEF,eAAO,MAAM,eAAe,WAClB,MAAM,QACR,MAAM,UACJ,OAAO,UACP,aAAa,KACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,cAAc,CAkCvC,CAAC;AAEF,eAAO,MAAM,eAAe,WAClB,MAAM,OACT,MAAM,UACH,aAAa,KACpB,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG,cAAc,CAQvC,CAAC"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pressKeyAndroid = exports.typeTextAndroid = exports.swipeAndroid = exports.tapAndroid = void 0;
4
+ const processRunner_1 = require("../../../../server/host/processRunner");
5
+ const constants_1 = require("./constants");
6
+ // `adb shell input text` maps characters through the default virtual keyboard
7
+ // keymap, which only covers ASCII. Anything outside that set crashes the input
8
+ // service with an opaque "Attempt to get length of null array" NPE. Refuse it
9
+ // up front with an actionable message.
10
+ // eslint-disable-next-line no-control-regex
11
+ const NON_ASCII_RE = /[^\x00-\x7F]/;
12
+ const escapeAdbInputText = (text) => {
13
+ const spaced = text.replace(/\s/g, '%s');
14
+ return spaced.replace(/([\\'"`$&|;<>()[\]{}*?!#~])/g, '\\$1');
15
+ };
16
+ const runAdbInput = async (serial, args, runner, action) => {
17
+ try {
18
+ const proc = await runner('adb', ['-s', serial, 'shell', 'input', ...args], {
19
+ timeoutMs: constants_1.INPUT_TIMEOUT_MS,
20
+ });
21
+ if (proc.timedOut) {
22
+ return { error: `Android ${action} timed out after ${constants_1.INPUT_TIMEOUT_MS}ms` };
23
+ }
24
+ if (proc.exitCode !== 0) {
25
+ return {
26
+ error: `adb shell input ${action} failed (exit ${proc.exitCode}): ${proc.stderr.toString('utf8').trim().slice(0, 500)}`,
27
+ };
28
+ }
29
+ return { ok: true };
30
+ }
31
+ catch (err) {
32
+ if (err instanceof processRunner_1.ProcessNotFoundError) {
33
+ return {
34
+ error: 'adb not found. Android host tools require Android platform-tools on PATH.',
35
+ };
36
+ }
37
+ return { error: `Failed to run Android ${action}: ${err.message}` };
38
+ }
39
+ };
40
+ const tapAndroid = (serial, x, y, runner) => {
41
+ return runAdbInput(serial, ['tap', String(x), String(y)], runner, 'tap');
42
+ };
43
+ exports.tapAndroid = tapAndroid;
44
+ const swipeAndroid = (serial, x1, y1, x2, y2, durationMs, runner) => {
45
+ return runAdbInput(serial, ['swipe', String(x1), String(y1), String(x2), String(y2), String(durationMs)], runner, 'swipe');
46
+ };
47
+ exports.swipeAndroid = swipeAndroid;
48
+ const typeTextAndroid = async (serial, text, submit, runner) => {
49
+ if (NON_ASCII_RE.test(text)) {
50
+ return {
51
+ error: 'Android type_text only supports ASCII — `adb shell input text` has no code path for non-ASCII characters. Workarounds: tap the target field then drive the content some other way (e.g. fiber_tree__call on onChangeText), or paste from the device clipboard via a helper app.',
52
+ };
53
+ }
54
+ // Select all + delete existing text first (consistent with iOS behavior).
55
+ // `input keycombination` sends keys simultaneously (Ctrl+A = select all).
56
+ try {
57
+ const selAll = await runner('adb', ['-s', serial, 'shell', 'input', 'keycombination', '113', '29'], {
58
+ timeoutMs: constants_1.INPUT_TIMEOUT_MS,
59
+ });
60
+ if (selAll.exitCode === 0) {
61
+ await runAdbInput(serial, ['keyevent', 'KEYCODE_DEL'], runner, 'clear');
62
+ }
63
+ }
64
+ catch {
65
+ // keycombination not supported — skip clear, just append
66
+ }
67
+ const escaped = escapeAdbInputText(text);
68
+ const typed = await runAdbInput(serial, ['text', escaped], runner, 'text');
69
+ if ('error' in typed) {
70
+ return typed;
71
+ }
72
+ if (submit) {
73
+ return runAdbInput(serial, ['keyevent', 'KEYCODE_ENTER'], runner, 'submit');
74
+ }
75
+ return typed;
76
+ };
77
+ exports.typeTextAndroid = typeTextAndroid;
78
+ const pressKeyAndroid = (serial, key, runner) => {
79
+ const keycode = constants_1.ANDROID_KEYCODES[key];
80
+ if (!keycode) {
81
+ return Promise.resolve({
82
+ error: `Unknown key '${key}'. Supported: ${constants_1.KEY_NAMES.join(', ')}.`,
83
+ });
84
+ }
85
+ return runAdbInput(serial, ['keyevent', keycode], runner, 'keyevent');
86
+ };
87
+ exports.pressKeyAndroid = pressKeyAndroid;
88
+ //# sourceMappingURL=android.js.map