@kaeawc/auto-mobile 0.0.92 → 0.0.93

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 (257) hide show
  1. package/dist/build-info.json +12 -12
  2. package/dist/schemas/test-plan.schema.json +370 -52
  3. package/dist/src/{chunk-jhnbfj19.js → chunk-00167wan.js} +5 -5
  4. package/dist/src/chunk-0jrrsnc9.js +6 -0
  5. package/dist/src/chunk-0n6swkwg.js +5 -0
  6. package/dist/src/chunk-0qsy1qsx.js +57 -0
  7. package/dist/src/chunk-11m8wj8j.js +237 -0
  8. package/dist/src/{chunk-4pfftt07.js → chunk-1p7xf5kb.js} +3 -3
  9. package/dist/src/chunk-23p5f095.js +4 -0
  10. package/dist/src/{chunk-a4k9rt7z.js → chunk-26k317v5.js} +3 -3
  11. package/dist/src/chunk-284ptqa4.js +7 -0
  12. package/dist/src/chunk-28re4xrg.js +4 -0
  13. package/dist/src/chunk-2f9rkmhx.js +5 -0
  14. package/dist/src/chunk-2fxdh48t.js +4 -0
  15. package/dist/src/chunk-2tbdrbt6.js +4 -0
  16. package/dist/src/chunk-2tqzq5qh.js +971 -0
  17. package/dist/src/chunk-32gvv9b4.js +21 -0
  18. package/dist/src/chunk-3f3t1x97.js +8 -0
  19. package/dist/src/chunk-3fspkbc7.js +4 -0
  20. package/dist/src/chunk-3qwrzxh0.js +11 -0
  21. package/dist/src/chunk-3sy6ahhz.js +26 -0
  22. package/dist/src/chunk-3vg455e6.js +4 -0
  23. package/dist/src/chunk-3xkpk44w.js +5 -0
  24. package/dist/src/chunk-3y6eykz9.js +4 -0
  25. package/dist/src/chunk-49bsqdx3.js +4 -0
  26. package/dist/src/chunk-4hw3665t.js +42 -0
  27. package/dist/src/chunk-58wzr3mt.js +5 -0
  28. package/dist/src/chunk-5d2hft6c.js +5 -0
  29. package/dist/src/chunk-5snsn9cf.js +4 -0
  30. package/dist/src/chunk-5tm9mn47.js +54 -0
  31. package/dist/src/chunk-5zc77a5t.js +4 -0
  32. package/dist/src/chunk-64j0majr.js +19 -0
  33. package/dist/src/chunk-65y8v4td.js +17 -0
  34. package/dist/src/chunk-6awz7vhq.js +5 -0
  35. package/dist/src/{chunk-stfzjr9y.js → chunk-6bznss4t.js} +5 -5
  36. package/dist/src/chunk-6ep7f5ge.js +4 -0
  37. package/dist/src/{chunk-0dfnyfkh.js → chunk-6wt9rgjf.js} +3 -3
  38. package/dist/src/chunk-6xmss8er.js +8 -0
  39. package/dist/src/chunk-710rxz9y.js +5 -0
  40. package/dist/src/chunk-7cs2da62.js +5 -0
  41. package/dist/src/chunk-7g103b54.js +4 -0
  42. package/dist/src/chunk-7j5vj4pa.js +4 -0
  43. package/dist/src/chunk-7rz9898k.js +5 -0
  44. package/dist/src/chunk-7tw8x05v.js +4 -0
  45. package/dist/src/chunk-7zy586cb.js +4 -0
  46. package/dist/src/{chunk-r0f1q783.js → chunk-8037tzzj.js} +3 -3
  47. package/dist/src/chunk-84nanf8s.js +5 -0
  48. package/dist/src/{chunk-950qcq1e.js → chunk-8g1922rp.js} +4 -4
  49. package/dist/src/chunk-8gvwcv2p.js +4 -0
  50. package/dist/src/{chunk-sz1a7p43.js → chunk-8ph29g99.js} +1 -1
  51. package/dist/src/chunk-8thrmfat.js +4 -0
  52. package/dist/src/chunk-8zgzzs7k.js +78 -0
  53. package/dist/src/chunk-97b1zmaq.js +4 -0
  54. package/dist/src/chunk-9fth9ayh.js +4 -0
  55. package/dist/src/chunk-9j6anhjr.js +4 -0
  56. package/dist/src/{chunk-w7zsh13a.js → chunk-aabchzxk.js} +4 -4
  57. package/dist/src/{chunk-wry6skrm.js → chunk-ayp07wbb.js} +1 -1
  58. package/dist/src/chunk-bfjwqk8q.js +4 -0
  59. package/dist/src/{chunk-jdqvcq0a.js → chunk-bfw6125s.js} +3 -3
  60. package/dist/src/chunk-bnhscm2n.js +4 -0
  61. package/dist/src/chunk-bxmsax22.js +5 -0
  62. package/dist/src/chunk-c1vs4g1n.js +4 -0
  63. package/dist/src/chunk-ct3e7yng.js +4 -0
  64. package/dist/src/{chunk-8en08r7q.js → chunk-cyy71ggq.js} +3 -3
  65. package/dist/src/chunk-ddzkz92z.js +4 -0
  66. package/dist/src/chunk-dgrbdpb7.js +9 -0
  67. package/dist/src/chunk-drdz8hee.js +5 -0
  68. package/dist/src/chunk-e98dqnc9.js +145 -0
  69. package/dist/src/chunk-eersndy7.js +5 -0
  70. package/dist/src/chunk-eggq53ks.js +4 -0
  71. package/dist/src/chunk-f2dya7cs.js +4 -0
  72. package/dist/src/chunk-fbakd6cw.js +4 -0
  73. package/dist/src/chunk-fgb98zjj.js +5 -0
  74. package/dist/src/chunk-fmpad823.js +5 -0
  75. package/dist/src/{chunk-v90es00d.js → chunk-g04bwyj3.js} +2 -2
  76. package/dist/src/chunk-g0xr8zw0.js +4 -0
  77. package/dist/src/chunk-g3rjs80x.js +4 -0
  78. package/dist/src/chunk-g78rtrfv.js +4 -0
  79. package/dist/src/{chunk-r20pe1nv.js → chunk-g7tmjbkt.js} +3 -3
  80. package/dist/src/chunk-gabgv3y5.js +4 -0
  81. package/dist/src/chunk-gmr45m8f.js +4 -0
  82. package/dist/src/chunk-gsyfebqj.js +4 -0
  83. package/dist/src/chunk-h5rpn9wr.js +247 -0
  84. package/dist/src/chunk-hb1x7v55.js +4 -0
  85. package/dist/src/chunk-hrfytkxh.js +168 -0
  86. package/dist/src/chunk-j4yjzbak.js +4 -0
  87. package/dist/src/chunk-jd6a5v6p.js +5 -0
  88. package/dist/src/chunk-jh6vhqzx.js +5 -0
  89. package/dist/src/chunk-kn5spq15.js +4 -0
  90. package/dist/src/{chunk-w2mwa0jk.js → chunk-m94qs0f0.js} +2 -2
  91. package/dist/src/chunk-mjrps0ac.js +7 -0
  92. package/dist/src/chunk-n03dmn5q.js +5 -0
  93. package/dist/src/chunk-n72qhwd9.js +4 -0
  94. package/dist/src/{chunk-km0dy5vc.js → chunk-ndt1ccxm.js} +9 -9
  95. package/dist/src/chunk-nr6y0n4y.js +5 -0
  96. package/dist/src/chunk-pcsen2vs.js +4 -0
  97. package/dist/src/chunk-ppfr0b8h.js +4 -0
  98. package/dist/src/chunk-q10bdnat.js +4 -0
  99. package/dist/src/chunk-q9xmq595.js +4 -0
  100. package/dist/src/{chunk-2v7tw1nj.js → chunk-qcxzr2my.js} +3 -3
  101. package/dist/src/chunk-qf6nynk6.js +7 -0
  102. package/dist/src/chunk-qyqypn28.js +5 -0
  103. package/dist/src/chunk-r2epb56s.js +4 -0
  104. package/dist/src/chunk-r5bxavdx.js +311 -0
  105. package/dist/src/{chunk-r14wwk37.js → chunk-r6z1eztj.js} +12 -12
  106. package/dist/src/{chunk-d57432wq.js → chunk-r7bpkgff.js} +2 -2
  107. package/dist/src/chunk-r8jf3d92.js +4 -0
  108. package/dist/src/{chunk-9rkfyt6q.js → chunk-rbpdk7m0.js} +3 -3
  109. package/dist/src/chunk-rc0dbypm.js +4 -0
  110. package/dist/src/chunk-rhcty4ms.js +4 -0
  111. package/dist/src/chunk-rpvckv3p.js +4 -0
  112. package/dist/src/{chunk-s1zq65ny.js → chunk-rqc9ap3x.js} +2 -2
  113. package/dist/src/chunk-rvvy1bte.js +7 -0
  114. package/dist/src/chunk-ry0mz41y.js +4 -0
  115. package/dist/src/{chunk-34zxqcmq.js → chunk-s3jc6cwp.js} +3 -3
  116. package/dist/src/chunk-sfv61xjb.js +6 -0
  117. package/dist/src/chunk-t6bfvfkg.js +4 -0
  118. package/dist/src/chunk-t6c8akcm.js +5 -0
  119. package/dist/src/chunk-t7w8rctc.js +4 -0
  120. package/dist/src/chunk-thbh3jew.js +5 -0
  121. package/dist/src/chunk-v2wd4n3e.js +5 -0
  122. package/dist/src/{chunk-zg67wjkh.js → chunk-v6pya0dm.js} +3 -3
  123. package/dist/src/chunk-vy3bwm1d.js +17 -0
  124. package/dist/src/chunk-w3vs79ex.js +27 -0
  125. package/dist/src/chunk-w4zga19f.js +4 -0
  126. package/dist/src/chunk-w5b2jwk3.js +14 -0
  127. package/dist/src/chunk-w7hkv422.js +5 -0
  128. package/dist/src/{chunk-qv2918jt.js → chunk-waqwcjyn.js} +2 -2
  129. package/dist/src/{chunk-b4cxdzwy.js → chunk-wbh8spm5.js} +7 -7
  130. package/dist/src/{chunk-ajsrz473.js → chunk-wyrkw6hw.js} +3 -3
  131. package/dist/src/chunk-xa73x2cx.js +5 -0
  132. package/dist/src/{chunk-eka89q3k.js → chunk-xgan0qqp.js} +1 -1
  133. package/dist/src/chunk-y2vs6jwg.js +4 -0
  134. package/dist/src/chunk-yattm52s.js +4 -0
  135. package/dist/src/{chunk-9y5bcy28.js → chunk-yb97j25b.js} +4 -4
  136. package/dist/src/{chunk-c9nk1r78.js → chunk-ybbtagbt.js} +3 -3
  137. package/dist/src/chunk-ycaj2sgf.js +9 -0
  138. package/dist/src/chunk-yf7ympyz.js +325 -0
  139. package/dist/src/chunk-yjawdzk8.js +4 -0
  140. package/dist/src/chunk-z637nqg8.js +11 -0
  141. package/dist/src/{chunk-0w1spptt.js → chunk-zgja5f3p.js} +4 -4
  142. package/dist/src/chunk-zs1sghs9.js +4 -0
  143. package/dist/src/daemon/processEntry.js +2 -2
  144. package/dist/src/index.js +4 -4
  145. package/dist/src/runtime/bunRuntimeGuard.js +2 -2
  146. package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -2
  147. package/ios/CameraPosterInjection/Injection/CameraPosterInjection.m +466 -0
  148. package/package.json +3 -2
  149. package/schemas/test-plan.schema.json +370 -52
  150. package/dist/src/chunk-09442h7v.js +0 -4
  151. package/dist/src/chunk-0e4gm1kj.js +0 -5
  152. package/dist/src/chunk-0eb8576f.js +0 -4
  153. package/dist/src/chunk-0rjm4nx7.js +0 -5
  154. package/dist/src/chunk-1zmh2eak.js +0 -4
  155. package/dist/src/chunk-28k63ha3.js +0 -5
  156. package/dist/src/chunk-2d4wmp8b.js +0 -4
  157. package/dist/src/chunk-2e6s75qv.js +0 -78
  158. package/dist/src/chunk-32jpxz2y.js +0 -323
  159. package/dist/src/chunk-3jmvqygr.js +0 -238
  160. package/dist/src/chunk-3swvfhqt.js +0 -5
  161. package/dist/src/chunk-44bt78m9.js +0 -5
  162. package/dist/src/chunk-488vt2bp.js +0 -4
  163. package/dist/src/chunk-4fgdhcwx.js +0 -5
  164. package/dist/src/chunk-4jp2se4w.js +0 -4
  165. package/dist/src/chunk-4vhr9e4t.js +0 -4
  166. package/dist/src/chunk-4xd6zs3y.js +0 -15
  167. package/dist/src/chunk-51567pg8.js +0 -4
  168. package/dist/src/chunk-5agqsfev.js +0 -4
  169. package/dist/src/chunk-5d706gmr.js +0 -4
  170. package/dist/src/chunk-5kd4rqk7.js +0 -5
  171. package/dist/src/chunk-61t538bm.js +0 -4
  172. package/dist/src/chunk-6d3mmqxt.js +0 -54
  173. package/dist/src/chunk-6hyt398x.js +0 -5
  174. package/dist/src/chunk-6mnr8kpm.js +0 -4
  175. package/dist/src/chunk-79q5xsdc.js +0 -42
  176. package/dist/src/chunk-7bdgand3.js +0 -4
  177. package/dist/src/chunk-84cp9dw5.js +0 -4
  178. package/dist/src/chunk-86f2h5ww.js +0 -5
  179. package/dist/src/chunk-8cghfzb2.js +0 -19
  180. package/dist/src/chunk-9tf2p9y9.js +0 -5
  181. package/dist/src/chunk-a2sc4jm0.js +0 -5
  182. package/dist/src/chunk-aa5ng3d1.js +0 -4
  183. package/dist/src/chunk-b3h0a6ca.js +0 -4
  184. package/dist/src/chunk-b6a737qt.js +0 -4
  185. package/dist/src/chunk-bn64x5z5.js +0 -5
  186. package/dist/src/chunk-bvh649za.js +0 -12
  187. package/dist/src/chunk-c9tyfg4j.js +0 -26
  188. package/dist/src/chunk-cfsdfqnm.js +0 -4
  189. package/dist/src/chunk-cxyf04jc.js +0 -7
  190. package/dist/src/chunk-da08tx5v.js +0 -4
  191. package/dist/src/chunk-f2tc08m2.js +0 -4
  192. package/dist/src/chunk-f8tnk179.js +0 -5
  193. package/dist/src/chunk-f9s1kkhx.js +0 -5
  194. package/dist/src/chunk-fbp8a4rx.js +0 -4
  195. package/dist/src/chunk-fd2z0sze.js +0 -4
  196. package/dist/src/chunk-fk927f4q.js +0 -54
  197. package/dist/src/chunk-fxmr3a0f.js +0 -4
  198. package/dist/src/chunk-gaqwhd44.js +0 -4
  199. package/dist/src/chunk-ggtd5x5a.js +0 -5
  200. package/dist/src/chunk-gndcfrm7.js +0 -4
  201. package/dist/src/chunk-h3n4adc6.js +0 -310
  202. package/dist/src/chunk-h5pjbb83.js +0 -4
  203. package/dist/src/chunk-hgnnh302.js +0 -4
  204. package/dist/src/chunk-hmke8nhx.js +0 -5
  205. package/dist/src/chunk-j2bx12hn.js +0 -4
  206. package/dist/src/chunk-j70y1a2g.js +0 -4
  207. package/dist/src/chunk-js1jpyxp.js +0 -6
  208. package/dist/src/chunk-kbjq0qvb.js +0 -4
  209. package/dist/src/chunk-kfwx57xd.js +0 -4
  210. package/dist/src/chunk-kzwctna2.js +0 -4
  211. package/dist/src/chunk-m9ehyehy.js +0 -4
  212. package/dist/src/chunk-mct91p1f.js +0 -4
  213. package/dist/src/chunk-mf9spd4g.js +0 -5
  214. package/dist/src/chunk-mgrcansb.js +0 -4
  215. package/dist/src/chunk-mqc1d0eb.js +0 -6
  216. package/dist/src/chunk-n1zmpk0z.js +0 -4
  217. package/dist/src/chunk-ncyjf63g.js +0 -4
  218. package/dist/src/chunk-nr64d21q.js +0 -973
  219. package/dist/src/chunk-nwm2pq5v.js +0 -168
  220. package/dist/src/chunk-pm06b05d.js +0 -9
  221. package/dist/src/chunk-q50s00ry.js +0 -4
  222. package/dist/src/chunk-qwye1958.js +0 -14
  223. package/dist/src/chunk-r8z9pfve.js +0 -5
  224. package/dist/src/chunk-rdpgkjf6.js +0 -4
  225. package/dist/src/chunk-rkr0dks9.js +0 -5
  226. package/dist/src/chunk-rn84t3sf.js +0 -11
  227. package/dist/src/chunk-s123kn7n.js +0 -4
  228. package/dist/src/chunk-s73qn3fx.js +0 -4
  229. package/dist/src/chunk-sjn0nj4p.js +0 -5
  230. package/dist/src/chunk-sns0c35v.js +0 -7
  231. package/dist/src/chunk-t4dr5c8v.js +0 -8
  232. package/dist/src/chunk-tc8k9c1j.js +0 -4
  233. package/dist/src/chunk-teznhase.js +0 -4
  234. package/dist/src/chunk-ty9xgmz4.js +0 -4
  235. package/dist/src/chunk-tyazf3sk.js +0 -145
  236. package/dist/src/chunk-v6npjrjm.js +0 -5
  237. package/dist/src/chunk-vbvtzkwz.js +0 -5
  238. package/dist/src/chunk-vefd8qee.js +0 -8
  239. package/dist/src/chunk-vs9r72ta.js +0 -17
  240. package/dist/src/chunk-w88k0bgr.js +0 -4
  241. package/dist/src/chunk-wzdt0enk.js +0 -4
  242. package/dist/src/chunk-xhhv854c.js +0 -4
  243. package/dist/src/chunk-y58270hd.js +0 -4
  244. package/dist/src/chunk-yk0hmbex.js +0 -4
  245. package/dist/src/chunk-ympy4fdz.js +0 -28
  246. package/dist/src/chunk-yw436axy.js +0 -4
  247. package/dist/src/chunk-z04jrpjy.js +0 -5
  248. package/dist/src/chunk-z2xznczw.js +0 -4
  249. package/dist/src/chunk-z4xnrgps.js +0 -4
  250. package/dist/src/chunk-z7csyszv.js +0 -4
  251. package/dist/src/chunk-z8t0v07j.js +0 -11
  252. package/dist/src/chunk-z916af47.js +0 -228
  253. package/dist/src/chunk-zcr8he8q.js +0 -5
  254. package/dist/src/chunk-zd9vmkzn.js +0 -9
  255. package/dist/src/chunk-zj939v0h.js +0 -5
  256. package/dist/src/chunk-zkdjwtc1.js +0 -4
  257. package/dist/src/chunk-zkv5kzt6.js +0 -4
@@ -0,0 +1,5 @@
1
+ // @bun
2
+ import{f,Be}from"./chunk-58wzr3mt.js";import{J,Ua,Ve,zm,bu,Kr,xo,gs,Co,Qw,ni,Ze,Ag,MB,o,kn,N,pa,ft,Tt,$t,pt,nt,K,Gi,ve,Pl,Ri,ub,MD,Ee,Zt,va,a9,El,jk,ja,O$,Hr,nO,$j,_l,B$,qr,vd,Wg,hf,Ou,Ji,ir,Eb,Ga,x,Ws,Xi}from"./chunk-r5bxavdx.js";import{s5,a5,nv,jS}from"./chunk-00167wan.js";import{Fr,te,e}from"./chunk-z637nqg8.js";import{Yn,Sf}from"./chunk-yf7ympyz.js";import{Sw,ra,sr,zi,vn,Cm,Dm,bn,Ao}from"./chunk-0qsy1qsx.js";import{SL,wv,DC,Oe,Kt,At}from"./chunk-3xkpk44w.js";import{dL,lL,uL,pL,mL,wT,qh}from"./chunk-7rz9898k.js";import{r_,n_,x4}from"./chunk-hrfytkxh.js";import{Kc,EF,rl,uv,_F,xF,CF,DF,OF,MF,NF,FF}from"./chunk-w7hkv422.js";import{ds,Ca,Wh,vr,sW,Wi,bL}from"./chunk-fgb98zjj.js";import{MT,tg,Sn,kw,Ew,Iw,WL,yi,ca,Iv,Gte,zL}from"./chunk-rvvy1bte.js";import{r,t,u,St}from"./chunk-rbpdk7m0.js";function h_(i=process.env){return Be(f.ALWAYS_LOAD_TOOLS,i)}var tv=30000;var g_=300000;var US=30000,mh=60000;var r5="automobile:observation/{deviceId}/{observationId}/screenshot";function WQ(i,n){return`automobile:observation/${Ze(i)}/${Ze(n)}/screenshot`}var iV=1e4,zQ=1000;class rv extends t{constructor(){super("This ProtoViewer build has no MCP entry point. Install a newer ProtoViewer and retry.")}}class oV extends t{constructor(i){super("Could not bring ProtoViewer to the foreground on the iOS simulator. Open ProtoViewer manually and retry.",i);this.name="ProtoViewerForegroundError"}}class os extends t{}var sV=250,HS=15000,M0=5000;class y_ extends t{constructor(){super("This ProtoViewer build did not advertise file inbox delivery. Install a newer ProtoViewer built with scripts/ios/protoviewer-build.sh and retry.");this.name="ProtoViewerInboxUnsupportedError"}}var N0=120000,fh=120000,z=30000;var jQ=["vendor_documented","cdd_derived","inferred"],MA=["samsung-sleeping","samsung-deep-sleeping","samsung-auto-disable","samsung-foreground-kill","screen-off-stop","xiaomi-autostart-off","oneplus-deep-optimization","recents-swipe-kill","recents-swipe-force-stop","oneplus-sleep-standby","motorola-adaptive","user-restricted","exact-alarm-denied","notifications-off","huawei-powergenie","vivo-autostart","realme-power-saver","meizu-flyme-background","asus-power-master","sony-stamina","tecno-app-halt"];var W=[{kind:"kill",mode:"hard"},{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"}],G="Approximated as a force-stop plus RUN_ANY_IN_BACKGROUND ignore: the app is stopped and may not run in the background until reset. The OEM's own trigger and exemption UI are not reproduced.",Y=" Boot-receiver observation predicts default delivery without sending BOOT_COMPLETED: shell is denied this protected broadcast (SecurityException). Root checks on stock API 35 show a force-stopped package receives no default broadcast (no process starts), but does with --include-stopped-packages. A non-stopped package still receives it with RUN_ANY_IN_BACKGROUND=ignore or the restricted bucket; only stopped state blocks delivery on stock Android when a receiver and permission are present.",um={"samsung-sleeping":{id:"samsung-sleeping",version:1,description:"Samsung 'Sleeping apps': on battery, app in the restricted standby bucket.",steps:[{kind:"batteryUnplug"},{kind:"standbyBucket",bucket:"restricted"}],evidenceStatus:"vendor_documented",evidenceNote:"Samsung documents sleeping apps as restricted from background work. The restricted bucket needs API 30+; below that the bucket step reports unsupported.",source:"https://developer.samsung.com/mobile/app-management.html"},"samsung-deep-sleeping":{id:"samsung-deep-sleeping",version:2,description:"Samsung 'Deep sleeping apps': stopped and never run in the background.",steps:[...W,{kind:"appOp",op:"WAKE_LOCK",mode:"ignore"}],evidenceStatus:"inferred",evidenceNote:G+" WAKE_LOCK ignore simulates Samsung's foreground-service wake-lock denial on Android 11; this is inferred, not a vendor-documented capture.",source:"https://developer.samsung.com/mobile/app-management.html"},"samsung-auto-disable":{id:"samsung-auto-disable",version:2,description:"Samsung auto-disable of unused apps: runtime permissions revoked and app hibernation.",steps:[{kind:"runtimePermissions"},{kind:"hibernation"}],evidenceStatus:"inferred",evidenceNote:"Approximated by explicit runtime permission revocation and AOSP app hibernation. Hibernation alone does not revoke permissions of preinstalled apps. Restores the captured granted permission set and hibernation state read before the first change; the unused-for-N-days trigger is not reproduced.",source:"https://developer.samsung.com/mobile/app-management.html"},"samsung-foreground-kill":{id:"samsung-foreground-kill",version:1,description:"Samsung Game Booster / Good Guardians: force-stop after another app comes to the foreground.",steps:[{kind:"foregroundChange"},{kind:"kill",mode:"hard"}],evidenceStatus:"inferred",evidenceNote:"Opens Settings, verifies another app is foreground, then force-stops. Approximates Game Booster / Good Guardians; OEM trigger and exemption policies are not reproduced.",source:"https://dontkillmyapp.com/samsung"},"screen-off-stop":{id:"screen-off-stop",version:1,description:"Screen-off cleanup: wait one minute with the screen off, then force-stop.",steps:[{kind:"screenOff",minutes:1},{kind:"kill",mode:"hard"}],evidenceStatus:"inferred",evidenceNote:"Approximates Asus Power Master, Meizu Protected apps and realme/Tecno screen-off cleanup with an explicit one-minute wait. Restores an initially awake screen; the N-days-unused trigger remains non-emulatable.",source:"https://dontkillmyapp.com/"},"xiaomi-autostart-off":{id:"xiaomi-autostart-off",version:2,description:"Xiaomi HyperOS/MIUI Autostart off: stopped and not restarted in the background.",steps:[...W,{kind:"bootReceiverCheck"}],evidenceStatus:"inferred",evidenceNote:G+Y,source:"https://dontkillmyapp.com/"},"oneplus-deep-optimization":{id:"oneplus-deep-optimization",version:1,description:"OnePlus deep optimization: stopped and restricted from background execution.",steps:W,evidenceStatus:"inferred",evidenceNote:G,source:"https://dontkillmyapp.com/"},"recents-swipe-kill":{id:"recents-swipe-kill",version:1,description:"Swipe away from recents, soft: background the app, then kill its processes.",steps:[{kind:"home"},{kind:"kill",mode:"soft"}],evidenceStatus:"inferred",evidenceNote:"Stock Android keeps the app's alarms and jobs after a recents swipe; `am kill` only ends its background processes. Nothing to restore.",source:"https://dontkillmyapp.com/"},"recents-swipe-force-stop":{id:"recents-swipe-force-stop",version:1,description:"Swipe away from recents, hard (several OEMs): background, then force-stop.",steps:[{kind:"home"},{kind:"kill",mode:"hard"}],evidenceStatus:"inferred",evidenceNote:"Several OEMs force-stop on a recents swipe, which also cancels alarms and jobs until the user opens the app again. Nothing to restore.",source:"https://dontkillmyapp.com/"},"oneplus-sleep-standby":{id:"oneplus-sleep-standby",version:1,description:"OnePlus sleep standby optimization: on battery, device forced into deep Doze.",steps:[{kind:"batteryUnplug"},{kind:"forceIdle"}],evidenceStatus:"inferred",evidenceNote:"Approximated with the AOSP Doze test recipe; force-idle needs the device on battery, so the battery is unplugged first. Doze must be enabled on the device.",source:"https://developer.android.com/topic/performance/power/test-power"},"motorola-adaptive":{id:"motorola-adaptive",version:1,description:"Motorola adaptive battery: app in the rare standby bucket.",steps:[{kind:"standbyBucket",bucket:"rare"}],evidenceStatus:"inferred",evidenceNote:"Approximated by the AOSP rare bucket that adaptive battery assigns.",source:"https://developer.android.com/topic/performance/power/test-power"},"user-restricted":{id:"user-restricted",version:1,description:"User-restricted background usage: RUN_ANY_IN_BACKGROUND ignore.",steps:[{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"}],evidenceStatus:"cdd_derived",evidenceNote:"Android 16 CDD 3.5.1: an OEM restriction stricter than the restricted bucket must return true for ActivityManager.isBackgroundRestricted(); this appop produces that signal on stock Android.",source:"https://source.android.com/docs/compatibility/16/android-16-cdd"},"exact-alarm-denied":{id:"exact-alarm-denied",version:1,description:"Exact alarms revoked: SCHEDULE_EXACT_ALARM denied for the app's uid.",steps:[{kind:"appOp",op:"SCHEDULE_EXACT_ALARM",mode:"deny"}],evidenceStatus:"vendor_documented",evidenceNote:"AOSP behaviour when the user turns off 'Alarms & reminders' (API 31+). Apps that declare USE_EXACT_ALARM keep the permission.",source:"https://developer.android.com/develop/background-work/services/alarms/schedule"},"notifications-off":{id:"notifications-off",version:2,description:"Notifications off: POST_NOTIFICATIONS runtime permission revoked (Android 13+).",steps:[{kind:"notificationPermission",mode:"revoke"}],evidenceStatus:"inferred",evidenceNote:"Revokes the POST_NOTIFICATIONS runtime permission, as the Settings notification toggle does on Android 13+. Restored to the grant read before the first change; an already-denied permission stays denied."},"huawei-powergenie":{id:"huawei-powergenie",version:2,description:"Huawei EMUI: Classic battery optimization: Don't allow and background restriction.",steps:[{kind:"standbyBucket",bucket:"restricted"},{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"},{kind:"appOp",op:"WAKE_LOCK",mode:"ignore"},{kind:"bootReceiverCheck"}],evidenceStatus:"inferred",evidenceNote:'Battery > App launch set to "Manage manually" with Auto-launch, Secondary launch and Run in background switched off is approximated by the restricted bucket, RUN_ANY_IN_BACKGROUND ignore and WAKE_LOCK ignore, plus boot receiver observation. Mechanisms from the dontkillmyapp.com Huawei entry (CC-BY-4.0). samsung-foreground-kill gives a foreground-change kill; screen-off-stop gives a screen-off kill. Not emulated: PowerGenie/HwPFWService killing every non-whitelisted app after about 60 minutes in the background, using a Huawei-maintained whitelist; System Manager Smart tune-up cleanup.'+Y,source:"https://dontkillmyapp.com/huawei"},"vivo-autostart":{id:"vivo-autostart",version:2,description:"Vivo Funtouch OS: Per-app background power restriction (Android 13).",steps:[{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"},{kind:"standbyBucket",bucket:"restricted"},{kind:"bootReceiverCheck"}],evidenceStatus:"inferred",evidenceNote:"Android 13 background power restriction is approximated by background restriction and the restricted bucket, plus boot receiver observation. Mechanisms from the dontkillmyapp.com Vivo entry (CC-BY-4.0). Not emulated: the proprietary Autostart permission (stock delivery is only observed); taskbar app lock."+Y,source:"https://dontkillmyapp.com/vivo"},"realme-power-saver":{id:"realme-power-saver",version:2,description:"realme UI: Power saving on battery with App battery management set to Optimize.",steps:[{kind:"batteryUnplug"},{kind:"standbyBucket",bucket:"restricted"},{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"}],evidenceStatus:"inferred",evidenceNote:"Power saving on battery and App battery management Optimize are approximated by battery unplug, the restricted bucket and background restriction. Mechanisms from the dontkillmyapp.com realme entry (CC-BY-4.0). The separate screen-off-stop profile approximates screen-off cleanup. Not emulated: Super power saving mode's 6-app limit; auto power-saving trigger levels; OEM sleep schedules.",source:"https://dontkillmyapp.com/realme"},"meizu-flyme-background":{id:"meizu-flyme-background",version:2,description:'Meizu Flyme: Background processes not allowed and "keep running after screen off" off (wake-lock denial).',steps:[{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"},{kind:"appOp",op:"WAKE_LOCK",mode:"ignore"}],evidenceStatus:"inferred",evidenceNote:"Background processes not allowed is approximated by background restriction. Keep running after screen off off is approximated by WAKE_LOCK ignore. Mechanisms from the dontkillmyapp.com Meizu entry (CC-BY-4.0). screen-off-stop gives a screen-off kill. Not emulated: Protected apps list; Power plan.",source:"https://dontkillmyapp.com/meizu"},"asus-power-master":{id:"asus-power-master",version:2,description:"Asus ZenUI: Power Master's auto-deny of auto-start.",steps:[{kind:"standbyBucket",bucket:"restricted"},{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"}],evidenceStatus:"inferred",evidenceNote:`Power Master auto-deny of auto-start is approximated by the restricted bucket and RUN_ANY_IN_BACKGROUND ignore. Mechanisms from the dontkillmyapp.com Asus entry (CC-BY-4.0). screen-off-stop approximates "Clean up in suspend". Not emulated: Power Master's own whitelist and settings UI; its auto-start denial, which can block a boot receiver from starting an app that targets below API 33 (stock Android still starts it, so a boot receiver check here can differ from a real Asus device).`,source:"https://dontkillmyapp.com/asus"},"sony-stamina":{id:"sony-stamina",version:2,description:"Sony Xperia: STAMINA mode (background processes and alarms restricted).",steps:[{kind:"batteryUnplug"},{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"},{kind:"appOp",op:"SCHEDULE_EXACT_ALARM",mode:"deny"}],evidenceStatus:"inferred",evidenceNote:'STAMINA mode on battery is approximated by battery unplug, background restriction and exact alarm denial. On Android 13 and later an app declaring USE_EXACT_ALARM can keep exact alarm access despite the SCHEDULE_EXACT_ALARM denial. Mechanisms from the dontkillmyapp.com Sony entry (CC-BY-4.0). Not emulated: the time-based "Prefer battery time" STAMINA level limits after screen off; the Power-saving feature Excepted list; Intelligence Engine.',source:"https://dontkillmyapp.com/sony"},"tecno-app-halt":{id:"tecno-app-halt",version:2,description:"Tecno HiOS: Background execution denied and foreground-service wake locks denied.",steps:[{kind:"appOp",op:"RUN_ANY_IN_BACKGROUND",mode:"ignore"},{kind:"appOp",op:"WAKE_LOCK",mode:"ignore"}],evidenceStatus:"inferred",evidenceNote:'Power Saving Management For Apps denial is approximated by background execution and wake-lock denial. Mechanisms from the dontkillmyapp.com Tecno entry (CC-BY-4.0). screen-off-stop approximates Power Marathon screen-off cleanup. Not emulated: app-freeze ("frozen in time") of timers and foreground services; the night-time Sleep Mode airplane-mode schedule; Auto-start management allow-list.',source:"https://dontkillmyapp.com/tecno"}},F0=[{id:"oem-unused-app-triggers",note:"OEM triggers such as 'unused for 3 days' that move an app into a sleeping list."},{id:"firmware-update-exemption-reset",note:"Battery-optimization exemptions that a firmware update resets."},{id:"xiaomi-proprietary-appops",note:"Xiaomi proprietary AppOps 10008/10021 (autostart, background start); community-reported only."}];var it=60000;function rt(i){return i.kind==="screenOff"?i.minutes*60000:0}function ae(i){if(i.action!=="apply"||typeof i.profile!=="string")return 0;if(!Object.hasOwn(um,i.profile))return 0;let s=um[i.profile].steps.reduce((a,d)=>a+rt(d),0);return s>0?s+it:0}var aV=30000,de=30000,ot={deadline:"the scan deadline passed",page_limit:"the scan page limit was reached",rewind:"the stream could not be scrolled back to its top"};function KQ(i,n,s){let a=`Listed ${i} notifications for ${n}`;return s?`${a}; the stream may hold more: ${ot[s]}. Retry with a larger awaitTimeout to read the whole stream.`:a}function cV(i){if(Array.from(i).length<=1000)return[i];let n=[],s="",a=0;for(let{segment:d}of new Intl.Segmenter(void 0,{granularity:"grapheme"}).segment(i)){let p=Array.from(d).length;if(a>0&&a+p>1000)n.push(s),s="",a=0;s+=d,a+=p}if(s)n.push(s);return n}function st(i){if(!i||typeof i!=="object")return;let n=i;return n.tagName??n.tag}function at(i){return i.find((n)=>st(n)==="tag:yaml.org,2002:merge")}function dt(){let i=a5,n=s5;if(n&&typeof i.withTags==="function")return i.withTags(n);let s=void 0,a=[...s?.implicit??[],...s?.explicit??[]],d=at(a);if(d&&typeof i.extend==="function")return i.extend({implicit:[d]});throw Error("js-yaml merge tag support is not available")}var qS={schema:dt()};function v_(i){return i.startsWith("base64:")?Buffer.from(i.substring(7),"base64").toString("utf-8"):i}function ct(i){return`<text, ${Array.from(i).length} characters>`}function P(i){return typeof i==="object"&&i!==null&&!Array.isArray(i)}function E(i,n){let s=i[n];return typeof s==="string"?{...i,[n]:ct(s)}:i}function pe(i,n){if(Array.isArray(i))return i.map(n);if(P(i))return Object.fromEntries(Object.entries(i).map(([s,a])=>[s,n(a)]));return i}var lt=(i)=>({...i,commands:pe(i.commands,(n)=>P(n)?E(n,"text"):n)}),ut=(i)=>E(E(i,"text"),"value"),mt=(i)=>E(i,"text"),ht=(i)=>({...i,fields:pe(i.fields,(n)=>P(n)?E(n,"value"):n)});function H(i){if(!P(i))return i;let n=typeof i.tool==="string"?i.tool:i.command;if(typeof n!=="string")return i;let s=hh(n,i);return P(s)&&P(s.params)?{...s,params:hh(n,s.params)}:s}function yt(i){let n;try{n=nv(v_(i),qS)}catch(a){return e.debug(`[redactTypedTextArguments] plan YAML did not parse: ${r(a)}`),`<plan, ${Array.from(i).length} characters>`}let s=n5(n);return s===n?i:jS(s,{lineWidth:-1})}function n5(i){if(!P(i)||!Array.isArray(i.steps))return i;let n=i.steps.map(H);return JSON.stringify(n)!==JSON.stringify(i.steps)?{...i,steps:n}:i}var gt=(i)=>typeof i.planContent==="string"?{...i,planContent:yt(i.planContent)}:i,bt=new Map([["sendKeys",lt],["inputText",ut],["clipboard",mt],["setUIState",ht],["executePlan",gt]]);function hh(i,n){let s=i===void 0?void 0:bt.get(i);return va(i,s&&P(n)?s(n):n)}class gh{static isRecord(i){return typeof i==="object"&&i!==null&&!Array.isArray(i)}static toolAndParams(i){if(!gh.isRecord(i))return;let n=i.tool||i.command;if(!n||typeof n!=="string")return;let s={};Object.keys(i).forEach((d)=>{if(d!=="tool"&&d!=="command"&&d!=="label"&&d!=="params"&&d!=="optional"&&d!=="expectations"&&d!=="expect"&&d!=="geometry")s[d]=i[d]});let a=gh.isRecord(i.params)?i.params:{};return{tool:n,params:{...s,...a}}}static normalizeStep(i,n){e.debug(`Processing step ${n}:`,JSON.stringify(H(i),null,2));let s=gh.toolAndParams(i);if(!s)throw Error(`Invalid step at index ${n}: missing or invalid tool/command name`);let a=s.tool,d={tool:a,params:s.params};if(i.expect!==void 0)d.expect=i.expect;if(i.geometry!==void 0)d.geometry=i.geometry;if(typeof i.label==="string")d.label=i.label;if(i.optional===!0)d.optional=!0;if(Array.isArray(i.expectations)&&i.expectations.length>0)d.expectations=i.expectations;return e.info(`Normalized step ${n}: ${a}`),e.debug(`Normalized step ${n}:`,JSON.stringify(H(d),null,2)),d}static normalizeSteps(i){return i.map((n,s)=>this.normalizeStep(n,s))}}var ce=[{name:"accessibility",title:"Control Accessibility",annotations:{destructiveHint:!1},description:"Check or control accessibility services. On Android: omit talkback to check TalkBack state, or pass talkback: true/false to enable/disable it. On iOS: omit voiceover to check VoiceOver state, or pass voiceover: true/false to enable/disable it (Simulator via simctl, physical devices via the Settings app). After enabling TalkBack, waits up to 4 s for a blocking system prompt (ending sooner once the screen is stable and TalkBack has no runtime permission left to request) and reports it in warning and blockingPrompt when detected: kind runtime-permission for a permission prompt (TalkBack's or another app's), system-dialog for a SystemUI or framework dialog activity; AutoMobile does not dismiss it. Use observe, then tapOn to answer or dismiss it. Always returns fresh state from the device, regardless of feature flags: enabled is what the device reports. When force-accessibility-mode or accessibility-auto-detect: off changes what the action tools assume, detectionOverride names it ({ mode: forced-on | auto-detect-off, effectiveEnabled }); it is absent otherwise.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{talkback:{description:"Enable (true) or disable (false) TalkBack on the active Android device",type:"boolean"},voiceover:{description:"Enable (true) or disable (false) VoiceOver on an iOS device (Simulator via simctl; physical devices are driven through the Settings app)",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{absentArguments:["talkback","voiceover"]}]}},{name:"accessibilityAction",title:"Run Accessibility Action",annotations:{destructiveHint:!0},description:"Perform an Android accessibility action on an element, the way TalkBack or Switch Access does: expand, collapse, dismiss, select, clear_selection, show_on_screen, scroll in a direction, page (API 29+), press_and_hold (API 30+), set_progress on a slider, or custom to run an app-defined action (e.g. a Compose customActions label) by its label. Target the element by resourceId, text or contentDesc; it needs a unique resource-id. An action the element does not offer is refused, and the error lists the actions it does offer (custom ones as custom:<label>).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"Accessibility action. page_* needs API 29+, press_and_hold API 30+; set_progress takes progress; custom runs the app-defined action labeled customAction",type:"string",enum:["expand","collapse","dismiss","select","clear_selection","show_on_screen","scroll_forward","scroll_backward","scroll_up","scroll_down","scroll_left","scroll_right","page_up","page_down","page_left","page_right","press_and_hold","set_progress","custom"]},resourceId:{description:"Target resource ID",type:"string"},text:{description:"Target text",type:"string"},contentDesc:{description:"Exact content-desc or accessible label; distinct from visible text",type:"string"},customAction:{description:"Label of the app-defined action, for action custom",type:"string",minLength:1},progress:{description:"Value in the control's own range, for action set_progress",type:"number"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"accessibilityAudit",title:"Audit Accessibility",annotations:{destructiveHint:!0},description:"Audit the accessibility of the current screen. engine wcag (default on Android; Android only) runs the host-side WCAG checks (contrast, touch targets, labels, headings) with every audit feature flag off and reports violations with the element from this observation; an appId that is not in the foreground is an error; scope.container limits it to one element's subtree; baseline record saves the violations under a name and compare reports baselineDiff (new, fixed, unchanged), and only new violations count toward failOn; failOn error|warning makes the call fail when findings reach that severity, for plan assertions (default never). engine platform (default on iOS) runs the platform's own engine: on iOS 17+ (Simulator and physical) XCUITest performAccessibilityAudit reports contrast, hitRegion, dynamicType, textClipped, sufficientDescription, trait and elementDetection issues, each with the element's accessibility identifier as elementId (usable with tapOn/highlight) and bounds; it sees real hit regions, Dynamic Type support and clipped text. On both engines an appId that is not in the foreground (background or not running) is an error naming the foreground app. checks and maxIssues apply to the platform engine, scope, baseline and failOn to wcag; passing one to the other engine is an error. The Android platform engine (Accessibility Test Framework) is not available yet and returns errorCode unsupported_platform, as does wcag on iOS; a runner that predates the iOS command returns errorCode unsupported_capability.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{engine:{description:"platform (XCUITest) or wcag (host-side checks); default wcag on Android, platform on iOS",type:"string",enum:["platform","wcag"]},appId:{description:"Package or bundle id of the app to audit (default: the foreground app)",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},checks:{description:"platform engine: checks to run (default: all)",type:"array",items:{type:"string",enum:["contrast","hitRegion","dynamicType","textClipped","sufficientDescription","trait","elementDetection","all"]}},maxIssues:{description:"platform engine: most issues to return (default 50); truncated reports a clip",type:"integer",minimum:1,maximum:500},scope:{description:"wcag engine: limit the audit to one container's subtree",type:"object",properties:{container:{type:"object",properties:{elementId:{description:"Container resource id",type:"string",minLength:1},text:{description:"Container text or content-desc",type:"string",minLength:1}},additionalProperties:!1}},required:["container"],additionalProperties:!1},baseline:{description:"wcag engine: named accessibility baseline",type:"object",properties:{name:{description:"Baseline name",type:"string",minLength:1},mode:{description:"record saves; compare reports the diff",type:"string",enum:["compare","record"]}},required:["name","mode"],additionalProperties:!1},failOn:{description:"wcag engine: fail the call at this violation severity (default never: report only)",type:"string",enum:["error","warning","never"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"accessibilityFocus",title:"Set Accessibility Focus",annotations:{destructiveHint:!1,idempotentHint:!0},description:"Set accessibility focus on Android (TalkBack) and iOS (VoiceOver) by resourceId, text, or contentDesc. Clearing focus is supported on Android only.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"set default or clear accessibility focus (clear is Android-only)",type:"string",enum:["set","clear"]},resourceId:{description:"Target resource ID",type:"string"},text:{description:"Target text",type:"string"},contentDesc:{description:"Exact content-desc or accessible label; distinct from visible text",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/debugOnly":!0}},{name:"ambient",title:"Change Ambient Power State",annotations:{destructiveHint:!0},description:`Wear OS watches only (other form factors are refused without a change): enter sends KEYCODE_SLEEP, exit sends KEYCODE_WAKEUP, then reads wakefulness and the watch face's inAmbient from dumpsys wear_service, reported as ambient (true, false or "unknown"). Enter succeeds when inAmbient is true; exit when inAmbient is false and wakefulness is Awake. Without that readback, enter succeeds on Dozing or Asleep and exit on Awake. Hardware wake by tilt or touch is untested.`,inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{type:"string",enum:["enter","exit"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"appLifecycle",title:"Control App Lifecycle",annotations:{destructiveHint:!0},description:"State-preserving background-process kill for saved-state restoration tests (background, killBackgrounded; iOS kills with SIGKILL after Home); trimMemory (Android only) sends onTrimMemory(level) to the running app without killing it.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},action:{type:"string",enum:["background","killBackgrounded","trimMemory"]},level:{description:"onTrimMemory level to send; required for trimMemory, rejected otherwise",type:"string",enum:["RUNNING_MODERATE","RUNNING_LOW","RUNNING_CRITICAL","UI_HIDDEN","BACKGROUND","MODERATE","COMPLETE"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId","action"],additionalProperties:!1}},{name:"audit",title:"Audit Current Screen",annotations:{destructiveHint:!0},description:"Deprecated: use accessibilityAudit (engine wcag) for accessibility and performanceAudit for performance and memory; this tool returns the same results and will be removed. Audit the current screen on demand, with every audit feature flag off and without changing flag state. kinds: accessibility (WCAG: contrast, touch targets, labels, headings; default), performance (UI jank and touch latency of the foreground app), memory (a memory snapshot of appId). Violations carry the element from this observation; accessibility of an appId that is not in the foreground is an error. scope.container limits the accessibility audit to one element's subtree. baseline record saves the accessibility violations under a name; compare reports baselineDiff (new, fixed, unchanged), and only new violations count toward failOn. failOn error|warning makes the call fail when findings reach that severity or a requested kind is unsupported, for plan assertions; default never. Android only.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{kinds:{description:"Audits to run (default: accessibility)",minItems:1,type:"array",items:{type:"string",enum:["accessibility","performance","memory"]}},appId:{description:"Package to audit (default: the foreground app)",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},scope:{description:"Limit the accessibility audit to one container's subtree",type:"object",properties:{container:{type:"object",properties:{elementId:{description:"Container resource id",type:"string",minLength:1},text:{description:"Container text or content-desc",type:"string",minLength:1}},additionalProperties:!1}},required:["container"],additionalProperties:!1},baseline:{description:"Named accessibility baseline",type:"object",properties:{name:{description:"Baseline name",type:"string",minLength:1},mode:{description:"record saves; compare reports the diff",type:"string",enum:["compare","record"]}},required:["name","mode"],additionalProperties:!1},failOn:{description:"Fail the call at this violation severity (default never: report only)",type:"string",enum:["error","warning","never"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"backgroundWork",title:"Control Background Jobs",annotations:{destructiveHint:!0},description:`Android: read and trigger an app's background work without waiting hours. action "list" shows JobScheduler jobs (constraints, next run, WorkManager worker class); {runJob:{jobId|worker,force}} runs one now (cmd jobscheduler run); {workManagerDiagnostics:true} maps WorkManager jobs to worker classes; {listAlarms:true} shows pending alarms. Alarms cannot be fired without moving the clock: use setDeviceState clock.`,inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Package whose background work to read or trigger",type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},action:{description:`"list" the app's JobScheduler jobs; {runJob} run one now; {workManagerDiagnostics} map jobs to worker classes; {listAlarms} pending alarms`,anyOf:[{type:"string",const:"list"},{type:"object",properties:{runJob:{type:"object",properties:{jobId:{description:"JobScheduler job id",type:"integer",minimum:0,maximum:2147483647},worker:{description:"WorkManager worker class (or simple name, or tag) to run instead of a jobId",type:"string",minLength:1,maxLength:256},force:{description:"Run even if the job's constraints are not satisfied",type:"boolean"}},additionalProperties:!1}},required:["runJob"],additionalProperties:!1},{type:"object",properties:{workManagerDiagnostics:{type:"boolean",const:!0}},required:["workManagerDiagnostics"],additionalProperties:!1},{type:"object",properties:{listAlarms:{type:"boolean",const:!0}},required:["listAlarms"],additionalProperties:!1}]},userId:{description:"Android user to run the job for (runJob)",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","action"],additionalProperties:!1}},{name:"barrier",title:"Synchronize Tracks",annotations:{destructiveHint:!1,openWorldHint:!1},description:"Synchronize multiple devices at a barrier, then let all proceed concurrently (no serialized section).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{lock:{description:"Shared barrier name; all devices using the same name synchronize together",type:"string"},deviceCount:{description:"Number of devices that must arrive before the barrier lifts",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},timeout:{description:"Barrier timeout ms (default 30000)",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["lock","deviceCount"],additionalProperties:!1},_meta:{"automobile/planOnly":!0}},{name:"biometricAuth",title:"Simulate Biometrics",annotations:{destructiveHint:!0},description:"Simulate biometric auth: Android emulator/SDK hook, or iOS via the app's AutoMobile SDK or Simulator.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"match/fail/enroll/unenroll on iOS Simulator; cancel/error need the AutoMobile SDK in the app",type:"string",enum:["match","fail","cancel","error","enroll","unenroll"]},modality:{description:"Modality: any default, fingerprint, or face",type:"string",enum:["any","fingerprint","face"]},fingerprintId:{description:"Fingerprint ID: default 1 for match/error, 2 for fail/cancel",type:"number"},errorCode:{description:"BiometricPrompt error code; action=error only",type:"number"},ttlMs:{description:"SDK override TTL ms (default 5000)",type:"number"},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"captureAudio",title:"Capture Emulator Audio Output",annotations:{readOnlyHint:!0},description:"Record up to 20 s of an Android emulator's or iOS Simulator's audio output and report its level: rmsDbfs, peakDbfs, the share of 20 ms windows with sound (activeRatio), and silent. A guest that plays nothing returns silent: true rather than an error. saveArtifact writes a WAV and returns its host path. Assert loosely (silent or not, duration within a margin); loaded hosts can glitch real-time audio. A simulator is read from the host's loopback default output, which mixes every simulator on the host. Physical devices are refused.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{seconds:{description:"How long to record the device's audio output.",type:"number",minimum:0.1,maximum:20},silenceThresholdDbfs:{description:"A 20 ms window at or above this level counts as sound. Default -50.",type:"number",minimum:-120,maximum:0},saveArtifact:{description:"Write the capture to a WAV file on the host.",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["seconds"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"captureTrace",title:"Capture Trace",annotations:{destructiveHint:!0},description:"Android: record a Perfetto trace from typed categories (sched, gfx, view, am, wm, binder_driver, memory, app). start returns a traceId; drive the flow; stop pulls the .perfetto-trace to the host. Released sessions stop their trace.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"start a recorder, or stop one by traceId",type:"string",enum:["start","stop"]},traceId:{description:"stop: the id start returned",type:"string",minLength:1},appId:{description:"start: enables the app's atrace tags (Choreographer, RenderThread, custom slices)",type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},categories:{description:"start: what to record; default sched, gfx, view. app needs an appId",minItems:1,type:"array",items:{type:"string",enum:["sched","gfx","view","am","wm","binder_driver","memory","app"]}},bufferMb:{description:"start: ring buffer size; default 32",type:"integer",minimum:1,maximum:256},maxDurationMs:{description:"start: the recorder stops itself after this; default 30000",type:"integer",minimum:1000,maximum:300000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"changeLocalization",title:"Change Locale",annotations:{destructiveHint:!0},description:"Change locale, time zone, text direction, time format, and calendar system",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},appId:{description:"Android app package for locale changes",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},locale:{description:"Locale tag (e.g., ar-SA, ja-JP)",type:"string",minLength:1},timeZone:{description:"Zone ID (e.g., America/Los_Angeles)",type:"string",minLength:1},textDirection:{description:"Text direction",type:"string",enum:["ltr","rtl"]},timeFormat:{description:"Time format",type:"string",enum:["12","24"]},calendarSystem:{description:"Calendar system (e.g., gregory, japanese, buddhist, islamic-civil)",type:"string",minLength:1,pattern:"^[a-z][a-z0-9-]*$"},restartApp:{description:"iOS bundle ID to relaunch after locale change",type:"string",minLength:1},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"clearKeyValueFile",title:"Clear Key Value File",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Clear app key-value storage file.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},name:{description:`Storage name. iOS: empty string, "standard" (any case) or the app bundle id select the app's standard UserDefaults; any other value is a UserDefaults suite name (e.g. an app group) and must be a valid suite with no leading or trailing whitespace. Android: SharedPreferences file name without the .xml extension (letters, digits, underscore, dash, dot).`,type:"string"},fileName:{description:"Deprecated alias for name",type:"string"},userId:{description:"Android only: user whose copy of the app the direct-file (run-as) fallback edits (e.g. a work profile). Defaults to user 0 when the app is installed for it; otherwise to the one other running user that has it (an error asks for userId if several do). The SDK route is not user-scoped.",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId"],additionalProperties:!1,description:"Provide either `name` (iOS UserDefaults suite / Android SharedPreferences name) or `fileName`"},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"clearMockNetwork",title:"Clear Mock Network Rules",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Clear mock network response rules.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{mockId:{description:"Mock ID; omit to clear all",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/hostSideState":!0}},{name:"clipboard",title:"Control Clipboard",annotations:{destructiveHint:!0},description:"Clipboard operations (copy/paste/clear/get)",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"Clipboard action",type:"string",enum:["copy","paste","clear","get"]},text:{description:"Text to copy (required for 'copy' action)",type:"string",minLength:1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["get"]}]}},{name:"compareScreenshot",title:"Compare Screenshot",annotations:{destructiveHint:!0},description:"Visual regression: record a named screenshot baseline (per device profile) or compare the current screen, an element, or a rectangle against it, ignoring masked regions and system bars. Returns match, diffRatio and a diff image path on mismatch.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{baseline:{description:"Baseline name; letters, digits, '.', '_' or '-' (host-side, per device profile)",type:"string",minLength:1},mode:{description:"compare against, (re)record, or record only when this profile has none",type:"string",enum:["compare","record","recordIfMissing"]},target:{description:"Region to compare; default the full screen",type:"object",properties:{elementId:{description:"Unique exposed element ID",type:"string",minLength:1},rect:{description:"Platform-native screen rectangle: Android pixels, iOS and tvOS points",type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1}},additionalProperties:!1},mask:{description:"Regions to ignore, e.g. a clock, avatar or ad",maxItems:64,type:"array",items:{type:"object",properties:{elementId:{description:"Unique exposed element ID",type:"string",minLength:1},rect:{description:"Platform-native screen rectangle: Android pixels, iOS and tvOS points",type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1}},additionalProperties:!1}},ignoreSystemBars:{description:"Ignore the status and navigation bars (default true)",type:"boolean"},threshold:{type:"object",properties:{pixelRatio:{description:"Largest share of compared pixels that may differ (default 0)",type:"number",minimum:0,maximum:1},perPixelDelta:{description:"Per-pixel colour distance treated as equal (default 0.1)",type:"number",minimum:0,maximum:1}},additionalProperties:!1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["baseline","mode"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"crashApp",title:"Crash App",annotations:{destructiveHint:!0},description:"Intentionally crash a running app through the platform crash path",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"criticalSection",title:"Run Critical Section",annotations:{destructiveHint:!0},description:"Synchronize multiple devices at a barrier, then run steps serially.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{lock:{description:"Shared barrier lock name",type:"string"},steps:{description:"Serial steps; each needs params.device",minItems:1,type:"array",items:{type:"object",properties:{tool:{description:"Tool name",type:"string"},params:{description:"Tool params; must include device",type:"object",propertyNames:{type:"string"},additionalProperties:{}},label:{description:"Step label",type:"string"}},required:["tool","params"],additionalProperties:{}}},deviceCount:{description:"Devices required at barrier",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},timeout:{description:"Barrier timeout ms (default 30000)",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["lock","steps","deviceCount"],additionalProperties:!1},_meta:{"automobile/planOnly":!0}},{name:"deleteDevice",title:"Delete Device",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Stop and permanently delete a device, with verified platform-inventory absence",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{target:{type:"object",properties:{platform:{description:"Platform reported by automobile:devices/booted",type:"string",enum:["android","ios","watchos","tvos","visionos"]},isVirtual:{description:"Virtual-device flag reported by automobile:devices/booted",type:"boolean",const:!0},stableId:{description:"Stable platform device identity from automobile:devices/booted",type:"string",minLength:1},stableName:{description:"Stable platform representation name when available",type:"string",minLength:1}},required:["platform","isVirtual","stableId"],additionalProperties:!1},mode:{description:"Stop and permanently delete the platform device representation",type:"string",const:"destroy"},verifyAbsence:{description:"Require a complete inventory observation proving durable absence",type:"boolean",const:!0},timeoutMs:{description:"Total bounded teardown timeout in ms",type:"integer",exclusiveMinimum:0,maximum:890000},cancellationPolicy:{description:"Cancel the accepted teardown if this MCP request is aborted. Use only for deadline-critical, caller-owned cleanup that must not continue in the background after its caller stops waiting.",type:"string",const:"cancel-on-request-abort"},force:{description:"Drop every AVD-name comparison on the way to the kill -- the emulator-console probe that confirms which AVD is running on this serial, and the platform kill's own check against a fresh discovery -- and act on whatever occupies the serial. Use only when the console has wedged and the normal call refuses because the AVD name cannot be confirmed. This does not override the conflict check, it removes it: force means 'act on whatever emulator currently occupies this serial', including a different AVD that took the serial over. It does NOT select a different serial, and a serial with nothing running on it still refuses. Nor does it override the refusal raised when this daemon's pool entry for the serial was retired and replaced while the action was being prepared, or deleteDevice's refusal to delete a stopped image while a booted emulator that cannot be identified at all is attached. Android emulators only; accepted and ignored for iOS and physical devices. Separately, on any platform, force also stops a device another session holds, which is otherwise refused.",default:!1,type:"boolean"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"}},required:["target","mode","verifyAbsence"],additionalProperties:!1}},{name:"deleteKeychainItem",title:"Delete Keychain Item",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Delete one exact, host-allowlisted, app-owned iOS generic-password Keychain item. Requires SDK opt-in, mutation authorization and explicit confirmation; never exports values.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},selector:{type:"object",properties:{itemClass:{type:"string",minLength:1},service:{type:"string",minLength:1},account:{type:"string",minLength:1},accessGroup:{type:"string",minLength:1}},required:["itemClass","service","account","accessGroup"],additionalProperties:!1},confirm:{description:"Explicit confirmation to delete this exact Keychain item",type:"boolean",const:!0},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","selector","confirm"],additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"deviceSnapshot",title:"Manage Snapshot",annotations:{destructiveHint:!0},description:"Capture, restore or delete a device snapshot. An Android VM restore in daemon mode returns the new deviceSessionUuid; the previous device-session UUID is superseded by the restore.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{type:"string",enum:["capture","restore","delete"]},snapshotName:{description:"Snapshot name",type:"string",minLength:1},includeAppData:{description:"Include app data (iOS app containers; ignored on non-VM Android, which is settings-only)",type:"boolean"},includeSettings:{description:"Include settings",type:"boolean"},useVmSnapshot:{description:"Use emulator VM snapshot",type:"boolean"},strictBackupMode:{description:"iOS-only: fail the whole snapshot unless every requested bundle is backed up (all-or-nothing)",type:"boolean"},vmSnapshotTimeoutMs:{description:"VM snapshot timeout in milliseconds (positive integer; maximum 1800000 ms / 30 minutes)",type:"integer",exclusiveMinimum:0,maximum:1800000},appBundleIds:{description:"iOS bundle IDs for app data snapshot",type:"array",items:{type:"string"}},fixture:{description:"Android emulator VM snapshots only. On capture, record the AVD, system image, config, emulator version and userdata image the snapshot depends on. On restore, require a fixture; a fixture whose identity changed is refused with its reasons either way",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/opaquePersistentState":!0}},{name:"displayConfig",title:"Configure Display",annotations:{destructiveHint:!0},description:"Read or set the visual display configuration \u2014 font/text scale, effective display density, light/dark (night mode) theme, and on Android the runtime screen size, navigation mode (gesture / 3-button / 2-button) and display-cutout emulation \u2014 for adaptive-layout, edge-to-edge and large-font accessibility testing. A call with no set field reads current values; providing fontScale, density, theme, size, navigationMode, displayCutout, or reset applies the change and returns applied + previous values so the client can restore. Android supports all three fields (density overrides are best-effort on physical devices); iOS supports theme (the Simulator via `simctl ui appearance`, physical devices through the CtrlProxy runner) and, on the Simulator only, font scale as a Dynamic Type category (via `simctl ui content_size`; fontScale maps to the nearest category and contentSize selects one exactly; reads report both). Android size, navigationMode and displayCutout use `wm size` and the system image's overlays; values the image does not ship are refused and `available` lists the ones it has; size, overlay and density changes invalidate cached observations and coordinates. On Android, reset restores font scale, density and screen size to device defaults, navigation mode and display cutout to the values recorded before they were first changed, and night mode only to the value displayConfig replaced earlier in this process; otherwise night mode is left unchanged. Releasing or rebinding the session that changed size, navigationMode or displayCutout restores them through the same record as displayProfile; sessionless changes persist until reset. Android reset never forces light mode. iOS Simulator reset restores light appearance and the content size category displayConfig replaced earlier in this process; physical iOS reset restores the appearance displayConfig first replaced there (light if none). The accessibility display preferences increaseContrast, reduceMotion and boldText are read and set on Android and the iOS Simulator, and colorInversion, colorCorrection, magnification, magnificationScale and extraDim (API 31+) on Android; `supported` reports each as true (proven by read-back), partial (stored setting reads back but running apps must relaunch; reason in supportNotes) or false, and reset restores the ones displayConfig changed. reset: \"factory\" additionally forces platform defaults (light theme, iOS content size large, accessibility display preferences off) regardless of recorded baselines, including after a daemon restart.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{fontScale:{description:"System text scale, or 'default' to remove Android's explicit override and restore its inherited default. On the iOS Simulator, selects the nearest Dynamic Type category (1 = large; 'default' = large). Omit to leave unchanged.",anyOf:[{type:"number",minimum:0.1,maximum:10},{type:"string",const:"default"}]},contentSize:{description:"iOS Simulator only: an exact Dynamic Type category for `simctl ui content_size`, instead of the nearest one to fontScale. Cannot be combined with fontScale. Omit to leave unchanged.",type:"string",enum:["extra-small","small","medium","large","extra-large","extra-extra-large","extra-extra-extra-large","accessibility-medium","accessibility-large","accessibility-extra-large","accessibility-extra-extra-large","accessibility-extra-extra-extra-large"]},density:{description:"Effective display density: an explicit dpi (e.g. 480), or a relative bucket (smaller/default/larger). Numeric values must be 72-1280 dpi. Android only; best-effort on physical devices. Omit to leave unchanged.",anyOf:[{type:"number",minimum:72,maximum:1280},{type:"string",enum:["smaller","default","larger"]}]},theme:{description:"Light, dark, system (follow-device), or custom (Android user-defined night-mode schedule) theme / night mode. Supported on Android; the iOS Simulator supports only 'light'/'dark'. 'custom' mainly exists to restore a device previously on a custom schedule (from an earlier call's `previous.theme`). Omit to leave unchanged.",type:"string",enum:["light","dark","system","custom"]},size:{description:"Android: override the screen size in pixels, natural orientation (`wm size WxH`), or 'default' to remove the override. Each side must be 200 px to twice the physical size. Best-effort on physical devices. Omit to leave unchanged.",anyOf:[{type:"object",properties:{width:{type:"integer",minimum:200,maximum:16384},height:{type:"integer",minimum:200,maximum:16384}},required:["width","height"],additionalProperties:!1},{type:"string",const:"default"}]},navigationMode:{description:"Android: gesture, threeButton or twoButton navigation via the system image's navbar overlay (`cmd overlay enable-exclusive --category`); 'default' disables every navbar overlay. Values the image does not ship are refused; read `available`. Omit to leave unchanged.",type:"string",enum:["gesture","threeButton","twoButton","default"]},displayCutout:{description:"Android: emulate a display cutout via the system image's cutout-emulation overlay, or 'none' to disable it. Values the image does not ship are refused; read `available`. Omit to leave unchanged.",type:"string",enum:["none","corner","double","hole","tall","waterfall"]},display:{description:"Android panel key, role, or active that size reads and sets; the default display when omitted. navigationMode and displayCutout are device-wide.",type:"string"},increaseContrast:{description:"Increase Contrast. Android: high-contrast text (secure high_text_contrast_enabled). iOS Simulator: `simctl ui increase_contrast`. Omit to leave unchanged.",type:"boolean"},reduceMotion:{description:"Reduce Motion. Android: Remove animations (all three animation scales 0; false restores the scales replaced earlier, else 1). iOS Simulator: partial, written to com.apple.Accessibility defaults; relaunch the app to observe. Omit to leave unchanged.",type:"boolean"},boldText:{description:"Bold Text. Android API 31+: secure font_weight_adjustment 300. iOS Simulator: partial, written to com.apple.Accessibility defaults; relaunch the app to observe. Omit to leave unchanged.",type:"boolean"},colorInversion:{description:"Android: color inversion (secure accessibility_display_inversion_enabled).",type:"boolean"},colorCorrection:{description:"Android: color correction (daltonizer) mode, or 'off'. 'grayscale' is monochromacy.",type:"string",enum:["off","deuteranomaly","protanomaly","tritanomaly","grayscale"]},magnification:{description:"Android: enable the triple-tap magnification gesture. Enabling it does not zoom the screen until the gesture is performed.",type:"boolean"},magnificationScale:{description:"Android: the magnification gesture's zoom factor (AOSP default 2).",type:"number",minimum:1,maximum:8},extraDim:{description:"Android API 31+: Extra dim (secure reduce_bright_colors_activated).",type:"boolean"},reset:{description:'Pass "factory" to restore platform defaults no matter which baselines were recorded, including after a daemon restart or for changes made outside a session: light theme, iOS content size large, accessibility display preferences off, font scale 1.0, density and size defaults. Pass true for the baseline-only reset described next. On Android, restore font scale, density and screen size to device defaults, and navigation mode and display cutout to the values recorded before they were first changed. Restore night mode only to the value displayConfig replaced earlier in this process; otherwise leave it unchanged. Android reset never forces light mode. On the iOS Simulator, reset restores light appearance and the content size category displayConfig replaced earlier in this process. On both, restore each accessibility display preference that displayConfig changed earlier in this process.',anyOf:[{type:"boolean"},{type:"string",const:"factory"}]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{absentArguments:["reset","fontScale","contentSize","density","theme","size","navigationMode","displayCutout","increaseContrast","reduceMotion","boldText","colorInversion","colorCorrection","magnification","magnificationScale","extraDim"]}]}},{name:"displayProfile",title:"Set Display Profile",annotations:{destructiveHint:!0},description:"Android: apply an OEM-style display profile in one call (screen size, density, font scale, display-cutout and navigation-mode overlays, force dark, fold posture), composing displayConfig and setPosture. Each step reports applied | partial | unsupported | failed. The state before each facet's first change is recorded once; reset restores every recorded facet, and in a daemon session release or rebind does too. Approximates OEM look and geometry; it cannot reproduce OEM SystemUI.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"apply the given fields, or reset every recorded change",type:"string",enum:["apply","reset"]},screenSize:{description:"wm size override WIDTHxHEIGHT, or 'default' to reset it",type:"string",pattern:"^(\\d+x\\d+|default)$"},density:{description:"Display density dpi or bucket, as displayConfig (approximates Samsung Screen zoom)",anyOf:[{type:"number",minimum:72,maximum:1280},{type:"string",enum:["smaller","default","larger"]}]},fontScale:{description:"System font scale, as displayConfig",type:"number",minimum:0.1,maximum:10},cutout:{description:"Display cutout emulation overlay, or none to disable it",type:"string",enum:["none","corner","double","hole","tall","waterfall"]},navigationMode:{description:"Navigation bar overlay",type:"string",enum:["gestural","threebutton","twobutton"]},forceDark:{description:"true forces dark rendering (debug.hwui.force_dark) and night mode, as OEM force dark",type:"boolean"},posture:{description:"Fold posture, as setPosture (foldable AVDs and devices)",type:"string",enum:["closed","half_opened","opened","rear_display","flipped","tent"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"dragAndDrop",title:"Drag and Drop Element",annotations:{destructiveHint:!0},description:"Drag and drop element",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:"Target panel key, role, or active",type:"string"},source:{description:"Source element",anyOf:[{type:"object",properties:{elementId:{description:"Source ID",type:"string"},container:{description:"Nested container scope for this endpoint; outermost container resolves first",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Endpoint selection strategy (default: first); unique requires one match at every unindexed scope level and at the target",type:"string",enum:["first","random","unique"]}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Source text",type:"string"},container:{description:"Nested container scope for this endpoint; outermost container resolves first",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Endpoint selection strategy (default: first); unique requires one match at every unindexed scope level and at the target",type:"string",enum:["first","random","unique"]}},required:["text"],additionalProperties:!1}]},target:{description:"Target element",anyOf:[{type:"object",properties:{elementId:{description:"Target ID",type:"string"},container:{description:"Nested container scope for this endpoint; outermost container resolves first",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Endpoint selection strategy (default: first); unique requires one match at every unindexed scope level and at the target",type:"string",enum:["first","random","unique"]}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Target text",type:"string"},container:{description:"Nested container scope for this endpoint; outermost container resolves first",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Endpoint selection strategy (default: first); unique requires one match at every unindexed scope level and at the target",type:"string",enum:["first","random","unique"]}},required:["text"],additionalProperties:!1}]},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},pressDurationMs:{description:"Press duration ms (min: 600, max: 3000, default: 600)",type:"number",minimum:600,maximum:3000},dragDurationMs:{description:"Drag duration ms (min: 300, max: 2000, default: 300)",type:"number",minimum:300,maximum:2000},holdDurationMs:{description:"Hold duration ms (min: 100, max: 3000, default: 100)",type:"number",minimum:100,maximum:3000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["source","target"],additionalProperties:!1,$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"dragPath",title:"Drag Along Path",annotations:{destructiveHint:!0},description:"Drag a finger (or, with pointer, a stylus on Android 12+) along a polyline with segment timing, an initial hold and a release hold.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{points:{description:"Polyline vertices; the finger goes down on the first and lifts on the last",minItems:2,maxItems:100,type:"array",items:{type:"object",properties:{x:{description:"x in the selected coordinateSpace (native by default)",type:"number"},y:{description:"y in the selected coordinateSpace (native by default)",type:"number"},durationMs:{description:"Milliseconds spent moving from the previous point to this one (default 200); ignored on the first point",type:"integer",minimum:1,maximum:5000},pressure:{description:"Stylus pressure 0-1 at this point (needs pointer); interpolated between points",type:"number",minimum:0,maximum:1},tilt:{description:"Stylus tilt in radians at this point (needs pointer)",type:"number",minimum:0,maximum:1.5707963267948966}},required:["x","y"],additionalProperties:!1}},holdMs:{description:"Press and hold at the first point before moving (long press, then drag)",type:"integer",minimum:0,maximum:3000},releaseHoldMs:{description:"Keep the finger down at the last point before lifting",type:"integer",minimum:0,maximum:3000},coordinateSpace:{description:"Coordinate units: native absolute (default), normalized 0\u20131, or percent 0\u2013100",type:"string",enum:["absolute","normalized","percent"]},display:{description:"Target panel key, role, or active",type:"string"},snapshotId:{description:"Short-lived reference from observe.snapshotReference; reject stale geometry or frame context",type:"string",minLength:1},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},pointer:{description:"Pointer for this gesture; omit for a finger. Fails with a capability error instead of falling back to a finger.",type:"object",properties:{toolType:{description:"Inject a stylus, or the pen's eraser end, instead of a finger (Android 12+, API 31). Pressure other than 1, tilt, orientation, buttons and any dragPath need stylus_input_v1 or a root adb shell with a uinput tool. An eraser needs a root adb shell with a uinput tool and supports pressure, tilt, orientation and buttons",type:"string",enum:["stylus","eraser"]},pressure:{description:"Stylus pressure 0-1. 1 or omitted uses the shell route; any other value needs stylus_input_v1 (Android 12+) or a root adb shell with a uinput tool, and is refused before input otherwise",type:"number",minimum:0,maximum:1},tilt:{description:"Stylus tilt in radians from the surface normal, 0 to PI/2 (Android 12+)",type:"number",minimum:0,maximum:1.5707963267948966},orientation:{description:"Stylus orientation in radians, -PI to PI (Android 12+)",type:"number",minimum:-3.141592653589793,maximum:3.141592653589793},buttons:{description:"Barrel buttons held for the gesture (Android 12+)",minItems:1,maxItems:2,type:"array",items:{type:"string",enum:["primary","secondary"]}}},required:["toolType"],additionalProperties:!1},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["points"],additionalProperties:!1,description:'Drag one finger along a polyline of points with per-segment timing, an initial hold and a release hold (Android and iOS). Use for drawing, unlock patterns, sliders, and long press then drag. With pointer: { toolType: "stylus" } it draws with a stylus (Android 12+) with per-point pressure and tilt, and is refused instead of using a finger if the device cannot.'}},{name:"executePlan",title:"Execute Automation Plan",annotations:{destructiveHint:!0},description:"Execute YAML plan steps; stops on first failed step.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{planContent:{description:"YAML plan content",type:"string"},startStep:{description:"Start step index",default:0,type:"number"},platform:{type:"string",enum:["android","ios","watchos","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},deviceId:{type:"string"},device:{description:"Device label",type:"string"},devices:{description:"Device labels",type:"array",items:{type:"string"}},deviceAllocationTimeoutMs:{description:"Allocation timeout ms",default:300000,type:"number"},abortStrategy:{description:"Abort strategy",default:"immediate",type:"string",enum:["immediate","finish-current-step"]},testMetadata:{description:"Test metadata",type:"object",properties:{testClass:{type:"string"},testMethod:{type:"string"},appVersion:{type:"string"},gitCommit:{type:"string"},targetSdk:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},jdkVersion:{type:"string"},jvmTarget:{type:"string"},gradleVersion:{type:"string"},isCi:{type:"boolean"}},required:["testClass","testMethod"],additionalProperties:!1},cleanupAppId:{description:"Cleanup app ID",type:"string"},cleanupClearAppData:{description:"Clear app data",type:"boolean"},holdSessionOnFailure:{description:"Keep session and device after a failed run (caller recovers, then releases)",type:"boolean"},captureObserveSteps:{description:"Attach observe snapshots",type:"string",enum:["summary","full"]}},required:["planContent","platform"],additionalProperties:!1}},{name:"explore",title:"Explore Screens",annotations:{destructiveHint:!0},description:"Automatically interact with the app to discover screens and record transitions in the navigation graph; on Android TV it moves D-pad focus and selects instead of tapping (touch if the TV check cannot read the device)",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{maxInteractions:{description:"Max interactions (default: 200)",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},timeoutMs:{description:"Timeout ms (default: 300000)",type:"number",exclusiveMinimum:0},strategy:{description:"Element choice (default: weighted): breadth-first tries the highest-scoring element on the current screen; depth-first prefers untried elements; weighted scores by navigation, novelty and coverage",type:"string",enum:["breadth-first","depth-first","weighted"]},resetToHome:{description:"Reset to home periodically (default: false)",type:"boolean"},resetInterval:{description:"Reset interval (default: 15)",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},mode:{description:"Goal (default: hybrid): discover favors new elements; validate re-walks known transitions to check they still hold; hybrid balances both",type:"string",enum:["discover","validate","hybrid"]},packageName:{description:"Package to limit exploration",type:"string"},dryRun:{description:"Dry run (no interactions)",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"exportPlan",title:"Export Plan",annotations:{destructiveHint:!1},description:"Stop the active recordDeviceGestures or recordToolCalls recording and export a YAML plan.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{recordingId:{description:"recordDeviceGestures recordingId; defaults to the active recording. Omit it to end this connection's recordToolCalls recording",type:"string"},planName:{description:"Plan name",type:"string"},resourceLink:{description:"Return the complete result as an automobile:tool-output resource and a resource_link block instead of inline (default off). Only the headline fields stay inline; read the link to get the rest.",type:"boolean"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"}},additionalProperties:!1}},{name:"exportPrototypeWeb",title:"Export Prototype Web Page",annotations:{destructiveHint:!0,openWorldHint:!1},description:"Write the automobile:prototype/<id>/web page (same bytes, offline, same CSP) to an HTML file; returns its path and sha256, not the HTML. Refuses to replace a different existing file without overwrite.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{id:{description:"Shown prototype id",type:"string",minLength:1},frame:{description:"Device frame id",type:"string"},revision:{description:"Kept spec revision (default latest)",type:"string"},variant:{description:"Variant id shown first",type:"string"},mcpSessionId:{description:"Only this MCP session's revisions",type:"string"},outputPath:{description:"Absolute .html file or directory (default: AutoMobile data dir)",type:"string"},overwrite:{description:"Replace a different existing file",type:"boolean"},sessionUuid:{description:"Session",type:"string"}},required:["id"],additionalProperties:!1}},{name:"focusNavigate",title:"Navigate D-pad Focus",annotations:{destructiveHint:!0},description:"Move D-pad focus to an element on a focus-driven UI such as Android TV or Apple TV. Observes, and until the focused element matches `until` (text, contentDesc, resourceId, or label/elementId resolved to the element tapOn would tap) presses the D-pad arrow (Siri Remote direction on Apple TV) that moves toward the nearest match, or `direction` when given. When a press leaves focus unchanged, or presses in one direction keep moving focus without getting closer, the other arrows are tried so focus can leave a list or slider that traps it. Returns the path of focused elements and a status: focused, max_steps (default 30) or stuck (every arrow from the focused element was tried; two unchanged presses with `direction`). With `select`, presses enter (select on Apple TV) once focused (`selected` reports whether it did); otherwise activate the result with sendKeys key enter on Android TV, or pressButton select on Apple TV.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{until:{description:"The element focus should land on; every field given must match",type:"object",properties:{text:{description:"Text of the element to focus (case-insensitive)",type:"string"},contentDesc:{description:"Content-desc of the element to focus",type:"string"},resourceId:{description:"Resource ID of the element to focus",type:"string"},label:{description:"Text or content-desc of the element to focus, resolved as tapOn's text",type:"string"},elementId:{description:"Element ID of the element to focus, resolved as tapOn's elementId",type:"string"}},additionalProperties:!1},direction:{description:"Press this D-pad direction every step instead of steering toward the target",type:"string",enum:["up","down","left","right"]},maxSteps:{description:"Maximum D-pad presses (default 30)",type:"integer",minimum:1,maximum:100},select:{description:"Press enter (D-pad select) once the target is focused (default false)",type:"boolean"},settleMs:{description:"Wait after each press before observing (default 200)",type:"integer",minimum:0,maximum:5000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["until"],additionalProperties:!1}},{name:"getAndroid",title:"Acquire Android",annotations:{destructiveHint:!0},description:"Find or recover an Android AVD and prepare it for automation. See the automobile:tools resource for every tool's default enabled/gated state before acquiring a device.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{bootTimeoutMs:{description:"Maximum time in ms to find, recover, or boot the device operating system (default 180000). bootTimeoutMs + automationReadyTimeoutMs must be <= 890000, including defaults for omitted fields.",type:"integer",exclusiveMinimum:0,maximum:890000},automationReadyTimeoutMs:{description:"Maximum time in ms to install, update, start, and verify the automation runner (default 180000). bootTimeoutMs + automationReadyTimeoutMs must be <= 890000, including defaults for omitted fields; when bootTimeoutMs is omitted, this must be <= 710000.",type:"integer",minimum:1000,maximum:890000},requires:{description:"Required display capabilities from device inventory, Google Play and vehicle states",type:"object",properties:{panels:{description:"Minimum number of display panels",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},posture:{description:"Supported device posture",type:"string",enum:["closed","half_opened","opened","rear_display","flipped","tent","unknown"]},playStore:{description:"Android emulators only: true needs Google Play (Play Billing, Play-dependent SDKs). Matches only an emulator built from a Play Store system image, and a new emulator is created from one (google_apis_playstore). Play Store images refuse adb root, so root-dependent features report that they need a non-Play image",type:"boolean"},screenRound:{description:"Wear OS emulators only: true matches only a round Wear profile, false only a square one; a new watch is created round unless this is false",type:"boolean"},vehicle:{description:"Simulated vehicle states the automotive emulator must support",type:"object",properties:{motion:{description:"Android Automotive only: the emulator can simulate driving state (deviceCondition vehicle.motion). Matches only a non-Play android-automotive image, and a new emulator is created from one; Play Store car images are user builds that refuse it",type:"string",const:"supported"}},additionalProperties:!1}},additionalProperties:!1},avdName:{description:"Configured Android Virtual Device name (the `name` field of automobile:devices/images/android)",type:"string",minLength:1},deviceId:{description:"Booted device serial, e.g. emulator-5554 (the `runtime.deviceId` field of automobile:devices/booted/android), or a defined AVD image name, which is cold-booted by name. Prefer avdName to boot or coordinate a named AVD.",type:"string",minLength:1},enableTools:{description:"Exact case-sensitive AutoMobile tool names to enable for the session this call mints, applied before the response is built so the returned enabledTools/gatedTools reflect discovery. Unknown or hidden names reject the call before device work; always-on names are returned in skipped.",minItems:1,type:"array",items:{type:"string",minLength:1,enum:["accessibility","accessibilityAction","accessibilityAudit","accessibilityFocus","ambient","appLifecycle","audit","backgroundWork","biometricAuth","captureAudio","captureTrace","changeLocalization","clearKeyValueFile","clearMockNetwork","clipboard","compareScreenshot","crashApp","deleteDevice","deleteKeychainItem","deviceSnapshot","displayConfig","displayProfile","dragAndDrop","dragPath","executePlan","explore","exportPlan","exportPrototypeWeb","focusNavigate","getAppPermissions","getDataStore","getDeepLinks","getDeviceState","getIosSimulatorCapabilities","getLogs","getNavigationGraph","getNetworkGraph","getNotificationPolicy","getPreference","glassesInput","heapDump","highlight","hitTest","homeScreen","hoverAt","identifyInteractions","injectAudioInput","inspectPackageSigning","installApp","keyboard","killDevice","killProfile","launchApp","listApps","listDataStores","listDeviceImages","listDevices","manufacturerProfile","measureStartup","mediaSession","mockNetwork","multiTouch","navigateTo","network","observe","openLink","performanceAudit","performanceTrace","phoneCall","pinchOn","portReverse","postNotification","pressButton","prototype","provisionDevice","putAppFile","recentApps","reconcileDeviceResources","recordDeviceGestures","recordToolCalls","removeKeyValue","resetAppLogs","resetKeychain","rotaryScroll","rotate","rotateCrown","seedContent","selectAllText","sendBroadcast","sendKeys","sendSms","setActiveDevice","setAppLinks","setAppPermissions","setDeviceResources","setDeviceState","setKeyValue","setNotificationPolicy","setPosture","setPreference","setSensor","setUIState","shake","siri","snapshotOf","sqlQuery","statusBar","stopAudioInput","swipeAt","swipeOn","systemAlerts","systemTray","tapAny","tapAt","tapOn","terminateApp","uninstallApp","videoRecording","wakeAndUnlock","wearSurface","windowMode"]}}},additionalProperties:!1}},{name:"getApple",title:"Acquire Apple",annotations:{destructiveHint:!0},description:"Find or recover an iOS Simulator and prepare it for automation. See the automobile:tools resource for every tool's default enabled/gated state before acquiring a device. getApple does not create iOS simulators; use provisionDevice (opt-in via enableTools) to create and boot one from a runtime and device type, and deleteDevice to remove it.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{bootTimeoutMs:{description:"Maximum time in ms to find, recover, or boot the device operating system (default 180000). bootTimeoutMs + automationReadyTimeoutMs must be <= 890000, including defaults for omitted fields.",type:"integer",exclusiveMinimum:0,maximum:890000},automationReadyTimeoutMs:{description:"Maximum time in ms to install, update, start, and verify the automation runner (default 180000). bootTimeoutMs + automationReadyTimeoutMs must be <= 890000, including defaults for omitted fields; when bootTimeoutMs is omitted, this must be <= 710000.",type:"integer",minimum:1000,maximum:890000},udid:{description:"iOS Simulator UDID (the `runtime.deviceId` field of automobile:devices/booted/ios or the `identity.stableId` field of automobile:devices/images/ios)",type:"string",minLength:1},deviceId:{description:"Booted device identifier (the `runtime.deviceId` field of automobile:devices/booted/ios); alias for udid",type:"string",minLength:1},enableTools:{description:"Exact case-sensitive AutoMobile tool names to enable for the session this call mints, applied before the response is built so the returned enabledTools/gatedTools reflect discovery. Unknown or hidden names reject the call before device work; always-on names are returned in skipped.",minItems:1,type:"array",items:{type:"string",minLength:1,enum:["accessibility","accessibilityAction","accessibilityAudit","accessibilityFocus","ambient","appLifecycle","audit","backgroundWork","biometricAuth","captureAudio","captureTrace","changeLocalization","clearKeyValueFile","clearMockNetwork","clipboard","compareScreenshot","crashApp","deleteDevice","deleteKeychainItem","deviceSnapshot","displayConfig","displayProfile","dragAndDrop","dragPath","executePlan","explore","exportPlan","exportPrototypeWeb","focusNavigate","getAppPermissions","getDataStore","getDeepLinks","getDeviceState","getIosSimulatorCapabilities","getLogs","getNavigationGraph","getNetworkGraph","getNotificationPolicy","getPreference","glassesInput","heapDump","highlight","hitTest","homeScreen","hoverAt","identifyInteractions","injectAudioInput","inspectPackageSigning","installApp","keyboard","killDevice","killProfile","launchApp","listApps","listDataStores","listDeviceImages","listDevices","manufacturerProfile","measureStartup","mediaSession","mockNetwork","multiTouch","navigateTo","network","observe","openLink","performanceAudit","performanceTrace","phoneCall","pinchOn","portReverse","postNotification","pressButton","prototype","provisionDevice","putAppFile","recentApps","reconcileDeviceResources","recordDeviceGestures","recordToolCalls","removeKeyValue","resetAppLogs","resetKeychain","rotaryScroll","rotate","rotateCrown","seedContent","selectAllText","sendBroadcast","sendKeys","sendSms","setActiveDevice","setAppLinks","setAppPermissions","setDeviceResources","setDeviceState","setKeyValue","setNotificationPolicy","setPosture","setPreference","setSensor","setUIState","shake","siri","snapshotOf","sqlQuery","statusBar","stopAudioInput","swipeAt","swipeOn","systemAlerts","systemTray","tapAny","tapAt","tapOn","terminateApp","uninstallApp","videoRecording","wakeAndUnlock","wearSurface","windowMode"]}}},additionalProperties:!1}},{name:"getAppPermissions",title:"Get Permissions",annotations:{readOnlyHint:!0},description:"Read app permission state",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},permissions:{description:"Optional permissions or simulator privacy services to query",type:"array",items:{type:"string",minLength:1}},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"getDataStore",title:"Read Data Store",annotations:{readOnlyHint:!0},description:"Read entries from an app Jetpack DataStore instance (Android, requires AutoMobile SDK adapter).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},adapterName:{description:"Name the host app registered its DataStore adapter under (AutoMobile SDK)",type:"string"},name:{description:"DataStore instance name",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","adapterName","name"],additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/deviceReadOnly":!0}},{name:"getDeepLinks",title:"Get Deep Links",annotations:{readOnlyHint:!0},description:"Query app deep links. On Android 12+ also reports appLinks: each web domain's App Links verification state, user selection, and whether the app may open it without a chooser.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"getDeviceState",title:"Get Device State",annotations:{readOnlyHint:!0},description:"Read device-level state including clock (Android epoch-second instant and automaticTime, readable without root; unsupported on iOS), Do Not Disturb, the connectivity toggles (airplaneMode, wifiEnabled, bluetoothEnabled, locationEnabled), iOS Simulator biometric enrollment, network condition (device-wide on Android; on an iOS Simulator the per-app offline rules the network filter enforces, with revision and lease), and Android emulator virtual sensor values (sensors: acceleration, gyroscope, magnetic-field, orientation, temperature, proximity, light, pressure, humidity via `emu sensor get`, with unavailable listing sensors the AVD refuses; change them with setSensor). Use it as the idempotency oracle before flipping a toggle \u2014 a bare call returns doNotDisturb + connectivity, so you can check whether Airplane mode is already on instead of inferring it from the status bar. Each connectivity field is true/false, or omitted when the device could not answer (the key is absent on this API level, or the value did not parse) \u2014 omitted never means off. Android only: iOS reports connectivity unsupported, because Airplane mode / Wi-Fi / Bluetooth / Location have no simctl or devicectl read verb and a simulator shares the host's network stack. screenLock (Android) reports the lock credential type (none, pin, password, pattern, or unknown) and whether it is secure, never the credential. On a multi-panel device, displays lists the panels and supported postures; on an Android foldable displays.current adds the live posture (from the committed device_state) and activePanel (key and role of the panel behind the default display), so a setPosture or fold shows up in the next read. displays.current.postureSource says where posture came from: device_state (Android committed posture), inferred_from_active_panel, or requested_hinge_angle, and is omitted when the Android posture read fails (posture unknown). On iPhone Duo, displays.current reports the active panel read live through devicectl: cover is closed; inner is half_opened (postureSource requested_hinge_angle) when the last angle setPosture applied lies strictly between 0 and 180 degrees, otherwise opened (inferred_from_active_panel). A named setPosture posture also sets that angle (closed 0, half_opened 130, opened 180). The hinge is never read; requestedHingeAngle echoes the last request. It is omitted when the active panel cannot be determined. Clock control supports only rootable Android emulators; Play Store images, physical devices and iOS return unsupported. Set accepts ISO-8601 instants within 2000-01-01T00:00:00Z .. 2100-01-01T00:00:00Z (inclusive); cumulative advance must stay in that window. Commands have second-level precision; advance requires integer byMs >= 1000 (maximum 315360000000), uses device read-back time, and verifies movement with a 2000ms tolerance; set within tolerance reports outcome=unchanged. On session release/rebind/teardown/reset, AutoMobile explicitly restores HOST-derived real time plus the original auto_time, even if it was 1, and verifies both. Failed restore is retried and quarantines the device until success or removal. Clock control restarts adbd on the emulator; connections such as port forwards may be re-established. Restore unroots adbd if AutoMobile rooted it (bounded, best-effort). Hierarchy/observe caches and freshness baselines are invalidated on every clock change. The restore slot is in memory only: daemon restart loses it; reset is recovery to HOST time plus auto_time=1 on a rootable emulator. Without a slot, unsupported targets report unsupported/nothing to reset without clock mutations; with a slot, refused root reports failure and retains pending restoration. Sessionless callers must reset explicitly. Session-bound and sessionless clock writes share one device queue and original ownership baseline; session release restores the device while sessionless ownership persists until reset or removal. Removal cancels clock work for that device incarnation. Changing the clock affects TLS/certificate validation, token expiry, and freshness checks.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{include:{description:"State fields to read; supports doNotDisturb, connectivity, biometrics, networkCondition, clock, sensors (Android emulator only), screenLock, and power (Android: battery, saver, Doze, data saver, thermal status, tracked app standby buckets). Defaults to doNotDisturb + connectivity, so a bare call answers whether Airplane mode / Wi-Fi / Bluetooth / Location are already on.",minItems:1,type:"array",items:{type:"string",enum:["doNotDisturb","connectivity","biometrics","networkCondition","clock","sensors","screenLock","power"]}},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"getIosSimulatorCapabilities",title:"Get iOS Simulator Capabilities",annotations:{readOnlyHint:!0},description:"Discover biometric capabilities for a selected iOS Simulator device type and runtime.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{deviceType:{description:"CoreSimulator device-type identifier selected from automobile:devices/images.",type:"string",minLength:1},runtime:{description:"CoreSimulator runtime identifier selected from automobile:devices/images.",type:"string",minLength:1},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"}},required:["deviceType","runtime"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"getLogs",title:"Read Device Logs",annotations:{readOnlyHint:!0},description:"Read device logs with filters: Android logcat by app (every process, so a crash survives process death), tags, priority, regex, buffers (main, system, crash, events) and since the last action or session start; iOS, Apple Watch, Apple TV and Apple Vision Pro Simulator unified log by app subsystem and process. Bounded output.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},appId:{description:"Package or bundle id; on Android every process of the app, not one pid",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},since:{description:'Window start: "lastAction", "sessionStart", "run-start" (executePlan only), or {seconds} (default 300s)',anyOf:[{type:"string",enum:["lastAction","sessionStart","run-start"]},{type:"object",properties:{seconds:{type:"integer",minimum:1,maximum:3600}},required:["seconds"],additionalProperties:!1}]},tags:{description:'Android logcat tag filters, "Tag" or "Tag:P" (other tags are silenced)',maxItems:32,type:"array",items:{type:"string",minLength:1}},minPriority:{description:"Lowest priority shown (default V). Apple unified log: V/D debug and up, I info and up, W default and up (no warning level), E error and fault, F fault",type:"string",enum:["V","D","I","W","E","F"]},grep:{description:"Regular expression applied host-side to each line",type:"string",minLength:1},buffers:{description:'Android logcat buffers (default ["main","crash"])',minItems:1,type:"array",items:{type:"string",enum:["main","system","crash","events"]}},includeSystem:{description:"Android: add ActivityManager/system lines that name appId (launch, death, ANR)",type:"boolean"},maxLines:{description:"Newest lines kept (default 1000)",type:"integer",minimum:1,maximum:5000},resourceLink:{description:"Return the complete result as an automobile:tool-output resource and a resource_link block instead of inline (default off). Only the headline fields stay inline; read the link to get the rest.",type:"boolean"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"getNavigationGraph",title:"Get Navigation Graph",annotations:{readOnlyHint:!0,openWorldHint:!1},description:"Get the learned navigation graph (screens, transitions, current screen) for the foreground or given app; use before navigateTo to find screen names",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},appId:{description:"Scope the graph to this app id instead of the device's current foreground app",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},prototypeSpec:{description:"A prototype spec to diff against this graph: returns prototypeDiff with matched screens, prototype screens and transitions the app lacks, and app screens the prototype lacks. Not with prototypeSpecPath",type:"object",propertyNames:{type:"string"},additionalProperties:{}},prototypeSpecPath:{description:"Absolute path of a prototype spec JSON file to diff against. Not with prototypeSpec",type:"string"},screenMapping:{description:"Explicit matches for the diff: prototype screen id (as screenMap reports it, e.g. stack:nav/home) to real screen name. Tried before testTag and name matching. Not with screenMappingPath",type:"object",propertyNames:{type:"string"},additionalProperties:{type:"string"}},screenMappingPath:{description:"Absolute path of a JSON file holding screenMapping. Not with screenMapping",type:"string"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/deviceReadOnly":!0}},{name:"getNetworkGraph",title:"Get Network Graph",annotations:{readOnlyHint:!0,openWorldHint:!1},description:"Get aggregate captured network graph.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{sinceSeconds:{description:"Lookback seconds",type:"number",exclusiveMinimum:0},method:{description:"Filter by HTTP method",type:"string"},minRequests:{description:"Minimum request count",type:"integer",minimum:1,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/deviceReadOnly":!0}},{name:"getNotificationPolicy",title:"Get Notification Policy",annotations:{readOnlyHint:!0},description:"Read app notification/DND policy state",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"getPreference",title:"Get Preference",annotations:{readOnlyHint:!0},description:"Read an Android system property, Android SharedPreferences key, or iOS UserDefaults key. On iOS, appId is required and the store selector is suite (not name or fileName as on setKeyValue); omit suite or use Standard for the default store. Uses an already connected embedded AutoMobile SDK with storage inspection enabled; storage access itself never starts a runner. Reads can fall back to the simulator data container's on-disk plist, which may lag the running app. Writes use the container only when no SDK connection is open before sending; SDK write failures never trigger a second write. App-group suites require the connected SDK.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{scope:{description:"Preference scope",type:"string",enum:["systemProperty","sharedPreferences","userDefaults"]},appId:{description:"App package or bundle id",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},suite:{description:"SharedPreferences file name or UserDefaults suite/app group",type:"string",pattern:"^(?:\\s*|[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*)$"},key:{description:"Preference key or Android system property name",type:"string",minLength:1},userId:{description:"Android sharedPreferences only: user whose copy of the app to read/write (e.g. a work profile). Defaults to user 0 when the app is installed for it; otherwise to the one other running user that has it (an error asks for userId if several do). The result reports the userId used.",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["scope","key"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"glassesInput",title:"Glasses Focus Input",annotations:{destructiveHint:!0},description:"Android XR glasses: tap clicks the focused item; swipeForward/swipeBack move focus using DPAD keys (vertical down/up by default, horizontal right/left). count repeats any gesture 1..20 times. Success means adb commands exited cleanly; no read-back is performed, so observe afterwards. Voice input uses the existing injectAudioInput tool. Long press and two-finger gestures are not injectable yet: key holds produce no long click and raw touchpad holds/gestures are swallowed by the unpaired glasses system UI (raw input also requires adb root). Direct DPAD avoids unreliable touchnavigation swipes and touchpad motion that does not change focus. Unconfirmed glasses receive a warning but input is still sent.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{gesture:{description:"tap clicks focus; swipeForward/swipeBack move focus along axis",type:"string",enum:["tap","swipeForward","swipeBack"]},axis:{description:"Focus axis, default vertical; ignored for tap",type:"string",enum:["vertical","horizontal"]},count:{description:"Repeat the gesture 1..20 times, default 1 (including tap)",type:"integer",minimum:1,maximum:20},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["gesture"],additionalProperties:!1}},{name:"heapDump",title:"Dump Heap",annotations:{destructiveHint:!1},description:"Android: dump a running debuggable or profileable app's heap (am dumpheap) to a host .hprof; refuses other apps with heap_dump_not_debuggable.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Running debuggable or profileable app to dump",type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},native:{description:"Dump the native heap (am dumpheap -n); default Java",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"highlight",title:"Highlight Screen Element",annotations:{destructiveHint:!1},description:"Draw a red hand-drawn circle around a UI element.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},deviceId:{type:"string"},timeoutMs:{description:"Highlight request timeout ms (default: 5000)",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},description:{description:"Optional description of the highlight",type:"string"},shape:{description:"Optional bounds for a red hand-drawn circle",type:"object",properties:{type:{type:"string",const:"circle"},bounds:{type:"object",properties:{x:{type:"integer",minimum:-9007199254740991,maximum:9007199254740991},y:{type:"integer",minimum:-9007199254740991,maximum:9007199254740991},width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},sourceWidth:{anyOf:[{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},{type:"null"}]},sourceHeight:{anyOf:[{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},{type:"null"}]}},required:["x","y","width","height"],additionalProperties:!1}},required:["type","bounds"],additionalProperties:!1},elementId:{description:"Resource ID, e.g. com.app:id/btn_login",type:"string"},text:{description:"Text, content-desc, or placeholder",type:"string"},container:{description:"Nested container scope; outermost resolves first, with per-level index and selectionStrategy",anyOf:[{$ref:"#/$defs/__schema0"},{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string"}},required:["text"],additionalProperties:!1}]}]},containerOf:{description:"Highlight selected element's container",type:"boolean"},selectionStrategy:{description:"Selection strategy when multiple match (default: first)",type:"string",enum:["first","random","unique"]},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1,$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"hitTest",title:"Inspect Point",annotations:{readOnlyHint:!0},description:"Preview hierarchy-bounds candidates at a platform-native screen point; no input is dispatched and the actual event recipient is unknown.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:"Target panel key, role, or active",type:"string"},snapshotId:{description:"Short-lived reference from observe.snapshotReference; reject stale geometry or frame context",type:"string",minLength:1},x:{description:"Screen x coordinate in the selected coordinateSpace (native by default)",type:"number"},y:{description:"Screen y coordinate in the selected coordinateSpace (native by default)",type:"number"},coordinateSpace:{description:"Coordinate units: native absolute (default), normalized 0\u20131, or percent 0\u2013100",type:"string",enum:["absolute","normalized","percent"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["x","y"],additionalProperties:!1,description:"Preview which hierarchy nodes sit beneath one absolute point without dispatching input."},_meta:{"automobile/deviceReadOnly":!0}},{name:"homeScreen",title:"Open Home Screen",annotations:{destructiveHint:!1},description:"Go to home screen",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"hoverAt",title:"Hover Over Path",annotations:{destructiveHint:!0},description:"Hover a stylus or mouse over a path with no contact: hover enter, move, exit (Android; needs hover_input_v1 or, for a stylus, a root adb shell with a writable /dev/uinput).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{points:{description:"Hover positions: the pointer enters at the first, moves through the rest and exits at the last. No contact is made",minItems:1,maxItems:100,type:"array",items:{type:"object",properties:{x:{description:"x in the selected coordinateSpace (native by default)",type:"number"},y:{description:"y in the selected coordinateSpace (native by default)",type:"number"},durationMs:{description:"Milliseconds spent moving from the previous point to this one (default 200); ignored on the first point",type:"integer",minimum:1,maximum:5000},distance:{description:"Stylus hover distance from the surface: 0 touching, 1 farthest. Stylus only; a mouse has none",type:"number",minimum:0,maximum:1}},required:["x","y"],additionalProperties:!1}},toolType:{description:"Pointer that hovers (default stylus). Apps see a different tool type and source: a stylus hover reports TOOL_TYPE_STYLUS with a hover distance, a mouse hover reports TOOL_TYPE_MOUSE",type:"string",enum:["stylus","mouse"]},coordinateSpace:{description:"Coordinate units: native absolute (default), normalized 0\u20131, or percent 0\u2013100",type:"string",enum:["absolute","normalized","percent"]},display:{description:"Target panel key, role, or active",type:"string"},snapshotId:{description:"Short-lived reference from observe.snapshotReference; reject stale geometry or frame context",type:"string",minLength:1},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["points"],additionalProperties:!1,description:"Hover a stylus or mouse over a path of points with no contact: hover enter, move and exit (Android, needs the hover_input_v1 capability or, for a stylus, a root adb shell with a writable /dev/uinput; refused on iOS and otherwise, never turned into a touch)."}},{name:"identifyInteractions",title:"Identify Interactions",annotations:{readOnlyHint:!0},description:"Suggest likely interactions",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},filter:{description:"Filter options",type:"object",properties:{types:{description:"Interaction types",type:"array",items:{type:"string",enum:["navigation","input","action","scroll","toggle"]}},minConfidence:{description:"Min confidence (0-1)",type:"number",minimum:0,maximum:1},limit:{description:"Max results",type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},additionalProperties:!1},includeContext:{description:"Context options",type:"object",properties:{navigationGraph:{description:"Include nav graph predictions",type:"boolean"},elementDetails:{description:"Include element details",type:"boolean"},suggestedParams:{description:"Include tool params",type:"boolean"}},additionalProperties:!1},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/debugOnly":!0,"automobile/deviceReadOnly":!0}},{name:"injectAudioInput",title:"Inject Emulator Microphone Audio",annotations:{destructiveHint:!1},description:"Play a WAV file or a built-in tone into an Android emulator's or iOS Simulator's microphone, so an app under test records known audio (voice notes, voice search, calls). An emulator streams through its own gRPC audio API, isolated per emulator. A simulator goes through the host's loopback input device, which every simulator on the host shares, so one simulator injection runs per host. For Android, AutoMobile opens and verifies a guest microphone capture before streaming and closes its recorder when injection ends. Returns an injectionId once streaming starts; stop it with stopAudioInput. Session release stops it. Errors lead with a code: [audio_injection_busy] another injection holds the microphone; [audio_injection_unsupported] no route (not a local emulator with gRPC audio, or a host without a loopback default input); [audio_loopback_failed] the host loopback helper failed; [audio_record_permission_not_granted] CtrlProxy lacks android.permission.RECORD_AUDIO: run adb shell pm grant dev.jasonpearson.automobile.ctrlproxy android.permission.RECORD_AUDIO; [audio_guest_capture_unavailable] a safe Android guest capture could not be verified; [audio_emulator_exited] the emulator exited during injection. Physical devices are refused.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{file:{description:"Host path to an uncompressed PCM WAV file. Pass file or tone, not both.",type:"string",minLength:1},tone:{description:"Built-in sine tone at -6 dBFS, for a known non-silent signal without a file.",type:"object",properties:{frequencyHz:{description:"Default 1000.",type:"number",minimum:20,maximum:20000},durationMs:{description:"Default 2000.",type:"integer",minimum:100,maximum:600000}},additionalProperties:!1},loop:{description:"Repeat until stopped or maxDurationMs (default 10 min).",type:"boolean"},startDelayMs:{description:"Wait before the first audio, so the app can start recording.",type:"integer",minimum:0,maximum:60000},gainDb:{description:"Gain applied before injection.",type:"number",minimum:-60,maximum:20},maxDurationMs:{type:"integer",minimum:100,maximum:3600000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"inspectPackageSigning",title:"Inspect Package Signing",annotations:{readOnlyHint:!0},description:"Fresh read of one app's presence (installed/absent/unknown) and signing. Android: a user's SHA-256 signer set and rotation history. iOS Simulator and physical: team, signing identity, CDHash, entitlements and embedded provisioning profile (expiry, UUID). Never cached.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},userId:{description:"Android user/profile to inspect; when omitted it is resolved and reported. Refused on iOS",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"installApp",title:"Install App",annotations:{destructiveHint:!0},description:"Install app on device (.apk, split APKs, .apks, .aab, .app, or .ipa)",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},artifactPath:{description:"Android: .apk, .apks, .aab (needs bundletool), or a directory of split APKs; iOS: .app or .ipa; watchOS: .app",type:"string"},splits:{description:"Android: split APKs installed with the base .apk artifactPath (install-multiple)",minItems:1,type:"array",items:{type:"string",minLength:1}},bundle:{description:"Android .aab/.apks options",type:"object",properties:{keystore:{description:".aab: signing key for the built APKs (default ~/.android/debug.keystore)",type:"object",properties:{path:{description:"Keystore file path",type:"string",minLength:1},alias:{description:"Key alias",type:"string",minLength:1},storePassword:{description:"Keystore password (redacted from logs)",type:"string",minLength:1},keyPassword:{description:"Key password (redacted from logs; default storePassword)",type:"string",minLength:1}},required:["path","alias","storePassword"],additionalProperties:!1},modules:{description:"Dynamic feature modules to install, or ['_ALL_']",minItems:1,type:"array",items:{type:"string",minLength:1}},localTesting:{description:".aab: build with bundletool --local-testing for on-demand modules",type:"boolean"}},additionalProperties:!1},grantAllPermissions:{description:"Android: grant all requested runtime permissions (install -g)",type:"boolean"},allowDowngrade:{description:"Android: allow a lower versionCode (install -d; debuggable apps only)",type:"boolean"},expectedSigningSha256:{description:"Android: complete signer set (SHA-256 of every signing certificate) an already installed copy must have before it is replaced; any other signer set, or signers that cannot be read, refuses the install. See inspectPackageSigning.",minItems:1,maxItems:16,type:"array",items:{type:"string",pattern:"^(?:[0-9a-fA-F]{2}:?){31}[0-9a-fA-F]{2}$"}},allowDestructiveRecovery:{description:"Android: true uninstalls the installed copy, deleting its app data, and reinstalls after INSTALL_FAILED_VERSION_DOWNGRADE (result dataPreserved: false). Default false: a downgrade fails with install_downgrade_refused and leaves the app untouched",type:"boolean"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["artifactPath"],additionalProperties:!1}},{name:"keyboard",title:"Control Keyboard",annotations:{destructiveHint:!0},description:"Open, close, detect, list/select installed Android IMEs, or switch the AutoMobile typing profile",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"Keyboard action; listProfiles returns AutoMobile behavior models and listImes returns installed Android input methods",type:"string",enum:["open","close","detect","setProfile","listProfiles","listImes","setIme","tapImeKey"]},profile:{description:"AutoMobile keyboard behavior profile; required for setProfile",type:"string",enum:["direct","gboard","samsung"]},imeId:{description:"Installed Android IME component; required for setIme",type:"string"},key:{description:"Exact visible key text or accessibility label; required for tapImeKey",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["detect","listImes","listProfiles"]}]}},{name:"killDevice",title:"Kill Device",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Kill device",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{device:{type:"object",properties:{name:{description:"Device image name",type:"string"},deviceId:{type:"string"},platform:{type:"string",enum:["android","ios","watchos","tvos","visionos"]}},required:["name","deviceId","platform"],additionalProperties:!1},force:{description:"Drop every AVD-name comparison on the way to the kill -- the emulator-console probe that confirms which AVD is running on this serial, and the platform kill's own check against a fresh discovery -- and act on whatever occupies the serial. Use only when the console has wedged and the normal call refuses because the AVD name cannot be confirmed. This does not override the conflict check, it removes it: force means 'act on whatever emulator currently occupies this serial', including a different AVD that took the serial over. It does NOT select a different serial, and a serial with nothing running on it still refuses. Nor does it override the refusal raised when this daemon's pool entry for the serial was retired and replaced while the action was being prepared, or deleteDevice's refusal to delete a stopped image while a booted emulator that cannot be identified at all is attached. Android emulators only; accepted and ignored for iOS and physical devices. Separately, on any platform, force also stops a device another session holds, which is otherwise refused.",default:!1,type:"boolean"}},required:["device"],additionalProperties:!1}},{name:"killProfile",title:"Set Kill Policy",annotations:{destructiveHint:!0},description:"Android: simulate an OEM background-kill policy (Samsung sleeping apps, Xiaomi autostart off, OnePlus deep optimization, recents swipe, Motorola adaptive battery, user-restricted, exact alarms denied) on a stock device with standby buckets, appops, Doze, permission revocation, foreground-change kills, timed screen-off cleanup, boot-receiver observations and force-stop. Each profile reports its evidence status and each step applied | unsupported | failed. apply is idempotent and records the state before the first change; reset restores it, and in a daemon session release or rebind does too. list shows the catalog and the OEM behaviour that cannot be simulated. Simulates effects, not firmware.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"apply a profile, reset what profiles changed, or list the catalog (no device change)",type:"string",enum:["apply","reset","list"]},appId:{description:"Android package; required for apply and reset",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},profile:{description:"Profile id; required for apply",type:"string",enum:["samsung-sleeping","samsung-deep-sleeping","samsung-auto-disable","samsung-foreground-kill","screen-off-stop","xiaomi-autostart-off","oneplus-deep-optimization","recents-swipe-kill","recents-swipe-force-stop","oneplus-sleep-standby","motorola-adaptive","user-restricted","exact-alarm-denied","notifications-off","huawei-powergenie","vivo-autostart","realme-power-saver","meizu-flyme-background","asus-power-master","sony-stamina","tecno-app-halt"]},baseline:{description:"reset only: when nothing is recorded (e.g. after a daemon restart), write the AOSP defaults",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["list"]}]}},{name:"launchApp",title:"Launch App",annotations:{destructiveHint:!0},description:"Launch app by package name. On Android an app that is already in the foreground returns success with alreadyForeground:true plus the observation, not an error; iOS re-launches it and returns an ordinary success without that marker. prototype:true (iOS simulators only) relaunches the app with the prototype agent injected, so its current state is lost.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},clearAppData:{description:"Clear app data before launch (default false); on watchOS wipes the app's data container",type:"boolean"},coldBoot:{description:"Cold boot app (default false)",type:"boolean"},launchArguments:{description:"Arguments passed to the launched iOS or watchOS app. On Android use intent instead.",type:"array",items:{type:"string"}},intent:{description:"Android only: start the app with this intent (component, action, data, categories, typed extras, flags) instead of the launcher intent. Always launches, even when the app is in front; am start refusals are typed (activity_not_exported, activity_not_found, intent_unresolved).",type:"object",properties:{component:{description:'Activity of the launched app: ".DebugActivity", a fully qualified class, or "<appId>/<class>". Omitted: Android resolves action/data within the app (one of them is required). Other packages are refused',type:"string",minLength:1},action:{description:"Intent action, e.g. android.intent.action.VIEW",type:"string",minLength:1},data:{description:"Data URI",type:"string",minLength:1},mimeType:{type:"string",minLength:1},categories:{type:"array",items:{type:"string",minLength:1}},extras:{type:"array",items:{anyOf:[{type:"object",properties:{key:{description:"Extra key",type:"string",minLength:1},type:{type:"string",const:"string"},value:{type:"string"}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{description:"Extra key",type:"string",minLength:1},type:{type:"string",enum:["int","long","float"]},value:{type:"number"}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{description:"Extra key",type:"string",minLength:1},type:{type:"string",const:"boolean"},value:{type:"boolean"}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{description:"Extra key",type:"string",minLength:1},type:{type:"string",const:"stringArray"},value:{type:"array",items:{type:"string"}}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{description:"Extra key",type:"string",minLength:1},type:{type:"string",const:"uri"},value:{type:"string",minLength:1}},required:["key","type","value"],additionalProperties:!1}]}},flags:{type:"array",items:{type:"string",enum:["clearTask","newTask","singleTop","clearTop","noHistory"]}}},additionalProperties:!1},prototype:{description:"iOS simulator only: inject the prototype agent so the prototype tool can draw over this app. Always relaunches the app, losing its state. Rejected on physical iOS devices (use the in-app SDK), on Android (prototypes need no injection) and for com.apple.* apps.",type:"boolean"},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"listApps",title:"List Installed Apps",annotations:{readOnlyHint:!0},description:"List installed apps on a device, with optional display label and launchable fields when reported by the platform or transport. The label is typically omitted on Android when the installed CtrlProxy APK lacks label support; launchable is typically omitted for physical iOS/devicectl records. Filters by type (default: launchable \u2014 every app with a launcher entry point, preinstalled ones included), search (package name or label), and profile.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},type:{description:"Filter by app type. Defaults to 'launchable': every app with a launcher entry point, user-installed or preinstalled, so the apps a human names (Contacts, Clock, Settings) are visible while content providers and RRO overlays are not. 'user' and 'system' keep their meaning and must be asked for explicitly; 'all' returns every installed package. The default degrades to 'user' when the device reports no launchability signal, and an explicit 'launchable' is then rejected rather than silently empty. On a physical iOS device, where user/system classification is unavailable (devicectl reports no such signal), an omitted type returns every app (reported as 'all') and an explicit 'user' or 'system' filter is rejected rather than silently honored.",type:"string",enum:["launchable","user","system","all"]},search:{description:"Filter by a case-insensitive substring of the package name/bundle id or of the app's display label ('contacts' matches both com.android.contacts and an app labelled Contacts). Android labels require the installed CtrlProxy APK; without it only the package name is matched.",type:"string"},profile:{description:"Filter to apps visible to this user profile id.",type:"integer",minimum:0,maximum:9007199254740991},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"listDataStores",title:"List Data Stores",annotations:{readOnlyHint:!0},description:"List app Jetpack DataStore instances (Android, requires AutoMobile SDK adapter).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},adapterName:{description:"Name the host app registered its DataStore adapter under (AutoMobile SDK)",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","adapterName"],additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/deviceReadOnly":!0}},{name:"listDeviceImages",title:"List Device Images",annotations:{readOnlyHint:!0},description:"List device images; when `truncated` is true the result was over 64 KiB and `images` is partial: read `artifact.resourceUri` or the resource_link for the full list",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session used for inventory admission",type:"string"},detail:{description:"compact (default): host-scoped capabilities once under `host`, shared `capabilityProfiles`, null fields omitted; full: every image carries its own `capabilityInventory` and null fields",type:"string",enum:["compact","full"]}},required:["platform"],additionalProperties:!1},_meta:{"automobile/hostInventory":!0,"automobile/deviceReadOnly":!0}},{name:"listDevices",title:"List Devices",annotations:{readOnlyHint:!0},description:"List booted devices; pending configured-image enrichment includes retry hints and failed provenance includes a non-retryable reason; resource pointers for images and detail in the note",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},requires:{description:"Filter booted devices by display inventory capabilities",type:"object",properties:{panels:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},posture:{type:"string",enum:["closed","half_opened","opened","rear_display","flipped","tent","unknown"]}},additionalProperties:!1}},additionalProperties:!1},_meta:{"automobile/hostInventory":!0,"automobile/deviceReadOnly":!0}},{name:"manufacturerProfile",title:"Set OEM Profile",annotations:{destructiveHint:!0},description:"Android: apply an OEM manufacturer profile (pixel-baseline, samsung-oneui, xiaomi-hyperos, oneplus-oxygenos, oppo-coloros, motorola, huawei-emui, vivo-funtouch, realme-ui, meizu-flyme, asus-zenui, sony-xperia, tecno-hios) on a stock device by composing the keyboard profile, killProfile and displayProfile executors. describe reports every facet's evidence status (focused_trace | vendor_documented | cdd_derived | inferred | experimental) and the OEM capabilities that cannot be emulated; apply with requires naming one of those returns route_to_real_device and changes nothing. applying a different manufacturer profile resets the recorded one first; reset restores the display, kill and keyboard changes (display, keyboard and device-wide kill state are shared with displayProfile, keyboard setProfile and killProfile, so reset also undoes their direct changes). In a daemon session, release or rebind restores all three. Simulates effects, not firmware.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"list the catalog or describe one manufacturer profile (no device change), apply one, or reset what manufacturer profiles changed",type:"string",enum:["list","describe","apply","reset"]},manufacturerProfile:{description:"Manufacturer profile id; required for describe and apply",type:"string",enum:["pixel-baseline","samsung-oneui","xiaomi-hyperos","oneplus-oxygenos","oppo-coloros","motorola","huawei-emui","vivo-funtouch","realme-ui","meizu-flyme","asus-zenui","sony-xperia","tecno-hios"]},appId:{description:"Android package the kill facet targets; required to apply a manufacturer profile with a kill profile",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},requires:{description:"apply only: OEM capabilities the task needs; one the manufacturer profile cannot emulate returns route_to_real_device and changes nothing",type:"array",items:{type:"string",enum:["samsung-dex","knox","flip-cover-screen","spen-air-actions","oem-systemui","oem-unused-app-triggers","firmware-update-exemption-reset","xiaomi-proprietary-appops"]}},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["list","describe"]}]}},{name:"measureStartup",title:"Measure Startup",annotations:{destructiveHint:!0},description:"Android: measure cold/warm/hot app startup over N launches; TTID/TTFD percentiles, stored in performance results.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Package to launch",type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},activity:{description:"Activity or pkg/.Activity component; default launcher activity",type:"string",pattern:"^[\\w.$/]+$"},mode:{description:"cold: process killed; warm: process kept, activity recreated; hot: activity resumed",type:"string",enum:["cold","warm","hot"]},iterations:{description:"Launches to measure; default 5",type:"integer",minimum:1,maximum:50},compilation:{description:"Recompile first (cmd package compile -m <mode> -f); default asIs",type:"string",enum:["asIs","speed-profile","speed","verify"]},dropCaches:{description:"Drop the page cache before each cold launch; needs a root shell",type:"boolean"},waitForFullyDrawn:{description:"Wait for reportFullyDrawn to record TTFD",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","mode"],additionalProperties:!1}},{name:"mediaSession",title:"Control Media",annotations:{destructiveHint:!0},description:"Android media sessions: read playback state, position, speed, metadata and actions (dumpsys media_session); dispatch a transport key to the media button session like a headset, reporting which session handled it; or set a music/ring/alarm stream volume. Mutations return a restore receipt. waitFor polls get until a session reports a state.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Package. get: only its sessions. dispatch: refuse unless it is the media button session",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},action:{description:'"get" reads sessions; {dispatch} sends a media key like a headset; {volume} sets a stream index',anyOf:[{type:"string",const:"get"},{type:"object",properties:{dispatch:{type:"string",enum:["play","pause","play-pause","next","previous","stop","fast-forward","rewind"]}},required:["dispatch"],additionalProperties:!1},{type:"object",properties:{volume:{type:"object",properties:{stream:{type:"string",enum:["music","ring","alarm"]},level:{description:"Volume index within the stream's range",type:"integer",minimum:0,maximum:9007199254740991}},required:["stream","level"],additionalProperties:!1}},required:["volume"],additionalProperties:!1}]},waitFor:{description:"get only: poll until a session (of appId, if given) reports this state",type:"object",properties:{mediaState:{type:"string",enum:["none","stopped","paused","playing","fast_forwarding","rewinding","buffering","error","connecting","skipping_to_previous","skipping_to_next","skipping_to_queue_item"]},timeoutMs:{description:"Wait timeout ms (default: 5000)",type:"integer",exclusiveMinimum:0,maximum:1770000}},required:["mediaState"],additionalProperties:!1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["get"]}]}},{name:"mockNetwork",title:"Mock Network Response",annotations:{destructiveHint:!1},description:"Add mock network response rule.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{host:{description:"Host pattern (regex)",type:"string"},path:{description:"Path pattern (regex)",type:"string"},method:{description:"HTTP method; default *",type:"string"},limit:{description:"Mock response limit",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},statusCode:{description:"Response status; default 200",type:"integer",minimum:100,maximum:599},responseHeaders:{description:"Response headers",type:"object",propertyNames:{type:"string"},additionalProperties:{type:"string"}},responseBody:{description:"Response body (max 10KB)",type:"string"},contentType:{description:"Content-Type; default application/json",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["host","path"],additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/hostSideState":!0}},{name:"multiTouch",title:"Multi Touch Gesture",annotations:{destructiveHint:!0},description:"Simultaneous 2-5 finger tap, long press, or swipe at a screen point.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"Simultaneous multi-finger gesture to perform",type:"string",enum:["tap","longPress","swipe"]},fingers:{description:"Simultaneous fingers (2-5, default 2); use tapAt/swipeOn for one finger. Counts above 2 on Android need the multi_finger_gesture_v1 CtrlProxy capability and are refused before dispatch otherwise",type:"integer",minimum:2,maximum:5},x:{description:"Finger-group center x in the selected coordinateSpace",type:"number"},y:{description:"Finger-group center y in the selected coordinateSpace",type:"number"},coordinateSpace:{description:"Units for x/y: native absolute (default), normalized 0-1, or percent 0-100",type:"string",enum:["absolute","normalized","percent"]},direction:{description:"Swipe finger direction; required for swipe, invalid otherwise",type:"string",enum:["up","down","left","right"]},distance:{description:"Swipe travel in native px (default 30% of the travel axis); clamped so every finger stays on screen",type:"number",exclusiveMinimum:0},fingerSpacing:{description:"Horizontal gap between neighbouring fingers in native px (10-400; default 10% of the width, 40-160). The row is centered on x and shifted to fit the screen",type:"number",minimum:10,maximum:400},durationMs:{description:"Duration in ms (max 3000). longPress 500-3000, default 1000; swipe default 300; tap is fixed at 50",type:"integer",minimum:1,maximum:3000},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action","x","y"],additionalProperties:!1,description:"Simultaneous 2-5 finger tap, long press, or swipe at a screen point. Fingers sit in a horizontal row centered on x/y."}},{name:"navigateTo",title:"Navigate to Screen",annotations:{destructiveHint:!0},description:"Navigate to a learned screen by replaying recorded transitions from the navigation graph",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{targetScreen:{description:"Screen name to reach; use a name from getNavigationGraph's screens",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["targetScreen"],additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"network",title:"Control Network Capture",annotations:{destructiveHint:!1},description:"Control network capture and error simulation.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{capture:{description:"Toggle capture",type:"boolean"},simulateErrors:{description:"Error simulation settings",type:"object",properties:{errorType:{description:"Error type; default http500",type:"string",enum:["http500","timeout","connectionRefused","dnsFailure","tlsFailure"]},limit:{description:"Max errors",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},durationSeconds:{description:"Simulation duration seconds",type:"number",exclusiveMinimum:0},cancel:{description:"Cancel active simulation",type:"boolean"}},additionalProperties:!1},notifFilter:{description:"Notification filter",type:"string",enum:["all","errors","slow"]},notifDebounceMs:{description:"Notification debounce ms",type:"integer",minimum:0,maximum:9007199254740991},slowThresholdMs:{description:"Slow threshold ms",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0,"automobile/hostSideState":!0}},{name:"observe",title:"Observe Screen",annotations:{readOnlyHint:!0},description:"Android synthetic s2- element ids are valid only for the observation that returned them; re-observe before using an id after the screen changes. The default skeleton lists only actionable rows; read static text (status labels, validation errors) from context. Without layer, waitFor text and textAny, and for: appear/textEquals with only text, also match rows in both arrays when no hierarchy node carries the text (textEquals stays exact and case-sensitive). Get screen view hierarchy and screenshot, with optional PNG crop from a fresh settled capture of one display. On an Apple Watch simulator (platform: 'watchos' or a watch session), observe keeps the screenshot and returns hierarchy-derived elements in XCTest points when a watch runner is connected (project: 'full' includes viewHierarchy). Without a connected runner it returns screenshot-only with physical screenSize and hierarchyUnavailable. With a runner hierarchy (watchOS, tvOS, visionOS), element waitFor polls the runner hierarchy; waitFor for/posture/activeDisplay/activeWindow and other advanced observe options are refused. On an Apple TV simulator (platform: 'tvos' or an Apple TV session), observe returns a screenshot and runner hierarchy with focusedElement when connected (project: 'full' includes viewHierarchy); without a runner, or when the runner does not answer, it returns screenshot-only with hierarchyUnavailable (project and waitFor are then refused). Use pressButton for focus navigation. On an Apple Vision Pro simulator (platform 'visionos'), observe returns a screenshot and the window-app runner hierarchy with focusedElement (project: 'full' includes viewHierarchy). hierarchyBundleId is the bundle ID of the window app the runner that returned the hierarchy was started for (the launchApp target when it started). It is present with the default projection too, and omitted when that runner has no target app or the hierarchy is unavailable. This can differ from the app in the screenshot when another app was brought forward outside launchApp; compare them and relaunch with launchApp to switch. The runner starts on demand, except that a deviceId read of a device another session holds only connects to an already-running runner; when it cannot start or be reached, observe returns screenshot-only with hierarchyUnavailable unless project is set, which then is refused. Opt-in Android display:'all' adds per-panel displays to the unchanged active-panel result, without updating observation baselines or transition fences; rejects waitFor, raw:true and includeScreenshotImage:true. An explicit deviceId without sessionUuid creates no session, assigns no device and leaves an idle device idle. It may start an unowned device's hierarchy service using session setup within the read deadline, serialized with acquisition, guarded against ownership/pool transitions, and shared across concurrent reads. hierarchyServiceStarted: true reports this; the service and resident client remain running. Owned devices stay connect-only: this read never starts, restarts or reconfigures their service. With sessionUuid, observe uses the session and deviceId must match the session's device. DeviceId reads reject waitFor, raw: true and skipBackStack: true; use project: 'full' for the full filtered hierarchy. They omit snapshotReference and default to a settled screenshot; async also awaits capture. Each screenshot path is kept for at least 10 minutes after the response that returned it unless evicted early under capacity pressure, so a returned path is not guaranteed to survive until its expiresAt; expiresAt metadata uses the host clock. Returning cached paths extends their lifetime. At the shared 128 MiB / 4096-file cap, new captures are never refused: the least recently returned screenshots are evicted early, unreferenced ones first and then referenced ones, to admit them. Release and device removal leave files until their guarantees expire. Restart uses a ten-minute process-start grace; other processes can only honor the ten-minute mtime floor. Capacity uses a per-process in-memory inventory reconciled on sweeps and near either cap. Concurrent processes can exceed the aggregate cap before reconciliation; discovered files count against subsequent admission. Expired files are swept at initial inventory, near capacity and every minute while idle. Copy files needed beyond the guarantee.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},waitFor:{$defs:{waitForContainer:{$schema:"https://json-schema.org/draft/2020-12/schema",anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#waitForContainer"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#waitForContainer"}},required:["text"],additionalProperties:!1}],$anchor:"waitForContainer"}},type:"object",additionalProperties:!1,properties:{for:{type:"string",enum:["appear","disappear","clickable","textEquals","countStable","stable"]},pollMs:{type:"number"},stableReads:{type:"number"},elementId:{type:"string"},testTag:{type:"string",description:"Android test tag, matched like tapOn testTag"},text:{type:"string"},textAny:{type:"array",items:{type:"string"}},className:{type:"string"},contentDescription:{type:"string"},matchType:{type:"string",enum:["all","any"]},textMatch:{type:"string",enum:["exact","contains","regex"],description:"How to match waitFor.text; does not affect contentDescription"},textSource:{type:"string",enum:["displayed"],description:"displayed: match text only against the element's shown text or value"},activeWindow:{type:"object",additionalProperties:!1,properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},packageName:{type:"string"},bundleId:{type:"string"},activityName:{type:"string"}},anyOf:[{required:["appId"]},{required:["packageName"]},{required:["bundleId"]},{required:["activityName"]}]},posture:{type:"string",enum:["closed","half_opened","opened","rear_display","flipped","tent"],description:"Wait for the observed device posture. Single-panel inventory fails immediately; multi-panel or unavailable inventory keeps polling. Timeout diagnostics distinguish unobservable posture (no hierarchy captured), unavailable inventory, and the last observed posture."},activeDisplay:{type:"string",description:"Physical panel key or role"},absent:{type:"object",additionalProperties:!1,description:"Wait until an element matching these fields is absent (text uses exact match)",properties:{selectionStrategy:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"string",enum:["first","random","unique"]},elementId:{type:"string"},testTag:{type:"string"},text:{type:"string"},className:{type:"string"},contentDescription:{type:"string"}},anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["className"]},{required:["contentDescription"]}]},container:{$ref:"#waitForContainer"},selectionStrategy:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"string",enum:["first","random","unique"]},timeout:{type:"number",maximum:1770000},timeoutMs:{type:"number",maximum:1770000}},anyOf:[{properties:{for:{const:"stable"},container:!1,selectionStrategy:!1},required:["for"]},{properties:{for:{enum:["appear","disappear","clickable","textEquals","countStable"]}},required:["for","elementId"]},{properties:{for:{enum:["appear","disappear","clickable","textEquals","countStable"]}},required:["for","text"]},{properties:{for:!1,selectionStrategy:!1},required:["textAny"]},{properties:{for:!1},anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["className"]},{required:["contentDescription"]},{required:["absent"]}]},{properties:{for:!1,selectionStrategy:!1},anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["className"]},{required:["contentDescription"]},{required:["activeWindow"]},{required:["absent"]},{required:["posture"]},{required:["activeDisplay"]}]}]},settled:{description:"After waitFor matches, wait for a quiet hierarchy period (requires waitFor)",type:"object",properties:{quietPeriodMs:{description:"Quiet-period ms (no hierarchy change) required after waitFor matches",type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["quietPeriodMs"],additionalProperties:!1},raw:{description:"Include raw view hierarchy",type:"boolean"},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},screenshot:{description:"Screenshot mode: await a fresh validated capture, use background capture, or skip",type:"string",enum:["settled","async","none"]},crop:{description:"Exactly one of element (tapOn selector) or rect {x,y,width,height} in native screen units. Implies settled capture; explicit async or none is rejected. Returns a PNG path and scalar metadata only.",anyOf:[{type:"object",properties:{element:{description:"Element to tap: elementId, Android testTag, text, semantic accessibility link, or ordered text variants",anyOf:[{type:"object",properties:{elementId:{description:"Resource ID, e.g. com.app:id/btn_login",type:"string",minLength:1}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{testTag:{description:"Android accessibility test tag",type:"string",minLength:1}},required:["testTag"],additionalProperties:!1},{type:"object",properties:{text:{description:"Text, content-desc, or placeholder",type:"string",minLength:1}},required:["text"],additionalProperties:!1},{type:"object",properties:{accessibilityLink:{description:"Exact visible text of a semantic accessibility link",type:"string",minLength:1}},required:["accessibilityLink"],additionalProperties:!1},{type:"object",properties:{textAny:{description:"Ordered text variants; first visible match wins",minItems:1,type:"array",items:{type:"string",minLength:1}}},required:["textAny"],additionalProperties:!1}]}},required:["element"],additionalProperties:!1},{type:"object",properties:{rect:{type:"object",properties:{x:{type:"number"},y:{type:"number"},width:{type:"number",exclusiveMinimum:0},height:{type:"number",exclusiveMinimum:0}},required:["x","y","width","height"],additionalProperties:!1}},required:["rect"],additionalProperties:!1}]},screenshotOptions:{description:"Encoding for a settled screenshot; omitted uses PNG",anyOf:[{type:"object",properties:{format:{type:"string",const:"png"}},additionalProperties:!1},{type:"object",properties:{format:{type:"string",const:"jpeg"},quality:{type:"integer",minimum:1,maximum:100}},required:["format"],additionalProperties:!1},{type:"object",properties:{format:{type:"string",const:"webp"},quality:{type:"integer",minimum:1,maximum:100},lossless:{type:"boolean",const:!1}},required:["format"],additionalProperties:!1},{type:"object",properties:{format:{type:"string",const:"webp"},lossless:{type:"boolean",const:!0}},required:["format","lossless"],additionalProperties:!1}]},includeScreenshotImage:{description:"Opt in to a bounded MCP image block from the completed settled capture (default: path only)",type:"boolean"},display:{description:"Panel key, role (inner, cover, rear, external, cluster, overlay, virtual), active, or opt-in Android all. All adds per-panel displays (never overlay or virtual displays) while retaining the active result; rejects waitFor, raw:true and includeScreenshotImage:true.",type:"string"},project:{description:"Output projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) in place of viewHierarchy/elements. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},skipBackStack:{description:"Skip back stack during waitFor polling",type:"boolean"},scope:{description:"Experimental progressive-disclosure scoping of the returned hierarchy (issue #4344)",type:"object",properties:{focus:{description:"Scope to a subtree: true = foreground app; objects with elementId or container use the recursive action selector; all other objects keep the legacy resourceId/text anchor with extras ignored.",anyOf:[{type:"boolean"},{type:"object",properties:{resourceId:{description:"Anchor by exact resource-id",type:"string"},text:{description:"Anchor by substring text match",type:"string"}},additionalProperties:!0},{$ref:"#/$defs/__schema0"}]},region:{description:"Crop to a normalized 0..1 box; true = inset content rect.",anyOf:[{type:"boolean"},{type:"object",properties:{x1:{type:"number",minimum:0,maximum:1},y1:{type:"number",minimum:0,maximum:1},x2:{type:"number",minimum:0,maximum:1},y2:{type:"number",minimum:0,maximum:1}},required:["x1","y1","x2","y2"],additionalProperties:!1}]},overview:{description:"Collapse to a container skeleton.",type:"boolean"}},additionalProperties:!1},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},additionalProperties:!1,dependentRequired:{settled:["waitFor"]},$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}},_meta:{"automobile/deviceReadOnly":!0,ui:{resourceUri:"ui://automobile/observe"}}},{name:"openLink",title:"Open Web Link",annotations:{destructiveHint:!0},description:'Open URL in browser. A transient Android ADB failure returns device_transport_unavailable (retryable: true, retryAfterMs, deviceId). dispatched is false before dispatch or "unknown" after transport loss (true is reserved for confirmed dispatch). For "unknown", the link may already have opened: observe before reissuing a single-use link.',inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{url:{description:"URL to open",type:"string"},acceptOpenAlert:{description:"On iOS, automatically tap Open when a system 'Open in <app>?' alert appears",type:"boolean"},chooserAppPackage:{description:"On Android, select this exact package if opening the URL displays an intent chooser",type:"string",minLength:1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},waitFor:{$defs:{waitForContainer:{$schema:"https://json-schema.org/draft/2020-12/schema",anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#waitForContainer"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#waitForContainer"}},required:["text"],additionalProperties:!1}],$anchor:"waitForContainer"}},type:"object",additionalProperties:!1,properties:{for:{type:"string",enum:["appear","disappear","clickable","textEquals","countStable","stable"]},pollMs:{type:"number"},stableReads:{type:"number"},elementId:{type:"string"},testTag:{type:"string",description:"Android test tag, matched like tapOn testTag"},text:{type:"string"},textAny:{type:"array",items:{type:"string"}},className:{type:"string"},contentDescription:{type:"string"},matchType:{type:"string",enum:["all","any"]},textMatch:{type:"string",enum:["exact","contains","regex"],description:"How to match waitFor.text; does not affect contentDescription"},textSource:{type:"string",enum:["displayed"],description:"displayed: match text only against the element's shown text or value"},activeWindow:{type:"object",additionalProperties:!1,properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},packageName:{type:"string"},bundleId:{type:"string"},activityName:{type:"string"}},anyOf:[{required:["appId"]},{required:["packageName"]},{required:["bundleId"]},{required:["activityName"]}]},posture:{type:"string",enum:["closed","half_opened","opened","rear_display","flipped","tent"],description:"Wait for the observed device posture. Single-panel inventory fails immediately; multi-panel or unavailable inventory keeps polling. Timeout diagnostics distinguish unobservable posture (no hierarchy captured), unavailable inventory, and the last observed posture."},activeDisplay:{type:"string",description:"Physical panel key or role"},absent:{type:"object",additionalProperties:!1,description:"Wait until an element matching these fields is absent (text uses exact match)",properties:{selectionStrategy:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"string",enum:["first","random","unique"]},elementId:{type:"string"},testTag:{type:"string"},text:{type:"string"},className:{type:"string"},contentDescription:{type:"string"}},anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["className"]},{required:["contentDescription"]}]},container:{$ref:"#waitForContainer"},selectionStrategy:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"string",enum:["first","random","unique"]},timeout:{type:"number",maximum:1770000},timeoutMs:{type:"number",maximum:1770000}},anyOf:[{properties:{for:{const:"stable"},container:!1,selectionStrategy:!1},required:["for"]},{properties:{for:{enum:["appear","disappear","clickable","textEquals","countStable"]}},required:["for","elementId"]},{properties:{for:{enum:["appear","disappear","clickable","textEquals","countStable"]}},required:["for","text"]},{properties:{for:!1,selectionStrategy:!1},required:["textAny"]},{properties:{for:!1},anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["className"]},{required:["contentDescription"]},{required:["absent"]}]},{properties:{for:!1,selectionStrategy:!1},anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["className"]},{required:["contentDescription"]},{required:["activeWindow"]},{required:["absent"]},{required:["posture"]},{required:["activeDisplay"]}]}]},settled:{description:"After waitFor matches, wait for a quiet hierarchy period (requires waitFor)",type:"object",properties:{quietPeriodMs:{description:"Quiet-period ms (no hierarchy change) required after waitFor matches",type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["quietPeriodMs"],additionalProperties:!1},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["url"],additionalProperties:!1,dependentRequired:{settled:["waitFor"]},$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"performanceAudit",title:"Audit Performance",annotations:{destructiveHint:!1},description:"Pass/fail performance checks of an app on the current screen, against the configured thresholds. kinds: performance (UI jank, frame time and touch latency of the foreground app; appId must be in the foreground) and memory (a memory snapshot of appId); default both. Each reports passed with its metrics and violations. failOn error|warning makes the call fail when a check does not pass or cannot run (performance of an appId not in the foreground is listed under unsupported), for plan assertions; default never. For raw captures use performanceTrace, captureTrace, measureStartup or heapDump. Android only.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{kinds:{description:"Checks to run (default: performance and memory)",minItems:1,type:"array",items:{type:"string",enum:["performance","memory"]}},appId:{description:"Package to audit (default: the foreground app)",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},failOn:{description:"Fail the call when a check does not pass or cannot run: error or warning (default never: report only)",type:"string",enum:["error","warning","never"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"performanceTrace",title:"Record Trace",annotations:{destructiveHint:!0},description:"Record a native performance trace (xctrace on iOS, Perfetto on Android): start with a template, drive the flow, then stop for the artifact path and a bounded summary.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"start a recorder, or stop one by traceId. iOS stop waits for finalisation: 60 seconds without output or artifact growth, at most 180 seconds total; a timeout reports an incomplete trace that cannot be summarised. Retry with a shorter timeLimitMs or on a quieter host.",type:"string",enum:["start","stop"]},appId:{description:"App to trace (required for appLaunch and allocations)",type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},template:{description:"start: what to record",type:"string",enum:["appLaunch","hitches","hangs","timeProfiler","allocations"]},timeLimitMs:{description:"start: recorder stops itself after this (default 30000)",type:"integer",minimum:1000,maximum:300000},traceId:{description:"stop: the id start returned",type:"string",minLength:1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"phoneCall",title:"Simulate Phone Call",annotations:{destructiveHint:!1},description:"Simulate a phone call: Android emulator gsm commands, or CallKit via the app's AutoMobile iOS SDK (iOS Simulator: accept/hold return supported:partial).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"call/accept/cancel/busy/hold; hold needs no phoneNumber",type:"string",enum:["call","accept","cancel","busy","hold"]},phoneNumber:{description:"Phone number; required except for hold",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"pinchOn",title:"Pinch Screen Element",annotations:{destructiveHint:!0},description:"Pinch to zoom",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:"Target panel key, role, or active",type:"string"},direction:{description:"Pinch direction; ignored when the finger distance does not change (rotation only)",type:"string",enum:["in","out"]},distanceStart:{description:"Initial finger distance (> 0) defaults to 60% of the target's smaller dimension for direction 'in' and 20% for 'out'; clamped to 10%-90% with a 10 px floor capped by the 90% ceiling (below 10 px for targets under 11.1 px).",type:"number",exclusiveMinimum:0},distanceEnd:{description:"Final finger distance (> 0) defaults to 20% of the target's smaller dimension for direction 'in' and 60% for 'out'; clamped to 10%-90% with a 10 px floor capped by the 90% ceiling (below 10 px for targets under 11.1 px).",type:"number",exclusiveMinimum:0},scale:{description:"Scale factor (> 0; overrides distances)",type:"number",exclusiveMinimum:0},duration:{description:"Gesture duration (integer 1-10000 ms, default: 300)",type:"integer",minimum:1,maximum:1e4},rotationDegrees:{description:"Degrees (-360 to 360) the two-finger axis rotates during the pinch (default: 0). The axis starts horizontal and ends rotated by this amount \u2014 a combined pinch+rotate, not a pinch along a fixed rotated axis. Same convention on Android and iOS. To rotate without zooming set scale: 1 (or equal distanceStart and distanceEnd); direction is then ignored.",type:"number",minimum:-360,maximum:360},includeSystemInsets:{description:"Use full screen including status/nav bars",type:"boolean"},container:{description:"Nested container scope; selectionStrategy (first/random/unique) is supported only inside each container level, not at the top level",$ref:"#/$defs/__schema0"},autoTarget:{description:"Auto-target pinchable containers",type:"boolean"},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["direction"],additionalProperties:!1,$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"portReverse",title:"Manage Port Reverse",annotations:{destructiveHint:!1,idempotentHint:!0},description:"Android: manage adb reverse mappings so the app or browser on the device reaches a host server at localhost:<port>. ensure adds mappings this session owns; list, verify and remove manage them. verify with probe:true also connects from the device to each mapped port: reachable (the host server accepted), unreachable (probeReason closed: nothing listens on the host; refused; timeout) or probe_unsupported; probe:{http:{path,expectStatus}} checks the HTTP response instead. list reports hostListening for each tcp: host port. ensure with reclaimStale:true replaces a stale mapping whose host port refuses. Conflicts carry conflictKind. list and verify report each port's deviceListener. Owned mappings lost to an adb or device restart are restored on the next call and removed when the session ends. Ports below 1024 are refused. iOS returns not_applicable.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"ensure: add missing mappings (idempotent). list: every reverse on the device. verify: whether ports are mapped now. remove: delete mappings this session created",type:"string",enum:["ensure","list","verify","remove"]},ports:{description:"Required for ensure and remove; verify defaults to this session's ports",minItems:1,maxItems:32,type:"array",items:{type:"object",properties:{devicePort:{description:"Device-side localhost port",type:"integer",minimum:1,maximum:65535},hostPort:{description:"Host loopback port; default devicePort",type:"integer",minimum:1,maximum:65535}},required:["devicePort"],additionalProperties:!1}},probe:{description:"verify only. true: connect to each mapped port from the device (about 1 s each, run together) and report reachable, unreachable or probe_unsupported. {http}: send a GET from the device through each mapping and check the status (and body); reports httpStatus and probeReason http_status, http_body or no_http_response when it does not match",anyOf:[{type:"boolean"},{type:"object",properties:{http:{type:"object",properties:{path:{description:"Request path sent from the device, e.g. /health",type:"string",maxLength:512,pattern:"^\\/[\\x21-\\x7e]*$"},expectStatus:{description:"Status codes that count as reachable",minItems:1,maxItems:16,type:"array",items:{type:"integer",minimum:100,maximum:599}},hostHeader:{description:"Host header; default localhost:<devicePort>",type:"string",maxLength:255,pattern:"^[A-Za-z0-9.\\-:\\[\\]]+$"},expectBodyContains:{description:"Text the response body must contain",type:"string",minLength:1,maxLength:256},timeoutMs:{description:"Device-side wait for the response, whole seconds (default 2000)",type:"integer",minimum:1000,maximum:1e4}},required:["path","expectStatus"],additionalProperties:!1}},required:["http"],additionalProperties:!1}]},reclaimStale:{description:"ensure only: replace a mapping no live session owns when its tcp: host port refuses a loopback connect (needs a session that holds the device). The result marks it reclaimed",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"postNotification",title:"Post Notification",annotations:{destructiveHint:!1},description:"Post notification via Android SDK hooks or iOS/watchOS/tvOS simulator simctl push.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{title:{description:"Notification title",type:"string",minLength:1},body:{description:"Notification body",type:"string",minLength:1},imageType:{description:"Notification image type (default: normal)",type:"string",enum:["normal","bigPicture"]},imagePath:{description:"Android: host image path for bigPicture. iOS/watchOS: host path or URL sent as automobile-image-url with mutable-content for the app's service extension",type:"string"},actions:{description:"Android action buttons; iOS/watchOS buttons come from the registered category",type:"array",items:{type:"object",properties:{label:{description:"Action label",type:"string",minLength:1},actionId:{description:"Action identifier",type:"string",minLength:1}},required:["label","actionId"],additionalProperties:!1}},channelId:{description:"Android channel ID; iOS/watchOS APNs category when category is omitted",type:"string"},category:{description:"iOS/watchOS: aps.category naming a UNNotificationCategory the app registered",type:"string",minLength:1},payload:{description:"iOS/watchOS: raw APNs JSON merged over the generated payload (aps fields override); 4096-byte limit",type:"object",propertyNames:{type:"string"},additionalProperties:{}},appId:{description:"Android target package name or iOS/watchOS/tvOS target bundle ID (required on iOS/watchOS/tvOS); Android defaults to the live foreground app when omitted",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["title","body"],additionalProperties:!1}},{name:"pressButton",title:"Press Button",annotations:{destructiveHint:!0},description:"Press a device or navigation button. On tvOS, use up/down/left/right to navigate focus, select, menu, home or playPause; durationMs long-presses any remote button (100-10000 ms); steps are unsupported. On Android (TV remotes), up/down/left/right/select send D-pad keys and playPause, fastForward, rewind, next and previous send media keys; select with durationMs is a long press of D-pad center (API 35+). On iOS simulators, volume_up, volume_down, and power use hardware-button events; menu is unsupported on iOS. action and camera are iOS-only (Action button, Camera Control) and return unsupported_button where the device lacks that hardware. Android-only system actions: lock, power_dialog, quick_settings, screenshot, split_screen (raw system toggle; windowMode places a chosen app) and dismiss_notification_shade; each needs the API level and CtrlProxy APK that supports it and otherwise returns unsupported_system_action. Android Automotive only: rotary_rotate_cw / rotary_rotate_ccw (steps detents), rotary_nudge_up/down/left/right and rotary_select drive a rotary controller; other devices refuse them. lock leaves the device locked (wakeAndUnlock); power_dialog and quick_settings stay open until back/home.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{button:{type:"string",enum:["up","down","left","right","select","playPause","fastForward","rewind","next","previous","home","back","menu","power","volume_up","volume_down","recent","action","camera","lock","power_dialog","quick_settings","screenshot","split_screen","dismiss_notification_shade","rotary_rotate_cw","rotary_rotate_ccw","rotary_nudge_up","rotary_nudge_down","rotary_nudge_left","rotary_nudge_right","rotary_select"]},steps:{description:"Detents for rotary_rotate_cw / rotary_rotate_ccw (default 1).",type:"integer",minimum:1,maximum:50},durationMs:{description:"Long press in ms (100-10000): any remote button on tvOS (steps are unsupported), or select (D-pad center) on Android API 35+.",type:"integer",minimum:100,maximum:1e4},display:{description:'Target panel key, role, or active; Android only. Sends the key to that display and checks it for the visual change. "headUnit" sends it to the Android Auto head unit',type:"string"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["button"],additionalProperties:!1}},{name:"prototype",title:"Manage UI Prototype",annotations:{destructiveHint:!0},description:'shared:{key,as:"element"|"bounds"} requires prototype_shared_element_v2; sharedKey remains the v1 bounds alias; do not set both. Repeat shared.key templates need repeat.key and must reference that field. Shared pairs cannot cross dialog or bottomSheet boundaries. style.shadows, style.cornerStyle, style.border.gradient, scroll.fadeEdges and image.filter require prototype_style_polish_v2. testSessionBegin (id, goal?, cohort?), testSessionEnd (id) and testSessionReport (id or testSessionId) record and report host-local user-testing sessions without a device request. Reports include screen funnels, time, validation failures and dead taps; text values are never stored. Show with window.deadTaps:true (prototype_dead_tap_v1) to enable dead taps. Show (always a full spec, inline as spec or from a local JSON file as specPath), patch (id and ops), dismiss (id or all:true), status (host-local, no device request), screenMap (host-only: spec or specPath in, {screenMap:{nodes,edges},mermaid} out; stack screens, pager pages, sheets and dialogs with the push/replace/pop/popToRoot/setPage actions between them), inspect (asks the device which prototypes it is showing and adopts them into status and awaitEvent; use it after a session release or reconnect), or awaitEvent for a prototype id on Android, or on an iOS simulator through the prototype agent that launchApp with prototype:true injects (show, patch, dismiss, status, inspect, awaitEvent; sizes are points). save (spec/assets/label/icon), listSaved and deleteSaved (id) need prototype_saved_v1 on Android, or an iOS simulator (no agent needed) using the verified viewer template (or AUTOMOBILE_IOS_PROTOTYPE_VIEWER) for save; icon is an asset uploaded in the same call. On Android, save with pin:true then asks the launcher to pin a shortcut (pinned: pinned|pending|unsupported; pending until the launcher dialog is accepted (autoConfirm taps it), declining sends nothing). After a pin or shortcut update the host looks for the shortcut on the home screen and, if it is missing, restarts the default launcher once (launcherRestarted, shortcutVisible); restartLauncher:false opts out. deleteSaved disables the shortcut, and removeIcon:true clears it with adb only when no saved prototype remains. iOS installs an app icon on the home screen and ignores pin. iOS listSaved ids are bundle ids accepted by deleteSaved and omit savedAt. On Android or an iOS simulator with the ProtoViewer app installed, save without pin or icon imports the spec and its assets into the ProtoViewer library instead of the platform save path, and returns viewer {app, libraryId, label} plus a warning: ProtoViewer marks the entry imported, keeps its requests off until the user allows network in ProtoViewer, and does not attach it to this host (no awaitEvent, patch or inspect). If ProtoViewer is absent, older than this route, or its inbox is unusable, save keeps the platform save path. Each such save is a new library entry that listSaved and deleteSaved do not see. open with id set to that libraryId launches it on Android or an iOS simulator; open needs ProtoViewer installed. share (spec or specPath, assets, url) is host-only and needs no device request: it writes the canonical .automobile-proto bundle under the AutoMobile data directory and returns share {bundlePath, sha256, bytes}; with url (where the team will host the bundle, https only) it also returns link (automobile-proto://import?url=\u2026&sha256=\u2026), qrPngPath and qr (a terminal rendering). AutoMobile uploads nothing: put the bundle at url byte-for-byte. An Android ProtoViewer with URL import opens the link from the QR after confirming the host and hash; otherwise send the bundle file, which ProtoViewer imports as a file. A show with the id of the prototype already on screen replaces it in place: it keeps the display and each pager\'s page (clamped), while the new spec\'s state is authoritative (values the user changed by tapping are not carried over unless the spec includes them); reset:true starts fresh instead. patch changes the prototype already on screen without re-sending the spec: {action:"patch",id,ops:[...]} with ops add/replace/remove/test on /data (content, agent-owned) or /state/<key> (needs baseRevision; the device refuses with conflict if the user changed that key since), and replaceNode {id,node} for one node by id; use show for a new screen or a window, theme or root change. patch needs a device advertising prototype_patch_v1 and is refused otherwise: use show. To present alternatives, show one design, describe it and the others in chat (what each is, what changed, which you recommend), and show the next on request; or show one spec whose pager holds every design with a visible label per page; or show each design under its own id with variant {group,label} sharing one group (host-side only, the device is unchanged), so automobile:prototype/<id>/web offers them as switchable variants. Ask the user in chat which they prefer; never wait on the device for a choice. awaitEvent returns one buffered event, supports eventName/kind and afterSequence, and times out successfully (timedOut:true); default 30000 ms, maximum 60000 ms. Input and state changes (text input, toggles, sliders etc.) arrive as kind emit with eventName change (there is no separate change kind), with payload {key,value} for one changed key or {keys,values} for severalBuffer: 64 events per session/device/id; overflow drops oldest and reports droppedCount. Lower-or-equal sequences are ignored, including late arrivals and reconnect replays. simulate with id and advanceTimeMs (integer 1..3600000) advances prototype timers without waiting and returns fired; it requires prototype_timers_v1. startTimer {id,afterMs,everyMs?,maxRuns?,actions} and cancelTimer {id} require that capability; inspect reports timers {id,nextFireInMs,runs}. Nodes: box/row/column/flow/grid/carousel, text/image/icon/spacer/textField/searchBar, Material switch/checkbox/button/radioGroup/listItem/slider/chip/card/iconButton/fab/segmentedButton/topAppBar/divider/badge/progress/chart/dialog/snackbar/timePicker/datePicker bound to state keys, scroll/pager/stack/tabBar/bottomNav/bottomSheet/tooltip/drawer/adaptive; actions: emit/setPage/push/pop/popToRoot/replace/setState/toggle/increment/decrement/dismiss/setData/appendData/prependData/removeData/request. Stack {type:"stack",id,start,screens} needs prototype_stack_v1; only its top screen renders, and status/inspect report stacks {id:{path,depth,params?}} (params parallel to path when any entry has route params). screen_changed has name = stack id and payload {screen,depth,params?}. Stack routes {screen:{params?,onEnter?,onBack?}}, push/replace params, pop force and setStack need prototype_routes_v1; see the guide. Reuse: a top-level components:{name:{root}} map placed with {type:"use",component,props} nodes, expanded on the host with {props.<field>} bound like repeat placeholders. Sizes and anchors use dp (points on iOS). A node\'s anchor {type:"element",selector:{elementId,text,testTag,container},alignment:cover|top|bottom|start|end,offset?} is resolved once at show against the app (the prototype excluded) and converted to dp with the display density (iOS bounds are already points); a missing, ambiguous or off-screen element fails the show, and the result reports anchors and hierarchyUpdatedAt (show again to re-anchor). {type:"bounds",bounds:{x,y,width,height}} is screen dp (screen points on iOS). Window placement: fullscreen/sheet/floating, window.opacity: 0-100 (default 100). window.chrome: none (default) or bar, fullscreen only: on a device advertising prototype_window_chrome_v1, none draws no host dismiss bar and fills the window including under the status bar (use safeAreaPadding on a top bar), and a two-finger long press (about 1 s) reveals a dismiss pill for 5 s; window.persistence: "device" defaults to bar. Without the capability the bar is kept, explicit none is refused, and lastResult.chrome says which was drawn. window.backdrop {material ultraThin|thin|regular|thick|glass, blur? 0-150 dp, tint? one hex or role} blurs what is behind the window and needs prototype_backdrop_v1 (refused without it); lastResult.backdrop is blur or fallback (a tonal fill where blur is unavailable). Example: {action:"show",spec:{id:"demo",window:{placement:{type:"fullscreen"},opacity:80},root:{type:"text",text:"Hello"}}}. show also accepts assets:[{id,path}] (absolute local PNG/JPEG/WebP file path, or a TTF/OTF font file referenced from style.fontFamily as {asset}, or an Android-only .agsl source referenced from style.shader as {asset,uniforms?}; AGSL needs AUTOMOBILE_PROTOTYPE_CUSTOM_SHADERS=1 and prototype_custom_shaders_v1 and is refused by iOS and ProtoViewer bundles) or [{id,observation}] (an observation screenshot URI) uploaded before the prototype is sent; image nodes reference the id. If the device reports supplied assets missing, they are re-uploaded and the prototype re-sent once; missingAssets and warning report what is still missing. Verify with observe; no screenshot is returned. A successful show or patch also returns accessibilityFindings, an advisory host-side lint (unlabeled controls, images and text fields, low text contrast in light and dark, tap targets under 48dp) with spec paths; it never refuses a show. On Android a session prototype is tied to the app it was shown over: while another app is in front it is hidden (state kept, no dismissed event, not in observe, layer "prototype" calls fail saying so) and it returns with the app; a device-persistent prototype is not tied to an app. Status makes no device request, marks a prototype suspended:true once an inspect finds it hidden that way (an awaitEvent that then times out warns), and includes pendingCount/lastSequence/droppedCount after events arrive. Device dismissed events remove shown status; the terminal event remains available until consumed or explicit show/dismiss. Awaiting consumes events; unmatched events remain buffered. Optional MCP progress reports wait start/finish without delaying the wait. Session release, device removal and unbinding clear buffers. A disconnect alone is not observed. window.layer: system (default, above system UI) or app (above apps only, so the shade, keyboard and screenshot preview draw over it; the daemon grants CtrlProxy SYSTEM_ALERT_WINDOW with appops first). window.persistence: session (default) or device: the prototype stays interactive after USB/adb disconnect and session end with no idle timeout, keeps its assets, and carries a visible Close control; remove it with that control, dismiss, or a new show. Both are Android only and need a CtrlProxy advertising prototype_window_options_v1. A device-persistent prototype keeps emitting taps, page changes and text input while no host is connected: the device buffers the last 200 events (oldest dropped, counted) and delivers them when a host connects or on inspect, with sequences continuing and no rewind; inspect returns deviceDroppedEvents. inspect needs a CtrlProxy advertising prototype_persistence_replay_v1 and is refused otherwise. On an iOS simulator inspect asks the agent (prototype_inspect_v1) for the one prototype it shows, with no suspended and no deviceDroppedEvents, and is refused with a relaunch hint on an older agent. Light and dark: show takes appearance device (default), light or dark, which pins what the system setting means for that show without changing the device; it replaces the system setting only (mode order: explicit theme.mode, then the flat theme.colors.background/surface luminance, then an opaque authored background, then appearance, else the device), and light or dark is refused unless the device advertises prototype_appearance_v1. Such a device reports appearance {mode, source, deviceDark} in the show result and per prototype in inspect; deviceDark (the device\'s own setting) appears only in those device answers. The host-local status reports mode and source only (kept current by appearance_changed events, which carry just mode and source), because the device can flip while a pinned mode stays put and then no event arrives; call inspect for the current deviceDark. It sends one appearance_changed event (match it with awaitEvent kind:"appearance_changed", not eventName: its name is null; payload {mode, source}) on any change of the resolved mode while shown (the device flipping, or prototype state changing an inferred mode), never for the show itself. If an appearance_changed event arrives while a show is in flight the host cannot order the two, so that status entry has no appearance until a later event or inspect states it. In a scrim slot only the scrim role gets alpha (0.4); other roles are drawn unchanged. row/listItem swipeActions {start?,end?,fullSwipe?} (1-3 {label,icon?,role?,color?,onTap} per side; not inside a horizontal pager or carousel) require prototype_swipe_actions_v1; revealed buttons are tagged <rowTag>.swipe.<index>. Flow/grid require prototype_flow_grid_v1; grid is non-lazy and never scrolls itself (wrap it in scroll). scroll.refresh {stateKey,onRefresh} (pull-to-refresh on a vertical scroll; stateKey is a boolean that shows the indicator) requires prototype_refresh_v1. carousel {itemWidth,variant?,itemSpacing?,children} (horizontal snapping row) and pager indicator "dots" require prototype_carousel_v1. Per-mode {light, dark} forms need prototype_theme_modes_v1. Stack {type:"stack",id,start,screens} requires prototype_stack_v1 and is refused otherwise. Data, repeat.items {path}, repeat.key, {data:/pointer} text and {data: pointer} conditions require prototype_data_model_v1. setData {path,value}, appendData {path,value}, prependData {path,value} and removeData {path} (path is /data/<pointer>, with a whole {index} segment inside a repeat; value is {value: json}, {state: key}, {data: pointer}, or {item: field}/{index: true} in a repeat) change /data from a tap and require prototype_data_actions_v1. Each device write is a change event (awaitEvent kind:"change") with name = the written /data path and payload {op, value?, revision}; once the device has written a prototype\'s data, a patch with /data ops needs baseRevision (the latest revision seen) and is refused with conflict {revision, state, data} if a newer write touched an overlapping path. request {url, method?, headers?, query?, body?, into?, statusKey?, via?, timeoutMs?, onSuccess?, onError?} calls an absolute http(s) URL from a tap (local and loopback destinations, and daemon ports on private addresses, are refused as blocked_destination; via "device" cannot use localhost for the host machine, so use via "host" for a host-local server; url takes {key} and {data:/pointer} placeholders; headers/query values and body are literals or {state}/{data}/{value}/{item} bindings) and needs prototype_network_v1, plus prototype_network_device_v1 for via "device" (default via "host": the host makes the call). A 2xx body (JSON, else a string) is written to into (a /data path naming an object member) like setData, and {status, headers, durationMs, error?} to into + "__meta" (/data/feed -> /data/feed__meta); a non-2xx status or failure leaves into alone and sets meta.error. statusKey names a declared string state key that moves loading -> success|error, for visibleWhen; onSuccess/onError are action lists (nest up to 4 deep). A newer request to the same into cancels the older. Limits: timeoutMs max 30000 (default 10000), response 262144 bytes, 4 in flight per device. Each finished request is an emit event named prototype_request (payload {requestId, method, url, via, into?, outcome, status?, durationMs, error?}; await it with kind emit, eventName prototype_request). Input checks, validateOn, enabledWhen, {valid: key|keys} conditions and emit.requireValid require prototype_checks_v1; see the guide for checks and formats. textField options (label, variant, supportingText, keyboardType, secure, multiline, minLines, maxLines, maxLength) require prototype_text_field_options_v1; a device without it refuses the show. textField trailingIcon {icon,label,onTap?}, imeAction (done|next|search|send|go) and onSubmit require prototype_text_field_actions_v1 (not allowed with multiline). textField leadingIcon (icon name) requires prototype_text_field_leading_icon_v1. onLongPress/onDoubleTap on box/row/column/text/image/icon/card require prototype_gestures_v1. On Android, show replaceOthers:false retains other windows up to a limit of 4 (prototype_multi_surface_v1); a fifth is refused listing the shown ids. Read the MCP resource automobile:prototype for the authoring guide (repeat grammar, limits, theme roles) and automobile:prototype/spec-schema for the full spec JSON Schema; look up icon names with automobile:prototype/icons?query=<word>. Read automobile:prototype/native?id=<id> for the spec, assets and a Compose or SwiftUI host file that embed it in an app. Read automobile:prototype/<id>/web (optional frame, revision, variant, mcpSessionId) for a shown prototype as one self-contained HTML page in a device frame; it updates on every show and landed patch. serve (id?, port?, remote?, idleTimeoutMs?) starts the host-only live preview server (one per daemon, 127.0.0.1 and a free port by default; remote:true binds every interface) and returns previewServer {url, pageUrl}: that page reloads within about a second of each show or landed patch; stop closes it, as do daemon exit and the idle timeout (default 30 min with no open page, request, show or patch); status reports previewServer after the first serve. tooltip requires prototype_tooltip_v1; drawer requires prototype_drawer_v1. searchBar requires prototype_search_bar_v1 for show and patch. State-key contains/startsWith/lengthGt/lengthLt conditions and textField errorWhen/errorText require prototype_string_conditions_v1. errorWhen forces error styling without changing checks-based validity. {data, empty} conditions and style shimmer require prototype_loading_states_v1. animate.tempo fast|default|slow requires prototype_motion_tokens_v1 (iOS 17+); tempo excludes durationMs and easing and uses contract springs by property role and spec motion scheme. animate, style scale/rotation, transition slideStart|slideEnd|scale and image zoomable require prototype_motion_v2. Keyframes: node keyframes {trigger: {key} or {data: pointer}, durationMs: 100-3000, tracks}; 2-8 [fraction,value] points per track, rest endpoints, 16 expanded nodes, prototype_keyframes_v1 (iOS 17+). Plays once on changes, skips mount; reduced retains alpha. Expressive motion, node press {scale?,alpha?}, and animate of border, cornerRadius, elevation, shadowColor, padding or dp width/height require prototype_motion_v3 (Android only). transition as {type, delayMs?} (0-600 ms) or blurReplace, and box/row/column stagger {ms 0-100, order? forward|reverse|center} (every child\'s total delay at most 600 ms), require prototype_choreography_v1. window.transition auto|none|fade|slide|scale and repeat.stagger (0-100 ms per instance, capped at 600 ms) require prototype_window_motion_v1 on Android. Text-only contentTransition numeric|crossfade|none (default none) requires prototype_content_transition_v1 unless none; numeric rolls changed digits by resolved value, spans crossfade; motion none snaps. icon.effect {type, trigger? | repeat?} requires prototype_icon_effects_v1: bounce|pulse|scale|variableColor|wiggle|rotate|breathe|replace|drawOn; trigger {key} or {data} replays per change, repeat is infinite or 1-20, mutually exclusive. String tables and {t:key|count} require prototype_strings_v1; show locale overrides device locales only for strings. Node semantics {heading,liveRegion,group,label,hint,traits} requires prototype_semantics_v1. list {repeat:{items:{path},as,key},children:[row],header?,footer?,axis?,spacing?,contentPadding?,onEndReached?,endThreshold?,refresh?,maxItems?} is a lazy scrolling collection requiring prototype_lazy_list_v1 and prototype_data_model_v1. Its row template counts once, supports up to 500 keyed data rows, and refresh needs a vertical list. prependData {path,value} inserts one row at the start and requires prototype_lazy_list_v1; maxItems trims from the end. request.append {from,to} extends an existing data array from a response array; maxItems trims oldest rows atomically. motion: "reduced" requires prototype_reduced_motion_v1; iOS Reduce Motion selects reduced, Android animator/transition scale 0 selects off. sharedKey requires prototype_shared_element_v1; visibility morphs require visibleWhen and exactly two non-nested nodes per key, while a zoom source key names exactly one node without visibleWhen. At most 16 keys, and no repeat templates. Full motion morphs shared bounds, reduced fades, none snaps. Stack transition platform|slide|fade|none (default platform) and optional push/replace transition overrides require prototype_stack_transitions_v1; sharedAxisX|sharedAxisY|fadeThrough|zoom and push/replace source require prototype_stack_patterns_v1. Zoom needs source naming exactly one sharedKey node; Android substitutes fadeThrough and iOS substitutes platform push; pop/popToRoot take no override. Stack transition controls screen navigation, not its own visibleWhen. chart (line/area/bar/ring over /data arrays) requires prototype_chart_v1; observe reports its summary. A root-level storage {version, keys:["state:<key>","data:<pointer>","stack:<id>"]} block (up to 64 unique keys: each state key declared in state, each data pointer a member of /data, each stack id a stack in the spec whose path is kept with its route params (prototype_routes_v1), no overlapping pointers, at most 262144 stored bytes) makes the device save those values per prototype id after every write (user edit, device data action, request response) and requires prototype_storage_v1. Precedence on the next show of the same id: stored values replace the spec\'s for the listed keys; a changed storage.version discards them all; a stored key no longer listed (or a show without storage) is dropped; a stored value that no longer fits (state type changed, data of another JSON kind, unwritable pointer) is dropped and the spec\'s value stands. A host patch to a stored key wins under the usual baseRevision rules and the device then stores it. inspect reports storage {version, keys:[{key,bytes}], totalBytes, skippedKeys?} per prototype (absent if the device does not report it); {action:"clearStorage",id} wipes an id\'s stored values (result cleared = keys removed) and is refused without prototype_storage_v1; deleteSaved also clears them. Mock backends (no server code): defineBackend {backendId, backend:{collections?, routes?, faults?, latencyMs?, seed?}} registers an in-process REST backend for this daemon session; a request action to https://<backendId>.mock.automobile.invalid/<path> with via "host" is answered by it, with no network, DNS or egress policy. Collections are json-server style (GET /<name> with ?field=value, q, _sort, _page/_limit, after/size; GET/POST/PATCH/PUT/DELETE /<name>/:id; every item needs an id); routes are canned {method,path:"/feed/:id",status?,headers?,body?,delayMs?} with {params.x}, {query.x} and {body:/pointer} placeholders; faults fail every nth or a seeded fraction of matching requests; rooms [{path:"/rooms/:roomId",onConnect?,echo?,relay?,timeline?:[{afterMs,frame}]}] serve websocket (wss://<backendId>.mock.automobile.invalid/<path>) and sse channels with via "host": onConnect frames greet each connection, timeline frames follow per connection, echo returns a send, relay fans it out to the room\'s other members; broadcasts {collection:{room:"/rooms/{item:/roomId}",frame:{item:"{item}"},on?}} send a successful collection write to a room; publish {backendId, room, frame} speaks as the other side to every member and returns delivered; backendLog {backendId, since?} returns the requests answered and room frames seen; clearBackend {backendId} removes it and closes its channels. show also takes mock ({backendId: definition}) or mockPath (an absolute JSON file of the same) to define backends before the spec is sent. Platform features (clipboard, share, haptics, sound, realtime channels, device state) use a root requires, the platform action and platform.on handlers; the Platform features guide section lists every module, call and event.',inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{type:"string",enum:["show","patch","dismiss","status","inspect","awaitEvent","save","listSaved","deleteSaved","open","share","clearStorage","simulate","screenMap","testSessionBegin","testSessionEnd","testSessionReport","defineBackend","clearBackend","backendLog","publish","serve","stop"]},goal:{description:"testSessionBegin only: screen label such as checkout/done; reaching it completes the session",type:"string",minLength:1,maxLength:200},cohort:{description:"testSessionBegin only: free label echoed in the report; no cross-session aggregation",type:"string",minLength:1,maxLength:64},backendId:{description:"defineBackend, clearBackend, backendLog and publish: the mock backend id; requests and channels to https://<backendId>.mock.automobile.invalid (wss:// for WebSocket) are answered by it",type:"string",pattern:"^[a-z0-9][a-z0-9-]{0,30}$"},backend:{description:"defineBackend only: {collections?:{name:[items with id]}, routes?:[{method,path,status?,headers?,body?,delayMs?}], faults?:[{path,method?,status,every|rate}], latencyMs?:{min,max}, seed?, rooms?:[{path:'/rooms/:roomId',onConnect?:[frame],echo?,relay?,timeline?:[{afterMs,frame}]}], broadcasts?:{collection:{room:'/rooms/{item:/roomId}',frame,on?:[POST|PUT|PATCH]}}, actors?:[{on:{route:'POST /path/:id'}|every+maxRuns, afterMs?, do:[{afterMs?, append|update|remove: collection, id?, value?}]}]}. Actors write to collections after a matching successful request or every N ms (at most 16 actors, 64 steps each; publish, advance and notify are not supported yet). Replaces the backend of that id and closes its open channels",type:"object",propertyNames:{type:"string"},additionalProperties:{}},mock:{description:"show only: mock backends to define before the spec is sent, as {backendId: definition} (the defineBackend definition shape); replaces any backend of the same id. Use with request actions to https://<backendId>.mock.automobile.invalid. Not allowed with mockPath",type:"object",propertyNames:{type:"string"},additionalProperties:{}},mockPath:{description:"show only: instead of mock, an absolute path of a local JSON file holding the same {backendId: definition} object (up to 2097152 bytes), read by the daemon; the path is never sent to the device",type:"string",minLength:1},since:{description:"backendLog only: return requests and frames with a sequence number above this",type:"integer",minimum:0,maximum:9007199254740991},room:{description:"publish only: the room path, such as /rooms/general",type:"string",maxLength:256,pattern:"^\\/.*"},frame:{description:"publish only: the frame every member of the room receives (a string as written, other JSON as JSON text)"},testSessionId:{description:"testSessionReport: stored session id, instead of the latest session for id",type:"string",minLength:1,maxLength:64},spec:{description:'Every node and field is in the spec JSON Schema at the MCP resource automobile:prototype/spec-schema (AUTOMOBILE_PROTOTYPE_FULL_SCHEMA=1 inlines it here); the server validates each spec against it and names the failing path. style.shadows, style.cornerStyle, style.border.gradient, scroll.fadeEdges and image.filter require prototype_style_polish_v2. Full prototype spec: id, window, optional theme (design material|platform, default platform; explicit platform requires prototype_design_platform_v1; mode light|dark|system, colors.seed hex or colors.source "device", plus optional per-role hex overrides in colors such as colors.primary or colors.surface applied over that scheme in light and dark, typography.scale 0.75-1.5 and fontFamily sans|serif|mono, shapes.corner none|small|medium|large|full; text style.textStyle names a Material type role such as titleLarge; style color, background and border.color take hex or a Material colour role such as primary, onSurface, surfaceContainer; style.cornerRadius takes dp, none|extraSmall|small|medium|large|extraLarge|full, or per-corner {topStart,topEnd,bottomEnd,bottomStart} dp), optional state, root. window.opacity is 0-100, default 100. window.chrome: none (default) or bar, fullscreen only: on a device advertising prototype_window_chrome_v1, none draws no host dismiss bar and fills the window including under the status bar (use safeAreaPadding on a top bar), and a two-finger long press (about 1 s) reveals a dismiss pill for 5 s; window.persistence: "device" defaults to bar. Without the capability the bar is kept, explicit none is refused, and lastResult.chrome says which was drawn. window.backdrop {material ultraThin|thin|regular|thick|glass, blur? 0-150 dp, tint? one hex or role} blurs what is behind the window and needs prototype_backdrop_v1 (refused without it); lastResult.backdrop is blur or fallback (a tonal fill where blur is unavailable). show always renders the whole spec; spec.state is authoritative. Use show for a new screen or a window, theme or root change; patch for content (/data), state (/state) or one node by id (replaceNode), requiring prototype_patch_v1. window.layer "app" and window.persistence "device" need a CtrlProxy advertising prototype_window_options_v1. Per-mode forms need a device advertising prototype_theme_modes_v1 and are refused otherwise: a colour field, gradient stop or scrim as {light, dark} (each hex or a role), a role name in a gradient stop or scrim, theme.colors.light / theme.colors.dark {role: hex} maps applied after the flat overrides for the resolved mode, and image.asset or a tabBar/bottomNav item image as {light, dark} asset ids. image.asset or an item image may instead be {data: "/pointer"} naming a device media item id in /data (prototype_platform_media_items_v1); asset ids starting with media: are reserved for the device. Stack {type:"stack",id,start,screens} requires prototype_stack_v1 and is refused otherwise. Data, repeat.items {path}, repeat.key, {data:/pointer} text and {data: pointer} conditions require prototype_data_model_v1. onLongPress/onDoubleTap on box/row/column/text/image/icon/card require prototype_gestures_v1. searchBar requires prototype_search_bar_v1 for show and patch. State-key contains/startsWith/lengthGt/lengthLt conditions and textField errorWhen/errorText require prototype_string_conditions_v1. errorWhen forces error styling without changing checks-based validity. {data: pointer, empty: true|false} conditions (missing, [], {} or "" is empty) and style shimmer on box/row/column/card require prototype_loading_states_v1. Node animate {durationMs?,easing?}, style scale (0-4)/rotation (degrees), transition slideStart|slideEnd|scale and image zoomable {maxScale 1-8} (not with onDoubleTap) require prototype_motion_v2. transition as {type, delayMs?} (0-600 ms) or blurReplace, and box/row/column stagger {ms 0-100, order? forward|reverse|center} (every child\'s total delay at most 600 ms), require prototype_choreography_v1. window.transition auto|none|fade|slide|scale and repeat.stagger (0-100 ms per instance, capped at 600 ms) require prototype_window_motion_v1 on Android. list {repeat:{items:{path},as,key},children:[row],header?,footer?,axis?,spacing?,contentPadding?,onEndReached?,endThreshold?,refresh?,maxItems?} is a lazy scrolling collection requiring prototype_lazy_list_v1 and prototype_data_model_v1. Its row template counts once, supports up to 2000shared:{key,as:"element"|"bounds"} requires prototype_shared_element_v2; sharedKey remains the v1 bounds alias; do not set both. Repeat shared.key templates need repeat.key and must reference that field. Shared pairs cannot cross dialog or bottomSheet boundaries. keyed data rows, and refresh needs a vertical list. prependData {path,value} inserts one row at the start and requires prototype_lazy_list_v1; maxItems trims from the end. request.append {from,to} extends an existing data array from a response array; maxItems trims oldest rows atomically. String tables and {t:key|count} require prototype_strings_v1; show locale overrides device locales only for strings. Node semantics {heading,liveRegion,group,label,hint,traits} requires prototype_semantics_v1. motion: "reduced" requires prototype_reduced_motion_v1; iOS Reduce Motion selects reduced, Android animator/transition scale 0 selects off. sharedKey requires prototype_shared_element_v1; visibility morphs require visibleWhen and exactly two non-nested nodes per key, while a zoom source key names exactly one node without visibleWhen. At most 16 keys, and no repeat templates. Full motion morphs shared bounds, reduced fades, none snaps. Stack transition platform|slide|fade|none (default platform) and optional push/replace transition overrides require prototype_stack_transitions_v1; sharedAxisX|sharedAxisY|fadeThrough|zoom and push/replace source require prototype_stack_patterns_v1. Zoom needs source naming exactly one sharedKey node inside the target stack screens; prototype_zoom_transition_v1 reports native container zoom on Android and iOS 18+; older agents substitute fadeThrough on Android or platform push on iOS 17 (reported in platformNotes); pop/popToRoot take no override. Stack transition controls screen navigation, not its own visibleWhen. chart {variant line|area|bar|ring, series:[{path,x?,y,label,color?}] (1-4, each a /data array of objects with a numeric y), yRange?, xLabels?, goal?} requires prototype_chart_v1. Text nodes take exactly one of text or spans (1\u201364 strict {text,style?,onTap?} entries with nonempty text and inline typography/color/background only); spans require prototype_rich_text_v1, resolved span texts concatenate without separators for observe, and span taps run actions without opening URLs. Input checks, validateOn, enabledWhen, {valid: key|keys} conditions and emit.requireValid require prototype_checks_v1; see the guide for checks and formats.',type:"object",properties:{root:{type:"object",description:"Root node {type,...}; type is one of box, row, column, flow, grid, carousel, adaptive, text, image, icon, spacer, textField, searchBar, switch, checkbox, pasteButton, button, radioGroup, select, listItem, slider, chip, card, iconButton, fab, segmentedButton, topAppBar, divider, badge, progress, map, webView, videoPlayer, castButton, cameraPreview, chart, dialog, tooltip, drawer, menu, snackbar, timePicker, datePicker, list, scroll, pager, stack, tabBar, bottomNav, bottomSheet, use. Every node's fields are in automobile:prototype/spec-schema."},id:{type:"string",minLength:1},window:{type:"object"},theme:{type:"object"},strings:{},data:{},state:{},motion:{type:"string",enum:["none","standard","reduced","expressive"]},storage:{type:"object"},requires:{type:"object"},platform:{type:"object"},channels:{type:"object"},auth:{type:"object"},commerce:{type:"object"},location:{type:"object"},notifications:{type:"object"},sensors:{type:"object"},media:{type:"object"},derive:{type:"object"},components:{type:"object"}},required:["root","id","window"],additionalProperties:!1},ops:{description:"patch only: 1\u201364 ordered ops on /data, /state/<key>, or replaceNode {id,node}; validated atomically before sending",minItems:1,maxItems:64,type:"array",items:{type:"object",properties:{op:{type:"string",enum:["add","replace","remove","test","replaceNode"]},path:{type:"string"},value:{},id:{type:"string"},node:{type:"object"}}}},baseRevision:{description:"patch only: required for /state ops, and for /data ops once the device has written the prototype's data with setData/appendData/removeData; the patch is refused with conflict if a touched key or an overlapping /data path changed since this revision",type:"integer",minimum:0,maximum:9007199254740991},specPath:{description:"show, screenMap or share: instead of spec, an absolute path of a local JSON file holding the same spec (up to 1048576 bytes) that the daemon reads and validates like an inline spec; the path is never sent to the device. Exactly one of spec or specPath. Use it for a spec a script generated, instead of pasting the JSON into the call.",type:"string",minLength:1},display:{description:"show only: panel key, role, or active to show the prototype on. Precedence: explicit display, then the session display pin, then the default display. Needs a CtrlProxy advertising prototype_display_id_v2; a disconnected panel is refused. Ignored, with a warning, by a same-id show without reset, which keeps the display the prototype is on.",type:"string"},replaceOthers:{description:"show only: true (default) replaces other prototypes; false adds this prototype as another window (max 4 on screen; a fifth is refused listing the ones shown). A same-id show replaces only that prototype when false. Needs an Android device advertising prototype_multi_surface_v1; iOS shows one prototype at a time.",type:"boolean"},variant:{description:"show only: host-side grouping of design alternatives; never sent to the device and does not change what it shows. Shows of different ids with the same group become variants of one web preview (automobile:prototype/{id}/web). Each show states it afresh; a later patch keeps it.",type:"object",properties:{group:{description:"Name shared by every alternative of one design",type:"string",minLength:1,maxLength:64},label:{description:"This alternative's name, shown in the web preview's variant switcher",type:"string",minLength:1,maxLength:64}},required:["group","label"],additionalProperties:!1},locale:{description:"show only: locale override for strings (prototype_strings_v1). Each show states it afresh; omitted uses the device preferred locales and re-resolves live. Forwarded only when spec has strings; missing translations return strings.fallback platformNotes.",type:"string",maxLength:35,pattern:"^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$"},pseudoLocale:{description:"show only: true sends a pseudo-localized copy of the spec: every string-table value/plural form, semantics label/hint, text, label, placeholder, headline, title and span is accented and padded by about 40%, wrapped in [ ], with {bindings} and {t:key|count} references left intact, so truncation and clipping show without a translation. The authored spec, status and patch base are unchanged; patch ops apply to the device copy. Each show states it afresh.",type:"boolean"},reset:{description:"show only: when the prototype with spec.id is already shown, start it fresh (pager pages from the spec, display re-resolved) instead of replacing it in place",type:"boolean"},appearance:{description:'show only: what the system light/dark setting means for this prototype. device (default) follows the device; light or dark pins it without changing the device or the app behind, so a spec with theme.mode "system" or no mode can be checked in both modes. It replaces the system setting only: an explicit theme.mode, a flat theme.colors.background/surface override and an opaque authored background still decide first. Each show states it afresh (a same-id show without it follows the device again). light and dark need a device advertising prototype_appearance_v1 and are refused otherwise.',type:"string",enum:["device","light","dark"]},advanceTimeMs:{description:"simulate only: advance the prototype clock without waiting",type:"integer",minimum:1,maximum:3600000},id:{description:"Prototype id required for dismiss (unless all: true), awaitEvent, deleteSaved and clearStorage; for open, the ProtoViewer library id (viewer.libraryId) a save returned",type:"string",minLength:1},assets:{description:"show, save or share only: images to upload before the prototype is sent, as {id, path} with an absolute local file path or {id, observation} with an observation screenshot URI (PNG, JPEG or WebP, up to 4 MiB each, 16 MiB total, 32 assets). Reference each id from image nodes, or from style.fontFamily as {asset} for a TTF/OTF font file (path only, up to 2 MiB). Uploads are sequential; any failure fails the call before the prototype changes and names the assets already stored. If the device reports a supplied asset missing after the prototype is sent, it is re-uploaded and the prototype re-sent once.",minItems:1,maxItems:32,type:"array",items:{type:"object",properties:{id:{description:"Opaque asset id that spec image nodes reference (image.asset, or style.fontFamily {asset})",type:"string",minLength:1,maxLength:256},path:{description:"Absolute path the daemon can read: PNG/JPEG/WebP, a TTF/OTF font (2 MiB), or Android-only AGSL .agsl source (16 KiB; AUTOMOBILE_PROTOTYPE_CUSTOM_SHADERS=1 and prototype_custom_shaders_v1 required)",type:"string",minLength:1},observation:{description:"Instead of path: an observation screenshot URI, automobile:observation/{deviceId}/{observationId}/screenshot (the observationScreenshotResourceUri that observe returns); it must still be that device's current observation",type:"string",minLength:1}},required:["id"],additionalProperties:!1}},url:{description:"share only: the https URL the team will upload the bundle to (a release asset, gist raw URL or object storage), without credentials or #fragment. With it, share also returns the automobile-proto://import link and its QR; without it, only the bundle is written",type:"string",minLength:1,maxLength:1024},label:{description:"save only: label, defaults to spec.id; ProtoViewer takes one line without control or direction-override characters",type:"string",minLength:1,maxLength:120},icon:{description:"save only: icon asset id uploaded in assets in this call",type:"string",minLength:1},pin:{description:"save only (Android): after saving, request a home-screen shortcut; the launcher then asks the user to confirm",type:"boolean",const:!0},autoConfirm:{description:"save only: requires pin; accepts the launcher dialog, verifies the pin",type:"boolean",const:!0},restartLauncher:{description:"save only (Android): false skips the automatic default-launcher restart that runs when a pinned or updated shortcut is not visible on the home screen",type:"boolean",const:!1},removeIcon:{description:"deleteSaved only (Android): clear CtrlProxy's shortcuts with adb when no saved prototype remains; otherwise a disabled icon remains",type:"boolean",const:!0},all:{description:"Dismiss all prototypes on the targeted device",type:"boolean",const:!0},eventName:{description:"awaitEvent only: filter event name; input and state changes use eventName change",type:"string",minLength:1},kind:{description:"awaitEvent only: filter event kind. screen_changed (name = stack id, payload {screen, depth, params?}; params are the top entry's route params, present only when it has any) is sent only when the top screen, depth or top params change. page_changed (name = pager id, payload = the new zero-based page index) is sent when a pager settles on another page. appearance_changed (name null, payload {mode, source}) is sent once whenever the shown prototype's resolved light/dark mode changes, by a device advertising prototype_appearance_v1. Input and state changes (text input, toggles, sliders etc.) arrive as kind emit with eventName change (there is no separate change kind), with payload {key,value} for one changed key or {keys,values} for several. A finished request action arrives as kind emit with eventName prototype_request",type:"string",enum:["emit","page_changed","screen_changed","dismissed","appearance_changed","change","validation_failed"]},afterSequence:{description:"awaitEvent only: return a sequence strictly above this cursor",type:"integer",minimum:0,maximum:9007199254740991},port:{description:"serve only: the preview server's TCP port; 0 or absent picks a free one. A different port restarts a running server",type:"integer",minimum:0,maximum:65535},remote:{description:"serve only: true binds every network interface so other machines can open the preview (anyone who can reach the port sees every shown prototype); default false binds 127.0.0.1 only",type:"boolean"},idleTimeoutMs:{description:"serve only: stop the server after this long with no open preview page, request, show or patch; default 1800000 ms",type:"integer",minimum:1000,maximum:86400000},timeoutMs:{description:"Device request timeout; awaitEvent defaults to 30000 ms, maximum 60000 ms; timeout is a successful empty result. save and open through ProtoViewer wait up to 15000 ms by default, maximum 60000 ms.",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["status","inspect","listSaved","screenMap","share","testSessionBegin","testSessionEnd","testSessionReport","defineBackend","clearBackend","backendLog","publish","serve","stop"]}]}},{name:"provisionDevice",title:"Provision Virtual Device",annotations:{destructiveHint:!0},description:"Provision exact virtual device",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{resources:{description:"Resource settings applied after boot and before automation readiness. Requires boot=true; omitted resources stay unchanged.",type:"object",properties:{wallpaperRendering:{description:"Home and Lock Screen wallpaper rendering; excludes widgets and Live Activities.",type:"string",enum:["enabled","disabled"]},widgets:{description:"Widget refresh, including app widgets; excludes wallpaper and Live Activities.",type:"string",enum:["enabled","disabled"]},liveActivities:{description:"Live Activities and Dynamic Island updates; excludes wallpaper and widgets.",type:"string",enum:["enabled","disabled"]},healthServices:{description:"HealthKit data and Health app background work. Health integrations become unavailable.",type:"string",enum:["enabled","disabled"]},homeServices:{description:"HomeKit accessories and automations. Home integrations become unavailable.",type:"string",enum:["enabled","disabled"]},fitnessServices:{description:"Apple Fitness, coaching, activity awards, and activity sharing.",type:"string",enum:["enabled","disabled"]},familyServices:{description:"Family Sharing, family approvals, and parental controls. Changes restriction behavior.",type:"string",enum:["enabled","disabled"]},screenTime:{description:"Screen Time limits and usage tracking. Changes restriction behavior.",type:"string",enum:["enabled","disabled"]},newsServices:{description:"Apple News background content.",type:"string",enum:["enabled","disabled"]},weatherServices:{description:"Apple Weather background forecasts.",type:"string",enum:["enabled","disabled"]},tipsServices:{description:"Apple Tips background content.",type:"string",enum:["enabled","disabled"]},gameServices:{description:"Game Center and saved-game synchronization; excludes controller input.",type:"string",enum:["enabled","disabled"]},mapsSync:{description:"Maps favorites, history, background updates, and suggested destinations; excludes MapKit rendering and location services.",type:"string",enum:["enabled","disabled"]},advertising:{description:"Promoted Apple content; excludes advertising privacy preferences and app integrity services.",type:"string",enum:["enabled","disabled"]},diagnosticReporting:{description:"Diagnostic collectors, feedback, location analytics, and call-quality reporting; reduces diagnostic evidence, not call transport.",type:"string",enum:["enabled","disabled"]},siriAndAppIntents:{description:"iOS Simulator Siri requests, Shortcuts actions, and App Intents; excludes speech services and proactive suggestions.",type:"string",enum:["enabled","disabled"]},speechServices:{description:"iOS Simulator speech recognition, dictation, and Siri speech synthesis; excludes Siri requests and App Intents orchestration.",type:"string",enum:["enabled","disabled"]},mediaTranscoding:{description:"iOS Simulator Photos image and video conversion; media imports and photo-picker conversions may fail.",type:"string",enum:["enabled","disabled"]},photoAnalysis:{description:"Background Photos analysis; may reduce photo search and recognition. Preserves library access, cloud transfers, and shared media-analysis infrastructure.",type:"string",enum:["enabled","disabled"]},assistantSuggestions:{description:"Siri inference, knowledge, and proactive suggestions; preserves speech, system voices, and shared language/model infrastructure.",type:"string",enum:["enabled","disabled"]},appleIntelligence:{description:"Apple Intelligence orchestration and generative experiences; system writing tools and intelligence integrations may become unavailable. Preserves shared model and speech services.",type:"string",enum:["enabled","disabled"]},searchIndexing:{description:"Spotlight and Settings search, including app-provided system indexes; excludes an app's own search service.",type:"string",enum:["enabled","disabled"]},appStoreServices:{description:"App Store installation/update services; excludes push and StoreKit payment services.",type:"string",enum:["enabled","disabled"]},appleMediaSync:{description:"Apple Music and subscribed/purchased media background services; excludes generic audio/video playback and StoreKit payments.",type:"string",enum:["enabled","disabled"]},mailServices:{description:"Apple Mail background services. Mail-based sign-in email workflows may be unavailable.",type:"string",enum:["enabled","disabled"]},calendarServices:{description:"Local Calendar database access; excludes server-side calendar integrations in apps.",type:"string",enum:["enabled","disabled"]},reminderServices:{description:"Apple Reminders database and background work; excludes reminders maintained by other apps.",type:"string",enum:["enabled","disabled"]},personalDataSync:{description:"Exchange, CalDAV, and CardDAV synchronization; preserves local Contacts database access.",type:"string",enum:["enabled","disabled"]},safariSync:{description:"Safari bookmark/history synchronization; preserves associated domains, shared credentials, browsing protections, and WebKit.",type:"string",enum:["enabled","disabled"]},icloudSettingsSync:{description:"iCloud system-settings synchronization and storage-plan recommendations; preserves accounts, credentials, CloudKit data, Drive, and Photos transfers.",type:"string",enum:["enabled","disabled"]},messagingMaintenance:{description:"Apple Messages history cleanup, attachment transfer, and FaceTime message storage; preserves identity, message database XPC helpers, and system calling services.",type:"string",enum:["enabled","disabled"]},watchConnectivity:{description:"Paired Watch and companion-device communication.",type:"string",enum:["enabled","disabled"]},carPlay:{description:"CarPlay vehicle connectivity.",type:"string",enum:["enabled","disabled"]},tvRemote:{description:"Apple TV discovery and remote control.",type:"string",enum:["enabled","disabled"]},findMy:{description:"Find My device-location services; excludes general location APIs.",type:"string",enum:["enabled","disabled"]},continuity:{description:"Nearby-device Continuity discovery; cross-device workflows may stop working. Preserves system share sheets.",type:"string",enum:["enabled","disabled"]},walletServices:{description:"Wallet, Apple Pay, digital identity, and merchant services. Payment sheets, including dependent StoreKit workflows, may fail.",type:"string",enum:["enabled","disabled"]},businessServices:{description:"Apple business messaging services; excludes ordinary app messaging.",type:"string",enum:["enabled","disabled"]},backgroundSync:{description:"General OS background app scheduling. Control is unsupported to preserve application behavior.",type:"string",enum:["enabled","disabled"]},animations:{description:"Android system animation scales: disabled sets all three to zero; enabled sets them to one. Excludes app-owned animation.",type:"string",enum:["enabled","disabled"]},screensavers:{description:"Android dream/screensaver activation; excludes wallpaper and widgets.",type:"string",enum:["enabled","disabled"]},backup:{description:"Android Backup Manager scheduling for the current user; disables backup and restore test behavior.",type:"string",enum:["enabled","disabled"]},mailApp:{description:"Android optional mail apps, including Gmail. Removes mail intent handlers; preserves other apps' messaging.",type:"string",enum:["enabled","disabled"]},calendarApp:{description:"Android Calendar app availability; preserves CalendarProvider.",type:"string",enum:["enabled","disabled"]},contactsApp:{description:"Android Contacts app availability; preserves ContactsProvider.",type:"string",enum:["enabled","disabled"]},mapsApp:{description:"Android Google Maps app; external navigation intents become unavailable.",type:"string",enum:["enabled","disabled"]},videoApp:{description:"Android YouTube app; native video links become unavailable.",type:"string",enum:["enabled","disabled"]},musicApp:{description:"Android YouTube Music app; preserves shared audio playback.",type:"string",enum:["enabled","disabled"]},photosApp:{description:"Android Google Photos app; changes cloud photo sources and choosers. Preserves MediaProvider and DocumentsUI.",type:"string",enum:["enabled","disabled"]},assistantApp:{description:"Android Google Search/Assistant app, including voice and home-search integrations.",type:"string",enum:["enabled","disabled"]},digitalWellbeing:{description:"Android Digital Wellbeing usage tracking, focus, and app limits.",type:"string",enum:["enabled","disabled"]},printing:{description:"Android print spooler and print recommendations; printing becomes unavailable.",type:"string",enum:["enabled","disabled"]},accessibilityApps:{description:"Optional Android accessibility apps. Active accessibility services are protected.",type:"string",enum:["enabled","disabled"]},textToSpeech:{description:"Android Google speech synthesis; speech-dependent functionality becomes unavailable.",type:"string",enum:["enabled","disabled"]},storeApp:{description:"Android Play Store app; installation, updates, billing and licensing may fail.",type:"string",enum:["enabled","disabled"]},healthConnect:{description:"Android Health Connect controller and backup app; health integrations become unavailable.",type:"string",enum:["enabled","disabled"]},adServices:{description:"Android AdServices API package; advertising/privacy APIs may fail. Does not remove mainline/APEX infrastructure.",type:"string",enum:["enabled","disabled"]},onDevicePersonalization:{description:"Android on-device personalization service package; dependent APIs may fail.",type:"string",enum:["enabled","disabled"]},wallpaperApps:{description:"Android wallpaper picker and optional live-wallpaper apps; changes wallpaper selection. Does not disable the shared wallpaper framework or widgets.",type:"string",enum:["enabled","disabled"]},dialerApp:{description:"Optional Android dialer apps. Default role holders remain protected.",type:"string",enum:["enabled","disabled"]},messagesApp:{description:"Optional Android SMS/Messages apps. Default role holders remain protected; excludes other apps' messaging.",type:"string",enum:["enabled","disabled"]},googleServicesFramework:{description:"Android Google Services Framework; aggressive control that can break Google account and push integrations.",type:"string",enum:["enabled","disabled"]},googlePlayServices:{description:"Android Google Play services; aggressive control that breaks dependent push, authentication, location and other integrations. Keep enabled for workflows that depend on those services.",type:"string",enum:["enabled","disabled"]},icloudSync:{description:"Broad iCloud/account synchronization. Control is unsupported; use the narrower icloudSettingsSync setting.",type:"string",enum:["enabled","disabled"]}},additionalProperties:!1,minProperties:1},device:{anyOf:[{type:"object",properties:{platform:{type:"string",const:"android"},name:{description:"Exact AVD name",type:"string",minLength:1},spec:{type:"object",properties:{runtime:{description:"Installed Android system-image package identifier",type:"string",minLength:1},deviceType:{description:"Android avdmanager device profile identifier",type:"string",minLength:1},displayCutout:{description:"Required display cutout class for the exact device type; 'any' accepts every class",type:"string",enum:["none","notch","dynamic_island","hole_punch","any"]},configuration:{type:"object",properties:{memoryMb:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},cpuCores:{type:"integer",minimum:1,maximum:16},gpuMode:{type:"string",enum:["auto","host","software","swiftshader","lavapipe","swangle"]},screenWidth:{type:"integer",minimum:240,maximum:7680},screenHeight:{type:"integer",minimum:240,maximum:7680},screenDensity:{type:"integer",minimum:72,maximum:1000},cameraFront:{type:"string",enum:["none","emulated"]},cameraBack:{type:"string",enum:["none","emulated"]},audioInput:{type:"boolean"},audioOutput:{type:"boolean"}},additionalProperties:!1},deviceProfile:{description:"Android: OEM manufacturer profile applied after automation readiness and reset when the session is released; the kill facet is deferred until an app is known (apply it with killProfile). Not the hardware deviceType. Requires boot=true and readiness=automation.",type:"object",properties:{manufacturerProfile:{description:"Manufacturer profile id, as listed by the manufacturerProfile tool",type:"string",enum:["pixel-baseline","samsung-oneui","xiaomi-hyperos","oneplus-oxygenos","oppo-coloros","motorola","huawei-emui","vivo-funtouch","realme-ui","meizu-flyme","asus-zenui","sony-xperia","tecno-hios"]},requires:{description:"OEM capabilities the task needs; one the manufacturer profile cannot emulate refuses with requires_real_device before anything is created",type:"array",items:{type:"string",enum:["samsung-dex","knox","flip-cover-screen","spen-air-actions","oem-systemui","oem-unused-app-triggers","firmware-update-exemption-reset","xiaomi-proprietary-appops"]}}},required:["manufacturerProfile"],additionalProperties:!1}},required:["runtime","deviceType"],additionalProperties:!1}},required:["platform","name","spec"],additionalProperties:!1},{type:"object",properties:{platform:{type:"string",const:"ios"},name:{description:"Exact simulator name",type:"string",minLength:1},deviceId:{description:"Exact simulator UDID; prevents same-named simulator selection",type:"string",minLength:1},spec:{type:"object",properties:{runtime:{description:"CoreSimulator runtime identifier",type:"string",minLength:1},deviceType:{description:"CoreSimulator device-type identifier",type:"string",minLength:1},displayCutout:{description:"Required display cutout class for the exact device type; 'any' accepts every class",type:"string",enum:["none","notch","dynamic_island","hole_punch","any"]}},required:["runtime","deviceType"],additionalProperties:!1}},required:["platform","name","spec"],additionalProperties:!1},{type:"object",properties:{platform:{type:"string",const:"watchos"},name:{description:"Exact watch simulator name",type:"string",minLength:1},deviceId:{description:"Exact watch simulator UDID; a UDID that names no watch is refused, not created",type:"string",minLength:1},spec:{type:"object",properties:{runtime:{description:"watchOS CoreSimulator runtime identifier",type:"string",minLength:1},deviceType:{description:"Apple Watch CoreSimulator device-type identifier",type:"string",minLength:1}},required:["runtime","deviceType"],additionalProperties:!1}},required:["platform","name","spec"],additionalProperties:!1},{type:"object",properties:{platform:{type:"string",const:"tvos"},name:{description:"Exact Apple TV simulator name",type:"string",minLength:1},deviceId:{description:"Exact Apple TV simulator UDID; a UDID that names no Apple TV is refused, not created",type:"string",minLength:1},spec:{type:"object",properties:{runtime:{description:"tvOS CoreSimulator runtime identifier",type:"string",minLength:1},deviceType:{description:"Apple TV CoreSimulator device-type identifier",type:"string",minLength:1}},required:["runtime","deviceType"],additionalProperties:!1}},required:["platform","name","spec"],additionalProperties:!1},{type:"object",properties:{platform:{type:"string",const:"visionos"},name:{description:"Exact Apple Vision Pro simulator name",type:"string",minLength:1},deviceId:{description:"Exact Apple Vision Pro simulator UDID; a UDID that names no Apple Vision Pro is refused, not created",type:"string",minLength:1},spec:{type:"object",properties:{runtime:{description:"visionOS CoreSimulator runtime identifier",type:"string",minLength:1},deviceType:{description:"Apple Vision Pro CoreSimulator device-type identifier",type:"string",minLength:1}},required:["runtime","deviceType"],additionalProperties:!1}},required:["platform","name","spec"],additionalProperties:!1}]},boot:{description:"Boot the resolved device after creation or adoption",default:!0,type:"boolean"},readiness:{description:'Whether to wait for the AutoMobile automation runner after device boot (default "automation"); watchOS and tvOS provisioning take only "none" (their default); visionOS also takes only "none" and prepares its window-app runner on the first observe, tapOn or sendKeys; startDevice prepares watchOS/tvOS runners',type:"string",enum:["automation","none"]},timeoutMs:{description:"Total provision, boot, resource configuration, and readiness timeout in ms",type:"integer",exclusiveMinimum:0,maximum:830000},enableTools:{description:"Exact case-sensitive AutoMobile tool names to enable for the session this call mints, applied before the response is built so the returned enabledTools/gatedTools reflect discovery. Unknown or hidden names reject the call before device work; always-on names are returned in skipped. Requires boot=true.",minItems:1,type:"array",items:{type:"string",minLength:1,enum:["accessibility","accessibilityAction","accessibilityAudit","accessibilityFocus","ambient","appLifecycle","audit","backgroundWork","biometricAuth","captureAudio","captureTrace","changeLocalization","clearKeyValueFile","clearMockNetwork","clipboard","compareScreenshot","crashApp","deleteDevice","deleteKeychainItem","deviceSnapshot","displayConfig","displayProfile","dragAndDrop","dragPath","executePlan","explore","exportPlan","exportPrototypeWeb","focusNavigate","getAppPermissions","getDataStore","getDeepLinks","getDeviceState","getIosSimulatorCapabilities","getLogs","getNavigationGraph","getNetworkGraph","getNotificationPolicy","getPreference","glassesInput","heapDump","highlight","hitTest","homeScreen","hoverAt","identifyInteractions","injectAudioInput","inspectPackageSigning","installApp","keyboard","killDevice","killProfile","launchApp","listApps","listDataStores","listDeviceImages","listDevices","manufacturerProfile","measureStartup","mediaSession","mockNetwork","multiTouch","navigateTo","network","observe","openLink","performanceAudit","performanceTrace","phoneCall","pinchOn","portReverse","postNotification","pressButton","prototype","provisionDevice","putAppFile","recentApps","reconcileDeviceResources","recordDeviceGestures","recordToolCalls","removeKeyValue","resetAppLogs","resetKeychain","rotaryScroll","rotate","rotateCrown","seedContent","selectAllText","sendBroadcast","sendKeys","sendSms","setActiveDevice","setAppLinks","setAppPermissions","setDeviceResources","setDeviceState","setKeyValue","setNotificationPolicy","setPosture","setPreference","setSensor","setUIState","shake","siri","snapshotOf","sqlQuery","statusBar","stopAudioInput","swipeAt","swipeOn","systemAlerts","systemTray","tapAny","tapAt","tapOn","terminateApp","uninstallApp","videoRecording","wakeAndUnlock","wearSurface","windowMode"]}},androidAuto:{description:"Android only. After boot, prepare the phone emulator for Android Auto projection (no Google account) and start a headless Desktop Head Unit. Requires boot=true and a Google Play system image; one projecting emulator per host.",type:"object",properties:{apkDirectory:{description:"Host directory holding the Android Auto split APKs you supplied: base.apk plus its split_*.apk config splits for the emulator's ABI, language and density. AutoMobile never downloads them. Installed only while the phone still runs the image's Android Auto stub.",type:"string",minLength:1},dhuPath:{description:"desktop-head-unit binary; defaults to $ANDROID_HOME/extras/google/auto/desktop-head-unit",type:"string",minLength:1},dhuConfig:{description:"Head unit config (.ini); defaults to config/default_720p.ini beside the DHU binary",type:"string",minLength:1},acceptAndroidAutoTerms:{description:"Tap Continue on Android Auto's welcome screen, which accepts its terms. Set only on the user's explicit instruction; otherwise a pending welcome screen is reported, not tapped.",type:"boolean"}},required:["apkDirectory"],additionalProperties:!1}},required:["device"],additionalProperties:!1}},{name:"putAppFile",title:"Write App File",annotations:{destructiveHint:!0},description:"Write files into a bounded logical storage target.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{target:{anyOf:[{type:"object",properties:{domain:{type:"string",const:"app_containers"},appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},container:{description:"App container",type:"string",enum:["documents","library","cache","tmp","externalFiles"]}},required:["domain","appId","container"],additionalProperties:!1},{type:"object",properties:{domain:{type:"string",const:"user_files"},namespace:{description:"One caller-named fixture namespace",type:"string"},reset:{description:"Remove only this fixture namespace before writing",type:"boolean"},indexMedia:{description:"Request an Android MediaStore scan of every written file so media apps and the system document picker can list it",default:!1,type:"boolean"}},required:["domain","namespace"],additionalProperties:!1},{type:"object",properties:{domain:{type:"string",const:"media_library"}},required:["domain"],additionalProperties:!1}]},files:{description:"Files to write",minItems:1,type:"array",items:{type:"object",properties:{sourcePath:{description:"Host file path",type:"string",minLength:1},contentText:{description:"UTF-8 content",type:"string"},contentBase64:{description:"Base64 content",type:"string"},destinationPath:{description:"Safe path relative to the declared storage target",type:"string"}},required:["destinationPath"],additionalProperties:!1,anyOf:[{required:["sourcePath"]},{required:["contentText"]},{required:["contentBase64"]}]}},userId:{description:"Android user ID",type:"integer",minimum:-9007199254740991,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["target","files"],additionalProperties:!1}},{name:"recentApps",title:"Open Recent Apps",annotations:{destructiveHint:!1},description:"Open recent apps",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"reconcileDeviceResources",title:"Reconcile Device Resources",annotations:{destructiveHint:!0},description:"Compare an iOS Simulator with a requested resource map (workload profile) and report typed drift: missingRequested, ownedExtra (overrides AutoMobile applied earlier), unsupported, commandFailure. Report-only by default; repair applies only the drifted delta, re-reads, and succeeds only when every requested resource is proven.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{resources:{description:"Requested workload profile: the resource map the simulator should match. It has no name; its identity is the returned profileFingerprint.",type:"object",properties:{wallpaperRendering:{description:"Home and Lock Screen wallpaper rendering; excludes widgets and Live Activities.",type:"string",enum:["enabled","disabled"]},widgets:{description:"Widget refresh, including app widgets; excludes wallpaper and Live Activities.",type:"string",enum:["enabled","disabled"]},liveActivities:{description:"Live Activities and Dynamic Island updates; excludes wallpaper and widgets.",type:"string",enum:["enabled","disabled"]},healthServices:{description:"HealthKit data and Health app background work. Health integrations become unavailable.",type:"string",enum:["enabled","disabled"]},homeServices:{description:"HomeKit accessories and automations. Home integrations become unavailable.",type:"string",enum:["enabled","disabled"]},fitnessServices:{description:"Apple Fitness, coaching, activity awards, and activity sharing.",type:"string",enum:["enabled","disabled"]},familyServices:{description:"Family Sharing, family approvals, and parental controls. Changes restriction behavior.",type:"string",enum:["enabled","disabled"]},screenTime:{description:"Screen Time limits and usage tracking. Changes restriction behavior.",type:"string",enum:["enabled","disabled"]},newsServices:{description:"Apple News background content.",type:"string",enum:["enabled","disabled"]},weatherServices:{description:"Apple Weather background forecasts.",type:"string",enum:["enabled","disabled"]},tipsServices:{description:"Apple Tips background content.",type:"string",enum:["enabled","disabled"]},gameServices:{description:"Game Center and saved-game synchronization; excludes controller input.",type:"string",enum:["enabled","disabled"]},mapsSync:{description:"Maps favorites, history, background updates, and suggested destinations; excludes MapKit rendering and location services.",type:"string",enum:["enabled","disabled"]},advertising:{description:"Promoted Apple content; excludes advertising privacy preferences and app integrity services.",type:"string",enum:["enabled","disabled"]},diagnosticReporting:{description:"Diagnostic collectors, feedback, location analytics, and call-quality reporting; reduces diagnostic evidence, not call transport.",type:"string",enum:["enabled","disabled"]},siriAndAppIntents:{description:"iOS Simulator Siri requests, Shortcuts actions, and App Intents; excludes speech services and proactive suggestions.",type:"string",enum:["enabled","disabled"]},speechServices:{description:"iOS Simulator speech recognition, dictation, and Siri speech synthesis; excludes Siri requests and App Intents orchestration.",type:"string",enum:["enabled","disabled"]},mediaTranscoding:{description:"iOS Simulator Photos image and video conversion; media imports and photo-picker conversions may fail.",type:"string",enum:["enabled","disabled"]},photoAnalysis:{description:"Background Photos analysis; may reduce photo search and recognition. Preserves library access, cloud transfers, and shared media-analysis infrastructure.",type:"string",enum:["enabled","disabled"]},assistantSuggestions:{description:"Siri inference, knowledge, and proactive suggestions; preserves speech, system voices, and shared language/model infrastructure.",type:"string",enum:["enabled","disabled"]},appleIntelligence:{description:"Apple Intelligence orchestration and generative experiences; system writing tools and intelligence integrations may become unavailable. Preserves shared model and speech services.",type:"string",enum:["enabled","disabled"]},searchIndexing:{description:"Spotlight and Settings search, including app-provided system indexes; excludes an app's own search service.",type:"string",enum:["enabled","disabled"]},appStoreServices:{description:"App Store installation/update services; excludes push and StoreKit payment services.",type:"string",enum:["enabled","disabled"]},appleMediaSync:{description:"Apple Music and subscribed/purchased media background services; excludes generic audio/video playback and StoreKit payments.",type:"string",enum:["enabled","disabled"]},mailServices:{description:"Apple Mail background services. Mail-based sign-in email workflows may be unavailable.",type:"string",enum:["enabled","disabled"]},calendarServices:{description:"Local Calendar database access; excludes server-side calendar integrations in apps.",type:"string",enum:["enabled","disabled"]},reminderServices:{description:"Apple Reminders database and background work; excludes reminders maintained by other apps.",type:"string",enum:["enabled","disabled"]},personalDataSync:{description:"Exchange, CalDAV, and CardDAV synchronization; preserves local Contacts database access.",type:"string",enum:["enabled","disabled"]},safariSync:{description:"Safari bookmark/history synchronization; preserves associated domains, shared credentials, browsing protections, and WebKit.",type:"string",enum:["enabled","disabled"]},icloudSettingsSync:{description:"iCloud system-settings synchronization and storage-plan recommendations; preserves accounts, credentials, CloudKit data, Drive, and Photos transfers.",type:"string",enum:["enabled","disabled"]},messagingMaintenance:{description:"Apple Messages history cleanup, attachment transfer, and FaceTime message storage; preserves identity, message database XPC helpers, and system calling services.",type:"string",enum:["enabled","disabled"]},watchConnectivity:{description:"Paired Watch and companion-device communication.",type:"string",enum:["enabled","disabled"]},carPlay:{description:"CarPlay vehicle connectivity.",type:"string",enum:["enabled","disabled"]},tvRemote:{description:"Apple TV discovery and remote control.",type:"string",enum:["enabled","disabled"]},findMy:{description:"Find My device-location services; excludes general location APIs.",type:"string",enum:["enabled","disabled"]},continuity:{description:"Nearby-device Continuity discovery; cross-device workflows may stop working. Preserves system share sheets.",type:"string",enum:["enabled","disabled"]},walletServices:{description:"Wallet, Apple Pay, digital identity, and merchant services. Payment sheets, including dependent StoreKit workflows, may fail.",type:"string",enum:["enabled","disabled"]},businessServices:{description:"Apple business messaging services; excludes ordinary app messaging.",type:"string",enum:["enabled","disabled"]},backgroundSync:{description:"General OS background app scheduling. Control is unsupported to preserve application behavior.",type:"string",enum:["enabled","disabled"]},animations:{description:"Android system animation scales: disabled sets all three to zero; enabled sets them to one. Excludes app-owned animation.",type:"string",enum:["enabled","disabled"]},screensavers:{description:"Android dream/screensaver activation; excludes wallpaper and widgets.",type:"string",enum:["enabled","disabled"]},backup:{description:"Android Backup Manager scheduling for the current user; disables backup and restore test behavior.",type:"string",enum:["enabled","disabled"]},mailApp:{description:"Android optional mail apps, including Gmail. Removes mail intent handlers; preserves other apps' messaging.",type:"string",enum:["enabled","disabled"]},calendarApp:{description:"Android Calendar app availability; preserves CalendarProvider.",type:"string",enum:["enabled","disabled"]},contactsApp:{description:"Android Contacts app availability; preserves ContactsProvider.",type:"string",enum:["enabled","disabled"]},mapsApp:{description:"Android Google Maps app; external navigation intents become unavailable.",type:"string",enum:["enabled","disabled"]},videoApp:{description:"Android YouTube app; native video links become unavailable.",type:"string",enum:["enabled","disabled"]},musicApp:{description:"Android YouTube Music app; preserves shared audio playback.",type:"string",enum:["enabled","disabled"]},photosApp:{description:"Android Google Photos app; changes cloud photo sources and choosers. Preserves MediaProvider and DocumentsUI.",type:"string",enum:["enabled","disabled"]},assistantApp:{description:"Android Google Search/Assistant app, including voice and home-search integrations.",type:"string",enum:["enabled","disabled"]},digitalWellbeing:{description:"Android Digital Wellbeing usage tracking, focus, and app limits.",type:"string",enum:["enabled","disabled"]},printing:{description:"Android print spooler and print recommendations; printing becomes unavailable.",type:"string",enum:["enabled","disabled"]},accessibilityApps:{description:"Optional Android accessibility apps. Active accessibility services are protected.",type:"string",enum:["enabled","disabled"]},textToSpeech:{description:"Android Google speech synthesis; speech-dependent functionality becomes unavailable.",type:"string",enum:["enabled","disabled"]},storeApp:{description:"Android Play Store app; installation, updates, billing and licensing may fail.",type:"string",enum:["enabled","disabled"]},healthConnect:{description:"Android Health Connect controller and backup app; health integrations become unavailable.",type:"string",enum:["enabled","disabled"]},adServices:{description:"Android AdServices API package; advertising/privacy APIs may fail. Does not remove mainline/APEX infrastructure.",type:"string",enum:["enabled","disabled"]},onDevicePersonalization:{description:"Android on-device personalization service package; dependent APIs may fail.",type:"string",enum:["enabled","disabled"]},wallpaperApps:{description:"Android wallpaper picker and optional live-wallpaper apps; changes wallpaper selection. Does not disable the shared wallpaper framework or widgets.",type:"string",enum:["enabled","disabled"]},dialerApp:{description:"Optional Android dialer apps. Default role holders remain protected.",type:"string",enum:["enabled","disabled"]},messagesApp:{description:"Optional Android SMS/Messages apps. Default role holders remain protected; excludes other apps' messaging.",type:"string",enum:["enabled","disabled"]},googleServicesFramework:{description:"Android Google Services Framework; aggressive control that can break Google account and push integrations.",type:"string",enum:["enabled","disabled"]},googlePlayServices:{description:"Android Google Play services; aggressive control that breaks dependent push, authentication, location and other integrations. Keep enabled for workflows that depend on those services.",type:"string",enum:["enabled","disabled"]},icloudSync:{description:"Broad iCloud/account synchronization. Control is unsupported; use the narrower icloudSettingsSync setting.",type:"string",enum:["enabled","disabled"]}},additionalProperties:!1},repair:{description:"Apply only the drifted requested entries, then re-read and fail closed. Defaults to false (report only).",type:"boolean"},releaseOwnedExtras:{description:"With repair, re-enable services AutoMobile disabled earlier that this profile omits. Never touches overrides AutoMobile did not apply.",type:"boolean"},timeoutMs:{description:"Total reconciliation budget in milliseconds. Defaults to 300000.",type:"integer",exclusiveMinimum:0,maximum:890000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["resources"],additionalProperties:!1},_meta:{"automobile/deviceResourceBudget":!0}},{name:"recordDeviceGestures",title:"Record Gestures",annotations:{destructiveHint:!1},description:"Start recording on-device user input (not tool calls) for exportPlan.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"}},additionalProperties:!1}},{name:"recordToolCalls",title:"Record Tool Calls",annotations:{destructiveHint:!1,openWorldHint:!1},description:"Record MCP tool calls to a YAML plan: action begin, end (returns the plan; exportPlan also ends it), or status.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"begin starts recording this connection's tool calls; end stops and returns the YAML plan; status reports state",type:"string",enum:["begin","end","status"]},planName:{description:"Plan name: on begin, the exported plan's name; on end, overrides the begin name",type:"string"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"}},required:["action"],additionalProperties:!1}},{name:"removeKeyValue",title:"Remove Key Value",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Remove app key-value storage entry.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},name:{description:`Storage name. iOS: empty string, "standard" (any case) or the app bundle id select the app's standard UserDefaults; any other value is a UserDefaults suite name (e.g. an app group) and must be a valid suite with no leading or trailing whitespace. Android: SharedPreferences file name without the .xml extension (letters, digits, underscore, dash, dot).`,type:"string"},fileName:{description:"Deprecated alias for name",type:"string"},key:{description:"Key",type:"string"},userId:{description:"Android only: user whose copy of the app the direct-file (run-as) fallback edits (e.g. a work profile). Defaults to user 0 when the app is installed for it; otherwise to the one other running user that has it (an error asks for userId if several do). The SDK route is not user-scoped.",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","key"],additionalProperties:!1,description:"Provide either `name` (iOS UserDefaults suite / Android SharedPreferences name) or `fileName`"},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"resetAppLogs",title:"Reset Logs",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Reset explicitly named app-container log files (and their rotated `<path>.N` siblings) on the session's device, reporting a per-path outcome.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"App package name or bundle identifier",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},container:{description:"Logical app container that holds the log files",default:"documents",type:"string",enum:["documents","library","cache","tmp","externalFiles"]},paths:{description:"Explicitly named log files to reset",minItems:1,maxItems:32,type:"array",items:{description:"Log file path relative to the container; rotated siblings (`<path>.N`) are reset too",type:"string"}},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","paths"],additionalProperties:!1}},{name:"resetKeychain",title:"Reset Keychain",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Reset secure test state. Android deletes app-declared scope/alias under app opt-in and SDK mutation authorization; confirm is not needed, but confirm:false refuses. On Android, action injectFault/clearFaults arms or clears a debug-SDK Keystore fault (kind, delayMs for DELAY) on the same declared selectors instead of deleting. iOS Simulator resets EVERY app's Keychain and requires confirm:true. Physical iOS is unsupported. Requires explicit device targeting.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Required. The app whose Keychain/Keystore state to reset. NOTE: iOS Simulator only supports a device-wide reset and erases EVERY app's Keychain regardless of this value.",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},scope:{description:"Android declared scope to reset or fault; required unless alias is given.",type:"string",minLength:1},alias:{description:"Android declared alias to delete or fault; with scope, must belong to it.",type:"string",minLength:1},action:{description:"Default reset. Android only: injectFault arms a debug-SDK Keystore fault on the selected declared aliases until clearFaults or app restart; clearFaults removes them.",type:"string",enum:["reset","injectFault","clearFaults"]},kind:{description:"injectFault only, required: the fault each Keystore use of the alias raises.",type:"string",enum:["KEY_STORE_EXCEPTION","PROVIDER_EXCEPTION","USER_NOT_AUTHENTICATED","DELAY","STRONGBOX_UNAVAILABLE"]},delayMs:{description:"injectFault with kind DELAY only, required: delay per Keystore operation.",type:"integer",minimum:1,maximum:1e4},confirm:{description:"Required true on iOS Simulator, which erases EVERY app's Keychain. Android does not need confirm (app opt-in, declared aliases and the SDK mutation gate authorize it), but confirm: false refuses the action.",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"rotaryScroll",title:"Scroll Rotary Input",annotations:{destructiveHint:!0},description:"Wear OS: scroll with the rotary crown. Tries `input rotaryencoder scroll`, the emulator console and finally a vertical swipe, in that order, and after each reads the screen back; success means the screen changed. Returns the method that worked and every attempt. The commands are unconfirmed on real images (see docs/design-docs/plat/android/form-factors.md), so check attempts. A screen that does not move when scrolled (already at the end) reports unchanged. On a device that does not announce a watch build the input is still sent and the result carries a warning.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{delta:{description:"Crown detents: positive scrolls content down (clockwise), negative scrolls up",type:"integer",minimum:-50,maximum:50},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["delta"],additionalProperties:!1}},{name:"rotate",title:"Rotate",annotations:{destructiveHint:!1,idempotentHint:!0},description:"Rotate device orientation",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{orientation:{type:"string",enum:["portrait","landscape"]},lockOrientation:{description:"Android only. true keeps automatic rotation off to hold the requested orientation. Omission restores the prior automatic-rotation setting after orientation confirmation, including in a device session; an unreadable initial setting is left unchanged. false enables automatic rotation, even if originally locked; in a session it also restores original user_rotation. orientationLockState reports the confirmed lock.",type:"boolean"},display:{description:"Android logical display ID (default 0). Non-default displays use the per-display window-manager rotation command and do not change or restore global rotation settings; iOS supports only the default display.",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["orientation"],additionalProperties:!1}},{name:"rotateCrown",title:"Rotate Digital Crown",annotations:{destructiveHint:!0},description:"watchOS only: rotate the Apple Watch Digital Crown by a signed, non-zero delta in full revolutions (1 = one turn; use fractions such as 0.25 for small changes), with optional positive velocity (default: 1). Target an Apple Watch session. Observe afterward to check the app's response.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{description:"Apple Watch only",type:"string",const:"watchos"},delta:{description:"Signed, non-zero crown turn in full revolutions: 1 is one full turn, 0.25 a quarter turn. How many value steps a turn moves depends on the app's crown step and sensitivity. Fractions are accepted; a turn smaller than one step of the focused control may not register",type:"number"},velocity:{description:"Positive Digital Crown rotation velocity (default: 1)",type:"number",exclusiveMinimum:0},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["delta"],additionalProperties:!1}},{name:"seedContent",title:"Seed System Content",annotations:{destructiveHint:!0},description:"Seed Android contacts, calendar events, call history and SMS inbox, tagged automobile.<namespace>. reset removes only this namespace before inserts (supplied kinds, or all kinds if no arrays). Contacts/calendar/SMS require the debug content-seeder APK and grant its SMS role and runtime permissions. Optional contact photoPath reads a host PNG/JPEG up to 512 KB. Dates are ISO 8601 with timezone; all-day events use UTC midnight and exclusive end. Data persists until reset. iOS is unsupported.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{namespace:{type:"string",pattern:"^[A-Za-z0-9_-]{1,32}$"},reset:{description:"Remove namespace rows before inserting. With arrays, reset those kinds; without arrays, reset all four kinds.",type:"boolean"},contacts:{type:"array",items:{type:"object",properties:{name:{type:"string",minLength:1},phones:{type:"array",items:{type:"string",minLength:1}},emails:{type:"array",items:{type:"string",minLength:1}},photoPath:{description:"Host PNG/JPEG file path, at most 512 KB (524288 bytes); checked by signature before writes.",type:"string",minLength:1,pattern:"\\.(?:[pP][nN][gG]|[jJ][pP][eE]?[gG])$"}},required:["name"],additionalProperties:!1}},calendarEvents:{type:"array",items:{type:"object",properties:{title:{type:"string",minLength:1},start:{type:"string",format:"date-time",pattern:"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"},end:{type:"string",format:"date-time",pattern:"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"},allDay:{type:"boolean"},location:{type:"string",minLength:1},calendar:{type:"string",minLength:1}},required:["title","start","end"],additionalProperties:!1}},callLog:{type:"array",items:{type:"object",properties:{number:{type:"string",minLength:1},type:{type:"string",enum:["incoming","outgoing","missed"]},date:{type:"string",format:"date-time",pattern:"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"},durationSec:{type:"integer",minimum:0,maximum:2147483647}},required:["number","type","date"],additionalProperties:!1}},smsInbox:{type:"array",items:{type:"object",properties:{address:{type:"string",minLength:1},body:{type:"string",minLength:1},date:{type:"string",format:"date-time",pattern:"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"},read:{type:"boolean"}},required:["address","body","date"],additionalProperties:!1}},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["namespace"],additionalProperties:!1}},{name:"selectAllText",title:"Select All Text",annotations:{destructiveHint:!1},description:"Select all text in focused input",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"sendBroadcast",title:"Send Broadcast",annotations:{destructiveHint:!0},description:"Android: send an explicit broadcast to the app under test (its package, or one of its receivers) with a typed intent (action, data, categories, typed extras), e.g. to toggle a debug flag or seed data. Reports the ordered-broadcast result; protected system broadcasts are refused with a typed error.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Target package: the broadcast is always explicit to it",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},intent:{type:"object",properties:{component:{description:'A class inside appId: ".Receiver", "com.app.Receiver", or "com.app/.Receiver"',type:"string",minLength:1},action:{description:"Broadcast action",type:"string",minLength:1},data:{description:"Data URI",type:"string",minLength:1},mimeType:{type:"string",minLength:1},categories:{maxItems:16,type:"array",items:{type:"string",minLength:1}},extras:{description:"Typed extras",maxItems:64,type:"array",items:{anyOf:[{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"string"},value:{type:"string"}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"int"},value:{type:"integer",minimum:-9007199254740991,maximum:9007199254740991}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"long"},value:{type:"integer",minimum:-9007199254740991,maximum:9007199254740991}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"float"},value:{type:"number"}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"boolean"},value:{type:"boolean"}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"stringArray"},value:{type:"array",items:{type:"string"}}},required:["key","type","value"],additionalProperties:!1},{type:"object",properties:{key:{type:"string",minLength:1,maxLength:256},type:{type:"string",const:"uri"},value:{type:"string"}},required:["key","type","value"],additionalProperties:!1}]}}},required:["action"],additionalProperties:!1},userId:{description:"Android user to deliver to",type:"integer",minimum:0,maximum:9007199254740991},waitForResult:{description:"Report the ordered-broadcast result code and data (default true)",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","intent"],additionalProperties:!1}},{name:"sendKeys",title:"Send Keyboard Input",annotations:{destructiveHint:!0},description:"Execute ordered typing, clear, raw-key, and semantic IME commands. Unicode: iOS any mode; Android a11y/ime/auto/eventAll/eventLast (event modes use a11y for unsupported runs). Android eventOnly/imeKeyEvents are ASCII-only. textLength counts code points.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:"Target panel key, role, or active",type:"string"},selector:{description:"Field to focus once before executing the ordered command sequence; supports nested container scope and unique selection",anyOf:[{type:"object",properties:{elementId:{description:"Resource ID, e.g. com.app:id/field",type:"string",minLength:1}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{testTag:{description:"Android accessibility test tag",type:"string",minLength:1}},required:["testTag"],additionalProperties:!1},{type:"object",properties:{text:{description:"Text, content-desc, or placeholder of the field",type:"string",minLength:1}},required:["text"],additionalProperties:!1},{type:"object",properties:{textAny:{description:"Ordered text variants; first visible match wins",minItems:1,type:"array",items:{type:"string",minLength:1}}},required:["textAny"],additionalProperties:!1}]},container:{description:"Nested container scope; outermost resolves first, each level searches strict descendants. Per-level index is zero-based. Requires a selector naming the field to focus.",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Selection strategy: first (default), random, or unique. Unique requires exactly one match at every unindexed scope and target. Requires a selector naming the field to focus.",type:"string",enum:["first","random","unique"]},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},commands:{description:"One to 100 commands executed serially; execution stops on the first failure",minItems:1,maxItems:100,type:"array",items:{anyOf:[{type:"object",properties:{action:{type:"string",const:"type"},text:{description:"Text to insert or replace; never echoed in the result",type:"string",minLength:1},operation:{description:"Insert at the current selection (default) or replace the focused field",default:"insert",type:"string",enum:["insert","replace"]},mode:{description:"Android delivery mode. Use ime, a11y, or auto for Unicode and emoji. auto uses the AutoMobile IME when supported, otherwise eventAll for insert or a11y for replace. ime commits complete graphemes; eventAll inserts whole graphemes and uses key events only for single printable ASCII characters. eventLast can split keycaps or decomposed letters. eventOnly and imeKeyEvents are ASCII-only; imeKeyEvents requires a compatible CtrlProxy APK and does not verify resulting editor text. A successful AutoMobile IME call leaves that IME selected for the device session, so later calls do not switch keyboards; the previous keyboard is restored, best-effort, when the session is released or before keyboard listImes, setIme or tapImeKey. iOS uses xcuiTypeText for every requested mode",default:"auto",type:"string",enum:["auto","a11y","eventLast","eventAll","eventOnly","ime","imeKeyEvents"]},keyboardProfile:{description:"Android keyboard behavior profile for this IME type call; restored afterward",type:"string",enum:["direct","gboard","samsung"]}},required:["action","text"],additionalProperties:!1,dependentSchemas:{keyboardProfile:{properties:{mode:{enum:["auto","ime"]}}}}},{type:"object",properties:{action:{type:"string",const:"key"},key:{description:"Raw key or semantic IME key. Semantic next/previous/done/search/send/go ignore modifiers",type:"string",enum:["enter","tab","escape","backspace","delete","arrow_up","arrow_down","arrow_left","arrow_right","next","previous","done","search","send","go"]},modifiers:{description:"Raw-key modifier chord: shift, ctrl, alt, or meta (maximum 4 entries, including duplicates)",maxItems:4,type:"array",items:{type:"string",enum:["shift","ctrl","alt","meta"]}}},required:["action","key"],additionalProperties:!1},{type:"object",properties:{action:{type:"string",const:"clear"},mode:{description:"Android clear delivery. auto (default) and ime clear through the AutoMobile IME, or key-event deletes on an older control-proxy APK or when the IME cannot be activated, so rich-text editors keep live formatting. a11y uses the accessibility set-text clear. iOS ignores this",type:"string",enum:["auto","ime","a11y"]}},required:["action"],additionalProperties:!1}]}},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["commands"],additionalProperties:!1,dependentRequired:{container:["selector"],selectionStrategy:["selector"],layer:["selector"]},$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"sendSms",title:"Simulate SMS",annotations:{destructiveHint:!1},description:"Send simulated incoming SMS: Android emulator, or a notification via the app's AutoMobile iOS SDK.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{phoneNumber:{description:"Sender phone number",type:"string"},message:{description:"SMS body; max 1024 chars, no newlines/NUL",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["phoneNumber","message"],additionalProperties:!1}},{name:"setActiveDevice",title:"Set Active Device",annotations:{destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},description:"Set active device using existing session binding or a sessionless per-MCP-connection device pin that lasts for that connection (cleared when the connection disconnects or the device is released). With a daemon session, display pins a display key or role (inner/cover/rear/external/overlay/virtual); null clears, omission preserves. Explicit display arguments (including active) bypass the pin; otherwise pin beats focus/posture. On single-display devices, active resolves to the sole key; on multi-display devices active cannot be pinned. all cannot be pinned. Missing or inactive pinned panels fail without dispatch; clear with display: null. Pins clear on release/rebind and are unsupported in direct mode. Returns a text JSON result with message, deviceId, optional sessionUuid, and displayPin (string or null) when display was passed or a pin is present/cleared; never-pinned calls omit displayPin.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{deviceId:{type:"string"},display:{description:"Session display pin: display key or inner/cover/rear/external/overlay/virtual; null clears, omitted preserves. On single-display devices, active resolves to the sole key; on multi-display devices active cannot be pinned. all cannot be pinned. Requires a daemon session. JSON result displayPin reports the resulting selector or null after clearing; omitted for a never-pinned session.",anyOf:[{type:"string"},{type:"null"}]},platform:{description:'Inferred from the device; "watchos", "tvos" or "visionos" is required to select an Apple Watch, Apple TV or Apple Vision Pro simulator',type:"string",enum:["android","ios","watchos","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"}},required:["deviceId"],additionalProperties:!1}},{name:"setAppLinks",title:"Set App Links",annotations:{destructiveHint:!0},description:"Android 12+: change an app's App Links state so https links open the app directly (or not). approve force-verifies autoVerify domains, leaving already-verified domains in non-settable states (system_configured, pre_verified, migrated, restored) untouched; reset clears them to none, reverify re-runs verification, userSelection enables/disables domains for a user, restore writes back the state recorded before the first change, or the closest shell-settable state with a note. Returns what changed, skipped domains, the per-domain state after, and a restore receipt; in a daemon session, release or rebind restores it. Read state with getDeepLinks.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Android package name.",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},userId:{description:"Android user for userSelection and the read-back; defaults to the current user.",type:"integer",minimum:0,maximum:9007199254740991},action:{description:"approve: force-approve autoVerify domains (pm set-app-links 2), leaving already-verified domains in non-settable states (system_configured, pre_verified, migrated, restored) untouched. reset: clear verification to none (pm set-app-links 0). reverify: ask the verifier again (asynchronous). userSelection: enable or disable domains for the user. restore: write back the state recorded before the first setAppLinks change, using the closest settable state when exact restoration is unavailable.",type:"string",enum:["approve","reset","reverify","userSelection","restore"]},domains:{description:"approve, reset, userSelection: domains to change; omit for every declared domain.",minItems:1,type:"array",items:{type:"string",pattern:"^(\\*\\.)?[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$"}},enabled:{description:"userSelection only: true enables the domains for the user, false disables them.",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","action"],additionalProperties:!1}},{name:"setAppPermissions",title:"Set Permissions",annotations:{destructiveHint:!0,idempotentHint:!0},description:"userId grant/revoke; device-wide reset ['all']; no POST_NOTIFICATIONS.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},action:{enum:["grant","revoke","reset"]},permissions:{type:"array",items:{type:"string",minLength:1}},userId:{type:"integer",minimum:0,maximum:9007199254740991},notificationsEnabled:{type:"boolean"},notificationPolicyAccess:{type:"boolean"},scheduleExactAlarm:{enum:["allow","deny"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{type:"string"},keepScreenAwake:{type:"boolean"},device:{type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"setDeviceResources",title:"Set Device Resources",annotations:{destructiveHint:!0},description:"Set selected device resources and verify native state, including disabled iOS service impacts. All settings are opt-in; omitted resources stay unchanged. iOS Simulator services and Android optional apps/settings are runtime-dependent. Android changes return a restore receipt for exact restoration during the same boot. Disabling Google infrastructure changes push/auth behavior. Disabling calendarServices on a booted simulator is refused with code unsafe_device_resource_combination unless its service is not running. Request it when provisioning a new simulator so it applies before first boot, or leave it enabled. Preboot is unaffected; unsafeWith lists the applicable phases.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{resources:{type:"object",properties:{wallpaperRendering:{description:"Home and Lock Screen wallpaper rendering; excludes widgets and Live Activities.",type:"string",enum:["enabled","disabled"]},widgets:{description:"Widget refresh, including app widgets; excludes wallpaper and Live Activities.",type:"string",enum:["enabled","disabled"]},liveActivities:{description:"Live Activities and Dynamic Island updates; excludes wallpaper and widgets.",type:"string",enum:["enabled","disabled"]},healthServices:{description:"HealthKit data and Health app background work. Health integrations become unavailable.",type:"string",enum:["enabled","disabled"]},homeServices:{description:"HomeKit accessories and automations. Home integrations become unavailable.",type:"string",enum:["enabled","disabled"]},fitnessServices:{description:"Apple Fitness, coaching, activity awards, and activity sharing.",type:"string",enum:["enabled","disabled"]},familyServices:{description:"Family Sharing, family approvals, and parental controls. Changes restriction behavior.",type:"string",enum:["enabled","disabled"]},screenTime:{description:"Screen Time limits and usage tracking. Changes restriction behavior.",type:"string",enum:["enabled","disabled"]},newsServices:{description:"Apple News background content.",type:"string",enum:["enabled","disabled"]},weatherServices:{description:"Apple Weather background forecasts.",type:"string",enum:["enabled","disabled"]},tipsServices:{description:"Apple Tips background content.",type:"string",enum:["enabled","disabled"]},gameServices:{description:"Game Center and saved-game synchronization; excludes controller input.",type:"string",enum:["enabled","disabled"]},mapsSync:{description:"Maps favorites, history, background updates, and suggested destinations; excludes MapKit rendering and location services.",type:"string",enum:["enabled","disabled"]},advertising:{description:"Promoted Apple content; excludes advertising privacy preferences and app integrity services.",type:"string",enum:["enabled","disabled"]},diagnosticReporting:{description:"Diagnostic collectors, feedback, location analytics, and call-quality reporting; reduces diagnostic evidence, not call transport.",type:"string",enum:["enabled","disabled"]},siriAndAppIntents:{description:"iOS Simulator Siri requests, Shortcuts actions, and App Intents; excludes speech services and proactive suggestions.",type:"string",enum:["enabled","disabled"]},speechServices:{description:"iOS Simulator speech recognition, dictation, and Siri speech synthesis; excludes Siri requests and App Intents orchestration.",type:"string",enum:["enabled","disabled"]},mediaTranscoding:{description:"iOS Simulator Photos image and video conversion; media imports and photo-picker conversions may fail.",type:"string",enum:["enabled","disabled"]},photoAnalysis:{description:"Background Photos analysis; may reduce photo search and recognition. Preserves library access, cloud transfers, and shared media-analysis infrastructure.",type:"string",enum:["enabled","disabled"]},assistantSuggestions:{description:"Siri inference, knowledge, and proactive suggestions; preserves speech, system voices, and shared language/model infrastructure.",type:"string",enum:["enabled","disabled"]},appleIntelligence:{description:"Apple Intelligence orchestration and generative experiences; system writing tools and intelligence integrations may become unavailable. Preserves shared model and speech services.",type:"string",enum:["enabled","disabled"]},searchIndexing:{description:"Spotlight and Settings search, including app-provided system indexes; excludes an app's own search service.",type:"string",enum:["enabled","disabled"]},appStoreServices:{description:"App Store installation/update services; excludes push and StoreKit payment services.",type:"string",enum:["enabled","disabled"]},appleMediaSync:{description:"Apple Music and subscribed/purchased media background services; excludes generic audio/video playback and StoreKit payments.",type:"string",enum:["enabled","disabled"]},mailServices:{description:"Apple Mail background services. Mail-based sign-in email workflows may be unavailable.",type:"string",enum:["enabled","disabled"]},calendarServices:{description:"Local Calendar database access; excludes server-side calendar integrations in apps.",type:"string",enum:["enabled","disabled"]},reminderServices:{description:"Apple Reminders database and background work; excludes reminders maintained by other apps.",type:"string",enum:["enabled","disabled"]},personalDataSync:{description:"Exchange, CalDAV, and CardDAV synchronization; preserves local Contacts database access.",type:"string",enum:["enabled","disabled"]},safariSync:{description:"Safari bookmark/history synchronization; preserves associated domains, shared credentials, browsing protections, and WebKit.",type:"string",enum:["enabled","disabled"]},icloudSettingsSync:{description:"iCloud system-settings synchronization and storage-plan recommendations; preserves accounts, credentials, CloudKit data, Drive, and Photos transfers.",type:"string",enum:["enabled","disabled"]},messagingMaintenance:{description:"Apple Messages history cleanup, attachment transfer, and FaceTime message storage; preserves identity, message database XPC helpers, and system calling services.",type:"string",enum:["enabled","disabled"]},watchConnectivity:{description:"Paired Watch and companion-device communication.",type:"string",enum:["enabled","disabled"]},carPlay:{description:"CarPlay vehicle connectivity.",type:"string",enum:["enabled","disabled"]},tvRemote:{description:"Apple TV discovery and remote control.",type:"string",enum:["enabled","disabled"]},findMy:{description:"Find My device-location services; excludes general location APIs.",type:"string",enum:["enabled","disabled"]},continuity:{description:"Nearby-device Continuity discovery; cross-device workflows may stop working. Preserves system share sheets.",type:"string",enum:["enabled","disabled"]},walletServices:{description:"Wallet, Apple Pay, digital identity, and merchant services. Payment sheets, including dependent StoreKit workflows, may fail.",type:"string",enum:["enabled","disabled"]},businessServices:{description:"Apple business messaging services; excludes ordinary app messaging.",type:"string",enum:["enabled","disabled"]},backgroundSync:{description:"General OS background app scheduling. Control is unsupported to preserve application behavior.",type:"string",enum:["enabled","disabled"]},animations:{description:"Android system animation scales: disabled sets all three to zero; enabled sets them to one. Excludes app-owned animation.",type:"string",enum:["enabled","disabled"]},screensavers:{description:"Android dream/screensaver activation; excludes wallpaper and widgets.",type:"string",enum:["enabled","disabled"]},backup:{description:"Android Backup Manager scheduling for the current user; disables backup and restore test behavior.",type:"string",enum:["enabled","disabled"]},mailApp:{description:"Android optional mail apps, including Gmail. Removes mail intent handlers; preserves other apps' messaging.",type:"string",enum:["enabled","disabled"]},calendarApp:{description:"Android Calendar app availability; preserves CalendarProvider.",type:"string",enum:["enabled","disabled"]},contactsApp:{description:"Android Contacts app availability; preserves ContactsProvider.",type:"string",enum:["enabled","disabled"]},mapsApp:{description:"Android Google Maps app; external navigation intents become unavailable.",type:"string",enum:["enabled","disabled"]},videoApp:{description:"Android YouTube app; native video links become unavailable.",type:"string",enum:["enabled","disabled"]},musicApp:{description:"Android YouTube Music app; preserves shared audio playback.",type:"string",enum:["enabled","disabled"]},photosApp:{description:"Android Google Photos app; changes cloud photo sources and choosers. Preserves MediaProvider and DocumentsUI.",type:"string",enum:["enabled","disabled"]},assistantApp:{description:"Android Google Search/Assistant app, including voice and home-search integrations.",type:"string",enum:["enabled","disabled"]},digitalWellbeing:{description:"Android Digital Wellbeing usage tracking, focus, and app limits.",type:"string",enum:["enabled","disabled"]},printing:{description:"Android print spooler and print recommendations; printing becomes unavailable.",type:"string",enum:["enabled","disabled"]},accessibilityApps:{description:"Optional Android accessibility apps. Active accessibility services are protected.",type:"string",enum:["enabled","disabled"]},textToSpeech:{description:"Android Google speech synthesis; speech-dependent functionality becomes unavailable.",type:"string",enum:["enabled","disabled"]},storeApp:{description:"Android Play Store app; installation, updates, billing and licensing may fail.",type:"string",enum:["enabled","disabled"]},healthConnect:{description:"Android Health Connect controller and backup app; health integrations become unavailable.",type:"string",enum:["enabled","disabled"]},adServices:{description:"Android AdServices API package; advertising/privacy APIs may fail. Does not remove mainline/APEX infrastructure.",type:"string",enum:["enabled","disabled"]},onDevicePersonalization:{description:"Android on-device personalization service package; dependent APIs may fail.",type:"string",enum:["enabled","disabled"]},wallpaperApps:{description:"Android wallpaper picker and optional live-wallpaper apps; changes wallpaper selection. Does not disable the shared wallpaper framework or widgets.",type:"string",enum:["enabled","disabled"]},dialerApp:{description:"Optional Android dialer apps. Default role holders remain protected.",type:"string",enum:["enabled","disabled"]},messagesApp:{description:"Optional Android SMS/Messages apps. Default role holders remain protected; excludes other apps' messaging.",type:"string",enum:["enabled","disabled"]},googleServicesFramework:{description:"Android Google Services Framework; aggressive control that can break Google account and push integrations.",type:"string",enum:["enabled","disabled"]},googlePlayServices:{description:"Android Google Play services; aggressive control that breaks dependent push, authentication, location and other integrations. Keep enabled for workflows that depend on those services.",type:"string",enum:["enabled","disabled"]},icloudSync:{description:"Broad iCloud/account synchronization. Control is unsupported; use the narrower icloudSettingsSync setting.",type:"string",enum:["enabled","disabled"]}},additionalProperties:!1,minProperties:1},restore:{description:"Restore exact prior Android overrides from a returned receipt. Requires the same boot and user. Specify resources or restore, never both.",type:"object",properties:{deviceId:{type:"string"},bootId:{type:"string",format:"uuid",pattern:"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},userId:{type:"integer",minimum:0,maximum:9007199254740991},entries:{minItems:1,maxItems:100,type:"array",items:{type:"object",properties:{resource:{type:"string",enum:["wallpaperRendering","widgets","liveActivities","healthServices","homeServices","fitnessServices","familyServices","screenTime","newsServices","weatherServices","tipsServices","gameServices","mapsSync","advertising","diagnosticReporting","siriAndAppIntents","speechServices","mediaTranscoding","photoAnalysis","assistantSuggestions","appleIntelligence","searchIndexing","appStoreServices","appleMediaSync","mailServices","calendarServices","reminderServices","personalDataSync","safariSync","icloudSettingsSync","messagingMaintenance","watchConnectivity","carPlay","tvRemote","findMy","continuity","walletServices","businessServices","backgroundSync","animations","screensavers","backup","mailApp","calendarApp","contactsApp","mapsApp","videoApp","musicApp","photosApp","assistantApp","digitalWellbeing","printing","accessibilityApps","textToSpeech","storeApp","healthConnect","adServices","onDevicePersonalization","wallpaperApps","dialerApp","messagesApp","googleServicesFramework","googlePlayServices","icloudSync"]},target:{type:"string"},kind:{type:"string",enum:["package","global","secure","backup"]},value:{anyOf:[{type:"string"},{type:"null"}]}},required:["resource","target","kind","value"],additionalProperties:!1}}},required:["deviceId","bootId","userId","entries"],additionalProperties:!1},timeoutMs:{description:"Total configuration budget in milliseconds. Defaults to 300000.",type:"integer",exclusiveMinimum:0,maximum:890000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceResourceBudget":!0,"automobile/hostSideState":!0}},{name:"setDeviceState",title:"Set Device State",annotations:{destructiveHint:!0},description:"Set device state such as Do Not Disturb, Android connectivity toggles (airplaneMode, wifiEnabled, bluetoothEnabled, locationEnabled), static location or background route playback on an Android emulator, iOS Simulator, or physical iOS device (through the CtrlProxy runner), iOS Simulator biometric enrollment, and device-wide network condition. A static fix, replacement route, or stop cancels the active route. The location result may include previousRoute with endedReason and lastError; stop also reports whether a route was active. On release or rebind of a session that set a location, iOS clears it (`simctl location clear` on a Simulator, the runner on a physical device); failed clears are retried and quarantine the device until success or removal. Android emulator fixes persist after the session because the emulator console has no unset command; reset the fix explicitly if needed. Direct-mode (sessionless) calls are unchanged; an existing session marker on the device also clears later sessionless fixes on release. cameraPoster sets or clears a virtual-scene back-camera poster (image path or generated QR, wall or table surface) on a running Android emulator through the emulator console, without a restart; it persists until cleared or the AVD is cold-booted, physical iOS and physical Android return unsupported. On iOS Simulator it records the poster for the next launchApp cold launch of each app, returns relaunchRequired: true, and ignores surface; running apps must be relaunched, a console refusal (for example an AVD whose back camera is not virtualscene) is returned as an error, and the default camera pose may not face the poster. Connectivity values are desired end states and are verified by a fresh Android read; iOS connectivity writes are unsupported. Degraded network profiles (offline/veryBad/2g/3g/4g) are best-effort cellular shaping on an Android emulator, reported `partial` (they may not affect Wi-Fi/app traffic); only reset to `none` is fully verified. A session always restores the network to a clean `none` state on release/rebind. On an iOS Simulator networkCondition is per-app only: profile offline or none with appId, within a session, refuses the app's new connections through the opt-in network-extension filter under a renewed 15s lease; release, rebind, expiry or a missed renewal removes it, and other sessions cannot clear it. screenLock (Android) sets a PIN, password, or pattern with locksettings, or clears one (type none plus currentCredential); a session's own credential is cleared on its release (a failed clear is reported in the release result as screenLockRestore), an existing credential the session did not set is refused with errorCode lock_credential_preexisting, and the result reports only the type and outcome (for example set: true). The credential is redacted from logs, telemetry, and recorded plans; it is in the device's process list while locksettings runs. power (Android) fakes battery level/charger, battery saver, light or deep Doze (the tool unplugs the battery and turns the screen off first and reports those preconditions), app standby buckets and inactive state, Data Saver and thermal status, and returns a restoreReceipt of the values it replaced; a session restores them on release in reverse order and reports failures as powerRestore in the release result. Battery, Doze and thermal faking is refused on physical devices (power_physical_device_refused). Clock control supports only rootable Android emulators; Play Store images, physical devices and iOS return unsupported. Set accepts ISO-8601 instants within 2000-01-01T00:00:00Z .. 2100-01-01T00:00:00Z (inclusive); cumulative advance must stay in that window. Commands have second-level precision; advance requires integer byMs >= 1000 (maximum 315360000000), uses device read-back time, and verifies movement with a 2000ms tolerance; set within tolerance reports outcome=unchanged. On session release/rebind/teardown/reset, AutoMobile explicitly restores HOST-derived real time plus the original auto_time, even if it was 1, and verifies both. Failed restore is retried and quarantines the device until success or removal. Clock control restarts adbd on the emulator; connections such as port forwards may be re-established. Restore unroots adbd if AutoMobile rooted it (bounded, best-effort). Hierarchy/observe caches and freshness baselines are invalidated on every clock change. The restore slot is in memory only: daemon restart loses it; reset is recovery to HOST time plus auto_time=1 on a rootable emulator. Without a slot, unsupported targets report unsupported/nothing to reset without clock mutations; with a slot, refused root reports failure and retains pending restoration. Sessionless callers must reset explicitly. Session-bound and sessionless clock writes share one device queue and original ownership baseline; session release restores the device while sessionless ownership persists until reset or removal. Removal cancels clock work for that device incarnation. Changing the clock affects TLS/certificate validation, token expiry, and freshness checks.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{doNotDisturb:{description:"Do Not Disturb state to apply.",type:"object",properties:{enabled:{description:"Enable or disable Do Not Disturb",type:"boolean"},mode:{description:"Do Not Disturb mode",type:"string",enum:["off","none","priority","alarms"]}},additionalProperties:!1},biometrics:{description:"iOS Simulator biometric enrollment state to apply.",type:"object",properties:{enrollment:{description:"Set iOS Simulator biometric enrollment state.",type:"string",enum:["enrolled","not_enrolled"]}},required:["enrollment"],additionalProperties:!1},connectivity:{description:"Android connectivity toggles to apply.",type:"object",properties:{airplaneMode:{description:"Enable or disable Airplane mode on Android.",type:"boolean"},wifiEnabled:{description:"Enable or disable Wi-Fi on Android.",type:"boolean"},bluetoothEnabled:{description:"Enable or disable Bluetooth on Android.",type:"boolean"},locationEnabled:{description:"Enable or disable Location on Android.",type:"boolean"}},additionalProperties:!1},networkCondition:{description:"Network condition to apply: device-wide on an Android emulator, or offline/none for one app (appId) on an iOS Simulator.",type:"object",properties:{profile:{description:"Device-wide network profile. Documented values: none=unshaped, offline=no data, veryBad\u2248GSM (550ms/14kbps), 2g\u2248EDGE (400ms/237kbps), 3g\u2248UMTS (200ms/1920kbps), 4g\u2248LTE. Degraded profiles are best-effort cellular shaping, reported `partial`, on Android emulators. iOS Simulator accepts only offline and none, for one app named by appId.",type:"string",enum:["none","offline","veryBad","2g","3g","4g"]},appId:{description:"iOS Simulator only, and required there: bundle id of the one app to take offline (profile=offline) or restore (profile=none). Its new connections are refused through AutoMobile's network filter; open connections continue. Needs a session.",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},cancel:{description:"Reset to normal connectivity (same as profile=none).",type:"boolean"},reset:{description:"Alias of cancel.",type:"boolean"},delayMs:{description:"Override added latency in milliseconds.",type:"number",minimum:0},downloadKbps:{description:"Override download cap in kbps (0=unlimited).",type:"number",minimum:0},uploadKbps:{description:"Override upload cap in kbps (0=unlimited).",type:"number",minimum:0},packetLossPercent:{description:"Documented target packet loss; the emulator console cannot enforce partial loss.",type:"number",minimum:0,maximum:100},expiresInSeconds:{description:"TTL in seconds. When set on a degrading request, a timer resets the device to normal connectivity after it elapses, independent of session lifetime; session release/expiry also restores connectivity, whichever comes first. Capped at 2147483s (~24.8 days) to fit the timer's 32-bit limit.",type:"number",minimum:0,maximum:2147483}},additionalProperties:!1,anyOf:[{required:["profile"]},{required:["cancel"],properties:{cancel:{const:!0}}},{required:["reset"],properties:{reset:{const:!0}}},{required:["delayMs"],properties:{delayMs:{}}},{required:["downloadKbps"],properties:{downloadKbps:{}}},{required:["uploadKbps"],properties:{uploadKbps:{}}},{required:["packetLossPercent"],properties:{packetLossPercent:{}}}]},clock:{description:"Set the real clock within 2000-01-01T00:00:00Z .. 2100-01-01T00:00:00Z, advance by integer byMs >= 1000 with second-level precision, or reset to host time and original auto_time (1 without a recorded slot). Rootable Android emulators only.",anyOf:[{type:"object",properties:{mode:{type:"string",const:"set"},instant:{type:"string",format:"date-time",pattern:"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-]\\d{2}:\\d{2})))$"}},required:["mode","instant"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"advance"},byMs:{type:"integer",minimum:1000,maximum:315360000000}},required:["mode","byMs"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"reset"}},required:["mode"],additionalProperties:!1}]},location:{description:"Set a static fix, start a timed route, or stop route playback on an Android emulator or iOS Simulator.",anyOf:[{type:"object",properties:{mode:{description:"Apply one static coordinate.",type:"string",const:"static"},latitude:{type:"number",minimum:-90,maximum:90},longitude:{type:"number",minimum:-180,maximum:180}},required:["mode","latitude","longitude"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"route"},waypoints:{minItems:2,type:"array",items:{type:"object",properties:{latitude:{type:"number",minimum:-90,maximum:90},longitude:{type:"number",minimum:-180,maximum:180},altitude:{type:"number"}},required:["latitude","longitude"],additionalProperties:!1}},loop:{type:"boolean"},updateIntervalMs:{type:"integer",minimum:200,maximum:60000},speedMetersPerSecond:{type:"number",exclusiveMinimum:0}},required:["mode","waypoints","speedMetersPerSecond"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"route"},waypoints:{minItems:2,type:"array",items:{type:"object",properties:{latitude:{type:"number",minimum:-90,maximum:90},longitude:{type:"number",minimum:-180,maximum:180},altitude:{type:"number"}},required:["latitude","longitude"],additionalProperties:!1}},loop:{type:"boolean"},updateIntervalMs:{type:"integer",minimum:200,maximum:60000},durationMs:{type:"number",exclusiveMinimum:0}},required:["mode","waypoints","durationMs"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"stop"}},required:["mode"],additionalProperties:!1}]},cameraPoster:{description:"Set (mode image or qr) or clear a virtual-scene back-camera poster on a RUNNING Android emulator via the emulator console, with no restart. surface defaults to wall. The AVD back camera must be virtualscene (see startDevice cameraPosterPath/cameraPosterQr). The console cannot confirm the poster is visible; the default camera pose may not face it. On iOS Simulator, records the image or generated QR for each app next launched with launchApp (cold launch), returning relaunchRequired: true. Running apps must be relaunched; surface is accepted and ignored. Physical iOS is unsupported.",anyOf:[{type:"object",properties:{mode:{type:"string",const:"image"},path:{description:"Host PNG/JPG/JPEG path; must not contain whitespace.",type:"string",minLength:1},surface:{type:"string",enum:["wall","table"]}},required:["mode","path"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"qr"},text:{description:"Payload encoded into a generated QR poster.",type:"string",minLength:1},surface:{type:"string",enum:["wall","table"]}},required:["mode","text"],additionalProperties:!1},{type:"object",properties:{mode:{type:"string",const:"clear"},surface:{type:"string",enum:["wall","table"]}},required:["mode"],additionalProperties:!1}]},screenLock:{description:"Android only. Set a secure lock-screen credential (type pin, password, or pattern as digits 1-9) with locksettings, or clear one with type none and currentCredential. A session clears the credential it set on release and reports a failed clear in the release result (screenLockRestore); a sessionless set is never cleared automatically. An existing credential this session did not set is never overwritten (errorCode lock_credential_preexisting). The credential is redacted from logs, telemetry and recorded plans, and never returned.",anyOf:[{type:"object",properties:{type:{type:"string",const:"pin"},credential:{type:"string",pattern:"^\\d{4,16}$"}},required:["type","credential"],additionalProperties:!1},{type:"object",properties:{type:{type:"string",const:"password"},credential:{type:"string",pattern:"^(?!-)[\\x20-\\x26\\x28-\\x7e]{4,16}$"}},required:["type","credential"],additionalProperties:!1},{type:"object",properties:{type:{type:"string",const:"pattern"},credential:{type:"string",pattern:"^[1-9]{4,9}$"}},required:["type","credential"],additionalProperties:!1},{type:"object",properties:{type:{type:"string",const:"none"},currentCredential:{type:"string",pattern:"^(?!-)[\\x20-\\x26\\x28-\\x7e]{4,16}$"}},required:["type","currentCredential"],additionalProperties:!1}]},power:{description:"Android only. Fake power constraints: battery {level 0-100, charging ac|usb|wireless|none, reset}, batterySaver, doze off|light|deep (light/deep unplug the battery and turn the screen off first and report these as preconditions), standbyBucket {appId, bucket}, appInactive {appId, inactive}, dataSaver and thermalStatus 0-6 or reset. Battery, Doze and thermal faking is refused on physical devices (errorCode power_physical_device_refused); thermal override needs API 29+ and the restricted bucket API 30+ (errorCode power_unsupported_api_level). The result carries a restoreReceipt; a session restores every changed field in reverse order on release and reports failures in the release result (powerRestore). A sessionless change is never restored automatically.",type:"object",properties:{battery:{type:"object",properties:{level:{description:"Fake battery level, 0-100.",type:"integer",minimum:0,maximum:100},charging:{description:"Fake charger source: ac, usb, wireless, or none (unplugged).",type:"string",enum:["ac","usb","wireless","none"]},reset:{description:"true: return the battery to real values (`dumpsys battery reset`).",type:"boolean"}},additionalProperties:!1},batterySaver:{description:"Turn battery saver on or off.",type:"boolean"},doze:{description:"Force light or deep Doze, or leave it (off). light/deep unplug the battery and turn the screen off first.",type:"string",enum:["off","light","deep"]},standbyBucket:{description:"Put an app in an App Standby bucket (restricted needs API 30+).",type:"object",properties:{appId:{type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},bucket:{type:"string",enum:["active","working_set","frequent","rare","restricted"]}},required:["appId","bucket"],additionalProperties:!1},appInactive:{description:"Mark an app inactive (idle) or active.",type:"object",properties:{appId:{type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},inactive:{type:"boolean"}},required:["appId","inactive"],additionalProperties:!1},dataSaver:{description:"Turn Data Saver (restrict background data) on or off.",type:"boolean"},thermalStatus:{description:"Override the thermal status 0 (none) to 6 (shutdown), or reset it (API 29+).",anyOf:[{type:"number",const:0},{type:"number",const:1},{type:"number",const:2},{type:"number",const:3},{type:"number",const:4},{type:"number",const:5},{type:"number",const:6},{type:"string",const:"reset"}]}},additionalProperties:!1},deviceCondition:{description:"Session-scoped root/integrity/fault test fixtures (behind the 'device-condition' feature flag). Every applied condition restores to a clean state on release, rebind or lease expiry. Send it in its own call, not combined with other setDeviceState fields.",type:"object",properties:{exportAttestation:{type:"boolean",const:!0,description:"Export public Android KeyStore attestation certificates and parsed fields for a test backend. Send alone; temporary key is deleted. No trust verdict."},version:{type:"number",const:1,description:"Request shape version; only 1 exists."},rootState:{type:"string",enum:["rooted-detectable","unset"],description:"Root fixture: 'rooted-detectable' plants inert su/busybox stubs and sets SELinux permissive so root-detection checks trip (Android, non-Play image, needs a writable /system); 'unset' restores."},integrityState:{anyOf:[{type:"string",enum:["maximally-detectable","minimally-detectable","unset"]},{type:"object",properties:{preset:{type:"string",enum:["maximally-detectable","minimally-detectable"]},signals:{type:"object",properties:{"su-binary":{type:"string",enum:["on","off"]},"superuser-apk":{type:"string",enum:["on","off"]},"selinux-permissive":{type:"string",enum:["on","off"]},"debuggable-build":{type:"string",enum:["on","off"]},"insecure-build":{type:"string",enum:["on","off"]},"test-keys":{type:"string",enum:["on","off"]},"missing-otacerts":{type:"string",enum:["on","off"]},"qemu-props":{type:"string",enum:["on","off"]},"emulator-hardware":{type:"string",enum:["on","off"]},"qemu-pipe":{type:"string",enum:["on","off"]},"emulator-build-fields":{type:"string",enum:["on","off"]}},additionalProperties:!1}},additionalProperties:!1}],description:"Integrity signals (Android): maximally-detectable enables su-binary, superuser-apk and selinux-permissive; minimally-detectable disables them. Or { preset?, signals?: { <signal-id>: 'on' | 'off' } }, with at least one field and signals overriding the preset. Needs root and writable /system for files. Image-fixed signals and missing-otacerts report unsupported. Results include per-signal status and post-apply active readings. 'unset' restores prior state; existing image/rootState files are never removed."},statusBar:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{time:{type:"string",minLength:1,maxLength:32},batteryLevel:{type:"integer",minimum:0,maximum:100},batteryState:{type:"string",enum:["charging","charged","discharging"]},cellularBars:{type:"integer",minimum:0,maximum:4},wifiBars:{type:"integer",minimum:0,maximum:3},dataNetwork:{type:"string",enum:["wifi","5g","lte","4g","3g","hide"]},operatorName:{type:"string",maxLength:64}},additionalProperties:!1}],description:"Override the status bar ({ time?, batteryLevel?, batteryState?, cellularBars?, wifiBars?, dataNetwork?, operatorName? }, at least one). iOS Simulator only so far; reset clears every override. Or unset."},privacy:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{appId:{type:"string",pattern:"^[A-Za-z0-9._-]+$",minLength:1,maxLength:256},service:{type:"string",enum:["calendar","contacts-limited","contacts","location","location-always","photos-add","photos","media-library","microphone","motion","reminders","siri"]},action:{type:"string",enum:["grant","revoke"]}},required:["appId","service","action"],additionalProperties:!1}],description:"Grant or revoke one privacy service for an installed app ({ appId, service, action }). iOS Simulator only so far; reset restores the app's earlier decisions for that service and its pair (photos/photos-add, location/location-always, contacts/contacts-limited): granted, denied, or not yet asked. Refused when that decision cannot be restored, such as limited Photos access. Or unset."},location:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{latitude:{type:"number",minimum:-90,maximum:90},longitude:{type:"number",minimum:-180,maximum:180}},required:["latitude","longitude"],additionalProperties:!1}],description:"Simulate the device location ({ latitude, longitude }). iOS Simulator only so far; reset clears the simulated location. Or unset."},faults:{type:"object",properties:{battery:{type:"string",enum:["unplug","low","full","unset"],description:"Battery fault via `dumpsys battery` (unplug / low 15% / full), or unset."},memoryPressure:{type:"string",enum:["on","unset"],description:"Hold anonymous memory until Android lmkd kills background apps. Unsupported if no kill follows. Uses a local build or AUTOMOBILE_LMK_PRESSURE_DIR, else downloads the checksum-verified release binary; reset stops the payload and removes its files. Or unset."},lowPower:{type:"string",enum:["on","unset"],description:"Toggle `settings global low_power`, restored to its prior value, or unset."},doze:{type:"string",enum:["on","unset"],description:"Force deep Doze via `dumpsys deviceidle force-idle`, or unset."},thermal:{type:"string",enum:["throttling","critical","unset"],description:"Override thermal status via `cmd thermalservice override-status`, or unset."},dontKeepActivities:{type:"string",enum:["on","unset"],description:"Developer options 'Don't keep activities' via `settings global always_finish_activities`, restored to its prior value, or unset. Applies to activities left after the change."},readOnlyFilesystem:{type:"string",enum:["on","unset"],description:"Make shared external storage /sdcard read-only for every app (device-wide EROFS). Rootable Android emulators only; reset restores writes. Or unset."},storage:{type:"string",enum:["low","full","unset"],description:"Use up free space on /data with a ballast file (`fallocate`): 'low' leaves about 128 MiB, 'full' about 8 MiB. Reset deletes the ballast. Or unset."},corruptAppFile:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{package:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"},path:{type:"string",pattern:"^(?!\\.{1,2}(?:\\/|$))[A-Za-z0-9_.-]+(?:\\/(?!\\.{1,2}(?:\\/|$))[A-Za-z0-9_.-]+)*$"},mode:{type:"string",enum:["overwrite","truncate"]}},required:["package","path","mode"],additionalProperties:!1}],description:"Damage one file in a debuggable app's data directory ({ package, path, mode }), e.g. a SQLite database or SharedPreferences XML. 'overwrite' zeroes its first 256 bytes, 'truncate' cuts it in half. Needs a debuggable app (run-as), force-stops the app, and keeps a copy that reset restores and verifies by checksum. Or unset."},revokePermission:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{package:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"},permission:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_.]*$"}},required:["package","permission"],additionalProperties:!1}],description:"Revoke one runtime permission from an installed app with `pm revoke` ({ package, permission }); reset re-grants it. Revoking kills the app's process, so it also restarts the app. Or unset."},lockScreen:{type:"string",enum:["pin","none","unset"],description:"Sets an AutoMobile test PIN, or removes the PIN; reset restores no lock screen. Keys bound to the lock screen are invalidated by a removal. 'unset' restores."},biometricEnrollment:{type:"string",enum:["add","none","unset"],description:"Android emulators only: 'add' enrolls one more fingerprint through Settings and the emulator console (`adb emu finger touch`), which invalidates keys created with setInvalidatedByBiometricEnrollment(true). The first add needs a device with no lock screen and sets the AutoMobile test PIN. 'none' removes every fingerprint by clearing that PIN. Reset or 'unset' restores no lock screen and no fingerprints. Refused on physical devices and when the console is unavailable."},disablePackage:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{package:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"}},required:["package"],additionalProperties:!1}],description:"Disable an installed app for the current user with `pm disable-user` ({ package }); reset runs `pm enable`. Or unset."},killApp:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{package:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"},mode:{type:"string",enum:["background","forceStop"]}},required:["package","mode"],additionalProperties:!1}],description:"End an app's process once ({ package, mode }): 'background' is `am kill`, which only ends a process the system could reclaim and leaves the foreground app running; 'forceStop' is `am force-stop`, the user's Force stop. Nothing to reset; 'unset' is a no-op."},trimMemory:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{package:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"},level:{type:"string",enum:["HIDDEN","RUNNING_MODERATE","BACKGROUND","RUNNING_LOW","MODERATE","RUNNING_CRITICAL","COMPLETE"]}},required:["package","level"],additionalProperties:!1}],description:"Send a running app an onTrimMemory level once ({ package, level }) with `am send-trim-memory`. The app must be running; a foreground app must get a RUNNING_* level (RUNNING_MODERATE, RUNNING_LOW, RUNNING_CRITICAL) because Android refuses HIDDEN, BACKGROUND, MODERATE and COMPLETE for a foreground app. Nothing to reset; 'unset' is a no-op."},clearPackageData:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{package:{type:"string",pattern:"^[A-Za-z][A-Za-z0-9_]*(\\.[A-Za-z][A-Za-z0-9_]*)+$"}},required:["package"],additionalProperties:!1}],description:"Clear an installed app's data with `pm clear` ({ package }). One-shot: it kills the app's process and cannot be undone, so there is nothing to reset. 'unset' is a no-op."},clockSkew:{anyOf:[{type:"string",const:"unset"},{type:"object",properties:{offsetSeconds:{type:"integer",minimum:-315360000,maximum:315360000}},required:["offsetSeconds"],additionalProperties:!1}],description:"Set the device clock offsetSeconds ahead of (positive) or behind (negative) real time ({ offsetSeconds }), 3 seconds to 10 years either way, with automatic time off. Reset restores real time and the original automatic-time setting and verifies them. Rootable Android emulators only (needs adb root, which restarts adbd). Shares the device clock with setDeviceState.clock: a reset from either restores real time. Or unset."}},additionalProperties:!1,description:"Power and lifecycle fault injectors (Android only, behind the feature flag)."},vehicle:{type:"object",properties:{motion:{type:"string",enum:["parked","driving","unset"],description:"Vehicle motion on an Android Automotive emulator: 'parked' (gear park, speed 0, parking brake on) or 'driving' (gear drive, moving, brake off), set together so the state is consistent. Restored to the values read before the first change; or unset."},nightMode:{type:"string",enum:["on","off","unset"],description:"Vehicle night-mode signal on an Android Automotive emulator: 'on' or 'off' sets the signal; unset or reset returns day/night to automatic sensor control without preserving a prior manual override."}},additionalProperties:!1,description:"Vehicle state (Android Automotive emulators only; 'unsupported' elsewhere), via `cmd car_service inject-vhal-event`."},expiresInSeconds:{type:"integer",minimum:1,maximum:86400,description:"Lease: restore every applied condition after this many seconds unless a later deviceCondition call renews it. Session-bound calls only."},reset:{type:"boolean",const:!0,description:"Restore every condition applied on this device and verify a clean read."}},additionalProperties:!1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"setKeyValue",title:"Set Key Value",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Set app key-value storage entry.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},name:{description:`Storage name. iOS: empty string, "standard" (any case) or the app bundle id select the app's standard UserDefaults; any other value is a UserDefaults suite name (e.g. an app group) and must be a valid suite with no leading or trailing whitespace. Android: SharedPreferences file name without the .xml extension (letters, digits, underscore, dash, dot).`,type:"string"},fileName:{description:"Deprecated alias for name",type:"string"},key:{description:"Key",type:"string"},value:{description:"Value; null clears",anyOf:[{anyOf:[{type:"string"},{type:"number"},{type:"boolean"}]},{type:"null"}]},type:{description:"Value type",type:"string",enum:["STRING","INT","LONG","FLOAT","DOUBLE","BOOLEAN","STRING_SET","DATA","DATE","ARRAY","DICTIONARY","UNKNOWN"]},userId:{description:"Android only: user whose copy of the app the direct-file (run-as) fallback edits (e.g. a work profile). Defaults to user 0 when the app is installed for it; otherwise to the one other running user that has it (an error asks for userId if several do). The SDK route is not user-scoped.",type:"integer",minimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","key","value","type"],additionalProperties:!1,description:"Provide either `name` (iOS UserDefaults suite / Android SharedPreferences name) or `fileName`"},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"setNotificationPolicy",title:"Set Notification Policy",annotations:{destructiveHint:!1,idempotentHint:!0},description:"Set app notification/DND policy state",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},policyAccess:{description:"Android: allow DND policy access",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId","policyAccess"],additionalProperties:!1}},{name:"setPosture",title:"Set Posture",annotations:{destructiveHint:!1,idempotentHint:!0},description:"Set Android device posture or iPhone Duo simulator posture, with an optional Resizable Android display preset. Specify exactly one of posture or hingeAngle (finite degrees, 0-180 inclusive). Hinge angle is BEST EFFORT, emulator/simulator only, without displayPreset; unsupported returns status: unsupported with a reason and no state change. Android console support is detected at call time; iOS requires a runner advertising set_hinge_angle (#8547). Angle results echo hingeAngle and device posture read-back, or unknown with postureReason. Android strictly parses emu sensor get hinge-angle0 output as hinge-angle0 = <n>, reports it as observedHingeAngle, and warns without failing when it is unavailable or differs by more than 1 degree. iOS cannot read the hinge, so it omits observedHingeAngle; posture comes from the active panel (cover=closed, inner=half_opened between 0 and 180 degrees, otherwise opened, including inner at 0 with a warning), and a warning with a next step is added when the panel contradicts the angle (cover above 90 degrees, inner at 0).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{posture:{type:"string",enum:["closed","half_opened","opened","rear_display","flipped","tent"]},hingeAngle:{description:"Best effort hinge angle in degrees, 0-180 inclusive; specify exactly one of posture or hingeAngle. Emulator/simulator only; no displayPreset.",type:"number",minimum:0,maximum:180},displayPreset:{type:"string",enum:["phone","unfolded","tablet"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"setPreference",title:"Set Preference",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Write an Android system property, Android SharedPreferences key, or iOS UserDefaults key and return read-back verification. On iOS, appId is required and the store selector is suite (not name or fileName as on setKeyValue); omit suite or use Standard for the default store. Uses an already connected embedded AutoMobile SDK with storage inspection enabled; storage access itself never starts a runner. Reads can fall back to the simulator data container's on-disk plist, which may lag the running app. Writes use the container only when no SDK connection is open before sending; SDK write failures never trigger a second write. App-group suites require the connected SDK.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{scope:{description:"Preference scope",type:"string",enum:["systemProperty","sharedPreferences","userDefaults"]},appId:{description:"App package or bundle id",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},suite:{description:"SharedPreferences file name or UserDefaults suite/app group",type:"string",pattern:"^(?:\\s*|[A-Za-z0-9_-]+(?:\\.[A-Za-z0-9_-]+)*)$"},key:{description:"Preference key or Android system property name",type:"string",minLength:1},userId:{description:"Android sharedPreferences only: user whose copy of the app to read/write (e.g. a work profile). Defaults to user 0 when the app is installed for it; otherwise to the one other running user that has it (an error asks for userId if several do). The result reports the userId used.",type:"integer",minimum:0,maximum:9007199254740991},value:{description:"Value to write",anyOf:[{type:"string"},{type:"boolean"},{type:"number"}]},type:{description:"Value type for typed preference stores",type:"string",enum:["string","bool","int","float"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["scope","key","value","type"],additionalProperties:!1}},{name:"setSensor",title:"Set Emulator Sensor",annotations:{destructiveHint:!0,idempotentHint:!0},description:'Set or reset one Android emulator virtual sensor (acceleration, gyroscope, magnetic-field, orientation, temperature, proximity, light, pressure, humidity) through the emulator console. Pass exactly one of value or reset: true. The result reports applied and previous values plus a restore receipt. The value read before the first change is kept; in a daemon session, release or rebind restores every sensor the session changed. Sessionless changes persist until reset. Physical devices and iOS are refused. Read current values with getDeviceState include: ["sensors"].',inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{sensor:{description:"Emulator sensor. Three values (x:y:z): acceleration m/s\xB2 \xB11000, gyroscope rad/s \xB1100, magnetic-field \xB5T \xB12000; orientation azimuth 0..360, pitch -180..180, roll -90..90 degrees. One value: temperature \xB0C -273.15..1000, proximity cm 0..100, light lux 0..200000, pressure hPa 0..2000, humidity % 0..100.",type:"string",enum:["acceleration","gyroscope","magnetic-field","orientation","temperature","proximity","light","pressure","humidity"]},value:{description:"Value(s) to set, in the sensor's arity and range; rounded to 6 decimals.",minItems:1,maxItems:3,type:"array",items:{type:"number"}},reset:{description:"true restores the value read before the first setSensor change; use instead of value.",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["sensor"],additionalProperties:!1}},{name:"setToolEnabled",title:"Set Tool Discovery",annotations:{destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},description:"Control tools/list discovery for this MCP session: one exact name via toolName, or a batch via toolNames. Omitted tools remain callable directly by name through tools/call, including default-off tools such as pinchOn and prototype that tools/list never shows until enabled; read the automobile:tools resource for every tool's name and default discovery state. Returns enabledTools, or enabledToolsError if post-write readback fails (the change still applies).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",description:"Control which configurable AutoMobile tools appear in tools/list for an active session. A tool omitted from discovery remains callable directly by name through tools/call.",type:"object",properties:{toolName:{description:"Exact case-sensitive AutoMobile tool name to show or omit in tools/list. Omitted tools remain callable directly by name. Provide either toolName or toolNames.",type:"string",minLength:1,enum:["accessibility","accessibilityAction","accessibilityAudit","accessibilityFocus","ambient","appLifecycle","audit","backgroundWork","biometricAuth","captureAudio","captureTrace","changeLocalization","clearKeyValueFile","clearMockNetwork","clipboard","compareScreenshot","crashApp","deleteDevice","deleteKeychainItem","deviceSnapshot","displayConfig","displayProfile","dragAndDrop","dragPath","executePlan","explore","exportPlan","exportPrototypeWeb","focusNavigate","getAppPermissions","getDataStore","getDeepLinks","getDeviceState","getIosSimulatorCapabilities","getLogs","getNavigationGraph","getNetworkGraph","getNotificationPolicy","getPreference","glassesInput","heapDump","highlight","hitTest","homeScreen","hoverAt","identifyInteractions","injectAudioInput","inspectPackageSigning","installApp","keyboard","killDevice","killProfile","launchApp","listApps","listDataStores","listDeviceImages","listDevices","manufacturerProfile","measureStartup","mediaSession","mockNetwork","multiTouch","navigateTo","network","observe","openLink","performanceAudit","performanceTrace","phoneCall","pinchOn","portReverse","postNotification","pressButton","prototype","provisionDevice","putAppFile","recentApps","reconcileDeviceResources","recordDeviceGestures","recordToolCalls","removeKeyValue","resetAppLogs","resetKeychain","rotaryScroll","rotate","rotateCrown","seedContent","selectAllText","sendBroadcast","sendKeys","sendSms","setActiveDevice","setAppLinks","setAppPermissions","setDeviceResources","setDeviceState","setKeyValue","setNotificationPolicy","setPosture","setPreference","setSensor","setUIState","shake","siri","snapshotOf","sqlQuery","statusBar","stopAudioInput","swipeAt","swipeOn","systemAlerts","systemTray","tapAny","tapAt","tapOn","terminateApp","uninstallApp","videoRecording","wakeAndUnlock","wearSurface","windowMode"]},toolNames:{description:"Exact case-sensitive AutoMobile tool names to show or omit in tools/list in ONE call. Omitted tools remain callable directly by name. Unknown or hidden names reject the whole request before anything is written; always-on names are returned in skipped. Provide either toolName or toolNames.",minItems:1,type:"array",items:{type:"string",minLength:1,enum:["accessibility","accessibilityAction","accessibilityAudit","accessibilityFocus","ambient","appLifecycle","audit","backgroundWork","biometricAuth","captureAudio","captureTrace","changeLocalization","clearKeyValueFile","clearMockNetwork","clipboard","compareScreenshot","crashApp","deleteDevice","deleteKeychainItem","deviceSnapshot","displayConfig","displayProfile","dragAndDrop","dragPath","executePlan","explore","exportPlan","exportPrototypeWeb","focusNavigate","getAppPermissions","getDataStore","getDeepLinks","getDeviceState","getIosSimulatorCapabilities","getLogs","getNavigationGraph","getNetworkGraph","getNotificationPolicy","getPreference","glassesInput","heapDump","highlight","hitTest","homeScreen","hoverAt","identifyInteractions","injectAudioInput","inspectPackageSigning","installApp","keyboard","killDevice","killProfile","launchApp","listApps","listDataStores","listDeviceImages","listDevices","manufacturerProfile","measureStartup","mediaSession","mockNetwork","multiTouch","navigateTo","network","observe","openLink","performanceAudit","performanceTrace","phoneCall","pinchOn","portReverse","postNotification","pressButton","prototype","provisionDevice","putAppFile","recentApps","reconcileDeviceResources","recordDeviceGestures","recordToolCalls","removeKeyValue","resetAppLogs","resetKeychain","rotaryScroll","rotate","rotateCrown","seedContent","selectAllText","sendBroadcast","sendKeys","sendSms","setActiveDevice","setAppLinks","setAppPermissions","setDeviceResources","setDeviceState","setKeyValue","setNotificationPolicy","setPosture","setPreference","setSensor","setUIState","shake","siri","snapshotOf","sqlQuery","statusBar","stopAudioInput","swipeAt","swipeOn","systemAlerts","systemTray","tapAny","tapAt","tapOn","terminateApp","uninstallApp","videoRecording","wakeAndUnlock","wearSurface","windowMode"]}},enabled:{description:"Whether to show the tools in tools/list (default: true).",default:!0,type:"boolean"},sessionUuid:{description:"Active connection or routing-session profile to update. Omit to update this MCP connection's profile.",type:"string",minLength:1}},additionalProperties:!1}},{name:"setUIState",title:"Set Form State",annotations:{destructiveHint:!0},description:"Set multiple form fields by desired state.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{fields:{description:"Fields to set",minItems:1,type:"array",items:{type:"object",properties:{selector:{description:"Field selector",type:"object",properties:{elementId:{description:"Resource ID, e.g. com.app:id/btn_login",type:"string"},text:{description:"Text, content-desc, or placeholder",type:"string"}},additionalProperties:!1},value:{description:"Text/dropdown value",type:"string"},selected:{description:"Checkbox/toggle state",type:"boolean"}},required:["selector"],additionalProperties:!1}},scrollDirection:{description:"Initial search scroll direction",type:"string",enum:["up","down"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["fields"],additionalProperties:!1},_meta:{"automobile/debugOnly":!0}},{name:"shake",title:"Shake",annotations:{destructiveHint:!1},description:"Shake device; iOS Simulator and Android emulator only (unsupported on physical iOS and Android devices).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{duration:{description:"Shake duration ms (1-1798000, default 1000)",type:"integer",minimum:1,maximum:1798000},intensity:{description:"Shake intensity on Android (1-1000, default 100); ignored on iOS",type:"number",minimum:1,maximum:1000},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"siri",title:"Activate Siri",annotations:{destructiveHint:!0},description:"iOS: activate Siri with a spoken phrase (XCUIDevice.siriService), e.g. to invoke an App Shortcut / App Intent, then return the observation. Android returns unsupported.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{phrase:{description:'What the user would say to Siri, e.g. an App Shortcut phrase "Show my orders in Playground"',type:"string",minLength:1,maxLength:500,pattern:"^[^\\u0000-\\u001f\\u007f]+$"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["phrase"],additionalProperties:!1}},{name:"snapshotOf",title:"Capture Snapshot",annotations:{readOnlyHint:!0},description:"Save a PNG crop of one exposed element or a platform-native screen rectangle; return path and geometry metadata only.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{platform:{type:"string",enum:["android","ios","tvos","visionos"]},elementId:{description:"Unique exposed element ID",type:"string",minLength:1},rectangle:{description:"Platform-native screen rectangle: Android pixels, iOS points",type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1},_meta:{"automobile/deviceReadOnly":!0}},{name:"sqlQuery",title:"Query Database",annotations:{destructiveHint:!0},description:"Execute SQL on an app SQLite database, or read a registered Core Data entity on iOS using store and entity.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},databasePath:{description:"Absolute path under the app data directory, or on Android a bare file name in the app databases directory; omit when store and entity are supplied",type:"string"},query:{description:"SQL query; omit when store and entity are supplied",type:"string"},store:{description:"Registered Core Data store identifier on iOS; supply with entity instead of databasePath and query",type:"string",minLength:1},entity:{description:"Registered Core Data entity to fetch on iOS; requires store",type:"string",minLength:1},limit:{description:"Maximum Core Data rows; only with store and entity, clamped to the host row limit",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId"],additionalProperties:!1},_meta:{"automobile/embeddedSdkOnly":!0}},{name:"statusBar",title:"Set Status Bar",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Deterministic status bar for screenshots and video: override time, battery, signal, data network and carrier (iOS Simulator simctl status_bar, Android SystemUI demo mode), clear it, or read it. A session's override is cleared when the session releases the device.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"override: set the given fields; clear: restore the live status bar; get: read",type:"string",enum:["override","clear","get"]},time:{description:'Clock text, e.g. "9:41" (Android demo mode needs H:MM or HH:MM)',type:"string",minLength:1},batteryLevel:{description:"Battery percent 0-100",type:"integer",minimum:0,maximum:100},batteryState:{type:"string",enum:["charging","charged","discharging"]},cellularBars:{description:"Cellular bars 0-4",type:"integer",minimum:0,maximum:4},wifiBars:{description:"Wi-Fi bars 0-3",type:"integer",minimum:0,maximum:3},dataNetwork:{type:"string",enum:["wifi","5g","lte","4g","3g","hide"]},operatorName:{description:"Carrier name (iOS Simulator only)",type:"string"},hideNotifications:{description:"Hide notification icons (Android only)",type:"boolean"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["get"]}]}},{name:"stopAudioInput",title:"Stop Emulator Microphone Audio",annotations:{destructiveHint:!1,idempotentHint:!0},description:"Stop an audio injection started by injectAudioInput, on the device it runs on. Idempotent: an injection that already ended returns its result (frames sent and why it ended); the last 64 ended injections are kept. [audio_emulator_exited] means the emulator exited during injection; restart it before starting another injection.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{injectionId:{description:"The id injectAudioInput returned.",type:"string",minLength:1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["injectionId"],additionalProperties:!1}},{name:"swipeAt",title:"Swipe at Coordinates",annotations:{destructiveHint:!0},description:"Swipe from one screen point to another, including diagonals, in native, normalized, or percent units.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{snapshotId:{description:"Short-lived reference from observe.snapshotReference; reject stale geometry or frame context",type:"string",minLength:1},from:{description:"Where the finger goes down, in the selected coordinateSpace; required with to unless image is given",type:"object",properties:{x:{description:"Screen x coordinate in the selected coordinateSpace",type:"number"},y:{description:"Screen y coordinate in the selected coordinateSpace",type:"number"}},required:["x","y"],additionalProperties:!1},to:{description:"Where the finger lifts, in the selected coordinateSpace; required with from unless image is given",type:"object",properties:{x:{description:"Screen x coordinate in the selected coordinateSpace",type:"number"},y:{description:"Screen y coordinate in the selected coordinateSpace",type:"number"}},required:["x","y"],additionalProperties:!1},coordinateSpace:{description:"Coordinate units for from/to: native absolute (default), normalized 0\u20131, or percent 0\u2013100",type:"string",enum:["absolute","normalized","percent"]},image:{description:"Screenshot-relative from/to points sharing one image source; mutually exclusive with outer from, to, and coordinateSpace. Without image, from and to are required.",type:"object",properties:{unit:{description:"Use normalized image fractions (preferred); pixels means the real file raster, never a resized preview",type:"string",enum:["normalized","pixels"]},source:{anyOf:[{type:"object",properties:{crop:{description:"Pass the whole observe.crop object from the referenced image",type:"object",properties:{cropPath:{type:"string"},unit:{type:"string",enum:["pixels","points"]},requestedBounds:{type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},clippedBounds:{type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},clipped:{type:"boolean"},screenSize:{type:"object",properties:{width:{type:"number",exclusiveMinimum:0},height:{type:"number",exclusiveMinimum:0}},required:["width","height"],additionalProperties:!1},imageSize:{type:"object",properties:{width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["width","height"],additionalProperties:!1},pixelsPerNativeUnit:{type:"object",properties:{x:{type:"number",exclusiveMinimum:0},y:{type:"number",exclusiveMinimum:0}},required:["x","y"],additionalProperties:!1},scaleProvenance:{type:"string",enum:["raster-dimensions","native-scale-confirmed"]},rasterBounds:{type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},screenshotOrientation:{type:"string",enum:["display","native"]}},required:["unit","requestedBounds","clippedBounds","clipped","screenSize","imageSize","pixelsPerNativeUnit","scaleProvenance","rasterBounds","screenshotOrientation"],additionalProperties:!1},rotation:{description:"observe.rotation; required for native screenshot orientation",anyOf:[{type:"number",const:0},{type:"number",const:1},{type:"number",const:2},{type:"number",const:3}]}},required:["crop"],additionalProperties:!1},{type:"object",properties:{screenshot:{type:"object",properties:{screenSize:{type:"object",properties:{width:{type:"number",exclusiveMinimum:0},height:{type:"number",exclusiveMinimum:0}},required:["width","height"],additionalProperties:!1},screenshotOrientation:{type:"string",enum:["display","native"]},rotation:{anyOf:[{type:"number",const:0},{type:"number",const:1},{type:"number",const:2},{type:"number",const:3}]},imageSize:{description:"Real file raster dimensions; required for pixels",type:"object",properties:{width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["width","height"],additionalProperties:!1},nativeScale:{description:"Optional provenance only; never screenScale",type:"number",exclusiveMinimum:0}},required:["screenSize","screenshotOrientation"],additionalProperties:!1}},required:["screenshot"],additionalProperties:!1}]},from:{description:"Where the finger goes down, in the image",type:"object",properties:{x:{description:"x in image.unit: a 0-1 fraction or a raster pixel",type:"number"},y:{description:"y in image.unit: a 0-1 fraction or a raster pixel",type:"number"}},required:["x","y"],additionalProperties:!1},to:{description:"Where the finger lifts, in the image",type:"object",properties:{x:{description:"x in image.unit: a 0-1 fraction or a raster pixel",type:"number"},y:{description:"y in image.unit: a 0-1 fraction or a raster pixel",type:"number"}},required:["x","y"],additionalProperties:!1}},required:["unit","source","from","to"],additionalProperties:!1},speed:{description:"Swipe speed preset",type:"string",enum:["slow","normal","fast"]},durationMs:{description:"Exact stroke duration in ms (integer 1-3000); exclusive with speed. Velocity = swipe distance / duration; the result reports the dispatched duration and velocityPxPerSecond. Android may quantize very short strokes.",type:"integer",minimum:1,maximum:3000},display:{description:"Target panel key, role, or active; from/to/image resolve against that panel's observed screenSize (Android only)",type:"string"},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},pointer:{description:"Pointer for this gesture; omit for a finger. Fails with a capability error instead of falling back to a finger.",type:"object",properties:{toolType:{description:"Inject a stylus, or the pen's eraser end, instead of a finger (Android 12+, API 31). Pressure other than 1, tilt, orientation, buttons and any dragPath need stylus_input_v1 or a root adb shell with a uinput tool. An eraser needs a root adb shell with a uinput tool and supports pressure, tilt, orientation and buttons",type:"string",enum:["stylus","eraser"]},pressure:{description:"Stylus pressure 0-1. 1 or omitted uses the shell route; any other value needs stylus_input_v1 (Android 12+) or a root adb shell with a uinput tool, and is refused before input otherwise",type:"number",minimum:0,maximum:1},tilt:{description:"Stylus tilt in radians from the surface normal, 0 to PI/2 (Android 12+)",type:"number",minimum:0,maximum:1.5707963267948966},orientation:{description:"Stylus orientation in radians, -PI to PI (Android 12+)",type:"number",minimum:-3.141592653589793,maximum:3.141592653589793},buttons:{description:"Barrel buttons held for the gesture (Android 12+)",minItems:1,maxItems:2,type:"array",items:{type:"string",enum:["primary","secondary"]}}},required:["toolType"],additionalProperties:!1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1,description:"Swipe from one screen point to another, including diagonals. Bare from/to use platform-native observe coordinates; image uses explicit normalized fractions (preferred) or real raster pixels from a screenshot or observe.crop."}},{name:"swipeOn",title:"Swipe Screen Element",annotations:{destructiveHint:!0},description:"Swipe/scroll on screen or elements",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:"Target panel key, role, or active",type:"string"},includeSystemInsets:{description:"Use full screen including status/nav bars; with display, requires the selected Android panel's own available insets",type:"boolean"},container:{description:"Nested swipe container scope; outermost resolves first, with per-level index and selectionStrategy",$ref:"#/$defs/__schema0"},autoTarget:{description:"Auto-target scrollable containers (default: true; with Android display, opt-in)",type:"boolean"},direction:{description:"Swipe/scroll direction",type:"string",enum:["up","down","left","right"]},gestureType:{description:"Finger direction or content scroll direction; default: swipeFingerTowardsDirection",type:"string",enum:["swipeFingerTowardsDirection","scrollTowardsDirection"]},lookFor:{description:"Element to find by scrolling; with display, observes and swipes only the selected Android panel",anyOf:[{type:"object",properties:{elementId:{description:"ID of the element to look for",type:"string"},maxUnchangedSwipes:{description:"Consecutive unchanged swipes that end each search direction (default: 2): forward, then a reverse sweep; increase for slow content",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},container:{description:"Additional nested scope within the swipe container; re-resolved on every observation",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Target selection strategy (default: first); unique requires one target and every unindexed scope",type:"string",enum:["first","random","unique"]}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Text to look for",type:"string"},maxUnchangedSwipes:{description:"Consecutive unchanged swipes that end each search direction (default: 2): forward, then a reverse sweep; increase for slow content",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},container:{description:"Additional nested scope within the swipe container; re-resolved on every observation",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Target selection strategy (default: first); unique requires one target and every unindexed scope",type:"string",enum:["first","random","unique"]}},required:["text"],additionalProperties:!1}]},boomerang:{description:"Return to start position after swipe apex",type:"boolean"},apexPause:{description:"Pause duration at swipe apex in ms (0-3000; default: 100)",type:"number",minimum:0,maximum:3000},returnSpeed:{description:"Speed multiplier for return swipe (> 0, <= 3000; default: 1); return duration <= 3000 ms and total boomerang <= 5000 ms",type:"number",exclusiveMinimum:0,maximum:3000},speed:{description:"Swipe speed preset",type:"string",enum:["slow","normal","fast"]},durationMs:{description:"Forward-stroke duration in ms (integer 1-3000); exclusive with speed and lookFor. Velocity = swipe distance / duration; the result reports the dispatched duration (boomerang: total) and, for a single swipe, velocityPxPerSecond (omitted for boomerang, lookFor, and the TalkBack route that ignores duration; uses effectiveDurationMs when clamped). Android may quantize very short strokes. Limits: the TalkBack semantic-scroll route has no timed stroke and ignores it (durationIgnored + warnings); the iOS XCUICoordinate route clamps velocity to 100-10000 pt/s (effectiveDurationMs + warnings).",type:"integer",minimum:1,maximum:3000},fromEdge:{description:"Start at this screen (or display panel) edge and swipe inward; direction must point inward (left->right, right->left, top->down, bottom->up). Exclusive with container, lookFor, autoTarget=true. By default the start point is inset from the edge by the system bars/gesture insets (Android left/right: gesture inset plus edgeInset, e.g. x=88 for 78px + edgeInset 10), so the swipe stays in the app; pass includeSystemInsets:true to start at the physical screen edge (edgeInset px in), where a very-near-edge swipe may be taken as system back/home",type:"string",enum:["left","right","top","bottom"]},edgeInset:{description:"With fromEdge: how far inside the edge the touch starts, px (iOS points); default 4 (iOS swipe-back needs the first ~20 pt). Measured from the content edge (after system insets) unless includeSystemInsets:true",type:"integer",minimum:0,maximum:50},at:{description:"With fromEdge: normalized 0-1 position along the edge (default 0.5)",type:"number",minimum:0,maximum:1},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["direction"],additionalProperties:!1,$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"systemAlerts",title:"Set Alert Policy",annotations:{destructiveHint:!0},description:"Set how OS permission and system alerts are handled before and after each UI interaction (tapOn, tapAt, tapAny, swipeOn, swipeAt, sendKeys, pressButton, dragAndDrop, dragPath, pinchOn, multiTouch) on this device, including executePlan steps. iOS: SpringBoard permission prompts; Android: permission-controller grant dialogs. report (default) never taps and surfaces the alert in the action's warnings; allow, deny and allowOnce tap that button; match names a button by label for localized or app-specific alerts. Every alert seen or answered is reported in the action's warnings. A policy set in a daemon session clears when the session is released.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"setPolicy for this device, clear it, or get the current policy",type:"string",enum:["setPolicy","clear","get"]},policy:{description:"setPolicy only, default report. report never taps and surfaces the alert in the action result; allow, deny and allowOnce tap that button",type:"string",enum:["report","allow","deny","allowOnce"]},match:{description:"setPolicy only: answer specific alerts by button label, e.g. a localized or app-specific alert the built-in permission labels do not cover",type:"array",items:{type:"object",properties:{textContains:{description:"Answer only an alert whose text contains this (case-insensitive)",type:"string",minLength:1},buttonText:{description:"Tap the button with exactly this label (case-insensitive), in any language",type:"string",minLength:1}},required:["buttonText"],additionalProperties:!1}},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1},_meta:{"automobile/deviceReadOnlyArgs":[{argument:"action",values:["get"]}]}},{name:"systemTray",title:"Control Notifications",annotations:{destructiveHint:!0},description:"System tray actions for notifications (open/close/list/find/tap/dismiss/clearAll)",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"open/close/list/find/tap/dismiss/clearAll notification",type:"string",enum:["open","close","list","find","tap","dismiss","clearAll"]},notification:{description:"Notification criteria to match; list requires appId and scans up to three swipes on Android",type:"object",properties:{title:{description:"Notification title to match",type:"string"},body:{description:"Notification body to match",type:"string"},appId:{description:"App package ID to match",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},tapActionLabel:{description:"Action button label to tap (for 'tap' action)",type:"string"},replyText:{description:"Inline reply text on watches (tap only; defaults tapActionLabel to Keyboard input)",type:"string",minLength:1},packageId:{type:"string"},package:{type:"string"},packageName:{type:"string"},appPackage:{type:"string"},appPackageId:{type:"string"},bundle:{type:"string"},bundleId:{type:"string"},bundleID:{type:"string"},bundleIdentifier:{type:"string"},application:{type:"string"},applicationId:{type:"string"},applicationIdentifier:{type:"string"},app:{type:"string"},appIdentifier:{type:"string"},package_id:{type:"string"},package_name:{type:"string"},bundle_id:{type:"string"},application_id:{type:"string"}},additionalProperties:!1},awaitTimeout:{description:"Timeout in ms to wait for notification (default: 5000)",type:"number"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"tapAny",title:"Tap Any Element",annotations:{destructiveHint:!0},description:"Tap any clickable element; scope with container or scrollableContainer.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:"Target panel key, role, or active",type:"string"},container:{description:"Nested container scope; outermost resolves first, each level searches strict descendants. Per-level index is zero-based.",$ref:"#/$defs/__schema0"},selectionStrategy:{description:"Element selection strategy: first (default), random, or unique; unique requires exactly one eligible target and every unindexed container",type:"string",enum:["first","random","unique"]},scrollableContainer:{description:"Search only scrollable containers/lists",type:"boolean"},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},action:{description:"Action type (default: longPress when duration is given, otherwise tap)",type:"string",enum:["tap","doubleTap","longPress"]},duration:{description:"Long press duration (ms; maximum 60000; must fit the remaining request budget including 2000 ms dispatch headroom; 0 or omitted uses the platform default)",type:"number",minimum:0,maximum:60000},searchUntil:{description:"Poll for clickable element before tapping",type:"object",properties:{duration:{description:"Polling duration (ms, default: 1500)",type:"number",minimum:100,maximum:12000}},additionalProperties:!1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1,$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"tapAt",title:"Tap at Coordinates",annotations:{destructiveHint:!0},description:"Tap, long press, or double tap at screen coordinates in native, normalized, or percent units.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{display:{description:'Target panel key, role, or active; "headUnit" taps the Android Auto head unit at x, y in head-unit pixels',type:"string"},snapshotId:{description:"Short-lived reference from observe.snapshotReference; reject stale geometry or frame context",type:"string",minLength:1},x:{description:"Screen x coordinate in the selected coordinateSpace (native by default)",type:"number"},y:{description:"Screen y coordinate in the selected coordinateSpace (native by default)",type:"number"},coordinateSpace:{description:"Coordinate units: native absolute (default), normalized 0\u20131, or percent 0\u2013100",type:"string",enum:["absolute","normalized","percent"]},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},image:{description:"Screenshot-relative point; mutually exclusive with outer x, y, and coordinateSpace. Without image, x and y are required.",type:"object",properties:{unit:{description:"Use normalized image fractions (preferred); pixels means the real file raster, never a resized preview",type:"string",enum:["normalized","pixels"]},x:{type:"number"},y:{type:"number"},source:{anyOf:[{type:"object",properties:{crop:{description:"Pass the whole observe.crop object from the referenced image",type:"object",properties:{cropPath:{type:"string"},unit:{type:"string",enum:["pixels","points"]},requestedBounds:{type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},clippedBounds:{type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},clipped:{type:"boolean"},screenSize:{type:"object",properties:{width:{type:"number",exclusiveMinimum:0},height:{type:"number",exclusiveMinimum:0}},required:["width","height"],additionalProperties:!1},imageSize:{type:"object",properties:{width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["width","height"],additionalProperties:!1},pixelsPerNativeUnit:{type:"object",properties:{x:{type:"number",exclusiveMinimum:0},y:{type:"number",exclusiveMinimum:0}},required:["x","y"],additionalProperties:!1},scaleProvenance:{type:"string",enum:["raster-dimensions","native-scale-confirmed"]},rasterBounds:{type:"object",properties:{left:{type:"number"},top:{type:"number"},right:{type:"number"},bottom:{type:"number"}},required:["left","top","right","bottom"],additionalProperties:!1},screenshotOrientation:{type:"string",enum:["display","native"]}},required:["unit","requestedBounds","clippedBounds","clipped","screenSize","imageSize","pixelsPerNativeUnit","scaleProvenance","rasterBounds","screenshotOrientation"],additionalProperties:!1},rotation:{description:"observe.rotation; required for native screenshot orientation",anyOf:[{type:"number",const:0},{type:"number",const:1},{type:"number",const:2},{type:"number",const:3}]}},required:["crop"],additionalProperties:!1},{type:"object",properties:{screenshot:{type:"object",properties:{screenSize:{type:"object",properties:{width:{type:"number",exclusiveMinimum:0},height:{type:"number",exclusiveMinimum:0}},required:["width","height"],additionalProperties:!1},screenshotOrientation:{type:"string",enum:["display","native"]},rotation:{anyOf:[{type:"number",const:0},{type:"number",const:1},{type:"number",const:2},{type:"number",const:3}]},imageSize:{description:"Real file raster dimensions; required for pixels",type:"object",properties:{width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["width","height"],additionalProperties:!1},nativeScale:{description:"Optional provenance only; never screenScale",type:"number",exclusiveMinimum:0}},required:["screenSize","screenshotOrientation"],additionalProperties:!1}},required:["screenshot"],additionalProperties:!1}]}},required:["unit","x","y","source"],additionalProperties:!1},action:{description:"Coordinate gesture (default: tap)",type:"string",enum:["tap","longPress","doubleTap"]},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},durationMs:{description:"Long-press duration in milliseconds (500\u201310000; default 1000); only with longPress",type:"integer",minimum:500,maximum:1e4},pointer:{description:"Pointer for this gesture; omit for a finger. Fails with a capability error instead of falling back to a finger.",type:"object",properties:{toolType:{description:"Inject a stylus, or the pen's eraser end, instead of a finger (Android 12+, API 31). Pressure other than 1, tilt, orientation, buttons and any dragPath need stylus_input_v1 or a root adb shell with a uinput tool. An eraser needs a root adb shell with a uinput tool and supports pressure, tilt, orientation and buttons",type:"string",enum:["stylus","eraser"]},pressure:{description:"Stylus pressure 0-1. 1 or omitted uses the shell route; any other value needs stylus_input_v1 (Android 12+) or a root adb shell with a uinput tool, and is refused before input otherwise",type:"number",minimum:0,maximum:1},tilt:{description:"Stylus tilt in radians from the surface normal, 0 to PI/2 (Android 12+)",type:"number",minimum:0,maximum:1.5707963267948966},orientation:{description:"Stylus orientation in radians, -PI to PI (Android 12+)",type:"number",minimum:-3.141592653589793,maximum:3.141592653589793},buttons:{description:"Barrel buttons held for the gesture (Android 12+)",minItems:1,maxItems:2,type:"array",items:{type:"string",enum:["primary","secondary"]}}},required:["toolType"],additionalProperties:!1}},additionalProperties:!1,description:"Tap, long press, or double tap a screen point. Bare x/y use platform-native observe coordinates, except on Android XR home-space, where they are screenshot pixels inside an app panel; XR observe node bounds stay in panel-window space and are not screenshot coordinates. image uses explicit normalized fractions (preferred) or real raster pixels from a screenshot or observe.crop."}},{name:"tapOn",title:"Tap Screen Element",annotations:{destructiveHint:!0},description:"Tap an element by text/content-desc, resource-id, or Android test tag; use sibling for adjacent controls. On an Android device without a touchscreen (TV), a plain text or elementId tap (no sibling, container, index or other touch-only option) moves D-pad focus to the match and presses enter only once focus reaches it.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{selector:{type:"object",additionalProperties:!1,properties:{elementId:{description:"Resource ID, e.g. com.app:id/btn_login",type:"string",minLength:1},testTag:{description:"Android accessibility test tag",type:"string",minLength:1},text:{description:"Text, content-desc, or placeholder",type:"string",minLength:1},accessibilityLink:{description:"Exact visible text of a semantic accessibility link",type:"string",minLength:1},textAny:{description:"Ordered text variants; first visible match wins",minItems:1,type:"array",items:{type:"string",minLength:1}}},description:"Element to tap: elementId, Android testTag, text, semantic accessibility link, or ordered text variants",anyOf:[{required:["elementId"]},{required:["testTag"]},{required:["text"]},{required:["accessibilityLink"]},{required:["textAny"]}]},display:{description:"Target panel key, role, or active",type:"string"},layer:{description:"app: exclude the AutoMobile prototype; prototype: prototype nodes only (error if none shown). Omit for both, topmost first",type:"string",enum:["app","prototype"]},exactText:{description:"Require selector.text to equal the element's text or content-desc (case-insensitive); no substring fallback",type:"boolean"},sibling:{description:"Tap a clickable sibling of the match, e.g. checkbox beside label",type:"boolean"},container:{description:"Nested container scope; outermost resolves first, each level searches strict descendants. Per-level index is zero-based.",$ref:"#/$defs/__schema0"},action:{description:"Action type (default: longPress with positive duration, otherwise tap)",type:"string",enum:["tap","doubleTap","longPress","focus"]},selectionStrategy:{description:"Selection strategy: first (default), random, or unique. Unique requires exactly one match at every unindexed scope and target.",type:"string",enum:["first","random","unique"]},index:{description:"0-based index into the full candidate list, ranked by topmost window, then smallest eligible area. Index 0 is the default first pick when candidates share an action. Out of range \u2192 no match.",type:"integer",minimum:0,maximum:9007199254740991},duration:{description:"Long press duration (ms; maximum 60000; must fit the remaining request budget including 2000 ms dispatch headroom). Positive duration without action means longPress; positive duration with action tap is refused. For longPress, 0 or omitted uses the platform default.",type:"number",minimum:0,maximum:60000},subtext:{description:"Semantic link inside the selected element; fails if the platform does not expose that link",type:"object",properties:{text:{description:"Exact visible text of a semantic link inside the selected element",type:"string",minLength:1},occurrence:{description:"Zero-based occurrence among exact semantic-link matches (default: 0)",type:"integer",minimum:0,maximum:9007199254740991}},required:["text"],additionalProperties:!1},searchUntil:{description:"Poll for element before tapping",type:"object",properties:{duration:{description:"Polling duration (ms, default: 1500)",type:"number",minimum:100,maximum:12000}},additionalProperties:!1},preTapStability:{description:"Require stable bounds before tapping; use for dynamic UI",type:"boolean"},retryIfNoChange:{description:"Retry once if the view hierarchy is unchanged after tap",type:"boolean"},ensureTap:{description:"Enable preTapStability and retryIfNoChange",type:"boolean"},settleTimeoutMs:{description:"Post-tap settle wait (ms, default 1000, max 3000); 0 skips it. An unsettled screen returns observation.settled:false.",type:"integer",minimum:0,maximum:3000},ensureChecked:{description:`Skip tapping if the resolved toggle element's checked state already matches this value; otherwise tap and verify it flipped. Requires the element to have the toggle affordance and action "tap".`,type:"boolean"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["selector"],additionalProperties:!1,$defs:{__schema0:{anyOf:[{type:"object",properties:{elementId:{description:"Container resource ID",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["elementId"],additionalProperties:!1},{type:"object",properties:{text:{description:"Container text",type:"string",minLength:1},index:{type:"integer",minimum:0,maximum:9007199254740991},selectionStrategy:{type:"string",enum:["first","random","unique"]},container:{$ref:"#/$defs/__schema0"}},required:["text"],additionalProperties:!1}]}}}},{name:"terminateApp",title:"Terminate App",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Terminate app by package name",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},includeExtras:{description:"Opt in to raw accessibility extras metadata in structuredContent only (default off). Only meaningful with project:'full' or raw:true; text content always omits extras.",type:"boolean"},raw:{description:"Return the raw view hierarchy instead of the compact skeleton",type:"boolean"},project:{description:"Observation projection. 'skeleton' (default) returns a flat, actionable-only list (elementId/label/bounds/affordances) under `skeleton` in place of `viewHierarchy`; 'full' returns the raw view hierarchy under `viewHierarchy`. Each skeleton elementId/label is directly usable as a tapOn selector, except the collapsed keyboard row `<ime>` (drive it with sendKeys); re-request with raw/project:'full' to disambiguate.",type:"string",enum:["full","skeleton"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"uninstallApp",title:"Uninstall App",annotations:{destructiveHint:!0,idempotentHint:!0},description:"Uninstall app by package name or bundle identifier",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},platform:{description:'Device platform. Name "watchos" to target an Apple Watch simulator, unless sessionUuid is a watch session. Name "tvos" for an Apple TV simulator; tools without tvOS support refuse it',type:"string",enum:["android","ios","watchos","tvos","visionos"]},keepData:{description:"Keep app data after uninstall (Android only, default false; refused on watchOS)",type:"boolean"},expectedSigningSha256:{description:"Android: complete signer set (SHA-256 of every signing certificate) the installed package must have; a different signer set, absence, or signers that cannot be read refuses the uninstall, and removal is confirmed by a fresh presence read.",minItems:1,maxItems:16,type:"array",items:{type:"string",pattern:"^(?:[0-9a-fA-F]{2}:?){31}[0-9a-fA-F]{2}$"}},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"},deviceId:{description:"Device id (Android serial such as emulator-5554, or iOS UDID) to target when several devices are booted",type:"string"}},required:["appId"],additionalProperties:!1}},{name:"videoRecording",title:"Record Video",annotations:{destructiveHint:!1},description:"Start or stop device video recording. resourceLink on stop links its full result; required fields stay inline, bounded.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{type:"string",enum:["start","stop"]},platform:{type:"string",enum:["android","ios","tvos","visionos"]},deviceId:{type:"string"},recordingId:{description:"Recording ID",type:"string"},qualityPreset:{type:"string",enum:["low","medium","high"]},targetBitrateKbps:{description:"Bitrate Kbps",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},maxThroughputMbps:{description:"Max throughput Mbps",type:"number",exclusiveMinimum:0},fps:{description:"FPS",type:"integer",exclusiveMinimum:0,maximum:9007199254740991},resolution:{description:"Resolution",type:"object",properties:{width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991}},required:["width","height"],additionalProperties:!1},format:{type:"string",enum:["mp4"]},maxDuration:{description:"Max duration seconds",type:"integer",exclusiveMinimum:0,maximum:3600},outputName:{description:"Recording label",type:"string"},audio:{description:"Also record the device's audio into the file (start only; local emulators and iOS Simulators; needs FFmpeg)",type:"boolean"},display:{description:'Android panel key, role, or "active" (start only)',type:"string"},highlights:{description:"Recording highlights",type:"array",items:{type:"object",properties:{description:{description:"Highlight description",type:"string"},shape:{description:"Red hand-drawn circle bounds",type:"object",properties:{type:{type:"string",const:"circle"},bounds:{type:"object",properties:{x:{type:"integer",minimum:-9007199254740991,maximum:9007199254740991},y:{type:"integer",minimum:-9007199254740991,maximum:9007199254740991},width:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},height:{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},sourceWidth:{anyOf:[{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},{type:"null"}]},sourceHeight:{anyOf:[{type:"integer",exclusiveMinimum:0,maximum:9007199254740991},{type:"null"}]}},required:["x","y","width","height"],additionalProperties:!1}},required:["type","bounds"],additionalProperties:!1},timing:{description:"Highlight timing",type:"object",properties:{startTimeMs:{description:"Start time in ms",type:"integer",minimum:0,maximum:9007199254740991}},additionalProperties:!1}},required:["shape"],additionalProperties:!1}},resourceLink:{description:"Return the complete result as an automobile:tool-output resource and a resource_link block instead of inline (default off). Only the headline fields stay inline; read the link to get the rest.",type:"boolean"},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"wakeAndUnlock",title:"Wake and Unlock",annotations:{destructiveHint:!1},description:"Wake a device and unlock its keyguard. Android: swipe lock or secure PIN via `pin`; iOS: wake + swipe-dismiss (pin ignored).",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{pin:{description:"Credential to unlock a secure Android device. Optional; logically required to unlock a secure lock unless a pin was already remembered this session. Ignored on iOS.",type:"string"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},additionalProperties:!1}},{name:"wearSurface",title:"Manage Wear OS Tiles, Watch Faces and Complications",annotations:{destructiveHint:!0},description:"Wear OS watches only (other form factors are refused without a change): tiles, watch faces and complications. listTileProviders lists the installed tile provider components. addTile adds a tile provider to the carousel (idempotent; reports its index; a component that is not a tile provider fails before anything is sent, naming the valid ones). removeTile removes it (also succeeds when it was absent). showTile scrolls the carousel to a tile by component (index resolved right before showing, adding the tile if absent) or by index, then observes; success requires the observe to confirm a tile container in the foreground Wear system UI. The debug broadcasts report success even when nothing happened, so verified is only true when an observe confirmed it. watchFace only reads dumpsys wear_service: the active face (package, favoriteId, fallback), each favorite's complication slots (slot, type, provider or null; the active favorite's are live) and ambient; available is false when the watch faces cannot be read. setWatchFace switches the active face (bare package for a WFF face, <package>/<class> for a classic one) and unsetWatchFace reverts it; setComplication puts a provider in a face slot with an androidx type int, unsetComplication empties the slot. Watch face changes succeed (applied: true) only when a dumpsys wear_service readback shows the change: setComplication fails before sending with error provider_not_found (naming the valid ones) when the provider is not a complication data source on the device. An accepted broadcast is ignored when the provider does not support the type: the slot keeps its previous provider and type (error unsupported_type). A complication request the slot already showed succeeds with change: unchanged.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{action:{description:"listTileProviders takes no other argument; addTile and removeTile need component; showTile needs component (index resolved right before showing) or index; watchFace takes neither and only reads. setWatchFace needs watchFace; unsetWatchFace takes nothing; setComplication needs watchFace, slot, type and provider; unsetComplication needs watchFace, slot and provider",type:"string",enum:["addTile","showTile","removeTile","listTileProviders","watchFace","setWatchFace","unsetWatchFace","setComplication","unsetComplication"]},component:{description:"Tile provider service as <package>/<service>",type:"string",pattern:"^[A-Za-z][\\w.]*\\/\\.?[A-Za-z_][\\w.]*$"},index:{description:"showTile only: carousel position; indexes shift when tiles are added",type:"integer",minimum:0,maximum:9007199254740991},watchFace:{description:"Watch face: the bare package for a resource-only (WFF) face, <package>/<class> for a classic face",type:"string",pattern:"^[A-Za-z][\\w.]*(?:\\/\\.?[A-Za-z_][\\w.]*)?$"},slot:{description:"Complication slot id on the watch face",type:"integer",minimum:0,maximum:9007199254740991},type:{description:"setComplication: androidx complication type int (SHORT_TEXT=3, RANGED_VALUE=5)",type:"integer",minimum:0,maximum:9007199254740991},provider:{description:"Complication data source service as <package>/<service>",type:"string",pattern:"^[A-Za-z][\\w.]*\\/\\.?[A-Za-z_][\\w.]*$"},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["action"],additionalProperties:!1}},{name:"windowMode",title:"Set Window Mode",annotations:{destructiveHint:!0},description:"Android: put an app's task into fullscreen, picture-in-picture (enter via HOME; the app must support PiP), freeform (optional bounds) or split screen with a second app, and read the mode and bounds back. Returns a restore receipt for the previous mode and any freeform settings it turned on. observe reports each task's windowingMode and bounds in backStack.tasks.",inputSchema:{$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:{appId:{description:"Package whose task to move",type:"string",minLength:1,maxLength:256,pattern:"^[A-Za-z0-9._-]+$"},mode:{description:'"fullscreen"; {pip: enter|exit}; {freeform: {bounds?}} (turns on freeform settings, receipted); {splitScreen: {with?, position?}}',anyOf:[{type:"string",const:"fullscreen"},{type:"object",properties:{pip:{type:"string",enum:["enter","exit"]}},required:["pip"],additionalProperties:!1},{type:"object",properties:{freeform:{type:"object",properties:{bounds:{description:"Window bounds in display pixels",type:"object",properties:{left:{type:"integer",minimum:0,maximum:9007199254740991},top:{type:"integer",minimum:0,maximum:9007199254740991},right:{type:"integer",minimum:0,maximum:9007199254740991},bottom:{type:"integer",minimum:0,maximum:9007199254740991}},required:["left","top","right","bottom"],additionalProperties:!1}},additionalProperties:!1}},required:["freeform"],additionalProperties:!1},{type:"object",properties:{splitScreen:{type:"object",properties:{with:{description:"Second app's package; required on API 32+",type:"string",minLength:1},position:{description:"appId's side: primary is top/left (default)",type:"string",enum:["primary","secondary"]}},additionalProperties:!1}},required:["splitScreen"],additionalProperties:!1}]},restore:{description:"A returned restore receipt: puts the window back, then the settings. Same boot only",type:"object",properties:{mode:{anyOf:[{type:"string",const:"fullscreen"},{type:"object",properties:{pip:{type:"string",enum:["enter","exit"]}},required:["pip"],additionalProperties:!1},{type:"object",properties:{freeform:{type:"object",properties:{bounds:{description:"Window bounds in display pixels",type:"object",properties:{left:{type:"integer",minimum:0,maximum:9007199254740991},top:{type:"integer",minimum:0,maximum:9007199254740991},right:{type:"integer",minimum:0,maximum:9007199254740991},bottom:{type:"integer",minimum:0,maximum:9007199254740991}},required:["left","top","right","bottom"],additionalProperties:!1}},additionalProperties:!1}},required:["freeform"],additionalProperties:!1},{type:"object",properties:{splitScreen:{type:"object",properties:{with:{description:"Second app's package; required on API 32+",type:"string",minLength:1},position:{description:"appId's side: primary is top/left (default)",type:"string",enum:["primary","secondary"]}},additionalProperties:!1}},required:["splitScreen"],additionalProperties:!1}]},settings:{type:"object",properties:{deviceId:{type:"string"},bootId:{type:"string",format:"uuid",pattern:"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"},entries:{minItems:1,maxItems:2,type:"array",items:{type:"object",properties:{key:{type:"string",enum:["enable_freeform_support","force_resizable_activities"]},value:{anyOf:[{type:"string",pattern:"^\\d+$"},{type:"null"}]}},required:["key","value"],additionalProperties:!1}}},required:["deviceId","bootId","entries"],additionalProperties:!1}},additionalProperties:!1},platform:{type:"string",enum:["android","ios","tvos","visionos"]},sessionUuid:{description:"Session",type:"string"},keepScreenAwake:{type:"boolean"},device:{description:"Device label",type:"string"}},required:["appId"],additionalProperties:!1}}];var M=ce,le="automobile/debugOnly",ue="automobile/embeddedSdkOnly",me="automobile/planOnly",he="automobile/deviceResourceBudget",ye="automobile/hostInventory",ge="automobile/hostSideState",fe="automobile/opaquePersistentState";function wt(i,n){let s=i._meta;return s?.[me]!==!0&&(s?.[le]!==!0||n?.debug===!0)&&(s?.[ue]!==!0||n?.embeddedSdk===!0)}var NA={isEnabled:()=>Be(f.PROTOTYPE_FULL_SCHEMA)},Z;function kt(i,n){if(i.name!=="prototype"||!n.isEnabled())return i.inputSchema;if(!Z){let{withFullAdvertisedSpecSchema:s}=import.meta.require("./chunk-hb1x7v55.js");Z=s(i.inputSchema)}return Z}function be(i,n){let s=h_();return M.filter((a)=>i===!1||wt(a,i)).map((a)=>{let d={...a._meta??{},...s?{"anthropic/alwaysLoad":!0}:{}};delete d[le],delete d[ue],delete d[me],delete d[he],delete d[ye],delete d[ge],delete d[fe];let p={name:a.name,title:a.title,annotations:a.annotations,inputSchema:kt(a,n)};if(a.description!==void 0)p.description=a.description;if(Object.keys(d).length>0)p._meta=d;return p})}function GQ(i=NA){return be(!1,i)}function YQ(i,n=NA){return be(i,n)}function we(i){return M.find((n)=>n.name===i)?._meta?.[he]===!0}function L0(i){return typeof i==="string"&&M.find((n)=>n.name===i)?._meta?.[ye]===!0}function Se(i,n){return M.find((s)=>s.name===i)?._meta?.[n]===!0}function JQ(i){return Se(i,ge)}function XQ(i){return Se(i,fe)}function ZQ(i,n){let s=M.find((a)=>a.name===i)?.inputSchema.properties;return typeof s==="object"&&s!==null&&n in s}var yh=1800000;function A(i){return i&&typeof i==="object"&&!Array.isArray(i)?i:void 0}function S(i){return typeof i==="number"&&Number.isFinite(i)&&i>0?i:void 0}function k(i,n,s){return Math.min((S(i)??n)+s,yh,Fr)}function Ae(i){let n=A(i.waitFor);if(!n)return 0;let s=n.for==="stable"?EF:Kc;return k(n.timeout??n.timeoutMs,s,rl)}function ke(i){return k(A(i.waitFor)?.timeoutMs,Kc,rl)}function xe(i){return i.method==="tools/call"&&(i.params?.name==="openLink"||i.params?.name==="observe")}function FA(i,n=process.env){if(i.method!=="tools/call")return;switch(i.params?.name){case"openLink":return Sf(f.OPEN_LINK_MCP_TIMEOUT_MS.name,f.OPEN_LINK_MCP_TIMEOUT_MS.legacyName,{env:n});case"observe":return Sf(f.OBSERVE_MCP_TIMEOUT_MS.name,f.OBSERVE_MCP_TIMEOUT_MS.legacyName,{env:n});default:return}}function R(i){let n=qr(i.hierarchy);if(n?.captureId!==i.captureId||n.hierarchy!==i.hierarchy)throw new t("Selected hierarchy capture changed before tap dispatch")}class X{deps;constructor(i){this.deps=i}async executeAndroidTap(i,n,s,{target:a,fenceOptions:d={}}){let{x:p,y:l}=n,{signal:c}=d,m=wv(d),{element:h,capture:y}=a;if(this.deps.beforeTap(),R(y),await this.deps.isAndroidXr(c)){await CF(()=>this.deps.accessibilityService,{action:i,element:h,signal:c,options:{displayFence:m,resolvedHierarchy:y.hierarchy,container:a.container},resolveContainer:(w)=>a.container?this.deps.resolveContainer(w,a.container):void 0});return}let{talkBack:g,unconfirmed:b}=a.talkBackState===void 0?await Wh(this.deps.accessibilityDetector,this.deps.device.deviceId,this.deps.getAdb(),this.deps.featureFlags):{talkBack:a.talkBackState,unconfirmed:!1};if(b)d.onActivationWarnings?.([Ca]);if(h["hierarchy-source"]!=="uiautomator"&&g===!0&&await this.executeAndroidTalkBackTap(i,{x:p,y:l},s,{element:h,fenceOptions:{displayFence:m,scoped:a.scoped,hierarchy:ft(y.hierarchy),onActivationWarnings:d.onActivationWarnings}}))return;if(i==="longPress"){if(await this.trySemanticAndroidLongPress(h,{signal:c,scoped:a.scoped}))return;await this.executeAndroidLongPress(p,l,s,{signal:c,fenceOptions:{displayFence:m}});return}await this.executeAndroidCoordinateTap(i,{x:p,y:l},{signal:c,fence:m,onActivationWarnings:d.onActivationWarnings})}async executeAndroidCoordinateTap(i,n,s){let{signal:a,fence:d}=s,p=async()=>{d.assertCurrent(),await kw(this.deps.accessibilityService,this.deps.getAdb(),n,{durationMs:10,options:{signal:a}})};if(i!=="doubleTap"){await p();return}await tg({client:this.deps.accessibilityService,point:n,timer:this.deps.timer,signal:a,assertCurrent:()=>d.assertCurrent(),onWarning:(l)=>s.onActivationWarnings?.([l]),tap:p})}async executeAndroidLongPress(i,n,s,{signal:a,fenceOptions:d={}}={}){let p=wv(d);o(a),await _F({adb:this.deps.getAdb(),x:i,y:n,durationMs:s,signal:a,assertCurrent:()=>p.assertCurrent(),logTag:"TapAnyElement"})}async trySemanticAndroidLongPress(i,n){let{signal:s,scoped:a}=n,d=yi(i);if(!d||a||i["hierarchy-source"]==="uiautomator")return!1;let p=ca(d);if(p&&!await this.deps.accessibilityService.supportsNodeActionSelectors())return!1;try{o(s);let l=p?await this.deps.accessibilityService.requestNodeAction("long_click",d):await this.deps.accessibilityService.requestAction("long_click",d.resourceId);if(l.success)return!0;let c=await MT({advertised:kn(i.actions,"long_click"),error:l.error,needsNodeSelector:p,selected:i,readHierarchy:()=>this.deps.refreshViewHierarchy(zi,void 0,s,!0)});if(o(s),c)throw new t(`Semantic long press failed for the selected element: ${l.error??"unknown error"}`);e.warn(`[TapAnyElement] Accessibility long click failed: ${l.error}`)}catch(l){if(o(s),l instanceof t)throw l;e.warn(`[TapAnyElement] Accessibility long click error: ${l}`)}return!1}async executeAndroidTalkBackTap(i,n,s,{element:a,fenceOptions:d={}}){let{x:p,y:l}=n,c=d.displayFence,m=this.deps.talkBackDriverFactory.createDriver(this.deps.device);if(i==="longPress"&&!d.scoped){let y=await this.deps.talkBackStrategy.executeLongPress({x:p,y:l},s,a,{driver:m,fenceOptions:{...d,displayFence:c}});if(!y.success&&y.semanticActionFailure)throw new t(`Semantic long press failed for the selected element: ${y.error??"unknown error"}`);return y.success}if(i==="tap"&&!d.scoped){let y=await this.deps.talkBackStrategy.executeDirectActivation(a,m,d);if(y.success)return!0;e.warn(`[TapAnyElement] Direct accessibility activation failed (${y.error}); trying coordinate fallback`)}let h=i==="tap"?await this.deps.talkBackStrategy.executePreciseTap(p,l,m,c):await this.deps.talkBackStrategy.executeCoordinateFallback({x:p,y:l},i,s,{driver:m,fenceOptions:{displayFence:c}});return d.onActivationWarnings?.(h.warnings),h.success}async retryAndroidTapIfNoChange(i,n,s,{durationMs:a,fenceOptions:d={}}){let p=d.displayFence,{signal:l,screenSize:c}=d,m=n;if(s!=="tap"||!i)return;if(await this.deps.isAndroidXr(l)){e.info("[TapAnyElement] XR node click; skipping ghost-tap retry");return}let h=await OF(this.deps.timer,(b)=>(d.refresh??this.deps.refreshViewHierarchy)(b,c,l),(b)=>bn(b),{preTapHash:i,signal:l});if(h.status==="unavailable"){e.warn("[TapAnyElement] Tap hierarchy unreadable or could not be fingerprinted; skipping retry");return}if(h.status==="changed")return;let y=d.selectionOptions;if(y&&ds(y,"any-container")){let b=vd(te(this.deps.device.platform,"tapAny"),h.hierarchy,"cached-ok",{timer:this.deps.timer}),v=await this.deps.findClickableElement(y,b.hierarchy,{observationScreenSize:c});if(!v.element)return;n={...n,element:v.element,capture:b}}let g=this.deps.resolveTapPoint(n,{observationScreenSize:c});if(e.warn(`[TapAnyElement] Hierarchy unchanged after tap at (${g.x}, ${g.y}); retrying`),await this.deps.timer.sleep(DF),await this.refreshTalkBackRetryTarget(n,y,d.refresh,{screenSize:c,signal:l}),n.talkBackState)m.element=n.element,m.capture=n.capture;if(g=this.deps.resolveTapPoint(n,{observationScreenSize:c}),d.dispatch){R(n.capture),await d.dispatch(g);return}await this.executeAndroidTap(s,g,a,{target:n,fenceOptions:{signal:l,displayFence:p,onActivationWarnings:d.onActivationWarnings}})}async refreshTalkBackRetryTarget(i,n,s,{screenSize:a,signal:d}={}){if(!i.talkBackState||!n)return;let p=await uv((m)=>(s??this.deps.refreshViewHierarchy)(m,a,d),this.deps.timer,d),l=vd(te(this.deps.device.platform,"tapAny"),p,"fresh",{timer:this.deps.timer}),c=await this.deps.findClickableElement(n,l.hierarchy,{observationScreenSize:a});if(!c.element)throw new t("Selected element moved or is gone and no clickable target remains. Observe again before tapping.");i.element=c.element,i.capture=l}}var _e=Gi;function C(i){return Math.max(Hr(i),_e)}class Q{deps;constructor(i){this.deps=i}async executeIosTap(i,n,s,{element:a,fenceOptions:d={}}={}){let{signal:p}=d,l=d.displayFence,c=x.getInstance(this.deps.device),m=d.voiceOverEnabled??await this.deps.iosVoiceOverDetector.isVoiceOverActiveOrUnknown(this.deps.device.deviceId,c,{featureFlags:this.deps.featureFlags,signal:p}),h=()=>m&&a?this.executeIosTapWithVoiceOver(c,i,a,{durationMs:s,scoped:d.scoped,signal:p}):this.executeIosTapWithCoordinates(c,i,n,{longPressDuration:s,fenceOptions:{signal:p,displayFence:l}});await(m?wT(h):h())}async executeIosTapWithCoordinates(i,n,s,{longPressDuration:a,fenceOptions:d={}}){let{signal:p}=d,l=wv(d),c=n==="longPress"?a:nO,m=n==="longPress"?Hr(c):C(c);if(n==="doubleTap"){l.assertCurrent(),await Iw(i,s,{durationMs:c,options:{signal:p,timeoutMs:m}});return}l.assertCurrent(),o(p);try{await Ew(i,s,{durationMs:c,options:{signal:p,timeoutMs:m}})}catch(h){if(e.warn(`[TapAnyElement] CtrlProxy iOS tap failed: ${r(h)}`,h),n==="longPress")throw new t(`iOS long press failed: ${r(h)}; press may still be held on the device for up to ${c} ms. Wait ${c} ms before retrying touch input.`,{cause:h});throw u(h,"CtrlProxy iOS tap failed")}}resolveIosVoiceOverLabel(i){return i["ios-accessibility-label"]??(typeof i["content-desc"]==="string"&&i["content-desc"]?i["content-desc"]:void 0)??(typeof i.text==="string"&&i.text?i.text:void 0)}resolveIosResourceId(i){return typeof i["resource-id"]==="string"&&i["resource-id"]?i["resource-id"]:void 0}async activateIosByResourceId(i,n,s,a){let{timeoutMs:d,duration:p,signal:l}=a,c=!1,m;try{m=await i.requestAction(s,n,void 0,{timeoutMs:d,...p===void 0?{}:{duration:p},abortSignal:l,onDispatch:()=>{c=!0}})}catch(h){if(c&&!(h instanceof t)&&h!==l?.reason)throw Sn(r(h));throw h}if(this.confirmIosVoiceOverDispatch(m),!m.success)throw new t(`VoiceOver action failed for resource-id "${n}": ${m.error??"unknown error"}`)}confirmIosVoiceOverDispatch(i){if(i.dispatched&&i.acknowledged!==!0)throw Sn(i.error)}async executeIosTapWithVoiceOver(i,n,s,a){let d=a.durationMs,p=this.resolveIosVoiceOverLabel(s),l=a.scoped?void 0:this.resolveIosResourceId(s),c=n==="longPress"?"long_press":"activate",m=n==="longPress"?Hr(d):C(nO);if(l){await this.activateIosByResourceId(i,l,c,{timeoutMs:m,duration:n==="longPress"?d:void 0,signal:a.signal});return}if(!p)throw new t(a.scoped?"Scoped VoiceOver activation requires a label and selected bounds; global resource-ID activation cannot preserve the scope":"VoiceOver is enabled but the selected element has no accessibility label, content-desc, text, or resource-id to activate; a coordinate press would only focus it under VoiceOver, not activate it");let h=await i.requestVoiceOverActivate(p,c,m,{bounds:s.bounds,duration:n==="longPress"?d:void 0});if(this.confirmIosVoiceOverDispatch(h),!h.success)throw new t(`VoiceOver action failed for label "${p}": ${h.error??"unknown error"}`)}}var O=1500,L=1500,q=1000,ee=12000,Pe=nO,Te=C(Pe),Ie=200,ie=2*Te+Ie,xt=$j,_t=1+DC,Pt=SL.reduce((i,n)=>i+n,0),De=MD+$j,Ot=_t*De+Pt,It=De,Me=20000,Dt=Me,F=xt+It+Ot+ja+Dt;var Et=1;function Ce(i,n,s,a={}){if(s=Ri(s,n.layer),i.xr)s=Mt(s,n);let d=i.isContainerAvailable(s,n.container),p={...a,platform:i.platform,iosMultiPanel:i.iosMultiPanel},l=Ji(s,p),c=i.elementSelector.select(s,{},{readingOrder:i.xr,screenSizeOptions:p,container:n.container,strategy:n.selectionStrategy,intentAction:n.action==="longPress"?"long-press":"tap",scrollableContainer:n.scrollableContainer});if(i.xr&&!c.element&&n.container)c.element=Ct(i.elementSelector,s,n,l);if(c.element&&!Ou(c.element.bounds,l))return{element:null,containerFound:d};return{element:c.element,containerFound:d}}function Le(i,n,s={}){let a=Ji(n.capture.hierarchy,{observationScreenSize:n.observationScreenSize,display:n.observationDisplay,...s,platform:i.platform,iosMultiPanel:i.iosMultiPanel}),d=hf(n.element.bounds,a);if(!d)throw new t("Matched element has no visible tap area; scroll it into view, then retry tapAny.");let p=i.geometry.getElementCenter({bounds:d});if(n.layer!==void 0||i.platform==="ios")return p;let l=B$(n.capture.hierarchy,n.element,d,p);if(!l)throw new t("Target is covered by an AutoMobile prototype window; hide or move the prototype, then retry tapAny.");return l}function Mt(i,n){i=xF(i).hierarchy;let s=new Set(Pl(i)),a=(c)=>c.packageName!==void 0&&c.packageName===i.packageName,d=i.windows?.filter((c)=>c.hierarchy!==void 0&&!s.has(c)&&!c.packageName?.startsWith("com.android.systemui")&&(a(c)||c.type===void 0||c.type===Et))??[],p=d.filter(a).flatMap((c)=>Tt(c.bounds)??[]),l=d.filter((c)=>a(c)||Rt(c,p));if(!n.container&&l.length)i={...i,hierarchy:{node:{node:l.flatMap((c)=>c.hierarchy?[c.hierarchy]:[])}},windows:l};return i}function Rt(i,n){let s=Tt(i.bounds);return!s||n.length===0||n.some((a)=>$t(s,a))}function Ct(i,n,s,a){let d=new ve().project(n),p=Lt(d,Re(i,n,s.container));if(!p)return null;let l=Re(i,n,s.container.container),c=Eb(p,d,{action:s.action==="longPress"?"long-press":"tap",viewport:a},qt(p,d,a,l));if(!c||s.scrollableContainer&&!Nt(c,d))return null;return new K().parseNodeBounds(c.source)}function Re(i,n,s){let a=s&&i.resolveContainer?.(n,s);return a?nt(a):void 0}function Lt(i,n){let s=n&&_l(i).find((a)=>a.source===n);if(!s?.bounds||pt(s.bounds)<=0||i.some((a)=>a.parentIndex===s.index))return;return s}function Nt(i,n){for(let s=i;s;){if(s.affordances.includes("scroll"))return!0;s=s.parentIndex===void 0?void 0:n[s.parentIndex]}return!1}function qt(i,n,s,a){let d=n.findLast((h)=>h.index<=i.index&&h.rootGroup===i.rootGroup&&h.parentIndex===void 0),p=d?.bounds??(s&&{left:0,top:0,right:s.width,bottom:s.height}),l=p?pt(p):0,c=new Set([i.index]),m=i;for(let h=0;h<3&&m.parentIndex!==void 0;h++){let y=n[m.parentIndex];if(y===d||!y.bounds||pt(y.bounds)>l/4)break;if(n.some((g)=>!c.has(g.index)&&g.affordances.some((b)=>b==="tap"||b==="toggle")&&Ga(g,y,n)))break;if(c.add(y.index),m=y,y.source===a)break}return m}function Ne(i,n,s){return{...s,observationDisplay:n.viewHierarchy,observationScreenSize:n.screenSize,scoped:ds(i),container:i.container,layer:i.layer}}function re(i,n,s){if(n.action!=="longPress")return 0;pL(n.duration);let a=i.platform==="ios"?L:q;if(n.duration&&n.duration>0)a=Math.max(1,Math.round(n.duration));return O$(a,s?.requestDeadlineMs===void 0?void 0:s.requestDeadlineMs-i.timer.now()),a}function qe(i,n){if(i.container&&!n){let a=i.container.elementId?`elementId '${i.container.elementId}'`:`text '${i.container.text}'`;throw new t(`Container element not found with provided ${a}`)}let s=i.container?` within container ${i.container.elementId?`elementId '${i.container.elementId}'`:`text '${i.container.text}'`}`:"";throw new t(`No clickable element found${s}`)}function je(i,n,s){if(MF(N.isRawElementSearchEnabled(),n))return n;if(i.platform==="android"){let a=i.viewHierarchy.filterViewHierarchy(n);return pa(a,n),a}if(i.platform==="ios")return jt(i,n,s);return n}function jt(i,n,s){if(s?.width&&s?.height){let a=i.viewHierarchy.filterOffscreenNodes(n,s.width,s.height);return pa(a,n),a}return n}class LA extends Oe{androidTapper;iosTapper;tapPlatform=te(this.device.platform,"tapAny");iosMultiPanel=this.device.platform==="ios"&&(this.device.displays?.panels.length??0)>1;lastRenderedObservation;geometry;elementSelector;accessibilityService;hierarchyAccessibilityService;viewHierarchy;hierarchyCapture;iosVoiceOverDetector;featureFlags;accessibilityDetector;talkBackStrategy;talkBackDriverFactory;refreshViewHierarchyOverrideForTesting;selectionXr=new WeakMap;selectionXrReads=new WeakMap;selectionXrDetector;beforeAndroidTapForTesting;static SEARCH_UNTIL_DEFAULT_MS=O;static SEARCH_UNTIL_MIN_MS=100;static SEARCH_UNTIL_MAX_MS=ee;static SEARCH_POLL_INTERVAL_MS=100;constructor(i,n=null,s={}){super(i,{adb:n,timer:s.timer,displayFence:s});this.selectionXrDetector=s.xrDetector,this.lastRenderedObservation=s.lastRenderedObservation??sW,this.geometry=new ir,this.elementSelector=s.elementSelector??new vr(void 0,void 0,{platform:this.tapPlatform,iosMultiPanel:this.iosMultiPanel}),this.accessibilityService=s.accessibilityService??Ws(i,this.adbFactory),this.hierarchyAccessibilityService=Ws(i,this.adbFactory),this.viewHierarchy=new Xi(i,this.adbFactory),this.hierarchyCapture=s.hierarchyCapture??new Wg(this.tapPlatform,{readCached:(d)=>this.viewHierarchy.getViewHierarchy({},{skipWaitForFresh:!0,minTimestamp:d.minTimestamp??0,signal:d.signal,timeoutMs:d.timeoutMs}),readFresh:async(d)=>{if(d.displayId!==void 0)return(await vn(i,{adbFactory:this.adbFactory,timer:this.timer}).capture(d)).hierarchy;let p=await this.readFreshHierarchy(d.timeoutMs??O,void 0,d.signal,d.requireFreshExtraction);if(!p)throw new t("Unable to retrieve a fresh tapAny hierarchy");return p},projectVisible:(d)=>this.viewHierarchy.projectActionableHierarchy(d)},this.timer),this.iosVoiceOverDetector=s.iosVoiceOverDetector??Ao,this.featureFlags=s.featureFlags??sr.getInstance(),this.accessibilityDetector=s.accessibilityDetector??ni,this.talkBackDriverFactory=s.talkBackDriverFactory??new qh(this.adbFactory),this.talkBackStrategy=s.talkBackStrategy??new Iv({timer:this.timer,driverFactory:this.talkBackDriverFactory});let a=this.createTappers(s);this.androidTapper=a.android,this.iosTapper=a.ios}createTappers(i){let n=i.xrDetector??Sw,s=i.androidTapper??new X({device:this.device,timer:this.timer,getAdb:()=>this.adb,accessibilityService:this.accessibilityService,accessibilityDetector:this.accessibilityDetector,featureFlags:this.featureFlags,talkBackStrategy:this.talkBackStrategy,talkBackDriverFactory:this.talkBackDriverFactory,resolveContainer:(d,p)=>this.elementSelector.resolveContainer?.(d,p),isAndroidXr:(d)=>ra({device:this.device,adb:this.adb,signal:d},n),beforeTap:()=>this.beforeAndroidTapForTesting?.(),refreshViewHierarchy:(d,p,l,c)=>this.refreshViewHierarchy(d,p,l,c),findClickableElement:async(d,p,l)=>(await this.prepareXrSelection(d),this.findClickableElement(d,p,l)),resolveTapPoint:(d,p)=>this.resolveTapPoint(d,p)}),a=i.iosTapper??new Q({device:this.device,iosVoiceOverDetector:this.iosVoiceOverDetector,featureFlags:this.featureFlags});return{android:s,ios:a}}get testHooks(){return{findClickableElement:this.findClickableElement.bind(this),refreshViewHierarchy:this.refreshViewHierarchy.bind(this),readFreshHierarchy:this.readFreshHierarchy.bind(this),setRefreshViewHierarchy:(i)=>{this.refreshViewHierarchyOverrideForTesting=i},setBeforeAndroidTap:(i)=>{this.beforeAndroidTapForTesting=i}}}createErrorResult(i,n){return mL(i,n)}getSearchUntilDuration(i){return dL(i.searchUntil?.duration,{defaultMs:LA.SEARCH_UNTIL_DEFAULT_MS,minMs:LA.SEARCH_UNTIL_MIN_MS,maxMs:LA.SEARCH_UNTIL_MAX_MS})}isContainerAvailable(i,n){return lL(this.elementSelector,i,n)}async prepareXrSelection(i,n){if(this.tapPlatform!=="android")return;let s=this.selectionXrReads.get(i);if(!s)s=ra({device:this.device,adb:this.adb,signal:n},this.selectionXrDetector),this.selectionXrReads.set(i,s);this.selectionXr.set(i,await s)}findClickableElement(i,n,s={}){return Ce({xr:this.selectionXr.get(i),elementSelector:this.elementSelector,isContainerAvailable:(a,d)=>this.isContainerAvailable(a,d),platform:this.tapPlatform,iosMultiPanel:this.iosMultiPanel},i,n,s)}resolveTapPoint(i,n={}){return Le({geometry:this.geometry,platform:this.tapPlatform,iosMultiPanel:this.iosMultiPanel},i,n)}async refreshViewHierarchy(i,n,s,a=!1){if(this.refreshViewHierarchyOverrideForTesting)return this.refreshViewHierarchyOverrideForTesting((d,p,l)=>this.refreshViewHierarchyDefault(d,p,l,a),i,n,s);return this.refreshViewHierarchyDefault(i,n,s,a)}async refreshViewHierarchyDefault(i,n,s,a=!1){if(o(s),i<=0)return null;try{let d=await this.hierarchyCapture.capture({freshness:"fresh",...a?{requireFreshExtraction:!0}:{},searchRaw:N.isRawElementSearchEnabled(),timeoutMs:i,signal:s});return vd(this.tapPlatform,d.hierarchy,"fresh",{timer:this.timer,captureId:d.captureId,iosMultiPanel:this.iosMultiPanel}),d.hierarchy}catch(d){return o(s),e.warn(`[TapAnyElement] Fresh capture failed: ${r(d)}`),null}}async readFreshHierarchy(i,n,s,a=!1){return NF({device:this.device,adb:this.adb,timer:this.timer,androidService:this.hierarchyAccessibilityService,viewHierarchy:this.viewHierarchy,prepareForResponse:(d,p)=>this.prepareViewHierarchyForResponse(d,p),actionLabel:"tap any element"},{timeoutMs:i,screenSize:n,signal:s,forceCapture:a})}async pollClickableTarget({options:i,observeResult:n,refresh:s,signal:a,selectedCapture:d,searchDurationMs:p,startTime:l,lastHash:c,containerFoundEver:m}){let h=0,y=0,g=null;if(h=(await FF({timer:this.timer,startTime:l,durationMs:p,intervalMs:LA.SEARCH_POLL_INTERVAL_MS,pacing:"sleepFirst",discardLateResult:!0,signal:a,fetch:async(v)=>{let w=await s(v,n.screenSize,a);if(w)await this.prepareXrSelection(i,a);return w},accept:(v)=>{let w=bn(v);if(w&&w!==c)y+=1,c=w;d=vd(this.tapPlatform,v,"fresh",{timer:this.timer,iosMultiPanel:this.iosMultiPanel});let _=this.findClickableElement(i,d.hierarchy,{observationScreenSize:n.screenSize,display:n.viewHierarchy});return g=_.element,m=m||_.containerFound,g!==null}})).requestCount,!g)qe(i,m);return{element:g,selectedCapture:d,startTime:l,requestCount:h,changeCount:y}}async tapObservedElement({options:i,observeResult:n,fence:s,targetDisplay:a,refresh:d,onActivationWarnings:p,onDispatched:l,perf:c,signal:m,requestDeadlineMs:h}){o(m);let y=n.viewHierarchy;if(!y)return c.end(),{success:!1,error:"Unable to get view hierarchy, cannot tap on element"};let g;if(this.device.platform==="android"){let D=await Wh(this.accessibilityDetector,this.device.deviceId,this.adb,this.featureFlags);if(g=D.talkBack,D.unconfirmed)p([Ca]);if(g)y=await uv((tt)=>d(tt,n.screenSize,m),this.timer,m),n.viewHierarchy=y}let b=vd(this.tapPlatform,y,"cached-ok",{timer:this.timer,captureId:n.observationId,iosMultiPanel:this.iosMultiPanel}),v=this.getSearchUntilDuration(i),w=this.timer.now(),_=0,T=0,B=bn(y);await this.prepareXrSelection(i,m);let ne=this.findClickableElement(i,b.hierarchy,{observationScreenSize:n.screenSize,display:n.viewHierarchy}),{element:I,containerFound:et}=ne;if(!I)({element:I,selectedCapture:b,requestCount:_,changeCount:T}=await this.pollClickableTarget({options:i,observeResult:n,refresh:d,signal:m,selectedCapture:b,searchDurationMs:v,startTime:w,lastHash:B,containerFoundEver:et}));let V=await this.refreshCachedHierarchy(y,g,_,{refresh:d,screenSize:n.screenSize,signal:m,requestDeadlineMs:h});if(g=V.accessibilityEnabled,V.hierarchy){y=V.hierarchy,n.viewHierarchy=y,w=this.timer.now(),b=vd(this.tapPlatform,y,"fresh",{timer:this.timer}),await this.prepareXrSelection(i,m);let D=this.findClickableElement(i,b.hierarchy,{observationScreenSize:n.screenSize,display:y});if(I=D.element,!I)({element:I,selectedCapture:b,requestCount:_,changeCount:T}=await this.pollClickableTarget({options:i,observeResult:n,refresh:d,signal:m,selectedCapture:b,searchDurationMs:v,startTime:w,lastHash:bn(y),containerFoundEver:D.containerFound}))}let j=Ne(i,n,{element:I,capture:b,talkBackState:g}),oe=this.resolveTapPoint(j);ub(j.capture.hierarchy,i.layer,oe,"tap");let se=i.action;return await this.dispatchTapTarget({options:i,observeResult:n,fence:s,targetDisplay:a,refresh:d,onActivationWarnings:p,onDispatched:l,signal:m,tapPoint:oe,target:j,action:se}),c.end(),this.createSuccessResult(se,j,w,{requestCount:_,changeCount:T})}async refreshCachedHierarchy(i,n,s,a){if(this.device.platform!=="android"&&this.device.platform!=="ios"||n||s!==0||Dm(i))return{accessibilityEnabled:n};if(this.device.platform==="ios"){if(n=await this.iosVoiceOverDetector.isVoiceOverActiveOrUnknown(this.device.deviceId,x.getInstance(this.device),{featureFlags:this.featureFlags,signal:a.signal}),n)return{accessibilityEnabled:n}}return{hierarchy:await uv((p)=>this.device.platform==="ios"?a.refresh(p,a.screenSize,a.signal,!0):a.refresh(p,a.screenSize,a.signal),this.timer,a.signal,{timeoutMs:Math.min(zi,a.requestDeadlineMs===void 0?zi:a.requestDeadlineMs-this.timer.now()),context:"while revalidating a cached observation",platform:this.device.platform}),accessibilityEnabled:n}}async dispatchTapTarget({options:i,observeResult:n,fence:s,targetDisplay:a,refresh:d,onActivationWarnings:p,onDispatched:l,signal:c,tapPoint:m,target:h,action:y}){let{element:g,capture:b}=h,v=re({platform:this.device.platform,timer:this.timer},i),w={signal:c,displayFence:s,onActivationWarnings:p};switch(e.info(`[TapAnyElement] Tapping (${m.x}, ${m.y}) on clickable element: text=${JSON.stringify(g.text)}, bounds=${JSON.stringify(g.bounds)}`),this.device.platform){case"android":{let _=bn(b.hierarchy),T=a?await WL(this.accessibilityService,this.adb,{action:y,duration:v},{target:a,signal:c,onDispatched:l,timer:this.timer,onWarning:(B)=>p([B]),talkBack:h.talkBackState===!0?{strategy:this.talkBackStrategy,driver:this.talkBackDriverFactory.createDriver(this.device)}:void 0}):void 0;if(T)R(b),await T(m);else await this.androidTapper.executeAndroidTap(y,m,v,{target:h,fenceOptions:w});await this.androidTapper.retryAndroidTapIfNoChange(_,h,y,{durationMs:v,fenceOptions:{...w,screenSize:n.screenSize,selectionOptions:i,refresh:d,dispatch:T}});break}case"ios":a?.assertCurrent(),R(b),await this.iosTapper.executeIosTap(y,m,v,{element:g,fenceOptions:{signal:c,displayFence:s,scoped:h.scoped,voiceOverEnabled:h.talkBackState??void 0}});break;default:throw St(this.device.platform,"tap any element")}}async execute(i,n,s,a){let{progress:d,signal:p,deadlineMs:l}=Gte(n,s,a),c=zL(l);return Cm(()=>this.executeWithReadScope(i,d,p,c))}async executeWithReadScope(i,n,s,a){if(i={...i},!i.action)return this.createErrorResult(i.action,"tap action is required");let d=uL(i.container,"tapAny");if(d)return this.createErrorResult(i.action,d);let p=J();p.serial("tapAnyElement");let l=0,c=i.display!==void 0;try{re({platform:this.device.platform,timer:this.timer},i,a),o(s);let m=i.display===void 0?void 0:await Wi(this.device,i.display,this.observeScreen,{adb:this.adb,lastRenderedObservation:this.lastRenderedObservation,signal:s,transitions:this.displayTransitionReader}),h=m&&this.device.platform==="android"?(v,w,_)=>bL(m,this.hierarchyCapture,v,{stale:()=>this.staleDisplay(m.observation.display.generation??this.displayTransitionReader.identityRevision(this.device.deviceId)),signal:_}):this.refreshViewHierarchy.bind(this),y=new Set,g=(v=[])=>{for(let w of v)y.add(w)},b=await this.observedInteraction((v,w)=>this.tapObservedElement({options:i,observeResult:v,fence:w,targetDisplay:m,refresh:h,onActivationWarnings:g,onDispatched:()=>{l++,c=i.action!=="doubleTap"||l!==1},perf:p,signal:s,requestDeadlineMs:a?.requestDeadlineMs}),{...Kt.selectorResolvedGesture,display:m?.followUpDisplay,previousObservation:m?.observation,timeoutMs:At.gesture,progress:n,perf:p,signal:s,predictionContext:{toolName:"tapAny",toolArgs:{action:i.action,duration:i.duration,container:i.container,selectionStrategy:i.selectionStrategy,scrollableContainer:i.scrollableContainer,platform:this.device.platform}}});return this.checkTapDeliveryDisplay(b,m?.assertCurrent,s),{...b,...y.size>0?{warnings:[...y]}:{}}}catch(m){p.end(),this.rethrowObservationAbort(m,s,c);let h=r(m);if(e.warn(`[TapAnyElement] Tap failed: ${h}`,m),m instanceof Ee)return Zt(this.createErrorResult(i.action,m.message),m);return Zt({success:!1,action:i.action,error:`Failed to tap clickable element: ${h}`,element:{bounds:{left:0,top:0,right:0,bottom:0}}},m)}}checkTapDeliveryDisplay(i,n,s){if(i.success)this.checkPostActionDisplay(i,n,s);else n?.()}createSuccessResult(i,n,s,{requestCount:a,changeCount:d}){return{success:!0,action:i,element:n.element,captureId:n.capture.captureId,searchUntil:{durationMs:Math.max(0,Math.round(this.timer.now()-s)),requestCount:a,changeCount:d}}}prepareViewHierarchyForResponse(i,n){return je({platform:this.device.platform,viewHierarchy:this.viewHierarchy},i,n)}}var Wc=120000,i5=120000;var BA=30000;function VS(i){if(typeof i!=="number"||!Number.isFinite(i)||i<=0)return;return Math.min(i,yh)}var Ut=600000,Ht=rl,Ft=1e6,Bt=5000,Vt=8,zt=180000,Wt=xo+Kr+gs,Gt=Kr+gs,Yt=90000,Xt=90000,Jt=450000,Qt=90000,ei=60000,ti=30000,ii=3*Wc+ti,Ue=60000,ri=60000;var oi=Math.max(L,q),si=new Map(Object.entries({deviceSnapshot:r_+x4,barrier:tv+rl,criticalSection:tv+rl,explore:g_+rl,putAppFile:fh+z,setDeviceResources:bu+gs,reconcileDeviceResources:bu+gs,uninstallApp:ei,crashApp:Xt,performanceTrace:Jt,getPreference:Ue,setPreference:Ue,setUIState:ri})),ai=90000,di=f.OPEN_LINK_MCP_TIMEOUT_MS.name,pi=f.OPEN_LINK_MCP_TIMEOUT_MS.legacyName,ci=90000,li=f.OBSERVE_MCP_TIMEOUT_MS.name,ui=f.OBSERVE_MCP_TIMEOUT_MS.legacyName;function He(i,n,s,a=process.env){return Yn(i,n,{fallback:s,env:a})}function mi(i){return typeof i==="string"?si.get(i):void 0}function ze(i,n){switch(i){case"executePlan":return Ut;case"getAndroid":case"getApple":case"startDevice":return zt;case"provisionDevice":return Wt;case"deleteDevice":return Gt;case"launchApp":return Yt;case"videoRecording":return Qt;case"installApp":return ii;case"openLink":return He(di,pi,ai,n);case"observe":return He(li,ui,ci,n);default:return mi(i)}}function hi(i,n){let s=Array.isArray(i.files)?Math.max(1,i.files.length):1;return k(s*n,n,z)}var gi=5000;function fi(i,n){let s=0;for(let a=0;a<n;a+=1){let d=A(i[a]);if(d!==void 0&&typeof d.observation==="string")s+=1}return s}function bi(i,n){let s=S(i.timeoutMs)??gi;if(n===0)return s;return fi(Array.isArray(i.assets)?i.assets:[],n)*iV+2*(n*MB+s)}function vi(i){return Array.isArray(i.assets)?Math.min(i.assets.length,Ag):0}function wi(i){let n=vi(i);return n===0?0:k(bi(i,n),MB,rl)}function Si(i){if(i.action==="show")return wi(i);if(i.action==="save"||i.action==="open")return k(Math.min(S(i.timeoutMs)??HS,mh),HS,rl);if(i.action!=="awaitEvent")return 0;return k(Math.min(S(i.timeoutMs)??US,mh),US,rl)}var $e=new Map([["deviceSnapshot",(i)=>k(Math.min(S(i.vmSnapshotTimeoutMs)??r_,n_),r_,x4)],["observe",Ae],["mediaSession",ke],["barrier",(i)=>k(i.timeout,tv,rl)],["criticalSection",(i)=>k(i.timeout,tv,rl)],["explore",(i)=>k(i.timeoutMs,g_,rl)],["putAppFile",(i)=>hi(i,fh)],["prototype",Si],["killProfile",ae],["systemTray",(i)=>i.action==="list"?k(i.awaitTimeout,aV,de):0]]);function Ai(i){if(i.method!=="tools/call")return 0;let n=i.params?.name,s=typeof n==="string"?$e.get(n):void 0;return typeof s==="function"?s(A(i.params?.arguments)??{}):0}function ki(i){let n=S(i.bootTimeoutMs)??Ve,s=S(i.automationReadyTimeoutMs)??Ua;return Math.min(n+s,Co)+gs}function xi(i){let n=A(i.device)?.timeoutMs,s=S(i.timeoutMs??n);return Math.min(s??zm,Co)+gs}function _i(i,n){return we(String(i))?Ti(n):void 0}function Ke(i){if(i.method!=="tools/call")return;let n=A(i.params?.arguments);if(!n)return;switch(i.params?.name){case"getAndroid":case"getApple":return ki(n);case"startDevice":return xi(n);case"provisionDevice":return Pi(n);case"deleteDevice":{let s=S(n.timeoutMs)??Kr;return Math.min(s,Co)+gs}default:return _i(i.params?.name,n)}}function Pi(i){let n=S(i.timeoutMs)??xo;return Math.min(n,Qw)+Kr+gs}function Ti(i){let n=S(i.timeoutMs)??bu;return Math.min(n,Co)+gs}function We(i){return i.action==="longPress"||i.action===void 0&&S(i.duration)!==void 0}function Ge(i){if(i.method!=="tools/call"||i.params?.name!=="tapAny")return;let n=A(i.params?.arguments);if(!n||!We(n))return;let s=S(n.duration)??oi;return Ye(n,s,F)}function Ye(i,n,s){let a=S(A(i.searchUntil)?.duration)??O;return Math.min(Math.round(n)+Math.round(a)+s,Fr)}function Xe(i){if(i.method!=="tools/call"||i.params?.name!=="tapOn")return;let n=A(i.params?.arguments);if(!n||n.action!==void 0&&n.action!=="longPress")return;let s=S(n.duration);return s===void 0?void 0:Ye(n,s,BA)}function Oi(i){if(i.method!=="tools/call"||i.params?.name!=="tapAny")return;let n=A(i.params?.arguments);if(n&&We(n))return;let s=S(A(n?.searchUntil)?.duration)??O,a=ie+Math.round(s)+F;return Math.min(a,Fr)}function Ii(i,n=BA){if(i.method!=="tools/call")return 0;let s=A(i.params?.arguments),a=i.params?.name==="sendKeys"?s?.commands:i.params?.name==="setUIState"?s?.fields:void 0;if(!Array.isArray(a))return 0;let p=a.map((l)=>{let c=A(l),m=i.params?.name==="sendKeys"?c?.action==="type"?c.text:void 0:c?.value;if(typeof m!=="string")return 0;return i.params?.name==="sendKeys"?cV(m).reduce((h,y)=>h+El(y),0):El(m)}).reduce((l,c)=>l+Math.max(0,c-a9),0);if(p===0)return 0;return Math.min(yh,n+p+jk)}function Di(i,n){if(i==="executePlan")return 0;let s=$e.get(i);if(s)return s(n);let a={id:"plan-step",type:"mcp_request",method:"tools/call",params:{name:i,arguments:n}};return Math.max(ze(i)??0,Ke(a)??0,Xe(a)??0,Ge(a)??0)}function Je(i,n,s,{accumulator:a,depth:d}){if(!Array.isArray(i))return;if(d>Vt){a.saturated=!0;return}for(let p of i){if(a.stepsLeft<=0){a.saturated=!0;return}a.stepsLeft-=1;let l=gh.toolAndParams(p);if(!l)continue;let c=s??(n&&typeof l.params.device==="string"?l.params.device:"");if(a.tracks.set(c,(a.tracks.get(c)??0)+Di(l.tool,l.params)),l.tool==="criticalSection")Je(l.params.steps,n,c,{accumulator:a,depth:d+1})}}function Ei(i){try{return A(nv(v_(i),qS))}catch(n){e.debug(`executePlan budget: plan content is not parseable YAML: ${r(n)}`);return}}function Mi(i){if(typeof i!=="string")return 0;if(i.length>Ft)return yh;let n=Ei(i);if(!n)return 0;let s={tracks:new Map,stepsLeft:Bt,saturated:!1},a=Array.isArray(n.devices)&&n.devices.length>0;if(Je(n.steps,a,void 0,{accumulator:s,depth:0}),s.saturated)return yh;let d=[...s.tracks.values()].reduce((p,l)=>Math.max(p,l),0);return Math.min(d+Ht,yh,Fr)}function Ci(i){if(i.method!=="tools/call"||i.params?.name!=="executePlan")return 0;return Mi(A(i.params?.arguments)?.planContent)}function B0(i,n=process.env){let s=VS(i.timeoutMs)??BA,a=i.method==="tools/call"?ze(i.params?.name,n):void 0;return Qe(i,s,a)}function Qe(i,n,s){return Math.max(n,Ai(i),Ci(i),Ii(i,s),s??0,Ke(i)??0,Xe(i)??0,Ge(i)??0,Oi(i)??0)}function Li(i,n=process.env){if(!xe(i))return B0(i,n);let s=VS(FA(i,n))??VS(i.requestedTimeoutMs);return s===void 0?B0(i,n):Qe(i,BA,s)}var Fe=new WeakMap;function $0(i,n=process.env){let s=Fe.get(i);if(s!==void 0)return s;let a=Li(i,n);return Fe.set(i,a),a}var Ni=300000;class vh{currentMs;ceilingMs;extensionListeners=new Set;constructor(i,n,s=Ni){this.currentMs=i+n,this.ceilingMs=i+Math.max(n,s)}get value(){return this.currentMs}get ceiling(){return this.ceilingMs}extendOnProgress(i,n){let s=Math.min(i+n,this.ceilingMs);if(s<=this.currentMs)return;this.currentMs=s;for(let a of[...this.extensionListeners])a()}onExtended(i){return this.extensionListeners.add(i),()=>{this.extensionListeners.delete(i)}}}
3
+ export{h_,tv,g_,US,mh,r5,WQ,iV,zQ,rv,oV,os,sV,HS,M0,y_,N0,fh,jQ,MA,um,F0,aV,KQ,cV,qS,v_,n5,hh,gh,NA,GQ,YQ,L0,JQ,XQ,ZQ,yh,FA,LA,Wc,i5,BA,VS,B0,$0,vh};
4
+
5
+ //# debugId=A44C4C5B1978D15E64756E2164756E21