@kaeawc/auto-mobile 0.0.92 → 0.0.94

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/ble-peripheral.py +153 -0
  4. package/dist/src/{chunk-r14wwk37.js → chunk-026y62r9.js} +12 -12
  5. package/dist/src/chunk-0jyfg947.js +4 -0
  6. package/dist/src/{chunk-950qcq1e.js → chunk-0zfpp1wh.js} +4 -4
  7. package/dist/src/chunk-13qxf7ym.js +7 -0
  8. package/dist/src/chunk-1scenrk7.js +4 -0
  9. package/dist/src/chunk-1vb5ph1k.js +4 -0
  10. package/dist/src/chunk-20g565q7.js +5 -0
  11. package/dist/src/chunk-21h6dhdm.js +5 -0
  12. package/dist/src/{chunk-2e6s75qv.js → chunk-25mfpthk.js} +8 -8
  13. package/dist/src/{chunk-9rkfyt6q.js → chunk-2b39zyxc.js} +3 -3
  14. package/dist/src/chunk-2gzd6wbd.js +4 -0
  15. package/dist/src/{chunk-eka89q3k.js → chunk-3dntffy9.js} +1 -1
  16. package/dist/src/chunk-3gfczcsn.js +4 -0
  17. package/dist/src/chunk-3h5jz1vb.js +9 -0
  18. package/dist/src/chunk-41zcy6b3.js +5 -0
  19. package/dist/src/chunk-47n9m2de.js +4 -0
  20. package/dist/src/chunk-4vxeq0vd.js +58 -0
  21. package/dist/src/chunk-59dx6qaf.js +4 -0
  22. package/dist/src/chunk-5sdf9y92.js +4 -0
  23. package/dist/src/chunk-5wk1t46v.js +5 -0
  24. package/dist/src/chunk-661c50hh.js +17 -0
  25. package/dist/src/chunk-68n6bjjd.js +21 -0
  26. package/dist/src/{chunk-zg67wjkh.js → chunk-69pmjdf2.js} +3 -3
  27. package/dist/src/chunk-6hrj3jt6.js +145 -0
  28. package/dist/src/{chunk-b4cxdzwy.js → chunk-6myr26wx.js} +8 -8
  29. package/dist/src/chunk-6n96k09n.js +4 -0
  30. package/dist/src/chunk-6vwrbkre.js +4 -0
  31. package/dist/src/chunk-6wk0yrab.js +4 -0
  32. package/dist/src/chunk-6yhm9een.js +4 -0
  33. package/dist/src/chunk-7k7gjg2t.js +7 -0
  34. package/dist/src/chunk-7n5fz68h.js +4 -0
  35. package/dist/src/chunk-8cvnpnbp.js +4 -0
  36. package/dist/src/chunk-8kzv7rk7.js +4 -0
  37. package/dist/src/chunk-8nj68t1v.js +167 -0
  38. package/dist/src/{chunk-r20pe1nv.js → chunk-96r3bpg7.js} +3 -3
  39. package/dist/src/chunk-97x887te.js +4 -0
  40. package/dist/src/{chunk-sz1a7p43.js → chunk-99a6tbvd.js} +1 -1
  41. package/dist/src/chunk-9p5d2994.js +5 -0
  42. package/dist/src/{chunk-w7zsh13a.js → chunk-9q265er0.js} +4 -4
  43. package/dist/src/chunk-9xgnrv5w.js +5 -0
  44. package/dist/src/chunk-9xgsmshb.js +5 -0
  45. package/dist/src/chunk-a02d1wgv.js +4 -0
  46. package/dist/src/{chunk-km0dy5vc.js → chunk-a9ps00a1.js} +10 -10
  47. package/dist/src/chunk-aewdveet.js +5 -0
  48. package/dist/src/chunk-b3tdtq7r.js +9 -0
  49. package/dist/src/chunk-bn7jx7a2.js +4 -0
  50. package/dist/src/chunk-bnyw27ja.js +4 -0
  51. package/dist/src/{chunk-s1zq65ny.js → chunk-bpwsg76p.js} +2 -2
  52. package/dist/src/chunk-bvranw3g.js +4 -0
  53. package/dist/src/chunk-c25a84zb.js +4 -0
  54. package/dist/src/chunk-c27yv1dx.js +5 -0
  55. package/dist/src/chunk-c3ewxm4x.js +5 -0
  56. package/dist/src/chunk-cb1ga9rd.js +7 -0
  57. package/dist/src/chunk-cn7fwy7k.js +4 -0
  58. package/dist/src/chunk-cnvy4a64.js +4 -0
  59. package/dist/src/chunk-cqhw4yr6.js +5 -0
  60. package/dist/src/{chunk-v90es00d.js → chunk-ctmfshjc.js} +2 -2
  61. package/dist/src/chunk-ctwmhz13.js +4 -0
  62. package/dist/src/{chunk-qv2918jt.js → chunk-d3jx9bz5.js} +2 -2
  63. package/dist/src/{chunk-wry6skrm.js → chunk-d6rb08ga.js} +1 -1
  64. package/dist/src/chunk-ddqhj4eg.js +5 -0
  65. package/dist/src/{chunk-d57432wq.js → chunk-ddrhs1c3.js} +2 -2
  66. package/dist/src/chunk-dnjnh9p6.js +4 -0
  67. package/dist/src/{chunk-ajsrz473.js → chunk-dw5rwgya.js} +3 -3
  68. package/dist/src/chunk-e0870khr.js +5 -0
  69. package/dist/src/chunk-ea3k10kj.js +4 -0
  70. package/dist/src/chunk-emv82m1w.js +7 -0
  71. package/dist/src/chunk-f3m6pdnx.js +4 -0
  72. package/dist/src/chunk-f84z32cb.js +4 -0
  73. package/dist/src/chunk-fpczgf0z.js +4 -0
  74. package/dist/src/chunk-g2js4c2v.js +971 -0
  75. package/dist/src/chunk-g3af2qbk.js +5 -0
  76. package/dist/src/chunk-gadtna7s.js +11 -0
  77. package/dist/src/{chunk-c9nk1r78.js → chunk-gcyx407v.js} +3 -3
  78. package/dist/src/{chunk-jdqvcq0a.js → chunk-gfpntwc1.js} +3 -3
  79. package/dist/src/chunk-gmnm5e3e.js +4 -0
  80. package/dist/src/chunk-gp6vb5gf.js +4 -0
  81. package/dist/src/chunk-gppgy7pa.js +4 -0
  82. package/dist/src/chunk-hegfz0ae.js +5 -0
  83. package/dist/src/chunk-hpzxdp1k.js +17 -0
  84. package/dist/src/{chunk-2v7tw1nj.js → chunk-j69g8b50.js} +3 -3
  85. package/dist/src/chunk-jvstjnqm.js +19 -0
  86. package/dist/src/chunk-jzqrv78s.js +4 -0
  87. package/dist/src/chunk-k2948b8d.js +4 -0
  88. package/dist/src/chunk-k4ftd40d.js +4 -0
  89. package/dist/src/chunk-kd9vfaxh.js +5 -0
  90. package/dist/src/{chunk-34zxqcmq.js → chunk-kdczmgwk.js} +3 -3
  91. package/dist/src/chunk-ke3wn14v.js +4 -0
  92. package/dist/src/chunk-kh5n7m6w.js +4 -0
  93. package/dist/src/{chunk-0dfnyfkh.js → chunk-khejfph4.js} +3 -3
  94. package/dist/src/chunk-kny2xemh.js +4 -0
  95. package/dist/src/chunk-knyzw9md.js +4 -0
  96. package/dist/src/chunk-mbzpt2hp.js +4 -0
  97. package/dist/src/chunk-mm8rcxad.js +4 -0
  98. package/dist/src/chunk-nc4516tx.js +4 -0
  99. package/dist/src/{chunk-stfzjr9y.js → chunk-ntfrqrqn.js} +5 -5
  100. package/dist/src/chunk-nz5h2j52.js +4 -0
  101. package/dist/src/chunk-p22s97qy.js +4 -0
  102. package/dist/src/chunk-p9kt1sgr.js +6 -0
  103. package/dist/src/{chunk-9y5bcy28.js → chunk-pf282r5g.js} +4 -4
  104. package/dist/src/chunk-pnd4mrxy.js +4 -0
  105. package/dist/src/chunk-pqqteyj6.js +4 -0
  106. package/dist/src/chunk-qj1tbnv2.js +8 -0
  107. package/dist/src/chunk-qnh9egwr.js +4 -0
  108. package/dist/src/chunk-qy3khhf8.js +8 -0
  109. package/dist/src/chunk-r0vp315h.js +11 -0
  110. package/dist/src/chunk-r4j43b9s.js +237 -0
  111. package/dist/src/{chunk-4pfftt07.js → chunk-r54cxxze.js} +3 -3
  112. package/dist/src/chunk-r6pvhj33.js +325 -0
  113. package/dist/src/chunk-rb7aa5gr.js +54 -0
  114. package/dist/src/chunk-rdj50kb4.js +4 -0
  115. package/dist/src/chunk-rnd4vcas.js +4 -0
  116. package/dist/src/chunk-s3y3zfcx.js +14 -0
  117. package/dist/src/chunk-s4g43k75.js +5 -0
  118. package/dist/src/chunk-sfqe223f.js +311 -0
  119. package/dist/src/chunk-sqdrxjw5.js +7 -0
  120. package/dist/src/{chunk-0w1spptt.js → chunk-t54k47em.js} +4 -4
  121. package/dist/src/chunk-tek4pnvv.js +26 -0
  122. package/dist/src/chunk-tn74y7af.js +4 -0
  123. package/dist/src/chunk-tvq0nzam.js +5 -0
  124. package/dist/src/chunk-tx4f0h9c.js +6 -0
  125. package/dist/src/chunk-vdqag3fj.js +5 -0
  126. package/dist/src/chunk-vz5zzs57.js +4 -0
  127. package/dist/src/chunk-w4s2vfpj.js +4 -0
  128. package/dist/src/chunk-w5yypt53.js +42 -0
  129. package/dist/src/{chunk-r0f1q783.js → chunk-w68v64vh.js} +3 -3
  130. package/dist/src/chunk-whwj0pdk.js +5 -0
  131. package/dist/src/chunk-wnmqt1dc.js +4 -0
  132. package/dist/src/{chunk-8en08r7q.js → chunk-wpe46vsa.js} +3 -3
  133. package/dist/src/chunk-wxdjeb4k.js +27 -0
  134. package/dist/src/chunk-xcqzwf9j.js +247 -0
  135. package/dist/src/chunk-xezekwwn.js +5 -0
  136. package/dist/src/chunk-xf19m15s.js +4 -0
  137. package/dist/src/chunk-xghbxha4.js +4 -0
  138. package/dist/src/{chunk-jhnbfj19.js → chunk-xn9m3xc2.js} +5 -5
  139. package/dist/src/{chunk-a4k9rt7z.js → chunk-yqfz4vts.js} +3 -3
  140. package/dist/src/chunk-z8tvs8nk.js +5 -0
  141. package/dist/src/chunk-zm2rehqb.js +5 -0
  142. package/dist/src/chunk-zs6dqm35.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 +4 -3
  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-32jpxz2y.js +0 -323
  158. package/dist/src/chunk-3jmvqygr.js +0 -238
  159. package/dist/src/chunk-3swvfhqt.js +0 -5
  160. package/dist/src/chunk-44bt78m9.js +0 -5
  161. package/dist/src/chunk-488vt2bp.js +0 -4
  162. package/dist/src/chunk-4fgdhcwx.js +0 -5
  163. package/dist/src/chunk-4jp2se4w.js +0 -4
  164. package/dist/src/chunk-4vhr9e4t.js +0 -4
  165. package/dist/src/chunk-4xd6zs3y.js +0 -15
  166. package/dist/src/chunk-51567pg8.js +0 -4
  167. package/dist/src/chunk-5agqsfev.js +0 -4
  168. package/dist/src/chunk-5d706gmr.js +0 -4
  169. package/dist/src/chunk-5kd4rqk7.js +0 -5
  170. package/dist/src/chunk-61t538bm.js +0 -4
  171. package/dist/src/chunk-6d3mmqxt.js +0 -54
  172. package/dist/src/chunk-6hyt398x.js +0 -5
  173. package/dist/src/chunk-6mnr8kpm.js +0 -4
  174. package/dist/src/chunk-79q5xsdc.js +0 -42
  175. package/dist/src/chunk-7bdgand3.js +0 -4
  176. package/dist/src/chunk-84cp9dw5.js +0 -4
  177. package/dist/src/chunk-86f2h5ww.js +0 -5
  178. package/dist/src/chunk-8cghfzb2.js +0 -19
  179. package/dist/src/chunk-9tf2p9y9.js +0 -5
  180. package/dist/src/chunk-a2sc4jm0.js +0 -5
  181. package/dist/src/chunk-aa5ng3d1.js +0 -4
  182. package/dist/src/chunk-b3h0a6ca.js +0 -4
  183. package/dist/src/chunk-b6a737qt.js +0 -4
  184. package/dist/src/chunk-bn64x5z5.js +0 -5
  185. package/dist/src/chunk-bvh649za.js +0 -12
  186. package/dist/src/chunk-c9tyfg4j.js +0 -26
  187. package/dist/src/chunk-cfsdfqnm.js +0 -4
  188. package/dist/src/chunk-cxyf04jc.js +0 -7
  189. package/dist/src/chunk-da08tx5v.js +0 -4
  190. package/dist/src/chunk-f2tc08m2.js +0 -4
  191. package/dist/src/chunk-f8tnk179.js +0 -5
  192. package/dist/src/chunk-f9s1kkhx.js +0 -5
  193. package/dist/src/chunk-fbp8a4rx.js +0 -4
  194. package/dist/src/chunk-fd2z0sze.js +0 -4
  195. package/dist/src/chunk-fk927f4q.js +0 -54
  196. package/dist/src/chunk-fxmr3a0f.js +0 -4
  197. package/dist/src/chunk-gaqwhd44.js +0 -4
  198. package/dist/src/chunk-ggtd5x5a.js +0 -5
  199. package/dist/src/chunk-gndcfrm7.js +0 -4
  200. package/dist/src/chunk-h3n4adc6.js +0 -310
  201. package/dist/src/chunk-h5pjbb83.js +0 -4
  202. package/dist/src/chunk-hgnnh302.js +0 -4
  203. package/dist/src/chunk-hmke8nhx.js +0 -5
  204. package/dist/src/chunk-j2bx12hn.js +0 -4
  205. package/dist/src/chunk-j70y1a2g.js +0 -4
  206. package/dist/src/chunk-js1jpyxp.js +0 -6
  207. package/dist/src/chunk-kbjq0qvb.js +0 -4
  208. package/dist/src/chunk-kfwx57xd.js +0 -4
  209. package/dist/src/chunk-kzwctna2.js +0 -4
  210. package/dist/src/chunk-m9ehyehy.js +0 -4
  211. package/dist/src/chunk-mct91p1f.js +0 -4
  212. package/dist/src/chunk-mf9spd4g.js +0 -5
  213. package/dist/src/chunk-mgrcansb.js +0 -4
  214. package/dist/src/chunk-mqc1d0eb.js +0 -6
  215. package/dist/src/chunk-n1zmpk0z.js +0 -4
  216. package/dist/src/chunk-ncyjf63g.js +0 -4
  217. package/dist/src/chunk-nr64d21q.js +0 -973
  218. package/dist/src/chunk-nwm2pq5v.js +0 -168
  219. package/dist/src/chunk-pm06b05d.js +0 -9
  220. package/dist/src/chunk-q50s00ry.js +0 -4
  221. package/dist/src/chunk-qwye1958.js +0 -14
  222. package/dist/src/chunk-r8z9pfve.js +0 -5
  223. package/dist/src/chunk-rdpgkjf6.js +0 -4
  224. package/dist/src/chunk-rkr0dks9.js +0 -5
  225. package/dist/src/chunk-rn84t3sf.js +0 -11
  226. package/dist/src/chunk-s123kn7n.js +0 -4
  227. package/dist/src/chunk-s73qn3fx.js +0 -4
  228. package/dist/src/chunk-sjn0nj4p.js +0 -5
  229. package/dist/src/chunk-sns0c35v.js +0 -7
  230. package/dist/src/chunk-t4dr5c8v.js +0 -8
  231. package/dist/src/chunk-tc8k9c1j.js +0 -4
  232. package/dist/src/chunk-teznhase.js +0 -4
  233. package/dist/src/chunk-ty9xgmz4.js +0 -4
  234. package/dist/src/chunk-tyazf3sk.js +0 -145
  235. package/dist/src/chunk-v6npjrjm.js +0 -5
  236. package/dist/src/chunk-vbvtzkwz.js +0 -5
  237. package/dist/src/chunk-vefd8qee.js +0 -8
  238. package/dist/src/chunk-vs9r72ta.js +0 -17
  239. package/dist/src/chunk-w2mwa0jk.js +0 -4
  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,54 @@
1
+ // @bun
2
+ import{Kae,Ur,L8,i,iM,tS,oM,OU,Yae,tm,Q,Lo,eo,Qae,jl,Vf,dr,Zu,l,st,V8,e}from"./chunk-r0vp315h.js";import{h,Y,I,$e,ep}from"./chunk-5wk1t46v.js";import{ni,bo,JN,Qy,MS,vq,bq,ev,tv,rv,YI,wr,t0,cc,LS,dc,Aq,mh,OA,kq,Eq,d0,Iq,QI}from"./chunk-tx4f0h9c.js";import"./chunk-aewdveet.js";import{$s,uB,jv,Yw,fB,Ni,w,Fre,ci,Jw,mz,Nr,ze,Gr,nn,Fr,Hre,Vre,dd,ps,yD,Ag,ld,Rp,vD,Tg,Yv,Zw,Jv,RB,Bt,Sr,kg,Qre,Qw,oY,tne,rne,Ap,Ko,rf,ok,sk,Tp,_u,nne,ck,Qv,ms,iR,sne,di,bl,Sl,ane,IB,Ig,aR,kz,$t,CB,Cz,Dz,dne,eb,Mz,_o,cY,He,H,Xe,me,an,Nz,ee,uk,DB,kn,uY,gne,ht,nt,ae,Yo,Uz,Pl,Un,pR,BB,qs,v,Va,ys,cf,Ane,Og,fR,ED,ga,Ve,ao,_D,yR,Vz,Dp,L,Kz,Gz,CD,Yz,db,md,Cu,Xo,qB,b,Zo,mt,Yt,gd,cn,De,pf,PR,pb,AR,tj,je,Gi,le,Ss,Tl,ln,kl,Xne,Zne,ij,xY,jB,In,at,KB,BD,Nu,YB,oj,gb,mf,Yi,Lp,Mc,_n,ER,$p,Ug,un,Fu,XB,tie,rie,IR,za,nie,_R,iie,oie,sie,xR,he,qD,bb,QB,Ai,DR,OY,It,die,lj,uj,xn,o,pn,Hp,NY,FY,mj,LY,N,GD,Pie,Aie,Tie,Fc,ZY,QY,Rs,bf,qk,it,zk,ve,JR,Rd,Bie,Pr,Sa,Cn,Yk,Jk,pi,Ps,Hu,eP,wa,tP,I$,Xn,xt,Ob,ry,M$,ny,tE,pO,Kie,Gie,lP,L$,zp,Fl,kf,hO,iE,gO,yO,sE,aE,Lb,j$,K$,wO,gP,a2,hoe,goe,yoe,O,Ub,Ar,x,Js,E}from"./chunk-sfqe223f.js";import{iJ,sJ}from"./chunk-whwj0pdk.js";import{B,fo,f,_d,Dr,G9,Mf,kt,Nf,jb,Zs,ti,Wn,Qa,Jt,_e,J9,X9,Z9,Q9,Gp}from"./chunk-r6pvhj33.js";import{ho,y,T,yr,j,g,Le,Dt,en,A,RE,n,a,m,TP,S,s,Ie,hce,p,_,Yp}from"./chunk-w5yypt53.js";import{oi,$n,Ow,Cte,Dte,RW,Ue,WC,zC,Rc,Nw,AW,TW,kW,EW,Pu,KC,Uw,A3,_r,ar,ml,Fe,Vw,QC,Ym,xe,ad,ma}from"./chunk-4vxeq0vd.js";import{tn,MA,e_,ir,bi,cu,Ho,lc,bm,Dq,ss,sv,m0,VZ,WZ,zZ,jZ,uc,fh,FA,Qd,Oq,jc,el,n_,na,C4,Ln,KZ,i_,GZ,$S,xa,qo,o_,N4,Fq,Ci,du,HS,Bn,qS,mc,g0,Hq,qq,VS,hh,$4,WS,y0,BA,gh,q4,fc,V4,ap,lu,R0,jS,jq,Ot,P0,A0,cQ,KS,T0,W4,u_,Kq,gQ,Gq,So,Si,uu,x0,Kc,At,K4,bh,wQ,hc,e5,V0,t5,r5,ol,n5,v_}from"./chunk-8nj68t1v.js";import{yc,mu,pp,Tm,km,tF,Oh,rF,iw,nF,XA,iF}from"./chunk-z8tvs8nk.js";import"./chunk-e0870khr.js";import"./chunk-9xgnrv5w.js";import"./chunk-xn9m3xc2.js";import{J0,lee,uee,YA,Z0,xh}from"./chunk-xezekwwn.js";import"./chunk-cqhw4yr6.js";import"./chunk-b3tdtq7r.js";import{NX,Z1,oN,Dy}from"./chunk-qj1tbnv2.js";import"./chunk-96r3bpg7.js";import{Zf,XM,Yl,wX,eN,RX,G1,Xl,kX,EX,sc,eA,_X,Y1}from"./chunk-wxdjeb4k.js";import"./chunk-g3af2qbk.js";import"./chunk-pf282r5g.js";import{sS,Fn,mJ,AG,KE,xM,fJ,hJ,oc,gJ,Kf,yJ,vJ,CM,e1,t1,Ay,GP,r1,aS,Ia,AJ,YP,JE,Gl,TJ,XE,n1,kG,EG,kJ,i1,d1,MM,ZE,OJ,bn,O1,M1,F1,L1,B1,nI,$1,U1,mS,iI,Cy,q1,fS,mX,KG}from"./chunk-r4j43b9s.js";import{Vo,dV,l5,jQ,W0,z0,u5,KQ,ia,up,Mr,p5,YQ,pV,K0,h5,QQ,eee,tee,ree,pu,G}from"./chunk-jvstjnqm.js";import{cs,PV,AV,TV,ye,wee,MF,xee,Gh,FF}from"./chunk-6hrj3jt6.js";import{rq,nq,iq,oq,sq,aq,cq,dq,IA,AZ,l4,os,p4,TZ,lq,m4,kZ}from"./chunk-3h5jz1vb.js";import{LU}from"./chunk-hegfz0ae.js";import{WK}from"./chunk-wpe46vsa.js";import{FE,Y8,J8,X8,Z8,Q8,Py,HU,qU,VU,LE,WU,BE,wM,zU,pG,jU}from"./chunk-p9kt1sgr.js";import{EZ,VI,_A,VN,Ds,uq,hm,WN,xA,zN,IZ,jN,pq,_Z,KN,xZ,y4,v4,GN,CZ,mq,b4,fq,hq,YN}from"./chunk-hpzxdp1k.js";import{hS}from"./chunk-emv82m1w.js";import{M5,LF}from"./chunk-c3ewxm4x.js";import{sH,aH,wI,KX,Oy,dN,lH,GX,h6,uH,YX,JX,XX,ZX,QX,nh,My,Gd,pH,mN,$6,TH,Ly,II,ch,MH,O7,M7,NH,N7,_I,RN,FH,PS,F7,V6,L7,B7,$7,pA,hA,z6,$H,AN,mm,ea,vo}from"./chunk-xcqzwf9j.js";import{tu,Q6,_S,HN,kA,xS,CS,d4,SZ,Jd,wZ,RZ}from"./chunk-gadtna7s.js";import{sG,aG,dG}from"./chunk-r54cxxze.js";import{$I,Y6}from"./chunk-s3y3zfcx.js";import{KU}from"./chunk-21h6dhdm.js";import"./chunk-qy3khhf8.js";import"./chunk-661c50hh.js";import"./chunk-tvq0nzam.js";import"./chunk-8cvnpnbp.js";import{Vv}from"./chunk-t54k47em.js";import"./chunk-9q265er0.js";import{rH}from"./chunk-13qxf7ym.js";import"./chunk-gfpntwc1.js";import"./chunk-gcyx407v.js";import{_V}from"./chunk-kdczmgwk.js";import{SM,UU}from"./chunk-20g565q7.js";import{zK,jK,KK}from"./chunk-ddqhj4eg.js";import{GK,YK,JK}from"./chunk-dw5rwgya.js";import{XK,ZK,QK}from"./chunk-s4g43k75.js";import{eG,tG,rG}from"./chunk-kd9vfaxh.js";import{BU,pM,mM,hM,nG,iG,oG}from"./chunk-w68v64vh.js";import{qd,Vd,_s,Wf,Ry,gM,ic,om,yM,vM,K8,G8,uG,bM}from"./chunk-41zcy6b3.js";import{cz}from"./chunk-9xgsmshb.js";import{VK}from"./chunk-9p5d2994.js";import{i5,aV,Am}from"./chunk-yqfz4vts.js";import{wn,Oi,Zc}from"./chunk-sqdrxjw5.js";import"./chunk-c27yv1dx.js";import"./chunk-vdqag3fj.js";import{Tn}from"./chunk-cb1ga9rd.js";import"./chunk-69pmjdf2.js";import{im,r,t,u}from"./chunk-2b39zyxc.js";var Cc={async push(d,c){let R=x.getExistingInstance(d),D=Va(d)?null:E.getExistingInstance(d);if(!D&&!R)throw new t(`No live CtrlProxy client to clear network state on ${d}`);if(D?.syncNetworkStateToDevice()===!1)throw new t(`Android network state was not delivered to ${d}`);await R?.syncNetworkStateFromHost(c)}};async function Tc(d,c,R,D){let k=new AbortController,P=R.now()+wr,C=R.setTimeout(()=>k.abort(Error("Network cleanup deadline expired")),wr);C.unref?.();try{await l(()=>Xe(()=>d.push(c,{deadlineMs:P,abortSignal:k.signal})),{timer:R,signal:k.signal,label:"push cleared network state"})}catch(M){e.warn(`[networkState] Failed to push cleared network state to ${c}: ${r(M)}`,M);try{D?.(M)}catch(F){e.warn("[networkState] Failed to mark uncleared network state",F)}}finally{R.clearTimeout(C)}}function Ec(d,c={}){let R=c.pusher??Cc,D=(k,P,C)=>{if(!(c.state?.()??ln.getInstance()).clearDeviceOwnedBySession(P,k))return;if(C?.deviceIdentityReplaced){e.debug(`[networkState] Cleanup for session ${k} on replaced serial ${P}: skipped cleared-state device push`);return}let F=c.gapMarkerFor?.(k);d.registerPendingDeviceCleanup(P,Tc(R,P,c.timer??i,(q)=>{F?.(`network mock rules and simulation may remain on ${P}: ${r(q)}`)}),{name:"push cleared network state",leftover:"the released session's network mock rules and error simulation"})};d.onSessionRelease((k,P,C,M)=>{D(k,P,M)}),d.onSessionDeviceUnbound(D)}function Bc(d,c={}){let R=c.pusher??Cc;return(D)=>{if(!(c.state?.()??ln.getInstance()).clearSessionlessDeviceState(D))return;CS(d,D,Tc(R,D,c.timer??i),{timer:c.timer??i,capMs:wr,label:"push cleared network state"})}}class _i extends Error{}var bv=25000,dt=new Map;function wv(d,c=St){let R=(dt.get(d)??[]).filter((D)=>Ke(c,D.sessionId,d,D.recordingIds).length>0);if(R.length>0)dt.set(d,R);else dt.delete(d);return R}var Rv={android:120000,ios:120000},Dv=/^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$/i;function kv(d){return Rv[Dv.test(d)?"ios":"android"]}var St={abandonRecordingsOnReplacedDevice:Pv,hasRecordingsToStop:(d,c)=>eA().length>0||GP.hasSegmentedVideoRecordingsForOwner(d,c)||Z1(d,c),stopSegmentedRecordings:GP.stopSegmentedVideoRecordingsForOwner,captureSegmentedRecordingIdsForOwner:GP.captureSegmentedRecordingIdsForOwner,listActiveVideoRecordings:(d)=>sc({deviceId:d}),stopVideoRecording:async(d)=>{await G1(d)},isDeviceGestureRecordingOwnedBy:Z1,ownedDeviceGestureRecordingId:oN,activeRecordingIdsForOwner:(d,c)=>{let R=oN(d,c);return[...Y1(d,c),...GP.segmentedVideoRecordingHandlesForOwner(d,c),...R===void 0?[]:[R]]},retainedCaptureIdsForOwner:(d,c)=>{let R=oN(d,c);return[...Y1(d,c),...R===void 0?[]:[R]]},stopDeviceGestureRecording:async(d)=>{await Dy(d)},timer:i,finalizeCapMs:kv,markVideoRecordingIncomplete:EX,teardownRetryBackoff:Q({initialDelayMs:1000,multiplier:2,maxDelayMs:8000}),teardownRetryBudgetMs:bv,markDeviceNeedsRecorderRecovery:(d)=>{let c=dt.get(d.deviceId)??[];c.push(d),dt.set(d.deviceId,c)}};function Oc(d,c=St){return(R)=>{St.markDeviceNeedsRecorderRecovery(R),d.markDeviceNeedsRecorderTeardown(R.deviceId,()=>Av(R.deviceId,c),Yl,"release-give-ups")}}async function Av(d,c){let R=dt.get(d)??[];for(let k of R){let P=Ke(c,k.sessionId,d,k.recordingIds);await hr(c,P,c.ownedDeviceGestureRecordingId(k.sessionId,d))}let D=wv(d,c).flatMap((k)=>Ke(c,k.sessionId,d,k.recordingIds));if(D.length>0)throw new t(`Recorder teardown on device ${d} is still unconfirmed for ${D.join(", ")}. Recover the device if retries fail.`);dt.delete(d)}async function Pv(d,c){let R=Y1(d,c),D=oN(d,c);await Promise.all([Fi(()=>GP.finalizeSegmentedVideoRecordingsForOwnerOnReplacedDevice(d,c)),...R.map((k)=>Fi(()=>kX(k))),...D===void 0?[]:[Fi(()=>Dy(D,void 0,void 0,{hostOnly:!0}))]])}async function Fi(d){try{await d()}catch(c){e.warn(`[RecordingSessionCleanup] Host-only recording cleanup failed: ${r(c)}`,c)}}var mr=new Map;function xc(d){let c=mr.get(d)??[];return mr.delete(d),c}class fr extends Error{}async function zt(d,c){try{await c()}catch(R){e.warn(`[recording] Failed to ${d}: ${r(R)}`,R)}}async function Iv(d,c,R,{state:D,deviceGestureRecordingId:k}){let{stopping:P}=D,C=()=>{if(D.capExpired)return;let M=new Set(d.activeRecordingIdsForOwner(c,R));for(let F of P)if(!M.has(F))P.delete(F)};if(await zt(`finalize segmented recordings of released session ${c??"(owner-less)"}`,()=>d.stopSegmentedRecordings(c,R)),C(),await zt(`stop video recordings of released session ${c??"(owner-less)"} on ${R}`,async()=>{let M=await d.listActiveVideoRecordings(R);for(let{recordingId:F,ownerSessionUuid:q}of M){if(q!==c||D.capExpired&&!P.has(F))continue;if(!D.capExpired)P.add(F),D.owned.add(F);await zt(`stop video recording ${F} of released session ${c??"(owner-less)"}`,async()=>{if(await d.stopVideoRecording(F),!D.capExpired)P.delete(F);e.info(`[recording] Stopped recording ${F} on ${R}: owning session ${c??"(owner-less)"} was released`)})}}),k!==void 0&&d.isDeviceGestureRecordingOwnedBy(c,R))await zt(`stop device gesture recording of released session ${c??"(owner-less)"} on ${R}`,async()=>{await d.stopDeviceGestureRecording(k),C(),e.info(`[recording] Device gesture recording on ${R} stopped: owning session ${c??"(owner-less)"} was released; its plan stays fetchable by the owner`)})}async function Cv(d,c,R,D){let k=new Set(d.activeRecordingIdsForOwner(c,R)),P={stopping:new Set(k),owned:k,capExpired:!1},C=d.captureSegmentedRecordingIdsForOwner?.(c,R),M=[],F=d.ownedDeviceGestureRecordingId(c,R),q=d.finalizeCapMs(R),U=c??"(owner-less)";try{await l(Iv(d,c,R,{state:P,deviceGestureRecordingId:F}),{timer:d.timer,timeoutMs:q,label:`finalize recordings of released session ${U}`,timeoutError:()=>new fr,onTimeout:()=>{P.capExpired=!0;let W=C?.()??[];for(let z of W)P.stopping.add(z),k.add(z);let V=new Set([...d.activeRecordingIdsForOwner(c,R),...W]);M=[...new Set([...[...P.stopping].filter((z)=>V.has(z)),...Ke(d,c,R,[...k])])]}})}catch(W){if(W instanceof fr)e.warn(`[recording] Finalizing recordings of released session ${U} on ${R} exceeded ${q}ms; force-stopping ${M.join(", ")||"none"} and marking incomplete`);else e.warn(`[recording] Finalizing recordings of released session ${U} on ${R} failed: ${r(W)}`,W)}if(!P.capExpired){let W=[...new Set([...k,...C?.()??[]])];if(M=Ke(d,c,R,W),M.length===0)return;e.warn(`[recording] Finalizing recordings of released session ${U} on ${R} left retained captures; force-stopping ${M.join(", ")} and marking incomplete`)}if(await hr(d,M,F),Ke(d,c,R,M).length===0)return;let K=Ev(d,{sessionId:c,deviceId:R,recordingIds:M,deviceGestureRecordingId:F,attempts:0});D(K,d.teardownRetryBudgetMs),await K}function Ke(d,c,R,D){let k=new Set(d.retainedCaptureIdsForOwner(c,R));return D.filter((P)=>k.has(P))}async function hr(d,c,R,D){await Promise.all(c.map((k)=>zt(`force-stop recording ${k}`,()=>l(()=>k===R?d.stopDeviceGestureRecording(k):d.markVideoRecordingIncomplete(k),{timer:d.timer,timeoutMs:Yl,signal:D,label:`force-stop recording ${k}`}))))}async function Tv(d,c,R){let D;try{await l(()=>new Promise((k)=>{D=d.timer.setTimeout(k,d.teardownRetryBackoff.delayForAttempt(c))}),{timer:d.timer,signal:R,label:"recording teardown retry backoff"})}finally{if(D!==void 0)d.timer.clearTimeout(D)}}async function Mv(d,c,R){let D=()=>Ke(d,c.sessionId,c.deviceId,c.recordingIds);while(!R.aborted&&D().length>0){if(await Tv(d,c.attempts+1,R),R.aborted)return;let k=D();if(k.length===0)return;c.attempts+=1,await hr(d,k,c.deviceGestureRecordingId,R)}}async function Ev(d,c){let R=new AbortController;try{await l(()=>Mv(d,c,R.signal),{timer:d.timer,timeoutMs:d.teardownRetryBudgetMs,label:`retry recording teardown on ${c.deviceId}`,timeoutError:()=>new _i,onTimeout:()=>R.abort()})}catch(D){if(!(D instanceof _i))e.warn(`[recording] Teardown retry failed on ${c.deviceId}: ${r(D)}`,D);let k=Ke(d,c.sessionId,c.deviceId,c.recordingIds);if(k.length>0){let P={deviceId:c.deviceId,sessionId:c.sessionId,recordingIds:k,attempts:c.attempts,budgetMs:d.teardownRetryBudgetMs};e.warn(`[recording] Teardown gave up on device ${P.deviceId}, released session ${P.sessionId??"(owner-less)"}: recordings ${k.join(", ")}; ${P.attempts} attempts, ${P.budgetMs}ms budget; device needs recorder recovery`),d.markDeviceNeedsRecorderRecovery(P);return}}finally{R.abort()}e.info(`[recording] Teardown retry settled recordings ${c.recordingIds.join(", ")} on ${c.deviceId} for released session ${c.sessionId??"(owner-less)"} after ${c.attempts} attempts`)}var Bv={timer:i,adoptVideoRecordings:_X,adoptSegmentedRecordings:GP.adoptOwnerlessSegmentedVideoRecordings,adoptDeviceGestureRecording:NX};function Ov(d,c){return d.finalizeCapMs(c)+Yl}function _c(d,c=Bv){return(R,D)=>{if(d.getSessionForDevice(R)!==D)return;c.adoptSegmentedRecordings(R,D),c.adoptDeviceGestureRecording(R,D);let k=c.adoptVideoRecordings(R,D);if(!k)return;CS(d,R,k,{timer:c.timer,capMs:Yl,label:`persist adopted recording ownership for session ${D}`})}}function Nc(d,c=St){let R=(D,k,P)=>{if(P?.deviceIdentityReplaced){Fi(()=>c.abandonRecordingsOnReplacedDevice(D,k));return}if(!c.hasRecordingsToStop(D,k))return;d.registerPendingDeviceCleanup(k,Cv(c,D,k,(C,M)=>d.registerPendingDeviceCleanup(k,C,M)),Ov(c,k))};d.onSessionRelease((D,k,P,C)=>{if(!C?.upgradeOnly){let M=[...new Set(c.activeRecordingIdsForOwner(D,k))];if(M.length>0)mr.set(D,M);R(D,k,C)}}),d.onSessionDeviceUnbound(R)}var gr=qD,Lc=3000;function $c(d){return async(c,R)=>{if(d.viewerRead&&await d.viewerRead.applies(c))return d.viewerRead.observe(c,R);let D=c.platform==="android"?await d.readAndroidDeviceClockMs(c,R):d.hostRequestStartMs;return R.throwIfAborted(),d.observe(c,{minTimestamp:D,signal:R})}}function xv(d,c,R){return{observationId:fo("failed_observation",d,c),display:{key:"0",role:"unknown",posture:"unknown",generation:0},updatedAt:d.now(),screenSize:{width:0,height:0},systemInsets:{top:0,right:0,bottom:0,left:0},error:R}}function Li(d,c,R,D){return{deviceId:R,observation:xv(d,c,D)}}async function Hc(d,c,R){let{timer:D,signal:k,assertDeviceActionable:P}=R,C=R.idGenerator??B,M=R.perDeviceTimeoutMs??gr;return(await Promise.allSettled(d.map(async(q)=>{if(k.aborted)return Li(D,C,q.id,`Observation request was aborted for device ${q.id}`);try{P?.(q)}catch(V){let z=r(V);return e.warn(`[Daemon] Skipped observation for ${q.id}: ${z}`),Li(D,C,q.id,z)}let U=new AbortController,K=Error(`Observation request timed out after ${M}ms for device ${q.id}`),W=AbortSignal.any([k,U.signal]);try{let V=await l(c(q,W),{timer:D,timeoutMs:M,label:"Observation request",timeoutError:()=>K,onTimeout:()=>U.abort()});return{deviceId:q.id,observation:V}}catch(V){let z=r(V);return e.warn(`[Daemon] Failed to observe ${q.id}: ${z}`),Li(D,C,q.id,z)}}))).map((q,U)=>{if(q.status==="fulfilled")return q.value;let K=d[U],W=r(q.reason);return e.warn(`[Daemon] Observation task for ${K.id} rejected unexpectedly: ${W}`),Li(D,C,K.id,W)})}function Ae(d){return()=>{throw Error(`DaemonSocketServer.${d} was called on a test double that did not define it`)}}function qc(d){return{start:Ae("start"),close:Ae("close"),quiesce:Ae("quiesce"),isListening:Ae("isListening"),evictDeviceInputCache:Ae("evictDeviceInputCache"),getClientConnectionCount:Ae("getClientConnectionCount"),getAcceptedClientConnectionCount:Ae("getAcceptedClientConnectionCount"),drainSessionReleaseNotifications:Ae("drainSessionReleaseNotifications"),liftSessionlessStrokesOn:Ae("liftSessionlessStrokesOn"),liftStrokesHeldByOn:Ae("liftStrokesHeldByOn"),...d}}function vr(d){return new Set((d??"").split(",").map((c)=>c.trim()).filter(Boolean))}function Uc(d,c){return{androidAppearanceSyncDevices:vr(I(h.ANDROID_APPEARANCE_SYNC_DEVICES,d)),androidObservationStreamDevices:vr(I(h.ANDROID_OBSERVATION_STREAM_DEVICES,d)),iosWarmupDevices:vr(I(h.IOS_WARMUP_DEVICES,d)),appearanceSyncEnabled:Gq(I(h.APPEARANCE_SYNC,d)),iosPassiveWorkEnabled:d[c]===void 0}}class br{settings;isOwned;constructor(d,c){this.settings=d;this.isOwned=c}allows(d,c,R){if(d==="watchos")return!1;if(d==="android"){if(c==="appearance-sync"&&!this.settings.appearanceSyncEnabled)return!1;if(c==="startup-warmup")return!1;let D=c==="appearance-sync"?this.settings.androidAppearanceSyncDevices:this.settings.androidObservationStreamDevices;return this.isOwned(R)||D.has(R)}if(c==="appearance-sync"||!this.settings.iosPassiveWorkEnabled)return!1;return this.isOwned(R)||this.settings.iosWarmupDevices.has(R)}isAppearanceSyncEnabled(){return this.settings.appearanceSyncEnabled}isIosPassiveWorkEnabled(){return this.settings.iosPassiveWorkEnabled}}import{resolve as bI}from"path";var _v=100;function Gc(d){let{timer:c,invalidate:R,notify:D,debounceMs:k=_v}=d,P,C=!1;return Object.assign((F)=>{if(R(),P||C)return;P=c.setTimeout(()=>{P=void 0,D().catch((q)=>{e.warn(`[DeviceStateChangeNotifier] Resource notification failed: ${r(q)}`)})},k)},{dispose:()=>{if(C=!0,P)c.clearTimeout(P),P=void 0}})}function Rr(d){return{appId:d.appId,nodes:d.nodes.map((c)=>({id:c.id,screenName:c.screenName,visitCount:c.visitCount,screenshotPath:c.screenshotPath})),edges:d.edges.map((c)=>({id:c.id,from:c.from,to:c.to,toolName:c.toolName,traversalCount:c.traversalCount})),currentScreen:d.currentScreen}}function Wc(d){return async(c)=>{try{let R=c?await d.exportGraphSummaryForApp(c):await d.exportGraphSummary();return Rr(R)}catch(R){throw e.warn(`[Daemon] Failed to export navigation graph on request: ${R}`),u(R,"Failed to export navigation graph on request")}}}var Fv="to watch stored values";class kr{deps;listenerManagers=new WeakSet;seededStreamManagers=new WeakMap;constructor(d){this.deps=d}listen(d){if(!d)return;this.attach(this.deps.defaultManager());for(let c of this.deps.sessionIds())this.attach(this.deps.managerForSession(c));d.setOnNavigationGraphRequested(Wc({exportGraphSummary:()=>this.resolveUnscopedManager().exportGraphSummary(),exportGraphSummaryForApp:(c)=>this.resolveUnscopedManager().exportGraphSummaryForApp(c)})),e.info("[Daemon] Navigation graph stream listener configured")}resolveUnscopedManager(){let d=this.deps.sessionIds();return d.length===1?this.deps.managerForSession(d[0]):this.deps.defaultManager()}attach(d){let c=this.deps.server();if(c&&!this.seededStreamManagers.get(c)?.has(d)){let R=this.seededStreamManagers.get(c)??new WeakSet;R.add(d),this.seededStreamManagers.set(c,R);for(let D of d.getBuildContexts())if(D.deviceId!==xR)c.pushBuildContextUpdate(D.deviceId,D.appId,{packageId:D.appId,versionCode:D.versionCode,...D.versionKey===void 0?{}:{versionKey:D.versionKey},contentHash:D.contentHash})}if(this.listenerManagers.has(d))return;this.listenerManagers.add(d),d.setBuildContextUpdateListener(({appId:R,deviceId:D,buildContext:k})=>{if(!this.listenerManagers.has(d)||D===xR)return;this.deps.server()?.pushBuildContextUpdate(D,R,k===null?null:{packageId:R,versionCode:k.versionCode,...k.versionKey===void 0?{}:{versionKey:k.versionKey},contentHash:k.contentHash})}),d.setGraphUpdateListener(async()=>{e.info("[Daemon] Navigation graph listener triggered, exporting summary...");try{let R=await d.exportGraphSummary();if(!this.listenerManagers.has(d)){e.debug("[Daemon] Ignoring navigation update from a released or rebound session");return}e.info(`[Daemon] Got summary: appId=${R.appId}, nodes=${R.nodes.length}, edges=${R.edges.length}`);let D=Rr(R),k=d.getDeviceIdForApp(R.appId);this.deps.server()?.pushNavigationGraphUpdate(D,k),e.info(`[Daemon] Pushed navigation graph update: ${R.nodes.length} nodes, ${R.edges.length} edges`)}catch(R){e.warn(`[Daemon] Failed to push navigation graph update: ${R}`)}})}}function bt(d,c,R){if(!dr(d)){e.info(`[Daemon] Skipping observation-stream ${R} for ${d} device ${c}: watchOS devices have no observation stream`);return}let D=d==="android"?h.ANDROID_OBSERVATION_STREAM_DEVICES.name:h.IOS_WARMUP_DEVICES.name;e.info(`[Daemon] Skipping observation-stream ${R} for ${d} device ${c}: passive-work policy filtered it; set ${D} to opt in`)}function Nv(d,c,R){let D=d.sessionManager.getSessionForDevice(c)??O(d.devicePool.getDevice(c));if(!D)return!1;let k=(P)=>at(P,d.sessionManager);return k(D)!==k(R?.trim()||void 0)}async function Vc(d,c,R){let D=c.id;if(Nv(d,D,R))return!0;if(d.sessionManager.getSessionForDevice(D)??O(c))return!1;let k=c.platform,P=R?.trim()||void 0;try{return await gb({action:"observe",deviceId:D,platform:k,requesterSessionUuid:P,sessionManager:d.sessionManager,gate:d.devicePool}),await mf({deviceId:D,platform:k,gate:d.devicePool}),!1}catch(C){if(C instanceof oi||C instanceof Yt)e.debug(`[Daemon] observation of ${D} is read-only: ${r(C)}`);else e.warn(`[Daemon] ownership of ${D} unreadable; observation is read-only: ${r(C)}`,C);return!0}}async function Jc(d,{deviceId:c,sessionUuid:R,packageName:D,fileName:k,subscribe:P}){let C=d.devicePool.getAllDevices().filter((q)=>c===null||q.id===c),M=[],F=_n("observationStream",{allowObserverSessions:!0});for(let q of C){if(q.platform!=="android")continue;try{F.authorize({sessionUuid:R,deviceId:q.id,admitViewer:!0})}catch(K){M.push(r(K));continue}if(P)try{d.devicePool.assertDeviceActionable(q.id,Fv)}catch(K){M.push(r(K));continue}let U=E.getExistingInstance(q.id);if(!U)continue;if(P)await U.subscribeStorage(D,k);else await U.unsubscribeStorage(`${D}:${k}`)}if(M.length>0)throw new t(M.join("; "))}function zc(d,c){let R=x.getInstance(d);return{ensureConnected:async()=>{let D=await R.ensureConnected(),k=c();if(D&&k)R.refreshObservationStreamHierarchyCadence(k.getHierarchyIntervalMsForDevice(d.deviceId));return D},getLatestHierarchy:(...D)=>R.getLatestHierarchy(...D),requestHierarchySyncWithoutObservationStreamPush:async(...D)=>{let k=await R.requestHierarchySyncWithoutObservationStreamPush(...D);return k?{hierarchy:k.hierarchy,...k.frameContext===void 0?{}:{frameContext:k.frameContext}}:null},convertToViewHierarchyResult:(D)=>R.convertToViewHierarchyResult(D),recordInitialObservationStreamHierarchy:(D,k)=>R.recordInitialObservationStreamHierarchy(D,k),requestScreenshotWithoutObservationStreamPush:(...D)=>R.requestScreenshotWithoutObservationStreamPush(...D)}}class Ir{misses;missIncarnations;confirmedDisconnectedIds;forceDisconnectedIds;forceDisconnectedGenerations;offlineRecoveryAttemptedIds;offlineRecoveryAttemptedIncarnations;offlineEpisodes;constructor(d={}){this.misses=d.misses??new dN,this.missIncarnations=d.missIncarnations??new Map,this.confirmedDisconnectedIds=d.confirmedDisconnectedIds??new Set,this.forceDisconnectedIds=d.forceDisconnectedIds??new Set,this.forceDisconnectedGenerations=d.forceDisconnectedGenerations??new Map,this.offlineRecoveryAttemptedIds=d.offlineRecoveryAttemptedIds??new Set,this.offlineRecoveryAttemptedIncarnations=d.offlineRecoveryAttemptedIncarnations??new Map,this.offlineEpisodes=d.offlineEpisodes??new Map}}class Cr{inProgress=!1;releaseNotifications=null;fallbackReleaseNotifications=null}class Tr{skipped=!1;mirrors=[];register(d){if(this.skipped)d.skip();return this.mirrors.push(d),d}skip(){this.skipped=!0;for(let d of this.mirrors)d.skip()}registryOpened(d){for(let c of this.mirrors)c.reconcile(d)}dispose(){for(let d of this.mirrors)d.dispose()}async idle(){await Promise.all(this.mirrors.map((d)=>d.idle()))}async releaseOwnedClaims(d){if(!d)return;for(let c of this.mirrors)await c.releaseOwnedClaims(d)}}class Er{deviceClaimMirrors=new Tr;pidFileWritten=!1;enteredDaemonProcess=!1;completeIdentityPublished=!1;socketBindCommitted=!1;lastDatabaseHealthFailure;healthCheck=null;heartbeatMonitor=null;navigationRetentionMonitor=null;forwardLeaseIdleReleaser=null;orphanWatchdog=null;socketServer=null;deviceDisconnectMonitor=null;deferredSessionRecoverySweeps=new Set;bindingRegistry;brokerDeviceAcquisition;managedExecutionReowner;deviceDataStreamServer=null;unsubscribeAdbMissingDevice=null;recorderDeviceIncarnationListener;backgroundRegistryUpgrade}import{createHash as Lv,randomBytes as $v,timingSafeEqual as Hv}from"crypto";import{closeSync as Yc,constants as Xc,fchmodSync as qv,fstatSync as Uv,lstatSync as Br,readdirSync as Kv,linkSync as Gv,mkdtempSync as Wv,rmdirSync as zv,mkdirSync as Xv,openSync as Qc,readFileSync as Zv,renameSync as tl,rmSync as ey,unlinkSync as ty,writeFileSync as iy}from"fs";import{basename as oy,join as sy,dirname as il}from"path";var ay=60000;function nl(d){return d?d.next():$v(32).toString("base64url")}class Or{path;idGen;publishedToken;removalFiles;platform;renameFile;sleep;now;constructor(d=Ag("token"),c=B,R={}){this.path=d;this.idGen=c;this.removalFiles=R.removalFiles??{createDirectory:Wv,list:Kv,inspect:(D)=>Br(D,{throwIfNoEntry:!1}),move:(D,k)=>{this.assertTarget(D),tl(D,k)},read:(D)=>this.readAt(D),restore:Gv,remove:ty,removeDirectory:zv},this.platform=R.platform??process.platform,this.now=R.now??Date.now,this.renameFile=R.renameFile??tl,this.sleep=R.sleep??((D)=>{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,D)})}assertTarget(d=this.path){let c=Br(d,{throwIfNoEntry:!1});if(c&&(!c.isFile()||c.isSymbolicLink()))throw Error("Unsafe daemon HTTP token file")}observeDestination(){let d=Br(this.path,{throwIfNoEntry:!1});if(!d)return"absent";return JSON.stringify([d.dev,d.ino,d.size,d.mtimeMs,this.readAt(this.path)])}publish(d){let c=this.observeDestination(),R=Q({initialDelayMs:10,maxDelayMs:100});for(let D=1;;D++){if(this.assertTarget(),D>1&&this.observeDestination()!==c)throw new t("Daemon HTTP token file changed while publication was retrying; another daemon may own it");try{this.renameFile(d,this.path);return}catch(k){let P=k instanceof Error&&"code"in k?k.code:void 0;if(this.platform!=="win32"||D>=5||P!=="EPERM"&&P!=="EBUSY"&&P!=="EACCES")throw u(k,"Unable to persist daemon HTTP token");e.debug("Retrying daemon HTTP token publication after a sharing violation"),this.sleep(R.delayForAttempt(D))}}}write(d){let c=`${this.path}.${this.idGen.next()}.tmp`,R=!1;try{Xv(il(this.path),{recursive:!0,mode:448}),this.assertTarget();let D=Qc(c,"wx",384);R=!0;try{if(process.platform!=="win32")qv(D,384);iy(D,d,"utf8")}finally{Yc(D)}this.publish(c),R=!1,this.publishedToken=d.trim(),this.sweepRemovalDirectories()}catch(D){throw e.warn("Unable to persist daemon HTTP token"),u(D,"Unable to persist daemon HTTP token")}finally{if(R)try{ey(c,{force:!0})}catch{e.debug("Daemon HTTP token temporary file cleanup unavailable")}}}read(){return this.readAt(this.path)}readAt(d){let c;try{this.assertTarget(d),c=Qc(d,Xc.O_RDONLY|(process.platform==="win32"?0:Xc.O_NOFOLLOW));let R=Uv(c);if(!R.isFile()||process.platform!=="win32"&&(R.uid!==process.getuid?.()||(R.mode&4095)!==384)){e.debug("Daemon HTTP token file permissions unavailable");return}return Zv(c,"utf8").trim()||void 0}catch{e.debug("Daemon HTTP token file unavailable");return}finally{if(c!==void 0)try{Yc(c)}catch{e.debug("Daemon HTTP token file close unavailable")}}}cleanClaim(d){let c=this.removalFiles;try{c.remove(`${d}/token`)}catch{e.debug("Daemon HTTP token claim cleanup unavailable")}try{c.removeDirectory(d)}catch{e.debug("Daemon HTTP token removal directory cleanup unavailable")}}isStaleRemovalDirectory(d){return!!d?.isDirectory()&&!d.isSymbolicLink()&&Number.isFinite(d.mtimeMs)&&d.mtimeMs<this.now()-ay&&(this.platform==="win32"||d.uid===process.getuid?.()&&(d.mode&4095)===448)}sweepRemovalDirectories(){let d=this.removalFiles;try{let c=il(this.path),R=`${oy(this.path)}.remove-`;for(let D of d.list(c)){if(!D.startsWith(R)||!/^[A-Za-z0-9]{6}$/.test(D.slice(R.length)))continue;let k=sy(c,D),P=d.inspect(k);if(this.isStaleRemovalDirectory(P))this.cleanClaim(k)}}catch{e.debug("Daemon HTTP token stale claim cleanup unavailable")}}remove(){let d=this.publishedToken;if(this.publishedToken=void 0,!d)return;let c=this.removalFiles,R;try{R=c.createDirectory(`${this.path}.remove-`);let D=`${R}/token`;if(c.move(this.path,D),!sl(c.read(D)??"",d)){let k=c.inspect(D);if(k?.isFile()&&!k.isSymbolicLink())c.restore(D,this.path)}}catch{e.debug("Daemon HTTP token file removal unavailable")}finally{if(R)this.cleanClaim(R)}}}function rl(d,c){let R=d?.slice(0,7).toLowerCase()==="bearer "?d.slice(7):"";return sl(R,c)}function sl(d,c){let R=(k)=>Lv("sha256").update(k).digest();return Hv(R(d),R(c))&&d.length>0&&c.length>0}import{createServer as my}from"http";class Pe extends Error{timeoutMs;phase;startupMs;constructor(d,c="query",R){super(`Database health probe timed out after ${d}ms`);this.timeoutMs=d;this.phase=c;this.startupMs=R;this.name="DatabaseHealthProbeTimeoutError"}}class $i extends Pe{constructor(d){super(d,"init",0);this.name="DatabaseHealthProbeInitTimeoutError",this.message=`Database health probe worker did not become ready within ${d}ms`}}import{Worker as dy}from"worker_threads";var cy=1000,ly=1e4,uy=50,py=`
3
+ const { parentPort, workerData } = require("node:worker_threads");
4
+ const { Database } = require("bun:sqlite");
5
+ const db = new Database(workerData.dbPath, { readonly: true, create: false });
6
+ db.exec("PRAGMA busy_timeout = " + Number(workerData.sqliteBusyTimeoutMs) + ";");
7
+ parentPort.on("message", (request) => {
8
+ try {
9
+ db.query("SELECT 1 as ok").get();
10
+ parentPort.postMessage({ id: request.id, ok: true });
11
+ } catch (error) {
12
+ parentPort.postMessage({
13
+ id: request.id,
14
+ ok: false,
15
+ message: error instanceof Error ? error.message : String(error),
16
+ stack: error instanceof Error ? error.stack : undefined,
17
+ });
18
+ }
19
+ });
20
+ parentPort.postMessage({ type: "ready" });
21
+ `;class xr{timer;getMigrationsError;executeSelectOne;getDatabasePath;timeoutMs;initTimeoutMs;sqliteBusyTimeoutMs;workerFactory;worker=null;workerRequestId=0;pendingRequest=null;constructor(d={}){this.timer=d.timer??i,this.getMigrationsError=d.getMigrationsError??J9,this.getDatabasePath=d.getDatabasePath??Gp,this.timeoutMs=d.timeoutMs??cy,this.initTimeoutMs=d.initTimeoutMs??ly,this.sqliteBusyTimeoutMs=d.sqliteBusyTimeoutMs??uy,this.workerFactory=d.workerFactory??((c,R)=>new dy(c,{eval:!0,workerData:R})),this.executeSelectOne=d.executeSelectOne}async check(){let d=this.getMigrationsError();if(d)throw d;let c=this.timer.monotonicNow?.()??this.timer.now(),R=this.executeSelectOne?void 0:this.getWorker(),D=0;if(R&&!R.ready)await l(R.readiness,{timer:this.timer,timeoutMs:this.initTimeoutMs,unref:!0,label:"Database health probe worker initialization",timeoutError:()=>new $i(this.initTimeoutMs),onTimeout:()=>{e.warn(`Database health probe worker init timed out after ${this.timer.now()-R.startedAt}ms (init budget ${this.initTimeoutMs}ms)`),this.abandonPendingWorkerRequest(R,new $i(this.initTimeoutMs))}}),D=Math.max(0,(this.timer.monotonicNow?.()??this.timer.now())-c);await l(()=>this.executeSelectOne?.()??this.executeSelectOneInWorker(R),{timer:this.timer,timeoutMs:this.timeoutMs,unref:!0,label:"Database health probe",timeoutError:()=>new Pe(this.timeoutMs,"query",D),onTimeout:()=>{if(R)this.abandonPendingWorkerRequest(R,new Pe(this.timeoutMs,"query",D))}})}async dispose(){let d=this.worker;this.worker=null;let c=Error("Database health probe disposed");if(d?.rejectReady(c),this.pendingRequest){let R=this.pendingRequest;this.pendingRequest=null,R.reject(c)}if(d)await d.worker.terminate()}abandonPendingWorkerRequest(d,c){if(this.worker!==d)return;this.worker=null,d.rejectReady(c),this.pendingRequest?.reject(c),this.pendingRequest=null,d.worker.terminate().catch((R)=>{e.debug("Abandoned database health probe worker termination failed",R)})}executeSelectOneInWorker(d){if(this.worker!==d)return Promise.reject(Error("Database health probe worker is no longer available"));if(this.pendingRequest)return Promise.reject(Error("Database health probe is already running"));let c=++this.workerRequestId;return new Promise((R,D)=>{this.pendingRequest={resolve:R,reject:D},d.worker.postMessage({id:c})})}getWorker(){if(this.worker)return this.worker;let d=this.timer.now(),c=this.workerFactory(py,{dbPath:this.getDatabasePath(),sqliteBusyTimeoutMs:this.sqliteBusyTimeoutMs}),R,D,k=new Promise((C,M)=>{R=C,D=M}),P={worker:c,readiness:k,ready:!1,startedAt:d,resolveReady:R,rejectReady:D};return this.worker=P,c.on("message",(C)=>{if(this.worker!==P)return;if("type"in C){if(!P.ready)P.ready=!0,P.resolveReady(),e.debug(`Database health probe worker ready after ${this.timer.now()-P.startedAt}ms`);return}if(!this.pendingRequest||C.id!==this.workerRequestId)return;let M=this.pendingRequest;if(this.pendingRequest=null,C.ok){M.resolve();return}let F=Error(C.message??"Database health probe failed");if(C.stack)F.stack=C.stack;M.reject(F)}),c.on("error",(C)=>{this.rejectWorker(P,C)}),c.on("exit",(C)=>{this.rejectWorker(P,Error(`Database health probe worker exited with code ${C}`))}),P}rejectWorker(d,c){if(this.worker!==d)return;this.worker=null,d.rejectReady(c),this.pendingRequest?.reject(c),this.pendingRequest=null}}function fy(){return Date.now()-Math.max(0,process.uptime()*1000)}function hy(d,c){return{deviceSessionRepository:d.deviceSessionRepository??new MS({timer:c}),idGenerator:d.idGenerator??B,databaseInitializer:d.databaseInitializer??new LU,startupFailureTracker:d.startupFailureTracker??new SM,databaseHealthProbe:d.databaseHealthProbe??new xr({timer:c})}}function gy(d){return{recoveryPolicyEnvironment:d.recoveryPolicyEnvironment??process.env,processBirthTime:d.processBirthTime??fy,processGenerationToken:d.processGenerationToken??Mf,liveDaemonSessionIdProvider:d.liveDaemonSessionIdProvider??new cY,incumbentOwnerGuard:d.incumbentOwnerGuard??new m4}}function vy(d){let c=d.deviceReadiness??Kc.createInstance();return{managedAdbServerShutdown:d.managedAdbServerShutdown??WK,toolSelectionProfileProvenanceLoader:d.toolSelectionProfileProvenanceLoader??zU,httpToken:d.httpToken??"",httpTokenStore:d.httpTokenStore??new Or,httpServerFactory:d.httpServerFactory??(()=>my()),avdManagerFactory:d.avdManagerFactory??(()=>new Ay),deviceReadiness:c,iosDeviceVerifier:d.iosDeviceVerifier??(()=>c),bindingExclusionFactory:d.bindingExclusionFactory??BA,daemonState:d.daemonState??Fre}}function al(d){let c=d.timer??i;return{...d,timer:c,...hy(d,c),...gy(d),...vy(d)}}class Lr{store;idGenerator;token;published=!1;constructor(d,c,R=""){this.store=d;this.idGenerator=c;this.token=R}get isPublished(){return this.published}get value(){return this.token}prepare(){this.published=!1,this.token=nl(this.idGenerator)}publish(){if(!this.token)throw new t("Daemon HTTP token is not configured");this.store.write(this.token),this.published=!0}remove(){if(this.published)this.store.remove(),this.published=!1;this.token=""}}function dl(){let d,c;return{promise:new Promise((D,k)=>{d=D,c=k}),resolve:d,reject:c}}var wt=25,Rt=1000,Pt=5000,ll=$4,cl=new WeakMap;class Me{closing=new AbortController;backoff;shared;options;constructor(d){this.options={...d,initialDelayMs:d.initialDelayMs??wt,maxDelayMs:d.maxDelayMs??Rt,maxBlockedWaitMs:d.maxBlockedWaitMs??Pt},this.backoff=d.backoff??Q(this.options);let c=cl.get(d.timer);if(!c)c={quietUntilMs:0,queue:[]},cl.set(d.timer,c);this.shared=c}close(){this.closing.abort()}delay(d){try{let c=this.backoff.delayForAttempt(d);if(!Number.isFinite(c))throw Error(`Registry retry backoff delay must be finite, got ${c}`);return Math.min(Math.max(c,this.options.initialDelayMs),this.options.maxDelayMs)}catch(c){if(!this.closing.signal.aborted)e.debug(`[Bindings] Registry retry backoff failed; using the cap: ${r(c)}`,c);return this.options.maxDelayMs}}async wait(d,c,R){let D,k,P=this.signal(c),C=()=>{if(D!==void 0)this.options.timer.clearTimeout(D)};P.addEventListener("abort",C,{once:!0});try{await l(()=>new Promise((M)=>{if(k=M,R?.addEventListener("abort",k,{once:!0}),R?.aborted)M();else D=this.options.timer.setTimeout(M,d)}),{timer:this.options.timer,signal:P,label:"Registry retry wait"})}finally{if(P.removeEventListener("abort",C),k)R?.removeEventListener("abort",k);if(D!==void 0)this.options.timer.clearTimeout(D)}}async run(d,c,R,D){let k=this.signal(R);k.throwIfAborted();let P=Promise.withResolvers(),C={resolve:P.resolve,reject:P.reject,expedited:D,started:!1},M=()=>this.schedule(),F=()=>{if(P.reject(k.reason),this.removeQueued(C),this.shared.active===C&&!C.started)this.shared.active=void 0;this.schedule()};k.addEventListener("abort",F,{once:!0}),D?.addEventListener("abort",M,{once:!0}),this.shared.queue.push(C);let q,U=!0;try{this.schedule(),await P.promise,k.throwIfAborted(),C.started=!0,q=this.options.timer.now();let K=await l(d,{timer:this.options.timer,signal:k,label:"Registry retry operation"});return U=!c(K),K}finally{if(k.removeEventListener("abort",F),D?.removeEventListener("abort",M),U&&q!==void 0)this.extendQuietPeriod(q);if(this.removeQueued(C),this.shared.active===C)this.shared.active=void 0;this.schedule()}}removeQueued(d){let c=this.shared.queue.indexOf(d);if(c!==-1)this.shared.queue.splice(c,1)}schedule(){let d=this.shared,c=this.options.timer,R=(P)=>P.expedited?.aborted||c.now()>=d.quietUntilMs,D=d.active?void 0:d.queue.find(R),k=!d.active&&!D&&d.queue.length>0;try{this.updateQuietTimer(k)}catch(P){e.warn(`[Bindings] Registry retry quiet timer failed: ${r(P)}`,P);for(let C of[...d.queue])if(!R(C))this.removeQueued(C),C.reject(P)}if(D)this.removeQueued(D),d.active=D,D.resolve()}updateQuietTimer(d){let c=this.shared,R=this.options.timer;if(!d||c.wakeAtMs!==c.quietUntilMs){if(c.quietTimer!==void 0){let D=c.quietTimer;c.quietTimer=void 0,c.wakeAtMs=void 0,R.clearTimeout(D)}}if(d&&c.quietTimer===void 0){let D=R.setTimeout(()=>{if(c.quietTimer!==D)return;c.quietTimer=void 0,c.wakeAtMs=void 0,this.schedule()},c.quietUntilMs-R.now());c.quietTimer=D,c.wakeAtMs=c.quietUntilMs}}noteBlocked(d){this.extendQuietPeriod(d)}extendQuietPeriod(d){if(this.closing.signal.aborted)return;let c=this.options.timer.now();this.shared.quietUntilMs=Math.max(this.shared.quietUntilMs,c+Math.min(Math.max(0,c-d),this.options.maxBlockedWaitMs)),this.schedule()}signal(d){return d?AbortSignal.any([this.closing.signal,d]):this.closing.signal}}var ul=500,Ee=700,pl=250,fl=300000,hl=30000,$r=Q({initialDelayMs:250,maxDelayMs:5000}),gl=256,vl="managed-execution-release",Hr=wt,qr=Rt,Kr=Pt,yl=5000;function Wr(){return{marked:[],owed:[],stamped:new Set,stampWarned:!1}}function Se(d){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex}}function Hi(d,c){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex,role:d.role,platform:d.platform,generation:d.generation,stableDeviceId:d.stableDeviceId,deviceName:d.deviceName,state:d.state,execOwnerReleased:c}}function qi(d,c){let R=(D)=>d.getSession(D)?.assignedDevice??d.getReleasingSession(D)?.assignedDevice??d.getTerminalReleaseSnapshot(D)?.deviceId??null;return{isSessionLive:(D)=>d.hasSession(D)||d.getReleasingSession(D)!==null,deviceOf:R,getKeepAwakeRestoreReport:(D)=>d.getKeepAwakeRestoreReport?.(D),releaseSession:async(D)=>{let k=R(D);return await Ds({manager:d,pool:c},k,D,{release:async()=>(k=await d.releaseSession(D),k)}),k},forceStuckRelease:async(D)=>{let k=!1;return await uq({forceStuckRelease:(P)=>{let C=d.forceStuckRelease(P);return k=C!==void 0,C}},c,D),k},hasDeviceCleanupInProgress:(D)=>d.hasDeviceCleanupInProgress(D)}}async function Rl(d,c,R,D){let k;try{k=await yy(d,c,R)}catch(C){let M=await wl(d,c,R);if(M===null)throw C;let F=Se(R);return d.warn(`[BrokerExecutionRelease] Marking binding ${F.scopeKey}/${F.bindingIndex} settling failed after the mark was written; going on from the written mark: ${r(C)}`,C),M}if(!("refused"in k))return k;let P=await wl(d,c,R);if(P===null)D.push({...Se(R),error:`could not mark settling: ${k.refused}`});return P}async function yy(d,c,R){let D=await Sy(d,c,R);if(D!=="unjournaled")return D;let k=Se(R),P=await c.updateBindingState(k,{generation:R.generation,stableDeviceId:R.stableDeviceId},"settling",{settler:d.settlerIdentity()});if(P.kind!=="updated")return{refused:P.kind};return{key:k,execOwner:P.assignment.execOwner,generation:P.assignment.generation,stableDeviceId:P.assignment.stableDeviceId}}async function wl(d,c,R){let D=Se(R),k=d.settlerIdentity(),P=await c.getAssignment(D);if(P===null||P.state!=="settling"||P.settler===null||!jc(P.settler,k)||P.stableDeviceId!==R.stableDeviceId||P.generation!==R.generation+1)return null;let C={key:D,execOwner:P.execOwner,generation:P.generation,stableDeviceId:P.stableDeviceId},M=d.options.journal;if(!M)return C;let F=(await c.listOpenBindingJournal(D)).find((q)=>q.kind==="release"&&jc(q.owner,k));if(!F)return C;return M.inFlight.add(F.id),{...C,journalEntryId:F.id}}async function Sy(d,c,R){let D=d.options.journal;if(!D)return"unjournaled";let k=Se(R),P=d.settlerIdentity(),C=await c.openBindingJournal(k,{kind:"release",phase:"intent",owner:P,target:{oldStableId:R.stableDeviceId,oldName:R.deviceName,newName:null,newStableId:null,requestedSpec:R.requestedSpec,resolvedSpec:R.resolvedSpec,specFingerprint:R.specFingerprint},assignment:{kind:"state",expected:{generation:R.generation,stableDeviceId:R.stableDeviceId},state:"settling",options:{settler:P}}});if(C.kind==="opened")return D.inFlight.add(C.entry.id),{key:k,execOwner:C.assignment.execOwner,generation:C.assignment.generation,stableDeviceId:C.assignment.stableDeviceId,journalEntryId:C.entry.id};if(C.kind==="journal_open")return"unjournaled";return{refused:C.kind}}class Vr{ctx;inFlight=new Set;constructor(d){this.ctx=d}async clearLeftover(d,c,R){if(R===null)return!0;if(this.ctx.isExecOwnerLive(R))return!1;try{await d.releaseExecution(c,R.sessionUuid)}catch(D){this.ctx.warn(`[BrokerExecutionRelease] Retrying the owner clear of binding ${c.scopeKey}/${c.bindingIndex} for ended session ${R.sessionUuid} failed; the binding still returns to ready and the clear is retried: ${r(D)}`,D),this.ctx.track(this.retry(d,c,R.sessionUuid))}return!0}async retry(d,c,R){let D=`${c.scopeKey}/${c.bindingIndex}/${R}`;if(this.ctx.isClosed()||this.inFlight.has(D))return;this.inFlight.add(D);let{timer:k}=this.ctx,P=k.now()+this.ctx.settlementCapMs;try{for(;;){if(await k.sleep(this.ctx.settlementPollMs),this.ctx.isClosed())return;let C=await this.ctx.retrier.run(`Clearing the owner of binding ${c.scopeKey}/${c.bindingIndex} for ended session ${R}`,P,()=>this.clearEndedOnce(d,c,R));if(!C.done||C.value==="done"||k.now()+this.ctx.settlementPollMs>P)return}}finally{this.inFlight.delete(D)}}async clearEndedOnce(d,c,R){let D=(await d.getAssignment(c))?.execOwner??null;if(D===null||D.sessionUuid!==R||this.ctx.isClosed())return"done";if(this.ctx.isSessionLive(R)||this.ctx.isExecOwnerLive(D))return"owner_live";return await d.releaseExecution(c,R),"done"}}class Jr{ctx;constructor(d){this.ctx=d}async run(d,c,R,{stopWhen:D,schedule:k}={}){if(k?.fastRecovery)return this.runRecovery(d,R);let{timer:P}=this.ctx,C=!1,M=await this.ctx.registryRetry.execute(R,{maxAttempts:Number.MAX_SAFE_INTEGER,signal:this.ctx.closing,shouldRetry:()=>!(D?.()??!1),delays:(F)=>P.now()>=c?this.ctx.settlementSlowPollMs:this.ctx.backoff.delayForAttempt(F),onRetry:(F,q,U)=>{if(q===1)this.ctx.warn(`[BrokerExecutionRelease] ${d} failed; retrying in ${U}ms: ${F.message}`,F);if(P.now()>=c&&!C)C=!0,this.ctx.warn(`[BrokerExecutionRelease] ${d} has kept failing past the ${this.ctx.settlementCapMs}ms settlement cap; it is retried every ${this.ctx.settlementSlowPollMs}ms until the registry recovers. a daemon restart (its settled-binding recovery) also recovers the binding: `+F.message,F)},expectedFailure:{reason:"the drain reports why it stopped retrying a registry step"}});if(M.success)return{done:!0,value:M.value};if(!this.ctx.isClosed())this.ctx.warn(`[BrokerExecutionRelease] ${d} failed and is no longer needed, so it is not retried: ${r(M.error)}`,M.error);return{done:!1}}async runRecovery(d,c){let R=this.ctx.timer.now(),D=0,k=!1,P;while(!this.ctx.isClosed()){D++;try{let C=await this.ctx.recoveryPacing.run(async()=>{let M=!1;try{return await l(()=>(P??=c(),P),{timer:this.ctx.timer,timeoutMs:this.ctx.recoveryTurnBudgetMs,signal:this.ctx.closing,label:d,onTimeout:()=>{M=!0}})}finally{if(!M)P=void 0}},()=>!0);if(this.ctx.isClosed())return{done:!1};if(D>1)e.info(`[BrokerExecutionRelease] ${d} resolved after ${this.ctx.timer.now()-R} ms (${D} attempts)`);return{done:!0,value:C}}catch(C){if(this.ctx.isClosed())return{done:!1};if(e.debug(`[BrokerExecutionRelease] ${d} failed: ${r(C)}`,C),!k&&this.ctx.timer.now()-R>this.ctx.recoveryWarnAfterMs)k=!0,this.ctx.warn(`[BrokerExecutionRelease] ${d} still failing after ${this.ctx.timer.now()-R} ms (${D} attempts): ${r(C)}`,C)}try{await this.ctx.recoveryPacing.wait(this.ctx.recoveryPacing.delay(D))}catch(C){if(!this.ctx.isClosed())e.debug(`[BrokerExecutionRelease] Recovery retry wait cancelled: ${r(C)}`,C);return{done:!1}}}return{done:!1}}}class jr{options;drainBudgetMs;releaseBudgetMs;settlementPollMs;settlementCapMs;settlementSlowPollMs;driven=new Map;recentBindings=new Map;background=new Set;closed=!1;closing=new AbortController;settler;isExecOwnerLive;retrier;ownerClearer;recoveryPacing;recovery;ownerHolds;ownerHoldCounts=new Map;constructor(d){this.options=d;this.isExecOwnerLive=d.isExecOwnerLive??mc,this.drainBudgetMs=d.drainBudgetMs??ul,this.releaseBudgetMs=d.releaseBudgetMs??Ee,this.settlementPollMs=d.settlementPollMs??pl,this.settlementCapMs=d.settlementCapMs??fl,this.settlementSlowPollMs=d.settlementSlowPollMs??hl,this.recoveryPacing=new Me({timer:d.timer,initialDelayMs:Hr,maxDelayMs:qr,maxBlockedWaitMs:Kr}),this.ownerHolds=d.ownerHolds??g0,this.retrier=new Jr({timer:d.timer,registryRetry:new kn(d.timer),recoveryPacing:this.recoveryPacing,backoff:d.registryRetryBackoff??$r,closing:this.closing.signal,isClosed:()=>this.closed,warn:(c,R)=>this.warn(c,R),settlementCapMs:this.settlementCapMs,settlementSlowPollMs:this.settlementSlowPollMs,recoveryTurnBudgetMs:Ee,recoveryWarnAfterMs:yl}),this.ownerClearer=new Vr({timer:d.timer,retrier:this.retrier,isExecOwnerLive:this.isExecOwnerLive,isSessionLive:(c)=>this.options.sessions.isSessionLive(c),isClosed:()=>this.closed,warn:(c,R)=>this.warn(c,R),track:(c)=>this.track(c),settlementCapMs:this.settlementCapMs,settlementPollMs:this.settlementPollMs})}releaseExecution(d){let c=this.driven.get(d);if(c)return c;let R=this.drainAndRelease(d).finally(()=>{this.driven.delete(d)});return this.driven.set(d,R),R}onSessionReleased(d,c){if(c?.upgradeOnly||d.livenessPolicy!==ni||this.driven.has(d.sessionId)||this.closed)return;this.track(this.releaseBindingsAfterExternalRelease(d.sessionId,d.deviceId))}async whenIdle(){while(this.background.size>0)await Promise.allSettled([...this.background])}recoverSettledBindings(){if(this.closed)return Promise.resolve([]);if(this.recovery)return this.recovery;let d=this.recoverSettledBindingsUntilReady().finally(()=>{this.recovery=void 0});return this.recovery=d,this.track(d.then(()=>{})),d}async recoverSettledBindingsUntilReady(){let d=await this.retrier.run("Recovering settled bindings",1/0,async()=>{let c=await this.options.registry();return this.closing.signal.throwIfAborted(),c.recoverSettledBindings()},{schedule:{fastRecovery:!0}});if(!d.done||this.closed)return[];if(d.value.length>0)e.info(`[BrokerExecutionRelease] Recovered ${d.value.length} settled binding(s) whose settling daemon is gone`);return d.value}close(){this.closed=!0,this.closing.abort(),this.recoveryPacing.close()}keepAwakeRestoreResult(d){let c=this.options.sessions.getKeepAwakeRestoreReport?.(d);return c?{keepAwakeRestore:c}:{}}async drainAndRelease(d){let{sessions:c}=this.options,R=await this.options.registry(),D=await R.findExecutionAssignments(d),k=c.isSessionLive(d);if(D.length===0&&!k)return this.reportReleased(R,d);this.rememberBindings(d,D);let P=c.deviceOf(d),C=this.holdOwner(d,P);try{return await this.drainHeldBindings(R,d,D,{live:k,device:P})}finally{C()}}async drainHeldBindings(d,c,R,{live:D,device:k}){let{cancellationRequested:P,drained:C}=await this.cancelAndDrain(c),M=[],F=Wr();if(!C)await this.markSettling(d,c,R,{failures:M,marks:F});let q=D?await this.releaseSessionWithinBudget(c,k):{releasedDevice:k,releaseSettled:!0,releaseForced:!1},{releasedDevice:U,releaseForced:K}=q,W=C&&q.releaseSettled&&this.isSettled(c,U);if(!W&&C)await this.markSettling(d,c,R,{failures:M,marks:F});let V=await this.releaseOwnership(d,c,R,{failures:M,owed:F.owed});if(F.marked.length>0)this.track(this.settleLater(d,c,U,F.marked));if(F.owed.length>0){let z=this.holdOwner(c,U);this.track(this.settleOwedMarks(d,c,U,{first:F,releaseHold:z}))}return{...this.keepAwakeRestoreResult(c),...await jN(c),...await KN(c),sessionId:c,outcome:W?"reusable_for_this_binding":"cleanup_pending",settlement:W?"confirmed":"settling",alreadyReleased:!D,cancellationRequested:P,releaseForced:K,device:U,bindings:V,bindingFailures:M}}async cancelAndDrain(d){let{work:c}=this.options,R=await c.cancelDeviceSessionExecutions(d,vl);if(R===0&&!c.hasActiveDeviceSessionExecutions(d))return{cancellationRequested:R,drained:!0};let D=await c.waitForDeviceSessionExecutionsToEnd(d,this.drainBudgetMs);return{cancellationRequested:R,drained:D}}async reportReleased(d,c){let R=this.recentBindings.get(c)??[],D=(await Promise.all(R.map((P)=>d.getAssignment(P)))).filter((P)=>P!==null),k=this.options.work.hasActiveDeviceSessionExecutions(c)||D.some((P)=>P.state==="settling");return{...this.keepAwakeRestoreResult(c),...await jN(c),...await KN(c),sessionId:c,outcome:k?"cleanup_pending":"reusable_for_this_binding",settlement:k?"settling":"confirmed",alreadyReleased:!0,cancellationRequested:0,releaseForced:!1,device:null,bindings:D.map((P)=>Hi(P,!1)),bindingFailures:[]}}async releaseSessionWithinBudget(d,c){let{sessions:R,timer:D}=this.options,k=R.releaseSession(d);try{return{releasedDevice:await l(k,{timer:D,timeoutMs:this.releaseBudgetMs,unref:!0,label:`Managed execution release of session ${d}`})??c,releaseSettled:!0,releaseForced:!1}}catch(C){if(this.options.ownership?.isReleaseHeld(d))return e.debug(`[BrokerExecutionRelease] Session ${d} release awaits ownership; settlement continues within its hold cap`,C),{releasedDevice:c,releaseSettled:!1,releaseForced:!1};this.warn(`[BrokerExecutionRelease] Session ${d} release did not finish within ${this.releaseBudgetMs}ms; forcing it into the stuck-release quarantine: `+r(C),C)}let P=!1;try{P=await R.forceStuckRelease(d)}catch(C){this.warn(`[BrokerExecutionRelease] Forcing the stuck release of ${d} failed: `+r(C),C)}return{releasedDevice:c,releaseSettled:!1,releaseForced:P}}isSettled(d,c){return!this.options.work.hasActiveDeviceSessionExecutions(d)&&(c===null||!this.options.sessions.hasDeviceCleanupInProgress(c))}async releaseBindingsAfterExternalRelease(d,c){let R=this.holdOwner(d,c);try{let D=await this.retrier.run(`Finding the bindings of released session ${d}`,this.options.timer.now()+this.settlementCapMs,async()=>{if(this.isSettled(d,c))R();let q=await this.options.registry();return{registry:q,held:await q.findExecutionAssignments(d)}});if(!D.done||D.value.held.length===0)return;let{registry:k,held:P}=D.value;this.rememberBindings(d,P);let C=[],M=Wr();if(!this.isSettled(d,c))await this.markSettling(k,d,P,{failures:C,marks:M});await this.releaseOwnership(k,d,P,{failures:C,owed:M.owed});for(let q of C)this.warn(`[BrokerExecutionRelease] Binding ${q.scopeKey}/${q.bindingIndex} bookkeeping after the release of ${d} failed: ${q.error}`);let F=M.owed.length>0?this.holdOwner(d,c):void 0;R(),await Promise.all([M.marked.length>0?this.settleLater(k,d,c,M.marked):void 0,F?this.settleOwedMarks(k,d,c,{first:M,releaseHold:F}):void 0])}finally{R()}}async markSettling(d,c,R,{failures:D,marks:k}){await this.stampOwners(d,c,R,k),(await Promise.allSettled(R.map((C)=>this.markBinding(d,C,D)))).forEach((C,M)=>{if(C.status==="rejected")D.push({...Se(R[M]),error:`could not mark settling: ${r(C.reason)}; the binding keeps its owner record and the mark is retried`}),k.owed.push(R[M]);else if(C.value){if(k.marked.push(C.value),C.value.execOwner?.sessionUuid===c)this.options.ownership?.confirmOwnership(c)}})}async stampOwners(d,c,R,D){let k=this.settlerIdentity();(await Promise.allSettled(R.map(async(C)=>{let M=C.execOwner;if(D.stamped.has(C)||M===null||M.sessionUuid!==c||jc(M,k))return M?.sessionUuid===c&&jc(M,k);let F=await d.claimExecution(Se(C),{generation:C.generation,stableDeviceId:C.stableDeviceId},{...k,sessionUuid:c},{supersedesSessionUuid:c});if(F.kind==="binding_in_use")this.options.ownership?.loseOwnership?.(c);return F.kind==="claimed"}))).forEach((C,M)=>{if(C.status==="fulfilled"){if(D.stamped.add(R[M]),C.value)this.options.ownership?.confirmOwnership(c)}else if(!D.stampWarned){D.stampWarned=!0;let F=Se(R[M]);this.warn(`[BrokerExecutionRelease] Binding ${F.scopeKey}/${F.bindingIndex} of released session ${c} still names another daemon as its owner and could not be re-stamped; it is retried with the settling mark: ${r(C.reason)}`,C.reason)}})}async markBinding(d,c,R){return Rl({warn:this.warn.bind(this),settlerIdentity:this.settlerIdentity.bind(this),options:this.options},d,c,R)}async settleOwedMarks(d,c,R,{first:D,releaseHold:k}){let P=[...D.owed],C={...D,marked:[],owed:[...P]},M=()=>this.isSettled(c,R);try{if(await this.retrier.run(`Marking the bindings of released session ${c} settling`,this.options.timer.now()+this.settlementCapMs,async()=>{if(M())return;let q=[],U=C.owed;if(C.owed=[],await this.markSettling(d,c,U,{failures:q,marks:C}),C.owed.length>0)throw Error(q.map((K)=>K.error).join("; "));for(let K of q)this.warn(`[BrokerExecutionRelease] Binding ${K.scopeKey}/${K.bindingIndex} of released session ${c}: ${K.error}`)},{stopWhen:M}),this.closed)return;let F=[];await this.releaseOwnership(d,c,P,{failures:F,owed:[]});for(let q of F)this.warn(`[BrokerExecutionRelease] Clearing the owner of binding ${q.scopeKey}/${q.bindingIndex} for released session ${c} failed; the dead record pins nothing in this daemon (#11339) and the clear is retried: ${q.error}`)}finally{k()}if(C.marked.length>0)await this.settleLater(d,c,R,C.marked)}async releaseOwnership(d,c,R,{failures:D,owed:k}){return(await Promise.allSettled(R.map(async(C)=>k.includes(C)?{released:!1,assignment:C}:d.releaseExecution(Se(C),c)))).flatMap((C,M)=>{if(C.status==="rejected")return D.push({...Se(R[M]),error:r(C.reason)}),this.track(this.ownerClearer.retry(d,Se(R[M]),c)),[Hi(R[M],!1)];let F=C.value.assignment??R[M];return[Hi(F,C.value.released)]})}async settleLater(d,c,R,D){let{timer:k}=this.options,P=k.now()+this.settlementCapMs,C=!1;while(!this.isSettled(c,R)){if(this.closed)return;if(!C&&k.now()>=P)C=!0,this.warn(`[BrokerExecutionRelease] Work of released session ${c} did not settle within ${this.settlementCapMs}ms; its bindings stay settling and are re-checked every ${this.settlementSlowPollMs}ms until the work settles (#11336)`);await k.sleep(C?this.settlementSlowPollMs:this.settlementPollMs)}await this.restoreOnceUnowned(d,D,P)}async restoreOnceUnowned(d,c,R){let D=(await Promise.all(c.map((P)=>this.restoreBindingOnceUnowned(d,P,R)))).filter((P)=>P!==null);if(D.length===0)return;let k=D.map((P)=>`${P.key.scopeKey}/${P.key.bindingIndex}`).join(", ");this.warn(`[BrokerExecutionRelease] A live execution still holds the owner record of settled binding(s) ${k} past the ${this.settlementCapMs}ms settlement cap; they stay settling. Once that execution ends, a daemon restart (its settled-binding recovery) returns them to ready (#11545)`)}async restoreBindingOnceUnowned(d,c,R){let{timer:D}=this.options;for(;;){if(await this.restoreReady(d,c,R)==="done"||this.closed)return null;if(D.now()>=R)return c;await D.sleep(this.settlementPollMs)}}async restoreReady(d,c,R){let D=await this.retrier.run(`Returning settled binding ${c.key.scopeKey}/${c.key.bindingIndex} to ready`,R,()=>this.restoreReadyOnce(d,c));return D.done?D.value:"done"}async restoreReadyOnce(d,c){let R=await d.getAssignment(c.key);if(!(R!==null&&R.state==="settling"&&R.generation===c.generation&&R.stableDeviceId===c.stableDeviceId))return await this.closeSupersededEntry(d,c,R),"done";if(!await this.ownerClearer.clearLeftover(d,c.key,R.execOwner))return"owner_live";let k=await this.restoreBindingState(d,c);if(k.kind!=="updated"&&k.kind!=="advanced")this.warn(`[BrokerExecutionRelease] Binding ${c.key.scopeKey}/${c.key.bindingIndex} settled but could not return to ready: ${k.kind}`);return"done"}async restoreBindingState(d,c){let R={generation:c.generation,stableDeviceId:c.stableDeviceId},D=this.options.journal;if(!D||c.journalEntryId===void 0)return d.updateBindingState(c.key,R,"ready");let k=await d.advanceBindingJournal(c.journalEntryId,{owner:this.settlerIdentity(),expectedPhase:"intent",phase:"committed",assignment:{kind:"state",expected:R,state:"ready"}});return D.inFlight.delete(c.journalEntryId),k}async closeSupersededEntry(d,c,R){let D=this.options.journal,k=R?.execOwner??null;if(!D||c.journalEntryId===void 0||k&&this.isExecOwnerLive(k))return;let P=!R||R.generation!==c.generation||R.stableDeviceId!==c.stableDeviceId;await d.advanceBindingJournal(c.journalEntryId,{owner:this.settlerIdentity(),expectedPhase:"intent",phase:P?"rolled_back":"committed"}),D.inFlight.delete(c.journalEntryId)}holdOwner(d,c){let R=this.ownerHoldCounts.get(d)??0;if(this.ownerHoldCounts.set(d,R+1),R===0)this.ownerHolds.add(d);let D=!1;return()=>{if(D||this.closed&&!this.isSettled(d,c))return;D=!0;let k=(this.ownerHoldCounts.get(d)??1)-1;if(k>0){this.ownerHoldCounts.set(d,k);return}this.ownerHoldCounts.delete(d),this.ownerHolds.delete(d)}}settlerIdentity(){return this.settler??=this.options.settler??{daemonId:`pid-${process.pid}`,...qq()},this.settler}rememberBindings(d,c){if(c.length===0)return;if(this.recentBindings.delete(d),this.recentBindings.set(d,c.map(Se)),this.recentBindings.size>gl){let R=this.recentBindings.keys().next().value;if(R!==void 0)this.recentBindings.delete(R)}}warn(d,c){if(this.closed)return;if(c===void 0)e.warn(d);else e.warn(d,c)}track(d){let c=d.catch((R)=>{this.warn(`[BrokerExecutionRelease] Background binding release failed: ${r(R)}`,R)}).finally(()=>{this.background.delete(c)});this.background.add(c)}}function Dl(d,c=`${VS()}.session-broker.lock`){return{acquire:()=>{if(!ti(c,{pid:d.pid,ownerToken:d.daemonId,ownerGeneration:kt}))throw new t("Another provider owns session-broker execution on this host; stop it before starting a replacement")},release:()=>Wn(c,d.pid,d.daemonId)}}import{createHash as by}from"crypto";function Ct(d,c){let R=by("sha256").update(JSON.stringify(c)).digest("hex").slice(0,16);return`${d}:sha256:${R}`}var zr="android-sdk-installed-catalog",wy="android-native-catalog-v1";function Al(d){let c=new Set,R=new Set;for(let D of d){if(c.has(D))R.add(D);c.add(D)}return R}function ky(d,c,R,D){let k=c.profileArchetypes[d.id];return{profileId:d.id,...k===void 0?{}:{archetype:k},metadataState:R==="stale"||D||d.id.length===0?"stale":"current"}}function Iy(d){if(d<=1)return"major";return d===2?"minor":"patch"}function Ty(d,c){if(c===void 0)return!1;return c.apiLevel===d.apiLevel&&c.apiIdentifier===d.apiIdentifier&&c.tag===d.tag&&c.abi===d.abi}function Ey(d,c,R){return d==="stale"||c||!R?"stale":"current"}function By(d){let c=mz(d);if(c===void 0)return{versionPrecision:"major"};let R=qo(c);if(!R.ok)return{versionPrecision:"major"};return{osVersion:R.value.value,versionPrecision:Iy(R.value.precision)}}function xy(d,c,R){let D=nn(d.packageName),k=Ey(c,R,Ty(d,D)),P=D?.apiLevel??d.apiLevel;return{systemImagePackage:d.packageName,...By(P),apiLevel:P,abi:D?.abi??d.abi,flavor:D?.tag??d.tag,installed:!0,metadataState:k}}function Il(d,c,R,D={}){let k=D.metadataState??"current",P=Al(d.map((U)=>U.id)),C=Al(c.map((U)=>U.packageName)),M=d.map((U)=>ky(U,R,k,P.has(U.id))).sort((U,K)=>U.profileId.localeCompare(K.profileId)),F=c.map((U)=>xy(U,k,C.has(U.packageName))).sort((U,K)=>U.systemImagePackage.localeCompare(K.systemImagePackage)),q=Ct(zr,{adapterVersion:wy,policy:Object.entries(R.profileArchetypes).sort(([U],[K])=>U.localeCompare(K)),profiles:M,releases:F});return{platform:"android",provenance:{source:zr,revision:q,state:"ready"},profiles:M,releases:F,hostAbis:Nw(D.hostArchitecture??process.arch)}}async function _y(d,c){let[R,D]=await Promise.allSettled([d.listDevices(c),d.listInstalledSystemImages(void 0,c)]);if(R.status==="rejected")throw R.reason;if(D.status==="rejected")throw D.reason;if(R.value.length===0)throw Error("Android emulator profile catalog returned no profiles.");return[R.value,D.value]}async function Yr(d,c,R={}){try{let[D,k]=await _y(d,R.signal);return Il(D,k,c,R)}catch(D){if(R.signal?.aborted)throw D;let k=`Unable to read the installed Android emulator catalog: ${r(D)}`;return(R.logger??e).warn(k,D),{platform:"android",provenance:{source:zr,revision:"unavailable",state:"unavailable",message:k},profiles:[],releases:[]}}}var Xr="simctl-installed-catalog",Fy="simctl-fields-v1";function Ny(d){if(d.family==="duo")return"duo";return d.family==="ipad"?"tablet":"phone"}function Cl(d){if(d===void 0)return;let[c,R]=d.split("."),D=R?.replace(/0+$/,"");return D?`${Number(c)}.${D}`:String(Number(c))}function $y(d,c){if(d===void 0)return{modelType:c,conflict:!1};if(d.family!==c.family||d.variant!==c.variant)return{modelType:d,conflict:!0};if(d.family!=="ipad"||c.family!=="ipad")return{modelType:d,conflict:!1};let R=Cl(d.sizeInches),D=Cl(c.sizeInches);if(R!==void 0&&D!==void 0&&R!==D)return{modelType:d,conflict:!0};return{modelType:R===void 0?c:d,conflict:!1}}function Hy(d){if(/^iPhone (?:\d+ )?Pro Max$/.test(d))return{family:"iphone",variant:"pro-max"};if(/^iPhone (?:\d+ )?Pro$/.test(d))return{family:"iphone",variant:"pro"};if(/^iPhone (?:\d+ )?Air$/.test(d))return{family:"iphone",variant:"air"};return/^iPhone (?:\d+(?:s|c)?(?: Plus| mini|e)?|SE \(\d+(?:st|nd|rd|th) generation\)|X|X\u0280|XR|Xs|XS|Xs Max|XS Max)$/.test(d)?{family:"iphone",variant:"standard"}:void 0}function qy(d){return/(?:^|[\s(])(\d+(?:\.\d+)?)-inch(?:[\s)]|$)/.exec(d)?.[1]}function Uy(d){let c=qy(d),R=(D)=>c===void 0?D:{...D,sizeInches:c};if(/^iPad Pro(?:\s|\()/.test(d))return R({family:"ipad",variant:"pro"});if(/^iPad Air(?:\s|\()/.test(d))return R({family:"ipad",variant:"air"});if(/^iPad mini(?:\s|\()/.test(d))return R({family:"ipad",variant:"mini"});if(/^iPad(?:\s+\(|\s+\d|$)/.test(d))return R({family:"ipad",variant:"standard"});return}function Ky(d){if(ys(d.identifier)||d.productFamily==="Duo"||d.name==="iPhone Duo")return{archetype:"duo",modelType:{family:"duo",variant:"duo"},conflict:!1};if(d.productFamily==="iPhone"){let c=Hy(d.name);return{archetype:"phone",...c===void 0?{}:{modelType:c},conflict:!1}}if(d.productFamily==="iPad"){let c=Uy(d.name);return{archetype:"tablet",...c===void 0?{}:{modelType:c},conflict:!1}}return{conflict:!1}}function Gy(d,c){let R=Ky(d),D=c.filter((M)=>M.simulatorDeviceTypeIdentifier===d.identifier);if(D.length>1)return{...R,conflict:!0};let k=D[0];if(!k)return R;let P=Ny(k.modelType);if(R.archetype!==void 0&&R.archetype!==P)return{...R,conflict:!0};let C=$y(R.modelType,k.modelType);return{archetype:R.archetype??P,modelType:C.modelType,...C.conflict||k.aliases===void 0?{}:{aliases:k.aliases},conflict:C.conflict}}function Wy(d){if(d===void 0)return;let c=[...new Set(d.filter((R)=>R.length>0))].sort();return c.length===0?void 0:c}function Vy(d,c,R,{classificationConflict:D,malformedBounds:k}){let P=d.identifier.length>0&&d.name.length>0&&d.productFamily.length>0;return c==="stale"||R||D||k||!P?"stale":"current"}function Jy(d,c,R,D){let k=Gy(d,c),P=zC(d),C=WC(d)&&P===void 0,M=Vy(d,R,D,{classificationConflict:k.conflict,malformedBounds:C}),F=Wy(k.aliases);return{simulatorDeviceTypeIdentifier:d.identifier,...d.modelIdentifier?{modelIdentifier:d.modelIdentifier}:{},name:d.name,productFamily:d.productFamily,...F===void 0?{}:{aliases:F},...k.archetype===void 0?{}:{archetype:k.archetype},...k.modelType===void 0?{}:{modelType:k.modelType},metadataState:M,...P===void 0?{}:{minOsVersion:P.minVersion,maxOsVersion:P.maxVersion}}}function jy(d){return d.platform==="iOS"||d.identifier.startsWith("com.apple.CoreSimulator.SimRuntime.iOS-")||d.name.startsWith("iOS ")}function zy(d,c,R){let D=qo(d.version);return{runtimeId:d.identifier,...D.ok?{osVersion:D.value.value}:{},installed:d.isAvailable===!0,metadataState:c==="stale"||R||!d.identifier||!D.ok||d.isAvailable===void 0?"stale":"current"}}function Ml(d){let c=new Set,R=new Set;for(let D of d){if(c.has(D))R.add(D);c.add(D)}return R}function El(d,c,R={}){let D=R.metadataState??"current",k=R.classifications??[],P=Ml(d.map((K)=>K.identifier)),C=c.filter(jy),M=Ml(C.map((K)=>K.identifier)),F=d.map((K)=>Jy(K,k,D,P.has(K.identifier))).sort((K,W)=>K.simulatorDeviceTypeIdentifier.localeCompare(W.simulatorDeviceTypeIdentifier)),q=C.map((K)=>zy(K,D,M.has(K.identifier))).sort((K,W)=>K.runtimeId.localeCompare(W.runtimeId)),U=Ct(Xr,{classificationVersion:Fy,classifications:[...k].sort((K,W)=>K.simulatorDeviceTypeIdentifier.localeCompare(W.simulatorDeviceTypeIdentifier)),models:F,releases:q});return{platform:"ios",provenance:{source:Xr,revision:U,state:"ready"},models:F,releases:q}}async function Yy(d,c){let R=(P)=>P.then((C)=>()=>C,(C)=>()=>{throw C}),[D,k]=await Promise.all([R(d.getDeviceTypesChecked(c)),R(d.getRuntimesChecked(void 0,c))]);return[D(),k()]}async function Qr(d,c={}){try{let[R,D]=await Yy(d,c.signal);return El(R,D,c)}catch(R){if(c.signal?.aborted)throw R;let D=`Unable to read the installed iOS simulator catalog: ${r(R)}`;return(c.logger??e).warn(D,R),{platform:"ios",provenance:{source:Xr,revision:"unavailable",state:"unavailable",message:D},models:[],releases:[]}}}var Ui="simctl-watch-catalog";function Bl(d){let c=d.runtimes.map((D)=>{let k=D.version.trim()||Vz(D.identifier);return{runtime:D.identifier,...k?{osVersion:k}:{},installed:D.isAvailable===!0}}).sort((D,k)=>D.runtime.localeCompare(k.runtime)),R=d.deviceTypes.map((D)=>({deviceType:D.identifier,name:D.name})).sort((D,k)=>D.deviceType.localeCompare(k.deviceType));return{platform:"watchos",provenance:{source:Ui,revision:Ct(Ui,{runtimes:c,deviceTypes:R}),state:"ready"},runtimes:c,deviceTypes:R}}async function Zr(d,c={}){if(!d)return{platform:"watchos",provenance:{source:Ui,revision:"not-installed",state:"not-installed",message:"Apple Watch simulators exist only on macOS hosts with Xcode's simctl."},runtimes:[],deviceTypes:[]};try{return Bl(await d.readCatalog(c.signal))}catch(R){if(c.signal?.aborted)throw R;let D=`Unable to read the Apple Watch simulator catalog: ${r(R)}`;return(c.logger??e).warn(D,R),{platform:"watchos",provenance:{source:Ui,revision:"unavailable",state:"unavailable",message:D},runtimes:[],deviceTypes:[]}}}function Ol(d){let c=new L(null),R=process.platform==="darwin"?new wa(c):void 0;return(D,k)=>{if(D==="watchos")return Zr(R,{signal:k});if(D==="ios")return Qr(c,{signal:k,classifications:d.iosClassifications});return Yr({listDevices:(P)=>eP(void 0,P),listInstalledSystemImages:(P,C)=>Hu(P,void 0,C)},{profileArchetypes:d.androidProfileArchetypes},{signal:k})}}class to{processTable;listDevicesChecked;constructor(d,c){this.processTable=d;this.listDevicesChecked=c}async hasLiveProcess(d){let c=await this.processTable.read({});if(!c.value||c.error||c.failure)throw new t(`Cannot verify AVD processes; retry cleanup after process discovery recovers: ${c.error??c.failure?.detail??"Process table unavailable"}`);if(c.incomplete)throw new t("Cannot verify AVD processes from an incomplete process inventory; restore /proc read access and parseable process data before retrying cleanup");let R=c.value.filter(Cu).map(({command:D})=>md(D).avdName);if(R.includes(void 0))throw new t("Cannot identify a running emulator's AVD; stop it or restore process discovery before retrying cleanup");return R.some((D)=>D?.toLowerCase()===d.toLowerCase())}findLiveEmulatorSerial(d){return aV(d,async()=>{let c=await this.listDevicesChecked();if(c.some((R)=>!R.name||Sa(R.name,R.deviceId)))throw new t("Cannot identify a discovered emulator's AVD; retry cleanup after emulator discovery recovers");return c})}}function Xy(d,c){let R=new pi;return{registry:d,resolver:new Nr,filesystem:xZ,liveness:new to(new lu(new ee,{timer:c,procFs:ap}),()=>R.getBootedDevicesChecked(!0))}}function io(d,c,R){return d??Xy(c?.avdSnapshotCleanupRegistry(),R)}var Xt=180;class no{adb;hinge;timer;constructor(d,c=new CM,R=i){this.adb=d;this.hinge=c;this.timer=R}async restore(d,c){try{if(c.throwIfAborted(),!d.deviceId.startsWith("emulator-"))throw new t("Fold posture baseline reset requires an Android emulator");let R=this.adb.create(d),D={signal:c,assertCurrent:()=>c.throwIfAborted()};if(await j$(R,"opened",void 0,{supportsRearDisplay:!0,operation:D}))throw new t("Emulator refused unfolded posture; cannot prove opened baseline");let P=await this.hinge.setHingeAngle(R,Xt,{signal:c});if(!P.ok)throw new t(`Cannot restore hinge angle to ${Xt}: ${P.reason}`);let C=await this.hinge.getHingeAngle(R,{signal:c});if(!C.ok||C.degrees!==Xt)throw new t(`Hinge angle read-back did not confirm ${Xt} degrees`);let M=await wO(R,D);await K$(R,"opened",{states:M},{timer:this.timer,observe:()=>{throw new t("The device exposes no committed posture state to read back")},operation:D}),c.throwIfAborted()}catch(R){throw new t(`Cannot restore Android device '${d.deviceId}' to opened posture (${Xt} degrees): ${r(R)}`,{cause:R})}}}class ro{reasons=new Map;mark(d,c){if(!this.reasons.has(d))this.reasons.set(d,c)}reasonFor(d){return this.reasons.get(d)}clear(d){this.reasons.delete(d)}}function xl(d,c){let R=d.restartReservationExclusions(c.platform,{});if(c.platform==="android"?R.names.has(c.name):R.ids.has(c.deviceId??""))return"restart recovery reservation";let D=d.getAllDevices().find((k)=>k.platform===c.platform&&(c.platform==="android"?(k.avdName??k.name)===c.name:k.id===c.deviceId));if(!D)return;if(!Ar(D))return`pooled runtime is ${Ub(D)}`;if(O(D)!==null)return"a session holds the runtime";if(d.isUnderShutdownReservation(D.id))return"shutdown reservation";return d.isDeviceLeasedForAndroidStartup(D.id)?"android startup lease":void 0}function fe(d){return d.platform==="android"?d.name:d.deviceId}var Zy=["android","ios","watchos"],_l=["assigned_active","assigned_idle","deleting","preparing","orphaned"],oo=10,eS={assigned_active:"committed: in use by a session",assigned_idle:"committed: assigned to a binding",free:"free",deleting:"committed: being deleted",deletion_stuck:"committed: deletion stuck",preparing:"committed: being prepared",orphaned:"orphaned"};function iS(d){if(d.kind!=="orphaned")return eS[d.kind];return d.orphanState==="transitioning"?"orphaned: booting or shutting down":"orphaned: running"}function nS(d){let{limit:c,usage:R,charged:D,chargedOmitted:k,retained:P,evictionFailures:C}=d;return{limit:c,usage:R,charged:D,...k?{chargedOmitted:k}:{},retained:P,evictionFailures:C}}function $l(d){let c=nS(d);return{message:rS(c),budget:c}}function rS(d){let c=`Managed-binding total-resource budget is exhausted (${d.usage.total} charged, limit ${d.limit}).`;if(d.charged.length===0)return c;let R=d.charged.map((k)=>`${k.name??k.stableDeviceId} (${k.platform}, ${iS(k)})`).join("; "),D=d.chargedOmitted??0;return`${c} Charged devices: ${R}${D>0?`; and ${D} more`:""}.`}function oS(d){let c={active:"assigned_active",assignedIdle:"assigned_idle",deleting:"deleting",preparing:"preparing",orphaned:"orphaned"};return d.map((R)=>({platform:R.platform,stableDeviceId:R.stableDeviceId,kind:c[R.category],...R.name?{name:R.name}:{},...R.orphanState?{orphanState:R.orphanState}:{}})).sort((R,D)=>_l.indexOf(R.kind)-_l.indexOf(D.kind)||R.platform.localeCompare(D.platform)||R.stableDeviceId.localeCompare(D.stableDeviceId))}function Be(d,c){return JSON.stringify([d,c])}function dS(d,c){return c.find((R)=>na(R)===d.platform&&n_(R)===d.stableDeviceId)}function cS(d,c){if(d.scopeState===null)return"preparing";if(c.has(Be(d.platform,d.stableDeviceId)))return"deleting";return d.execSessionUuid!==null?"active":"assignedIdle"}function lS(d,c,R){return[{category:cS(d,c),platform:d.platform,stableDeviceId:d.stableDeviceId,journal:dS(d,R)}]}function Nl(d,c){let R=n_(c)??c.target.newName??c.target.oldStableId??c.target.oldName;if(!R)return;d.push({category:"preparing",platform:na(c),stableDeviceId:R,journal:c})}function uS(d){let{charges:c,seen:R}=Hl(d);return vS(d,c,R),c}function Hl(d){let c=d.openJournal.filter((C)=>FA(C.phase)),R=new Set(c.filter((C)=>C.kind==="replace"&&["intent","deleting"].includes(C.phase)&&C.target.oldStableId!==null).map((C)=>Be(C.platform,C.target.oldStableId))),D=new Map(d.managed.filter((C)=>!c.some((M)=>M.kind==="create"&&C.holder==="session_broker"&&C.scopeState!==null&&M.scopeKey===C.scopeKey&&M.bindingIndex===C.bindingIndex&&n_(M)!==C.stableDeviceId)).map((C)=>[Be(C.platform,C.stableDeviceId),C])),k=new Set(D.keys()),P=[...D.values()].flatMap((C)=>lS(C,R,c));for(let C of c){if(C.kind==="release")continue;let M=n_(C);if(M!==null){let F=Be(na(C),M);if(!k.has(F))Nl(P,C),k.add(F)}else if(!SS(C,D))Nl(P,C)}return{charges:P,seen:k}}function pS(d){if(d.isRunning===!0)return"running";if(d.isRunningStateKnown===!1)return null;return d.platform!=="android"&&d.state!==void 0&&d.state!=="Shutdown"?"transitioning":null}function gS(d){return C4(d.platform)}function ql(d,c){let R=new Set(c),D=[];for(let k of d.inventory??[]){let P=fe(k);if(!gS(k)||!P||!uc(k.name))continue;let C=Be(k.platform,P);if(!(d.managed.some((F)=>Be(F.platform,F.stableDeviceId)===C)||d.openJournal.some((F)=>F.platform===k.platform&&[F.target.oldStableId,F.target.oldName].some((q)=>q===P||q===k.name)||na(F)===k.platform&&[F.target.newStableId,F.target.newName].some((q)=>q===P||q===k.name)))&&!R.has(C)&&!k.name.startsWith(jZ))D.push(k),R.add(C)}return D}function vS(d,c,R){for(let D of ql(d,R)){let k=pS(D),P=fe(D);if(k===null||!P)continue;c.push({category:"orphaned",platform:D.platform,stableDeviceId:P,name:D.name,orphanState:k}),R.add(Be(D.platform,P))}}function yS(d){return ql(d,Hl(d).seen).filter((c)=>c.isRunning!==!0&&c.isRunningStateKnown===!1)}function SS(d,c){return d.target.oldStableId!==null&&c.has(Be(d.platform,d.target.oldStableId))}function bS(d){let c={total:d.length,active:0,assignedIdle:0,preparing:0,deleting:0,orphaned:0};for(let R of d)c[R.category]+=1;return c}async function wS(d,c,R,D){let k=Be(c.platform,fe(c)??c.name),P=D.get(k);if(P)return P;let C=d.probeRunning?d.probeRunning(c,{signal:R}).catch((M)=>(R?.throwIfAborted(),e.debug(`[Bindings] running-state probe of ${c.name} failed: ${M}`),!1)):Promise.resolve(!1);return D.set(k,C),C}async function RS(d,c,R,D){let k=yS(c),P=new Set((await Promise.all(k.map(async(C)=>await wS(d,C,R,D)?C:null))).filter((C)=>C!==null));return(c.inventory??[]).map((C)=>P.has(C)?{...C,isRunning:!0,isRunningStateKnown:!0}:C)}async function DS(d,c,R,{timer:D,probes:k}){Ki(R,D);let P=await d.snapshotBindingResources(),C=[];for(let q of Zy){Ki(R,D);let U=await c.list(q,{signal:R.signal});if(!U.complete&&U.toolchain==="not_installed")continue;if(!U.complete)throw new t(`${q} inventory is incomplete; total-resource usage is unknown.`);C.push(...U.devices)}Ki(R,D);let M=await RS(c,{...P,inventory:C},R.signal,k),F=uS({...P,inventory:M});return{charges:F,charged:oS(F)}}function Ki(d,c){if(d.signal?.throwIfAborted(),d.deadlineMs!==void 0&&c.now()>=d.deadlineMs)throw new t("Managed-binding preparation deadline passed during resource admission.")}function Ll(d,c){let R=d.filter((k)=>k.category!=="preparing"||k.journal?.kind!=="create"||k.journal.id<=c),D=R.some((k)=>k.category==="preparing"&&k.journal?.id===c);return R.length+(D?0:1)}class so{deps;timer;constructor(d){this.deps=d;this.timer=d.timer??i}async admitCreation(d){let c=this.deps.policy.limit();if(c===null)return{kind:"admitted",enforced:!1};if(!Number.isSafeInteger(c)||c<0)throw new t("Managed-binding total-resource limit must be a nonnegative safe integer or null; correct the budget policy.");try{Ki(d,this.timer);let R=async()=>this.admitFromRegistry(await this.deps.registry(),c,d);return d.deadlineMs===void 0?await R():await l(R,{timer:this.timer,timeoutMs:Math.max(0,d.deadlineMs-this.timer.now()),signal:d.signal,label:"Managed-binding resource admission"})}catch(R){return d.signal?.throwIfAborted(),e.warn(`[Bindings] Resource admission could not read capacity: ${r(R)}`,R),{kind:"unknown",message:r(R)}}}async admitFromRegistry(d,c,R){let D=new Map,k=()=>DS(d,this.deps.inventory,R,{timer:this.timer,probes:D}),P=await k();if(Ll(P.charges,R.journalEntryId)>c)P=await k();let C=bS(P.charges);return Ll(P.charges,R.journalEntryId)<=c?{kind:"admitted",enforced:!0,limit:c,usage:C,evicted:[]}:{kind:"exhausted",limit:c,usage:C,charged:P.charged.slice(0,oo),...P.charged.length>oo?{chargedOmitted:P.charged.length-oo}:{},retained:[],evictionFailures:[]}}}var kS=["device_assigned_to_binding","device_owned_by_other_session","device_owned_by_other_daemon","inventory_incomplete","booted_inventory_incomplete","target_identity_conflict","target_identity_unresolved","target_not_destroyable"];class co{timer;deletion;constructor(d,c=kJ){this.timer=d;this.deletion=c}async deleteAndVerifyAbsence(d){let c=this.deletion();if(!c)return{kind:"failed",message:"The device delete workflow is not available yet",notAttempted:{reason:"workflow_unavailable"}};let R=await c({target:{platform:d.platform,isVirtual:!0,stableId:d.stableId,...d.name?{stableName:d.name}:{}},mode:"destroy",verifyAbsence:!0,timeoutMs:Math.max(1,d.deadlineMs-this.timer.now())},d.signal);if(Vw(R))return{kind:"failed",...AS(R),evidence:R};return{kind:"absent",evidence:R}}}function AS(d){let c=d.content[0]?.text;if(c===void 0)return{message:"deleteDevice failed"};try{let R=JSON.parse(c);if(R&&typeof R==="object"){let D="error"in R&&typeof R.error==="string"?R.error:c,k="failure"in R?IS(R.failure):void 0;if(k)return{message:D,notAttempted:{reason:k}};if(TS("failure"in R?R.failure:void 0))return{message:D,escalationExhausted:!0};return{message:D}}}catch(R){e.debug(`[Bindings] Unparsed deleteDevice failure text: ${r(R)}`)}return{message:c}}function IS(d){if(!d||typeof d!=="object"||!("phase"in d)||d.phase!=="precondition"||!("code"in d))return;return kS.find((c)=>c===d.code)}function TS(d){return!!d&&typeof d==="object"&&"code"in d&&d.code===EG}class Ge extends Error{reason;constructor(d){super("Journal drive cancelled");this.reason=d}}function ue(d){if(d?.aborted)throw new Ge(d.reason)}function lo(d,c,R){return d.devices.find((D)=>D.platform===c&&fe(D)===R)}var uo=1000,Wi=3,po=6,Vi=500;class mo{registry;stages;constructor(d,c){this.registry=d;this.stages=c}async checkDeviceFree(d,c,R){let D=await this.stages.listInventory(d,d.platform,R);if(!D)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let k=lo(D,d.platform,c);if(!k)return D.complete?{kind:"free"}:{kind:"blocked",reason:"discovery_incomplete",message:`Device '${c}' was not listed and discovery was incomplete.`};let P=await this.stages.describeClaim(d,k,R);if(P.kind==="free")return{kind:"free"};return{kind:"blocked",reason:P.kind==="held"?"device_busy":"discovery_incomplete",message:`Device '${c}' is not free: ${P.reason}`}}async locateForDeletion(d,c,R,D){if(D)return{kind:"present",device:D};let k=await this.stages.listInventory(d,d.platform,R);if(!k)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let P=lo(k,d.platform,c);if(!P)return k.complete?{kind:"absent"}:{kind:"blocked",reason:"discovery_incomplete",message:`Device '${c}' was not listed and discovery was incomplete.`};let C=await this.stages.describeClaim(d,P,R);if(C.kind!=="free")return{kind:"blocked",reason:C.kind==="held"?"device_busy":"discovery_incomplete",message:`Device '${c}' cannot be deleted: ${C.reason}`};let M=await this.registry.findDeviceHolder(d.platform,c);if(ue(R),M?.kind!=="binding"||M.assignment.scopeKey!==d.scopeKey||M.assignment.bindingIndex!==d.bindingIndex||!el(M.assignment,d.binding))return{kind:"blocked",reason:"reconcile_in_progress",message:`Device '${c}' is no longer this binding's device.`};return{kind:"present",device:P}}async locateCreated(d,c){let{newStableId:R,newName:D}=d.target;if(!R&&!D)return{kind:"absent"};let k=na(d),P=await this.stages.listInventory(d,k,c);if(!P)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let C=P.devices.filter((F)=>F.platform===k&&(R?fe(F)===R:F.name===D));if(C.length===0)return P.complete?{kind:"absent"}:{kind:"blocked",reason:"discovery_incomplete",message:`Created device '${R??D}' was not listed and discovery was incomplete.`};let M=C.length===1?fe(C[0]):void 0;if(!M)return{kind:"blocked",reason:"discovery_incomplete",message:`Created device '${D}' is ambiguous (${C.length} listed).`};return{kind:"present",device:C[0],stableId:M}}}class Qt{ids=new Set;removals=new Map;operations=new WeakMap;warned=new Set;hasRemoval(d,c){return(this.removals.get(JSON.stringify([d,c]))?.size??0)>0}hasRemovalForPass(d,c,R){let D=this.removals.get(JSON.stringify([d,c]));for(let k of D??[])if(k.overdueAtMs!==void 0&&R-k.overdueAtMs>=uo)k.abandoned=!0;return this.removalBlocked(d,c)}removalBlocked(d,c){let R=JSON.stringify([d,c]),D=this.removals.get(R);if(!D)return!1;if([...D].filter((P)=>P.abandoned).length>=Wi){if(!this.warned.has(R))this.warned.add(R),e.warn(`[BindingJournal] Removal of '${c}' reached the pending abandoned delete bound.`);return!0}return[...D].some((P)=>!P.abandoned)}markRemovalOverdue(d,c){let R=this.operations.get(d);if(R&&R.overdueAtMs===void 0)R.overdueAtMs=c}trackRemoval(d,c,R){let D=JSON.stringify([d,c]),k=this.removals.get(D)??new Set,P={abandoned:!1};k.add(P),this.removals.set(D,k);let C=Promise.resolve().then(R).finally(()=>{if(P.abandoned)e.debug(`[BindingJournal] Abandoned removal of '${c}' settled late.`);if(k.delete(P),this.operations.delete(C),k.size===0)this.removals.delete(D);if([...k].filter((M)=>M.abandoned).length<Wi)this.warned.delete(D)});return this.operations.set(C,P),C}add(d){this.ids.add(d)}delete(d){this.ids.delete(d)}has(d){return this.ids.has(d)}}function Ul(d){if(d.kind==="release")return"binding_settling";if(d.phase!=="deleting")return"reconcile_in_progress";return d.target.quarantinedAtMs===void 0?"cleanup_pending":"cleanup_quarantined"}function Kl(d){return{stableDeviceId:null,deviceName:null,requestedSpec:d,resolvedSpec:null,specFingerprint:null,state:"provisioning"}}function go(d){return{entryId:d.entry.id,kind:d.entry.kind,phase:d.entry.phase,outcome:d.kind,...d.kind==="blocked"?{reason:d.reason}:{}}}var ES={android:Cte,ios:Dte,watchos:RW};function Wl(d){let c=ES[na(d)].safeParse(d.target.requestedSpec);return c.success?c.data:void 0}class yo{deps;removalIntents=new Set;constructor(d){this.deps=d}clear(d){this.removalIntents.delete(d)}removalIntended(d){return d.target.removalRequested===!0||this.removalIntents.has(d.id)}markRemovalIntended(d){if(!d.target.removalRequested)this.removalIntents.add(d.id)}async requestRemoval(d,c={}){if(d.target.removalRequested)return d;this.markRemovalIntended(d);let R=await this.tryRemovalFlag(d,new AbortController().signal,!0);if(R)return R.kind==="advanced"?R.entry:d;if(c.deadlineMs!==void 0&&this.deps.timer.now()>=c.deadlineMs)return e.warn(`[BindingJournal] Removal flag for entry ${d.id} missed its deadline.`),d;let D=new AbortController,k=c.signal?AbortSignal.any([c.signal,D.signal]):D.signal;try{return await l(()=>this.retryRemovalFlag(d,k),{timer:this.deps.timer,timeoutMs:c.deadlineMs===void 0?void 0:Math.max(0,c.deadlineMs-this.deps.timer.now()),signal:k,label:`removal flag for entry ${d.id}`,onTimeout:()=>D.abort()})}catch(P){if(!k.aborted)throw P;return e.warn(`[BindingJournal] Removal flag for entry ${d.id} interrupted: ${r(P)}`,P),d}}async retryRemovalFlag(d,c){for(let R=2;R<=po;R++){c.throwIfAborted(),await this.deps.pacing.wait(this.deps.pacing.delay(R-1),c);let D=await this.tryRemovalFlag(d,c);if(D)return D.kind==="advanced"?D.entry:d}return e.warn(`[BindingJournal] Removal flag for entry ${d.id} exhausted registry retries.`),d}async tryRemovalFlag(d,c,R=!1){let D=this.deps.timer.now(),k=Error(`Removal flag for entry ${d.id} exceeded its write budget.`);try{let P=()=>this.deps.advance(d,{expectedPhase:d.phase,phase:d.phase,target:{removalRequested:!0,...d.target.newStableId?{newStableId:d.target.newStableId}:{}}},c),C=await(R?l(P,{timer:this.deps.timer,timeoutMs:Vi,timeoutError:()=>k,label:`first removal flag write for entry ${d.id}`}):this.deps.pacing.run(P,(M)=>M.kind==="advanced",c));if(C.kind==="advanced"||C.kind==="journal_conflict")this.clear(d.id);return C}catch(P){if(P===k)return e.warn(`[BindingJournal] ${r(P)}`,P),{kind:"removal_flag_timed_out"};if(Qa(P)!=="retryable")throw e.warn(`[BindingJournal] Removal flag failed: ${r(P)}`,P),P;if(R)this.deps.pacing.noteBlocked(D);e.debug(`[BindingJournal] Removal flag deferred: ${r(P)}`,P);return}}}class We extends Error{}class wo{deps;constructor(d){this.deps=d}async boundedStage(d,c,R){ue(c.cancel);let D=new AbortController,k=c.signal?AbortSignal.any([c.signal,D.signal]):D.signal,P=Error(`${c.label} timed out after ${c.timeoutMs}ms`);try{let C=await l(()=>d(k),{timer:this.deps.timer,timeoutMs:Math.max(0,c.timeoutMs),signal:c.signal,label:c.label,timeoutError:()=>P,onTimeout:()=>D.abort(P)});return ue(c.cancel),C}catch(C){if(c.cancel?.aborted)throw D.abort(c.cancel.reason),new Ge(c.cancel.reason);return e.warn(`[BindingJournal] ${c.label} failed: ${r(C)}`,C),R(c.signal?.aborted?Error(`${c.label} cancelled: ${r(C)}`):C)}}listInventory(d,c=d.platform,R){return this.boundedStage((D)=>this.deps.inventory.list(c,{signal:D}),{label:`discovery for entry ${d.id}`,timeoutMs:this.deps.budgets.discoveryMs,signal:R,cancel:R},()=>null)}describeClaim(d,c,R){return this.boundedStage(()=>this.deps.claims.describe(c),{label:`claim for entry ${d.id}`,timeoutMs:this.deps.budgets.claimMs,signal:R,cancel:R},(D)=>({kind:"unknown",reason:r(D)}))}async deleteDevice(d,c,R){let{inFlight:D}=this.deps;if(D.removalBlocked(d.platform,d.stableId))return{kind:"failed",message:`Removal of device '${d.stableId}' is still in flight.`};let k;try{let P=await this.boundedStage((C)=>(k=D.trackRemoval(d.platform,d.stableId,()=>this.deps.deleter.deleteAndVerifyAbsence({...d,signal:C})),k),{label:`deleting '${d.stableId}'`,timeoutMs:Math.max(0,Math.min(d.deadlineMs+this.deps.budgets.deleteGraceMs,R??1/0)-this.deps.timer.now()),signal:d.signal,cancel:c},(C)=>({kind:"failed",message:r(C)}));return{...P,nativeDeleteFailed:k!==void 0&&P.kind==="failed"&&!P.notAttempted}}finally{if(k)D.markRemovalOverdue(k,this.deps.timer.now())}}}function Vl(d,c){return{target:{quarantinedAtMs:d},attempt:{error:c,nextAttemptAtMs:d+600000}}}function Jl(d,c,R){let D=c.lastError??"its emulator would not stop";return{advance:{attempt:{error:D,nextAttemptAtMs:d+600000}},message:`Device '${R}' is quarantined: ${D}`}}var zl=120000,BS=30000,OS=1e4,FS=1e4,NS=5000,US=25,GS=1000,JS=5000,zS=6,YS=Q({initialDelayMs:1000,multiplier:2,maxDelayMs:60000});function Ce(d,c,R){return{kind:"blocked",entry:d,reason:c,message:R}}function Ro(d){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex}}class Do{deps;inFlight;isOwnerLive;isExecOwnerLive;backoff;budgets;removalFlags;stages;locator;constructor(d){this.deps=d;this.inFlight=d.inFlight??new Qt,this.isOwnerLive=d.isOwnerLive??mc,this.isExecOwnerLive=d.isExecOwnerLive??mc,this.backoff=Lo(d.backoff??YS),this.budgets={discoveryMs:BS,claimMs:OS,matchMs:FS,deleteGraceMs:NS,...d.stageBudgets},this.removalFlags=new yo({timer:d.timer,pacing:new Me({timer:d.timer,initialDelayMs:US,maxDelayMs:GS,maxBlockedWaitMs:JS}),advance:(c,R,D)=>this.advanceStep(c,R,D)}),this.stages=new wo({inventory:d.inventory,deleter:d.deleter,claims:d.claims,timer:d.timer,inFlight:this.inFlight,budgets:this.budgets}),this.locator=new mo(d.registry,this.stages)}get owner(){return this.deps.owner}markRemovalIntended(d){this.removalFlags.markRemovalIntended(d)}requestRemoval(d,c={}){return this.removalFlags.requestRemoval(d,c)}async redriveBinding(d,c={}){try{return await this.redriveBindingEntries(d,c.signal)}catch(R){if(R instanceof Ge)throw e.debug("[BindingJournal] acquisition redrive cancelled"),R.reason;throw R}}async redriveBindingEntries(d,c){ue(c);let R=[],D=await this.deps.registry.listOpenBindingJournal(d);if(ue(c),D.length===0){let k=await this.adoptUnjournaledWork(d,c);D=k?[k]:[]}for(let k of D){let P=await this.driveEntry(k,c);if(P.kind==="skipped")return{kind:"blocked",reason:Ul(P.entry),message:`Binding ${d.bindingIndex} has unfinished ${P.entry.kind} work (${P.why}).`,entry:P.entry,redriven:R};if(R.push(go(P)),P.kind==="blocked")return{kind:"blocked",reason:P.reason,message:P.message,entry:P.entry,redriven:R}}return{kind:"clear",redriven:R}}async runPass(d={}){let{signal:c}=d,R={settled:[],blocked:[],skipped:0};if(c?.aborted)return R;let D=await this.deps.registry.listOpenBindingJournal();for(let k of D){if(c?.aborted)break;try{let P=await this.driveEntry(k,c,{fromPass:!0});if(P.kind==="skipped")R.skipped+=1;else(P.kind==="settled"?R.settled:R.blocked).push(go(P))}catch(P){if(P instanceof Ge){e.debug("[BindingJournal] pass cancelled");break}e.warn(`[BindingJournal] redrive of entry ${k.id} failed: ${r(P)}`,P),R.blocked.push({entryId:k.id,kind:k.kind,phase:k.phase,outcome:"blocked"})}}return R}async driveDeletion(d,c={}){return(d.target.oldStableId?this.pendingRemoval(d,d.platform,d.target.oldStableId):void 0)??this.deletionStep(d,c)}async deletionStep(d,c,R){ue(R);let D=d.target.oldStableId,k=await this.deps.registry.getAssignment(Ro(d));if(ue(R),!D||!k||!el(k,d.binding))return this.closeStep(d,"rolled_back",R);if(k.execOwner&&this.isExecOwnerLive(k.execOwner))return Ce(d,"binding_in_use",`Binding is held by ${k.execOwner.sessionUuid}.`);let P=this.pendingRemoval(d,d.platform,D,"step");if(P)return P;let C=await this.locator.locateForDeletion(d,D,R,c.device);if(C.kind==="blocked")return this.recordBlocked(d,C.reason,C.message,{signal:R});if(C.kind==="present"&&d.target.quarantinedAtMs!==void 0)return this.probeQuarantine(d,D,R);let M=C.kind==="present"?await this.stages.deleteDevice({platform:d.platform,stableId:D,name:d.target.oldName,deadlineMs:c.deadlineMs??this.deps.timer.now()+zl,signal:c.signal},R):{kind:"absent",evidence:{listed:!1}};return ue(R),this.recordDeletion(d,D,M,R)}async probeQuarantine(d,c,R){let D=Jl(this.deps.timer.now(),d,c),k=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleting",...D.advance},R);return{kind:"blocked",entry:k.kind==="advanced"?k.entry:d,reason:"cleanup_quarantined",message:D.message}}async recordDeletion(d,c,R,D){if(R.kind==="failed"){let P=R.escalationExhausted===!0,C=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleting",assignment:{kind:"state",expected:d.binding,state:"cleanup_pending"},...P?Vl(this.deps.timer.now(),R.message):{attempt:this.attemptAfter(d,R.message,this.entryRemovalInFlight(d))}},D);return{kind:"blocked",entry:C.kind==="advanced"?C.entry:d,reason:P?"cleanup_quarantined":"cleanup_pending",message:`Deleting device '${c}' failed: ${R.message}`,evidence:R.evidence}}let k=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleted",assignment:{kind:"commit",expected:d.binding,next:{...Kl(d.target.requestedSpec),platform:na(d)}}},D);if(k.kind!=="advanced"||!k.assignment)return{kind:"blocked",entry:d,reason:"reconcile_in_progress",message:`Recording the deletion failed: ${k.kind}.`};return{kind:"deleted",entry:k.entry,assignment:k.assignment,evidence:R.evidence}}async settleCreation(d,c={adopt:!0}){return(d.target.newStableId?this.pendingRemoval(d,na(d),d.target.newStableId):void 0)??this.creationStep(d,c)}async removalRegistryStage(d,c){let R=Math.min(Vi,c===void 0?1/0:Math.max(0,c-this.deps.timer.now()));return l(d,{timer:this.deps.timer,timeoutMs:R,label:"uncommitted cleanup registry stage",timeoutError:()=>new We("Removal deferred to journal redrive: registry stage timed out.")})}async creationStep(d,c,R){try{return await this.creationRegistryStep(d,c,R)}catch(D){if(!(D instanceof We))throw D;let k=c.adopt?`Settling created entry ${d.id} deferred to the next redrive: registry stage timed out`:"Creation cleanup deferred to journal redrive: registry stage timed out";return e.warn(`[BindingJournal] ${k}`,D),Ce(d,"reconcile_in_progress",k)}}async creationRegistryStep(d,c,R){ue(R);let D=await this.locator.locateCreated(d,R);if(D.kind==="absent")return this.removalRegistryStage(()=>this.closeStep(d,"rolled_back",R),c.deadlineMs);if(D.kind==="blocked")return this.removalBlocked(d,D.reason,D.message,{signal:R,deadlineMs:c.deadlineMs});let{device:k,stableId:P}=D,C=this.pendingRemoval(d,na(d),P,"step");if(C)return C;let M=await this.removalRegistryStage(()=>this.deps.registry.findDeviceHolder(na(d),P),c.deadlineMs);if(ue(R),M)return this.removalRegistryStage(()=>this.closeStep(d,"rolled_back",R),c.deadlineMs);let F=await this.removalRegistryStage(()=>this.deps.registry.getAssignment(Ro(d)),c.deadlineMs);ue(R);let q=F!==null&&el(F,d.binding),U=Wl(d);if(c.adopt&&!this.removalFlags.removalIntended(d)&&q&&U){let K=await this.stages.boundedStage(()=>this.deps.matcher.matches(k,U),{label:`configuration for entry ${d.id}`,timeoutMs:this.budgets.matchMs,signal:R,cancel:R},()=>"unknown");if(K==="unknown")return this.recordBlocked(d,"discovery_incomplete",`Configuration of '${P}' is unreadable.`,{signal:R});if(K==="match")return this.adoptCreated(d,k,P,R)}return this.removeCreated(d,k,P,{deadlineMs:c.deadlineMs,signal:R})}async close(d,c){return this.closeStep(d,c)}async closeStep(d,c,R){let D=await this.advanceStep(d,{expectedPhase:d.phase,phase:c},R);return this.removalFlags.clear(d.id),{kind:"settled",entry:D.kind==="advanced"?D.entry:d}}async advance(d,c){let R=await this.advanceStep(d,c);if(R.kind==="journal_conflict"||R.kind==="advanced"&&R.entry.target.removalRequested)this.removalFlags.clear(d.id);return R}async advanceStep(d,c,R){ue(R);let D=await this.deps.registry.advanceBindingJournal(d.id,{...c,owner:this.deps.owner});return ue(R),D}async driveEntry(d,c,R={}){if(ue(c),this.inFlight.has(d.id))return!R.fromPass&&this.pendingEntryRemoval(d)||{kind:"skipped",entry:d,why:"in progress in this process"};let D=await this.takeOwnership(d,c);if(D.kind==="skipped")return D;let k=D.entry,P=this.pendingEntryRemoval(k,R.fromPass);if(P)return P;if(k.attempts>0&&k.nextAttemptAtMs>this.deps.timer.now())return{kind:"skipped",entry:k,why:`retry due in ${k.nextAttemptAtMs-this.deps.timer.now()}ms`};this.inFlight.add(k.id);try{for(let C=0;C<zS;C+=1){ue(c);let M=await this.step(k,c);if(M.kind!=="next")return M;k=M.entry}return Ce(k,"reconcile_in_progress","Journal entry did not settle.")}finally{this.inFlight.delete(k.id)}}async takeOwnership(d,c){if(jc(d.owner,this.deps.owner))return{kind:"owned",entry:d};if(this.isOwnerLive(d.owner))return{kind:"skipped",entry:d,why:`owned by live daemon ${d.owner.daemonId}`};let R=await this.deps.registry.claimBindingJournal(d.id,d.owner,this.deps.owner);if(ue(c),R.kind!=="claimed")return{kind:"skipped",entry:R.entry??d,why:"claimed by another redrive"};return e.info(`[BindingJournal] adopted ${d.kind} entry ${d.id} (${d.phase}) of binding ${d.scopeKey.slice(0,8)}/${d.bindingIndex} from dead owner ${d.owner.daemonId}`),{kind:"owned",entry:R.entry}}async step(d,c){if(d.kind==="release")return this.settleRelease(d,c);switch(d.phase){case"deleting":{let R=await this.deletionStep(d,{signal:c},c);return R.kind==="deleted"?{kind:"next",entry:R.entry}:R}case"deleted":return this.closeStep(d,"committed",c);case"intent":case"creating":case"created":return this.creationStep(d,{adopt:!0},c);default:return{kind:"settled",entry:d}}}async settleRelease(d,c){let R=await this.deps.registry.getAssignment(Ro(d));if(ue(c),!R||!el(R,d.binding))return this.closeStep(d,"rolled_back",c);if(R.state!=="settling")return this.closeStep(d,"committed",c);if(R.settler&&this.isOwnerLive(R.settler))return Ce(d,"binding_settling","The binding's settler is still watching its work.");if(R.execOwner&&this.isExecOwnerLive(R.execOwner))return Ce(d,"binding_in_use",`Binding is held by ${R.execOwner.sessionUuid}.`);let D=R.stableDeviceId;if(D){let P=await this.locator.checkDeviceFree(d,D,c);if(P.kind==="blocked")return this.recordBlocked(d,P.reason,P.message,{signal:c})}let k=await this.advanceStep(d,{expectedPhase:d.phase,phase:"committed",assignment:{kind:"state",expected:d.binding,state:"ready"}},c);if(k.kind!=="advanced")return Ce(d,"reconcile_in_progress",`Restoring the binding failed: ${k.kind}.`);return{kind:"settled",entry:k.entry}}async adoptCreated(d,c,R,D){if(this.removalFlags.removalIntended(d))return this.removeCreated(d,c,R,{signal:D});let k=await this.advanceStep(d,{expectedPhase:d.phase,phase:"committed",target:{newStableId:R,newName:c.name},assignment:{kind:"commit",expected:d.binding,next:{stableDeviceId:R,deviceName:c.name,requestedSpec:d.target.requestedSpec,resolvedSpec:d.target.resolvedSpec,specFingerprint:d.target.specFingerprint,state:"provisioning"}}},D);if(k.kind==="advanced")return{kind:"settled",entry:k.entry};if(k.kind==="journal_conflict")return Ce(d,"reconcile_in_progress","The journal entry changed during adoption.");return this.removeCreated(d,c,R,{signal:D})}async removeCreated(d,c,R,{deadlineMs:D,signal:k}={}){if(!d.target.removalRequested){this.markRemovalIntended(d);let F=await this.removalRegistryStage(()=>this.advanceStep(d,{expectedPhase:d.phase,phase:d.phase,target:{removalRequested:!0,newStableId:R}},k),D);if(F.kind==="advanced"||F.kind==="journal_conflict")this.removalFlags.clear(d.id);if(F.kind!=="advanced")return Ce(d,"reconcile_in_progress",`Recording removal of '${R}' failed: ${F.kind}.`);d=F.entry}let P=await this.stages.describeClaim(d,c,k);if(P.kind!=="free")return this.removalBlocked(d,P.kind==="held"?"device_busy":"discovery_incomplete",`Uncommitted device '${R}' cannot be removed: ${P.reason}`,{target:{newStableId:R},signal:k,deadlineMs:D});let C=await this.stages.deleteDevice({platform:na(d),stableId:R,name:c.name,deadlineMs:D??this.deps.timer.now()+zl,signal:k},k);if(C.kind==="failed")return this.removalBlocked(d,"cleanup_pending",`Removing uncommitted device '${R}' failed: ${C.message}`,{target:{newStableId:R},signal:k,deadlineMs:D});let M=await this.removalRegistryStage(()=>this.advanceStep(d,{expectedPhase:d.phase,phase:"rolled_back",target:{newStableId:R}},k),D);return this.removalFlags.clear(d.id),{kind:"settled",entry:M.kind==="advanced"?M.entry:d}}async adoptUnjournaledWork(d,c){let R=await this.deps.registry.getAssignment(d);if(ue(c),!R?.stableDeviceId||R.state!=="replacing"&&R.state!=="cleanup_pending"||R.execOwner&&this.isExecOwnerLive(R.execOwner))return null;let D=await this.deps.registry.openBindingJournal(d,{kind:"replace",phase:"deleting",owner:this.deps.owner,target:{oldStableId:R.stableDeviceId,oldName:R.deviceName,newName:null,newStableId:null,requestedSpec:R.requestedSpec,resolvedSpec:R.resolvedSpec,specFingerprint:R.specFingerprint},assignment:{kind:"state",expected:{generation:R.generation,stableDeviceId:R.stableDeviceId},state:R.state}});if(ue(c),D.kind==="opened")return e.warn(`[BindingJournal] binding ${d.bindingIndex} was left ${R.state} without a journal entry; redriving it as entry ${D.entry.id}`),D.entry;return D.kind==="journal_open"?D.entry:null}removalBlocked(d,c,R,{target:D,signal:k,deadlineMs:P}){return this.removalRegistryStage(()=>this.recordBlocked(d,c,R,{target:D,signal:k}),P)}async recordBlocked(d,c,R,{target:D,signal:k}={}){let P=D?.newStableId&&d.phase==="creating"?"created":d.phase,C=await this.advanceStep(d,{expectedPhase:d.phase,phase:P,...D?{target:D}:{},attempt:this.attemptAfter(d,R,this.entryRemovalInFlight(d))},k);return Ce(C.kind==="advanced"?C.entry:d,c,R)}entryRemovalInFlight(d){return this.inFlight.hasRemoval(d.platform,d.target.oldStableId??"")||this.inFlight.hasRemoval(na(d),d.target.newStableId??"")}attemptAfter(d,c,R=!1){return{error:c,nextAttemptAtMs:this.deps.timer.now()+(R?0:this.backoff.delayForAttempt(d.attempts+1))}}pendingEntryRemoval(d,c=!1){let R=d.phase==="deleting",D=R?d.target.oldStableId:d.target.newStableId;return D?this.pendingRemoval(d,R?d.platform:na(d),D,c?"pass":"caller"):void 0}pendingRemoval(d,c,R,D="caller"){if(!(D==="pass"?this.inFlight.hasRemovalForPass(c,R,this.deps.timer.now()):D==="caller"?this.inFlight.hasRemoval(c,R):this.inFlight.removalBlocked(c,R)))return;return Ce(d,"cleanup_pending",`Removal of device '${R}' is still in flight.`)}}import{createHash as XS}from"crypto";function Ql(d,c){if(d.isAvailable===!1||d.runtime===void 0||d.deviceType===void 0||c.deviceType===void 0)return"unknown";return d.runtime===c.runtime&&d.deviceType===c.deviceType?"match":"mismatch"}async function Zl(d,c,R){let D=RW.safeParse(c);if(!D.success)return{kind:"unsupported",code:"spec_unsupported",message:`A watchOS binding spec names exactly runtime and deviceType: ${RE(D.error)}`};if(!d)return{kind:"unsupported",code:"spec_unsupported",message:"Apple Watch simulators exist only on macOS hosts with Xcode's simctl."};let k;try{k=await d.readCatalog(R)}catch(C){return R?.throwIfAborted(),e.warn(`[Bindings] watch catalog unreadable: ${r(C)}`,C),{kind:"unresolved",message:`The Apple Watch simulator catalog could not be read: ${r(C)}`}}let P=D.data;try{kG(P,k)}catch(C){if(!(C instanceof t))throw C;let M=k.runtimes.find((q)=>q.identifier===P.runtime);return{kind:"unsupported",code:k.deviceTypes.some((q)=>q.identifier===P.deviceType)&&M&&!M.isAvailable?"runtime_incompatible":"spec_unsupported",message:C.message}}return{kind:"resolved",resolvedSpec:{runtime:P.runtime,deviceType:P.deviceType,displayCutout:"unknown"}}}var eu=1,ru="pixel_8",QS={phone:ru,tablet:"pixel_tablet",foldable:"pixel_fold",tv:jl("tv"),watch:jl("watch"),automotive:jl("automotive"),"xr-headset":jl("xr-headset"),"xr-glasses":jl("xr-glasses")};function Ao(d,c){let R=XS("sha256").update(Fr({version:eu,platform:d,resolvedSpec:c})).digest("hex");return{version:eu,hash:R}}function ei(d){let c={...d};return delete c.deviceFamily,c}function ZS(d,c){if(c.deviceFamily===void 0)return;if(c.deviceType===void 0)return d==="android"?tb(c):void 0;let R=d==="ios"?cf(c.deviceType):Vf({profileId:c.deviceType,systemImageTag:nn(c.runtime)?.tag});if(R===void 0||R==="unknown")return`The family of deviceType '${c.deviceType}' cannot be verified before creation for deviceFamily '${c.deviceFamily}'. Request either deviceType or deviceFamily, not both.`;return R===c.deviceFamily?void 0:`deviceType '${c.deviceType}' is a ${R}; it conflicts with deviceFamily '${c.deviceFamily}'.`}function tb(d){let c=Vf({systemImageTag:nn(d.runtime)?.tag});return Qae(c)?c===d.deviceFamily?void 0:`runtime '${d.runtime}' is a ${c} image; it conflicts with deviceFamily '${d.deviceFamily}'.`:void 0}function ib(d,c){if(d!=="android"||c.deviceFamily===void 0||!("configuration"in c))return;return["screenWidth","screenHeight","screenDensity"].some((D)=>c.configuration?.[D]!==void 0)?"The family is classified from screen geometry, so it cannot be verified before creation when the geometry is overridden. Request deviceFamily without screen overrides, or an explicit deviceType without deviceFamily.":void 0}var iu="com.apple.CoreSimulator.SimRuntime.";class Ji{iosRuntimeCatalog;androidDefaultDeviceType;androidDefaultDeviceTypesByFamily;androidImageCatalog;androidProfileCatalog;watchCatalog;constructor(d,c={}){this.iosRuntimeCatalog=d;this.androidDefaultDeviceType=c.androidDefaultDeviceType??ru,this.androidDefaultDeviceTypesByFamily={...QS,phone:this.androidDefaultDeviceType,...c.androidDefaultDeviceTypesByFamily},this.androidImageCatalog=c.androidImageCatalog,this.androidProfileCatalog=c.androidProfileCatalog,this.watchCatalog=c.watchCatalog}async checkCreatable(d,c,R){if(d==="ios"||d==="watchos"){let k=await this.resolve(d,{runtime:c.runtime,deviceType:c.deviceType},R);return k.kind==="resolved"?{kind:"creatable"}:k}if(!this.androidProfileCatalog)return{kind:"creatable"};let D;try{D=await this.androidProfileCatalog.listProfileIds(R.signal)}catch(k){return e.warn(`[Bindings] Android profile catalog unreadable: ${r(k)}`,k),{kind:"unresolved",message:`The Android hardware profile catalog could not be read: ${r(k)}`}}if(D.includes(c.deviceType))return{kind:"creatable"};return{kind:"unsupported",code:"spec_unsupported",message:`Android hardware profile '${c.deviceType}' is not available on this host. List valid profile IDs with avdmanager list device.`}}async resolve(d,c,R){if(d==="watchos"){let q=await Zl(this.watchCatalog,c,R.signal);return q.kind==="resolved"?{...q,fingerprint:Ao(d,q.resolvedSpec)}:q}let D=this.catalogRead(R.signal),k=await this.findUnsupportedSpec(d,c,R.signal,D);if(k)return{kind:"unsupported",code:"spec_unsupported",message:k};let P=await this.resolveDeviceType(d,c,D);if(P.kind!=="resolved")return P.resolution;let C={...ei(c),deviceType:P.deviceType},M=kW(d,C);if(M.kind!=="resolved")return{kind:"unsupported",code:"spec_unsupported",message:M.message};if(d==="ios"&&this.iosRuntimeCatalog&&c.deviceType!==void 0){let q=await this.findIosIncompatibility(C,D);if(q)return{kind:"unsupported",code:"runtime_incompatible",message:q}}let F={...C,displayCutout:M.displayCutout};return{kind:"resolved",resolvedSpec:F,fingerprint:Ao(d,F)}}catalogRead(d){let c;return()=>{if(!c){let R=this.iosRuntimeCatalog;if(!R)throw new t("The simulator catalog is unavailable");c=R.getCatalogChecked?R.getCatalogChecked(d):Promise.all([R.getRuntimesChecked(void 0,d),R.getDeviceTypesChecked(d)]).then(([D,k])=>({runtimes:D,deviceTypes:k}))}return c}}async findUnsupportedSpec(d,c,R,D){let k=ib(d,c)??ZS(d,c);if(k!==void 0)return k;if(d==="android")return nn(c.runtime)?await this.findMissingAndroidImage(c.runtime,R):`Android runtime '${c.runtime}' is not a system-image identifier.`;return c.runtime.startsWith(iu)?await this.findMissingIosCatalogEntry(c,D):`iOS runtime '${c.runtime}' is not a CoreSimulator runtime identifier (${iu}...).`}async resolveDeviceType(d,c,R){if(c.deviceType!==void 0)return{kind:"resolved",deviceType:c.deviceType};if(c.displayCutout!==void 0&&c.displayCutout!=="any")return ko("spec_unsupported",`A display cutout preference ('${c.displayCutout}') needs an explicit deviceType.`);if(d==="android")return{kind:"resolved",deviceType:c.deviceFamily===void 0?this.androidDefaultDeviceType:this.androidDefaultDeviceTypesByFamily[c.deviceFamily]};if(!this.iosRuntimeCatalog)return ko("spec_unsupported","An iOS spec without deviceType needs the simulator catalog to choose a model.");let D,k;try{({runtimes:D,deviceTypes:k}=await R())}catch(C){return e.warn(`[Bindings] iOS catalog unreadable; cannot choose a model: ${r(C)}`,C),{kind:"refused",resolution:{kind:"unresolved",message:`The simulator catalog could not be read to choose a model: ${r(C)}`}}}let P=ou(c.runtime,D,k,c.deviceFamily);return P?{kind:"resolved",deviceType:P}:ko("runtime_incompatible",`No installed ${c.deviceFamily??"iPhone"} model supports runtime '${c.runtime}', or the runtime is not available.`)}async findMissingAndroidImage(d,c){if(!this.androidImageCatalog)return;let R;try{R=await this.androidImageCatalog.listInstalledPackages(c)}catch(D){e.warn(`[Bindings] Android image check skipped: ${r(D)}`,D);return}if(R.includes(d))return;return`Android system image '${d}' is not installed. Install it with sdkmanager, or request an installed image (${R.join(", ")||"none installed"}).`}async findMissingIosCatalogEntry(d,c){if(!this.iosRuntimeCatalog)return;let R,D;try{({runtimes:R,deviceTypes:D}=await c())}catch(P){e.warn(`[Bindings] iOS catalog check skipped: ${r(P)}`,P);return}if(!R.some((P)=>P.identifier===d.runtime)){let P=R.map((C)=>C.identifier);return`iOS runtime '${d.runtime}' is not installed on this host. Install it with Xcode, or request an installed runtime (${P.join(", ")||"none installed"}).`}if(d.deviceType===void 0||D.some((P)=>P.identifier===d.deviceType))return;let k=D.filter((P)=>P.productFamily==="iPhone").map((P)=>P.identifier);return`iOS device type '${d.deviceType}' is not installed on this host. Request an installed device type (iPhone types: ${k.join(", ")||"none installed"}; all types: xcrun simctl list devicetypes).`}async findIosIncompatibility(d,c){let R,D;try{({runtimes:R,deviceTypes:D}=await c())}catch(C){e.warn(`[Bindings] iOS catalog check skipped: ${r(C)}`,C);return}let k=EW(d,R,D);if(!k)return;let P=k.compatibleRuntimes.map((C)=>C.id).join(", ")||"none installed";return k.unavailable?`Runtime '${d.runtime}' is not available. Compatible installed runtimes: ${P}.`:`Device type '${d.deviceType}' does not support runtime '${d.runtime}'. Compatible installed runtimes: ${P}.`}}function ko(d,c){return{kind:"refused",resolution:{kind:"unsupported",code:d,message:c}}}function ou(d,c,R,D){let k=c.find((q)=>q.identifier===d);if(!k?.isAvailable)return;let P=R.filter((q)=>D===void 0?q.productFamily==="iPhone"&&!q.modelIdentifier?.startsWith("iPod")&&!ys(q.identifier):cf(q.identifier)===D),C=(q)=>Rc(q,k.version).status,M=P.filter((q)=>C(q)==="supported"),F=P.filter((q)=>C(q)==="unknown");return(M.toSorted(nu).at(-1)??F.toSorted(nu).at(-1))?.identifier}function nu(d,c){let R=/^(iPhone|iPad)(\d+),(\d+)$/.exec(d.modelIdentifier??""),D=/^(iPhone|iPad)(\d+),(\d+)$/.exec(c.modelIdentifier??"");if(!R||!D)return Number(Boolean(R))-Number(Boolean(D));return Number(R[2])-Number(D[2])||Number(D[3])-Number(R[3])||c.name.length-d.name.length||(d.identifier<c.identifier?1:d.identifier>c.identifier?-1:0)}class ne extends Error{failure;constructor(d){super(d.message);this.failure=d;this.name="ReconcileAbort"}}var nb={spec_unsupported:!1,runtime_incompatible:!1,scope_not_valid:!1,discovery_incomplete:!0,binding_in_use:!0,binding_settling:!0,device_busy:!0,reconcile_in_progress:!0,cleanup_pending:!0,cleanup_quarantined:!1,capacity_exhausted:!0,binding_budget_exhausted:!0,concurrent_modification:!0,readiness_incomplete:!0,stale_session:!0,provision_failed:!1,timeout:!0,cancelled:!0},rb={spec_unsupported:"Fix the requested spec; nothing was changed.",runtime_incompatible:"Request a model/runtime pair the host supports; nothing was changed.",scope_not_valid:"Use the current runner incarnation; this scope no longer accepts work.",discovery_incomplete:"Retry once device discovery completes; nothing destructive was done.",binding_in_use:"Wait for the binding's live execution to end, then retry.",binding_settling:"Wait for the previous execution's released work to settle, then retry.",device_busy:"Wait for the device's live session or foreign claim to end, then retry.",reconcile_in_progress:"Another reconciliation of this binding is in progress; retry later.",cleanup_pending:"The previous device could not be removed; retry after cleanup succeeds.",cleanup_quarantined:"The previous device would not stop even after the process-level kill; stop its emulator process by hand, then retry.",binding_budget_exhausted:"Free unused broker resources or raise limits.totalDeviceCap in the broker host configuration, then retry.",capacity_exhausted:"Shut down a device or raise the boot limit, then retry.",concurrent_modification:"The binding changed concurrently; retry to converge on its new state.",readiness_incomplete:"Retry; the device did not reach automation readiness.",stale_session:"Retry; an earlier execution's session on the binding device could not be released.",provision_failed:"Inspect the provision failure code; retry if it is retryable.",timeout:"Retry with a longer preparation timeout.",cancelled:"The preparation was cancelled; retry when needed."};function Po(d,c,R){let D=R.toLowerCase().replace(/[^a-z0-9]/g,"").slice(0,8);if(D.length===0)throw Error(`Binding device name nonce '${R}' has no usable characters`);return`${zZ}${Io(d)}${c}-${D}`}function Io(d){return`${d.scopeKey.slice(0,8)}-${d.bindingIndex}-g`}function ct(d){return`v${d.version}:${d.hash}`}function Z(d,c,R={}){return{code:d,retryable:R.retryable??nb[d],message:c,nextAction:rb[d],...R.provision?{provision:R.provision}:{},...R.capacity?{capacity:R.capacity}:{},...R.budget?{budget:R.budget}:{}}}function Co(d,c){switch(d.kind){case"scope_not_valid":return Z("scope_not_valid",`Binding scope is no longer valid (${c}).`);case"binding_missing":return Z("concurrent_modification",`Binding disappeared during ${c}.`);case"stale_binding":return Z("concurrent_modification",`Binding binding changed during ${c} (now generation ${d.current.generation}).`);case"device_assigned_elsewhere":return Z("concurrent_modification",`Device is already assigned to binding ${d.holder.bindingIndex} of another scope (${c}).`)}}function Oe(d,c){switch(d.kind){case"binding_in_use":return Z("binding_in_use",`Binding is held by live session ${d.owner.sessionUuid} (${c}).`);case"binding_not_ready":return Z("concurrent_modification",`Binding stopped being ready during ${c}.`);default:return Co(d,c)}}function ji(d){return d&&d.length>0?{externalDevices:[...d]}:{}}function Tt(d){if(d instanceof $n)return Z("capacity_exhausted",d.message,{capacity:{limit:d.limit,booted:d.booted,retryAfterMs:d.retryAfterMs,...ji(d.details.externalDevices),...d.details.heldDevices?.length?{heldDevices:[...d.details.heldDevices]}:{}}});if(d instanceof Ue){if(d.code==="discovery_incomplete")return Z("discovery_incomplete",d.message);if(d.code==="runtime_incompatible")return Z("runtime_incompatible",d.message);let c=d.diagnostics.capacity;if(d.code==="capacity_exhausted"&&c)return Z("capacity_exhausted",d.message,{capacity:{limit:c.limit,booted:c.booted,retryAfterMs:d.diagnostics.retryAfterMs??0,...ji(c.externalDevices),...c.heldDevices?.length?{heldDevices:[...c.heldDevices]}:{}}});return Z("provision_failed",d.message,{retryable:d.retryable,provision:{code:d.code,retryable:d.retryable}})}return Z("provision_failed",r(d),{retryable:!1})}function Te(d){return{generation:d.generation,stableDeviceId:d.stableDeviceId}}function su(d){let{createDeadlineMs:c,deadlineMs:R}=d.request;if(c===void 0||c>=R)return d;return{...d,request:{...d.request,deadlineMs:c}}}function ob(d){return d.isRunning||d.platform!=="android"&&d.state!==void 0&&V4.has(d.state)}class To{deps;host;constructor(d,c){this.deps=d;this.host=c}async createAndCommit(d,c,R,{replacing:D,...k}={}){let{request:P}=d,C;if(D===void 0)try{if(this.host.checkBudget(P),await this.assertCreatable(d),!k.bootReservation)C=await this.assertBootCapacity(P)}catch(q){throw await this.removeNeverBoundBinding(d,c,"pre-provision refusal"),q}else if(this.host.checkBudget(P),!k.bootReservation)C=await this.assertBootCapacity(P);let M=Po(P.key,c.generation+1,this.deps.idGenerator.next());d.evidence.createdName=M;let F=D?await this.advanceToCreating(d,D,M):await this.openCreateEntry(d,c,M);this.deps.journal.inFlight.add(F.id);try{if(D===void 0&&this.deps.resourceBudget)await this.admitFreshCreation(d,c,F);let q;try{let K=()=>this.deps.provisioner.provision({platform:P.platform,name:M,spec:{...ei(P.requestedSpec),deviceType:d.resolvedSpec.deviceType},mode:"create",deadlineMs:P.deadlineMs,signal:P.signal}),W=P.platform,V=()=>W==="watchos"?K():AJ({platform:W,name:M,spec:{runtime:P.requestedSpec.runtime,deviceType:d.resolvedSpec.deviceType}},C,this.deps.timer,K);q=k.bootReservation?await k.bootReservation.run(V):await V()}catch(K){return await this.failedCreate(d,c,F,{fresh:D===void 0,error:K})}let U=this.host.isBindingReady(P.platform,q);return await this.host.readyOrReleaseOnBusy(q,async(K)=>{if(q.created&&!U)this.deps.journal.markRemovalIntended(F);if(F=await this.recordCreated(d,F,q.device,{release:K,removalRequested:q.created&&!U}),!U)return await this.discardUncommitted(d,q,F,{release:K,reason:Z("readiness_incomplete",`Device '${M}' did not reach ${Fq(P.platform)}.`)});let W=await this.deps.journal.advance(F,{expectedPhase:"created",phase:"committed",assignment:{kind:"commit",expected:F.binding,next:{stableDeviceId:q.device.stableId,deviceName:q.device.name,requestedSpec:P.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ct(d.fingerprint),state:"ready"}}});if(W.kind==="journal_conflict")throw await this.host.releaseSession(q.sessionUuid),new ne(Z("concurrent_modification","The binding's journal entry was taken over."));if(W.kind!=="advanced")return await this.discardUncommitted(d,q,F,{release:K,reason:Oe(W,"create commit")});return this.noteJournal(d,W.entry),await this.host.claimAndReady(d,R,W.assignment,{provisioned:q})})}finally{this.deps.journal.inFlight.delete(F.id)}}async openCreateEntry(d,c,R){let{request:D}=d,k=await this.deps.registry.openBindingJournal(D.key,{kind:"create",phase:"creating",owner:this.deps.journal.owner,target:this.journalTarget(d,c,R),assignment:{kind:"state",expected:Te(c),state:"provisioning"}});if(k.kind==="journal_open")throw new ne(Z("reconcile_in_progress",`Binding ${D.key.bindingIndex} has unfinished work.`));if(k.kind!=="opened")throw new ne(Oe(k,"create"));return this.noteJournal(d,k.entry),k.entry}async advanceToCreating(d,c,R){let D=await this.deps.journal.advance(c,{expectedPhase:"deleted",phase:"creating",target:{newName:R}});if(D.kind!=="advanced")throw new ne(Z("concurrent_modification",`Replacement journal changed: ${D.kind}.`));return this.noteJournal(d,D.entry),D.entry}async failedCreate(d,c,R,{fresh:D,error:k}){let{request:P}=d;if(k instanceof Ue&&k.retryable&&k.code==="timeout"&&k.diagnostics.retainedDevice&&k.diagnostics.retainedDevice.name===R.target.newName&&k.diagnostics.retainedDevice.platform==="ios"&&P.platform==="ios"&&!P.signal?.aborted){try{await this.recordCreated(d,R,k.diagnostics.retainedDevice)}catch(M){throw e.warn(`[Bindings] retaining created device failed: ${r(M)}`,M),new ne(Tt(k))}throw new ne({...Tt(k),retainedDevice:k.diagnostics.retainedDevice})}let C=await this.settleFailedCreate(d,R);if(D)await this.removeFailedUnboundBinding(d,c,C);throw new ne(Tt(k))}async recordCreated(d,c,R,{release:D,removalRequested:k=!1}={}){let P=await this.deps.journal.advance(c,{expectedPhase:"creating",phase:"created",target:{newStableId:R.stableId,newName:R.name,...k?{removalRequested:!0}:{}}}).catch(async(C)=>{throw e.warn(`[Bindings] recording created device failed: ${r(C)}`,C),await D?.(),C});if(P.kind!=="advanced")throw await D?.(),new ne(Z("concurrent_modification","The binding's journal entry was taken over."));return this.noteJournal(d,P.entry),P.entry}async admitFreshCreation(d,c,R){let D;try{D=await this.deps.resourceBudget.admitCreation({journalEntryId:R.id,deadlineMs:d.request.deadlineMs,signal:d.request.signal}),this.host.checkBudget(d.request)}catch(M){let F=await this.settleFailedCreate(d,R,!0);throw await this.removeFailedUnboundBinding(d,c,F),M}if(D.kind==="admitted")return;let k=await this.settleFailedCreate(d,R,!0);if(await this.removeFailedUnboundBinding(d,c,k),D.kind==="unknown")throw new ne(Z("discovery_incomplete",D.message));let{message:P,budget:C}=$l(D);throw new ne(Z("binding_budget_exhausted",P,{budget:C}))}async removeFailedUnboundBinding(d,c,R){if(R?.phase!=="rolled_back")return;await this.removeNeverBoundBinding(d,c,`failed creation entry ${R.id}`)}async withEmptyBindingCleanup(d,c,R){try{return await R()}catch(D){throw await this.removeNeverBoundBinding(d,c,"empty-binding discovery refusal"),D}}async removeNeverBoundBinding(d,c,R){if(c.generation!==0||c.stableDeviceId!==null)return;try{await this.deps.registry.removeUnboundBinding(d.request.key,{generation:c.generation,stableDeviceId:null})}catch(D){e.warn(`[Bindings] removing never-bound binding after ${R} failed: ${r(D)}`,D)}}async settleFailedCreate(d,c,R=!1){try{if(R){let k=(await this.deps.journal.close(c,"rolled_back")).entry;return this.noteJournal(d,k),k}let D=await this.deps.journal.settleCreation(c,{adopt:!1,deadlineMs:d.request.deadlineMs});return this.noteJournal(d,D.entry),D.entry}catch(D){e.warn(`[Bindings] settling failed creation entry ${c.id} failed; redrive will retry: `+r(D),D)}}async discardUncommitted(d,c,R,{release:D,reason:k}){try{if(c.created)this.deps.journal.markRemovalIntended(R),R=await this.deps.journal.requestRemoval(R,{deadlineMs:d.request.deadlineMs,signal:d.request.signal})}finally{await D()}try{await this.cleanupUncommitted(d,c,R)}catch(P){if(P instanceof We)e.warn(`[Bindings] uncommitted cleanup deferred: ${r(P)}`,P),d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:P.message};else if(Qa(P)!=="retryable")throw e.warn(`[Bindings] uncommitted cleanup failed: ${r(P)}`,P),P;e.debug(`[Bindings] uncommitted cleanup deferred: ${r(P)}`)}throw new ne(k)}async cleanupUncommitted(d,c,R){if(!c.created){this.noteJournal(d,(await this.deps.journal.removalRegistryStage(()=>this.deps.journal.close(R,"rolled_back"),d.request.deadlineMs)).entry);return}if(this.noteJournal(d,R),!R.target.removalRequested){d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:"Removal deferred to journal redrive or its current driver."};return}let D=await this.deps.journal.removalRegistryStage(()=>this.deps.registry.findDeviceHolder(d.request.platform,c.device.stableId),d.request.deadlineMs);if(D){let C=D.kind==="binding"?`binding ${D.assignment.bindingIndex} of scope ${D.assignment.scopeKey}`:"the managed free pool";d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:`kept: held by ${C}`},e.warn(`[Bindings] not discarding '${c.device.stableId}': it is held by ${C}`),this.noteJournal(d,(await this.deps.journal.removalRegistryStage(()=>this.deps.journal.close(R,"rolled_back"),d.request.deadlineMs)).entry);return}let k=await this.deps.journal.settleCreation(R,{adopt:!1,deadlineMs:d.request.deadlineMs});this.noteJournal(d,k.entry);let P=k.kind==="settled";if(d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:P,...k.kind==="blocked"?{message:k.message}:{}},!P)e.warn(`[Bindings] uncommitted device '${c.device.stableId}' was not removed: `+(k.kind==="blocked"?k.message:"unknown"))}async replaceOrphan(d,c,R){let{request:D}=d;await this.assertCreatable(d),this.host.checkBudget(D);let k=await this.reserveReplacement(D,c,R);try{this.host.checkBudget(D);let P={stableDeviceId:fe(R),deviceName:R.name,requestedSpec:D.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ct(d.fingerprint),state:"replacing"},C=await this.deps.registry.openBindingJournal(D.key,{kind:"replace",phase:"deleting",owner:this.deps.journal.owner,target:{...this.journalTarget(d,c,null),oldStableId:P.stableDeviceId,oldName:R.name},assignment:{kind:"commit",expected:Te(c),next:P}});if(C.kind==="journal_open")throw new ne(Z("reconcile_in_progress",`Binding ${D.key.bindingIndex} has unfinished work.`));if(C.kind!=="opened")throw new ne(Oe(C,"reclaim"));return d.evidence.adoptedFrom="orphan",await this.finishReplacement(d,C.entry,R,k)}finally{k?.release()}}async replaceAssigned(d,c,R,D){let{request:k}=d;await this.assertCreatable(d),await this.assertReplaceable(k,c,R,D);let P=await this.reserveReplacement(k,c,R);try{return this.host.checkBudget(k),await this.replaceReserved(d,c,R,P)}finally{P?.release()}}async replaceReserved(d,c,R,D){let{request:k}=d,P=await this.deps.registry.openBindingJournal(k.key,{kind:"replace",phase:"deleting",owner:this.deps.journal.owner,target:this.journalTarget(d,c,null),assignment:{kind:"state",expected:Te(c),state:"replacing"}});if(P.kind==="journal_open")throw new ne(Z("reconcile_in_progress",`Binding ${k.key.bindingIndex} has unfinished work.`));if(P.kind!=="opened")throw new ne(Oe(P,"replace"));return await this.finishReplacement(d,P.entry,R,D)}async finishReplacement(d,c,R,D){let{request:k,evidence:P}=d,C=c.target.oldStableId;this.noteJournal(d,c),this.deps.journal.inFlight.add(c.id);let M,F;try{let q=await this.deps.journal.driveDeletion(c,{device:R,deadlineMs:k.deadlineMs,signal:k.signal});if(this.noteJournal(d,q.entry),q.kind!=="deleted"){if(q.kind==="blocked")throw P.deletion=q.evidence,new ne(Z(q.reason,q.message));throw new ne(Z("concurrent_modification",`Device '${C}' is no longer this binding's device.`))}P.deletion=q.evidence,P.deletedStableId=C,M=q.entry,F=q.assignment,D?.markReplacedDeviceGone()}finally{this.deps.journal.inFlight.delete(c.id)}return await this.createAndCommit(d,F,"replaced",{replacing:M,bootReservation:D})}journalTarget(d,c,R){return{oldStableId:c.stableDeviceId,oldName:c.deviceName,...c.platform!==d.request.platform?{newPlatform:d.request.platform}:{},newName:R,newStableId:null,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ct(d.fingerprint)}}noteJournal(d,c){d.evidence.journal={entryId:c.id,kind:c.kind,phase:c.phase}}async assertReplaceable(d,c,R,D){let k=c.stableDeviceId;if(!D)throw new ne(Z("discovery_incomplete","Replacement requires complete device discovery."));let P=await this.deps.claims.describe(R);if(P.kind!=="free")throw new ne(Z(P.kind==="held"?"device_busy":"discovery_incomplete",`Device '${k}' cannot be replaced: ${P.reason}`));this.host.checkBudget(d);let C=await this.deps.registry.findDeviceHolder(c.platform,k);if(C?.kind!=="binding"||C.assignment.scopeKey!==d.key.scopeKey||C.assignment.bindingIndex!==d.key.bindingIndex||!Oq(C.assignment,Te(c)))throw new ne(Z("concurrent_modification",`Device '${k}' is no longer this binding's device.`))}async reserveReplacement(d,c,R){if(!this.deps.capacity)return;let D=R0(c.platform)===R0(d.platform)&&ob(R);this.host.checkBudget(d);let k=await this.deps.capacity.reserve(d.platform,{replacingDeviceId:D?R.deviceId:void 0,resolveReplacingDeviceId:D&&!R.deviceId?(P)=>this.deps.inventory.runtimeDeviceId?.(R,P)??Promise.resolve(void 0):void 0,timeoutMs:Math.max(1,d.deadlineMs-this.deps.timer.now()),signal:d.signal});if(k.kind==="available")return k.reservation;throw this.assertCapacityCheck(d,k),new ne(Z("discovery_incomplete","Boot capacity reservation returned no admission."))}async assertCreatable(d){if(d.creatabilityChecked)return;let{request:c}=d,R=await this.deps.resolver.checkCreatable?.(c.platform,d.resolvedSpec,{signal:c.signal});if(this.host.checkBudget(c),R?.kind==="unsupported")throw new ne(Z(R.code,R.message));if(R?.kind==="unresolved")throw new ne(Z("discovery_incomplete",R.message));d.creatabilityChecked=!0}async assertBootCapacity(d){if(!this.deps.capacity)return;this.host.checkBudget(d);let c=await this.deps.capacity.check(d.platform,{signal:d.signal,timeoutMs:Math.max(1,d.deadlineMs-this.deps.timer.now())});return this.assertCapacityCheck(d,c),c.kind==="available"?this.deps.timer.now():void 0}assertCapacityCheck(d,c){if(c.kind==="unknown")throw new ne(Z("discovery_incomplete",c.message));if(c.kind==="exhausted"&&c.booted>=c.limit)throw new ne(Z("capacity_exhausted",`${c.booted} ${d.platform} device(s) booted; limit is ${c.limit}.${q4(c)}`,{capacity:{limit:c.limit,booted:c.booted,retryAfterMs:c.retryAfterMs,...ji(c.externalDevices),...c.heldDevices?.length?{heldDevices:[...c.heldDevices]}:{}}}))}}function Mo(){return{daemonId:`pid-${process.pid}`,pid:process.pid,processGenerationToken:Mf()??null}}function au(d){return`${d.scopeKey}#${d.bindingIndex}`}class zi{androidConfigReader;constructor(d){this.androidConfigReader=d}async matches(d,c){switch(d.platform){case"watchos":return Ql(d,c);case"android":return await this.matchesAndroid(d,c);case"ios":return sb(d,c);case"tvos":case"visionos":return"mismatch"}}async matchesAndroid(d,c){let R;try{R=await this.androidConfigReader.readConfig(d.name)}catch(k){return e.warn(`[Bindings] cannot read AVD config for '${d.name}': ${r(k)}`,k),"unknown"}if(!R)return"unknown";let D={...c,deviceType:c.deviceType??R.deviceName};if(!AW(D,R))return"mismatch";return fu(c.deviceFamily,()=>Vf({systemImageTag:R.systemImagePackage?nn(R.systemImagePackage)?.tag:void 0,profileId:R.deviceName,width:R.screenWidth,height:R.screenHeight,density:R.screenDensity}))}}function sb(d,c){if(d.isAvailable===!1||d.runtime===void 0||c.deviceType!==void 0&&d.deviceType===void 0)return"unknown";let R={runtime:c.runtime,deviceType:c.deviceType??d.deviceType};return TW(R,d)===void 0?fu(c.deviceFamily,()=>cf(d.deviceType)):"mismatch"}function fu(d,c){if(d===void 0)return"match";let R=c();if(R===void 0||R==="unknown")return"unknown";return R===d?"match":"mismatch"}class Eo{deps;inFlight=new Map;isExecOwnerLive;idGenerator;reservations;creation;journal;constructor(d){this.deps=d;this.isExecOwnerLive=d.isExecOwnerLive??mc,this.idGenerator=d.idGenerator??B,this.reservations=d.reservations??g0,this.journal=new Do({registry:d.registry,inventory:d.inventory,matcher:d.matcher,deleter:d.deleter,claims:d.claims,isBusy:d.isBusy,timer:d.timer,owner:d.journal?.owner??Mo(),isExecOwnerLive:this.isExecOwnerLive,...d.journal?.isOwnerLive?{isOwnerLive:d.journal.isOwnerLive}:{},...d.journal?.inFlight?{inFlight:d.journal.inFlight}:{},...d.journal?.backoff!==void 0?{backoff:d.journal.backoff}:{}}),this.creation=new To({registry:d.registry,inventory:d.inventory,provisioner:d.provisioner,resolver:d.resolver,claims:d.claims,capacity:d.capacity,resourceBudget:d.resourceBudget,idGenerator:this.idGenerator,timer:d.timer,journal:this.journal},{checkBudget:(c)=>this.checkBudget(c),isBindingReady:N4,releaseSession:(c)=>this.releaseSession(c),readyOrReleaseOnBusy:(c,R)=>this.readyOrReleaseOnBusy(c,R),claimAndReady:(c,R,D,{provisioned:k,reservation:P})=>this.claimAndReady(c,R,D,{provisioned:k,reservation:P})})}async reconcile(d){let c=au(d.key),R=this.inFlight.get(c),D=!1,k=(R??Promise.resolve()).then(()=>{return},()=>{return}).then(()=>D?void 0:this.reconcileSerialized(d));this.inFlight.set(c,k);try{if(R){let P=await this.waitForQueue(R,d);if(P)return D=!0,{outcome:"failed",failure:P,assignment:await this.failedResultAssignment(d,void 0),evidence:{initial:null,inventoryComplete:null}}}return await k}finally{let P=()=>{if(this.inFlight.get(c)===k)this.inFlight.delete(c)};if(D)k.then(P,P);else P()}}async waitForQueue(d,c){try{await l(d.then(()=>{return},()=>{return}),{timer:this.deps.timer,timeoutMs:Math.max(0,c.deadlineMs-this.deps.timer.now()),...c.signal?{signal:c.signal}:{},label:"Waiting for the binding's in-flight reconcile"});return}catch(R){return e.debug(`[Bindings] queued reconcile stopped waiting: ${r(R)}`),c.signal?.aborted?Z("cancelled","Binding preparation was cancelled."):Z("timeout","Binding preparation deadline passed.")}}async failedResultAssignment(d,c){try{return await this.journal.removalRegistryStage(()=>this.deps.registry.getAssignment(d.key),c)}catch(R){if(R instanceof We||Qa(R)==="retryable")return e.warn(`[Bindings] failed result assignment unavailable: ${r(R)}`,R),null;throw R}}async reconcileSerialized(d){let c={initial:null,inventoryComplete:null};try{return await this.reconcileSteps(d,c)}catch(R){if(R instanceof ne||Qa(R)==="retryable")return{outcome:"failed",failure:R instanceof ne?R.failure:Z("discovery_incomplete",r(R)),assignment:await this.failedResultAssignment(d,d.deadlineMs),evidence:c};throw R}}async reconcileSteps(d,c){let{registry:R}=this.deps;this.checkBudget(d);let D=await this.deps.resolver.resolve(d.platform,d.requestedSpec,{signal:d.signal});if(D.kind==="unsupported")throw new ne(Z(D.code,D.message));if(D.kind==="unresolved")throw new ne(Z("discovery_incomplete",D.message));let k={request:d,resolvedSpec:D.resolvedSpec,fingerprint:D.fingerprint,evidence:c},P=await R.initBinding(d.key,{role:d.role,platform:d.platform,requestedSpec:d.requestedSpec});if(P.kind==="scope_not_valid")throw new ne(Z("scope_not_valid","Binding scope is not valid."));let C=await this.redriveUnfinished(d,P.assignment,c),M=await this.recoverIfSettled(d,C);if(c.initial={generation:M.generation,stableDeviceId:M.stableDeviceId,state:M.state},this.assertBindingAcceptsWork(d,M),M.platform!==d.platform)return await this.changePlatform(k,M);let F=async()=>{let W=await this.deps.inventory.list(d.platform,{signal:d.signal});return c.inventoryComplete=W.complete,this.checkBudget(d),W},q=M.stableDeviceId===null?await this.withEmptyBindingCleanup(k,M,F):await F();if(M.stableDeviceId===null)return await this.fillEmptyBinding(k,M,q);let U=q.devices.find((W)=>W.platform===d.platform&&fe(W)===M.stableDeviceId);if(!U){if(!q.complete)throw new ne(Z("discovery_incomplete",`Assigned device '${M.stableDeviceId}' was not listed and discovery was incomplete.`));return c.assignedMissing=!0,await this.createAndCommit(k,M,"created")}let K=await this.deps.matcher.matches(U,d.requestedSpec);if(c.assignedMatch=K,K==="unknown")throw new ne(Z("discovery_incomplete",`Configuration of assigned device '${M.stableDeviceId}' could not be read.`));if(K==="match")return await this.reuseAssigned(k,M,U);return await this.replaceAssigned(k,M,U,q.complete)}async redriveUnfinished(d,c,R){let D=await this.journal.redriveBinding(d.key);if(D.redriven.length>0)R.redriven=D.redriven;if(D.kind==="blocked")throw new ne(Z(D.reason,D.message));if(D.redriven.length===0)return c;let k=await this.deps.registry.getAssignment(d.key);if(!k)throw new ne(Z("scope_not_valid","Binding disappeared during redrive."));return k}async recoverIfSettled(d,c){if(c.state!=="settling")return c;let R=(await this.deps.registry.recoverSettledBindings(d.key.scopeKey)).find((D)=>D.bindingIndex===d.key.bindingIndex);if(R)return R;throw new ne(Z("binding_settling",`Binding ${d.key.bindingIndex} is settling the released work of its previous execution.`))}assertBindingAcceptsWork(d,c){if(c.execOwner&&this.isExecOwnerLive(c.execOwner))throw new ne(Z("binding_in_use",`Binding ${d.key.bindingIndex} is held by live session ${c.execOwner.sessionUuid}.`));if(c.state==="cleanup_pending")throw new ne(Z("cleanup_pending",`Binding ${d.key.bindingIndex} still holds device '${c.stableDeviceId}' pending cleanup.`));if(c.state==="replacing")throw new ne(Z("reconcile_in_progress",`Binding ${d.key.bindingIndex} is mid-replacement of '${c.stableDeviceId}'.`))}async changePlatform(d,c){let{request:R,evidence:D}=d;if(c.stableDeviceId===null){let C=await this.withEmptyBindingCleanup(d,c,async()=>{let M=await this.deps.inventory.list(R.platform,{signal:R.signal});return D.inventoryComplete=M.complete,this.checkBudget(R),M});return await this.fillEmptyBinding(d,c,C)}let k=await this.deps.inventory.list(c.platform,{signal:R.signal});D.inventoryComplete=k.complete,this.checkBudget(R);let P=k.devices.find((C)=>C.platform===c.platform&&fe(C)===c.stableDeviceId);if(!P){if(!k.complete)throw new ne(Z("discovery_incomplete",`Assigned device '${c.stableDeviceId}' was not listed and discovery was incomplete.`));D.assignedMissing=!0,await this.assertCreatable(d);let C=await this.emptyOnRequestedPlatform(d,c);return await this.createAndCommit(d,C,"created")}return D.assignedMatch="mismatch",await this.replaceAssigned(d,c,P,k.complete)}async emptyOnRequestedPlatform(d,c){let{request:R}=d,D=await this.deps.registry.commitBinding(R.key,Te(c),{platform:R.platform,stableDeviceId:null,deviceName:null,requestedSpec:R.requestedSpec,resolvedSpec:null,specFingerprint:null,state:"provisioning"});if(D.kind!=="committed")throw new ne(Co(D,"platform change"));return D.assignment}async reuseAssigned(d,c,R){this.assertNoLiveExecutionOn(d,R);let D=await this.reserveExecution(d,c);try{return await this.reuseReserved(d,c,R,D)}catch(k){if(D)await this.releaseReservation(d.request.key,D);throw k}finally{if(D)this.reservations.delete(D)}}async reuseReserved(d,c,R,D){d={...d,resolvedSpec:await this.existingSpec(R)};let k=await this.provisionExisting(d,R);return await this.readyOrReleaseOnBusy(k,async()=>{let P=Te(c),C=ct(d.fingerprint),F=c.state==="ready"&&c.specFingerprint===C&&Fr(c.requestedSpec)===Fr(d.request.requestedSpec)&&this.resolvedIdentityMatches(c.resolvedSpec,d.resolvedSpec)?await this.deps.registry.updateBindingState(d.request.key,P,"ready"):await this.deps.registry.commitBinding(d.request.key,P,{stableDeviceId:c.stableDeviceId,deviceName:k.device.name,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:C,state:"ready"});if(F.kind!=="updated"&&F.kind!=="committed")throw await this.releaseSession(k.sessionUuid),new ne(Oe(F,"reuse"));return await this.claimAndReady(d,"reused",F.assignment,{provisioned:k,reservation:D})})}resolvedIdentityMatches(d,c){if(d===null||typeof d!=="object")return!1;return["runtime","deviceType","displayCutout"].every((R)=>Reflect.get(d,R)===c[R])}async reserveExecution(d,c){let{owner:R,key:D}=d.request;if(!R||c.state!=="ready")return;let k=`reserve-${this.idGenerator.next()}`;this.reservations.add(k);try{let P=await this.deps.registry.claimExecution(D,Te(c),{...R,sessionUuid:k});if(P.kind!=="claimed")throw new ne(Oe(P,"reservation"))}catch(P){throw this.reservations.delete(k),P}return k}async releaseReservation(d,c){try{await this.deps.registry.releaseExecution(d,c)}catch(R){e.warn(`[Bindings] releasing reservation ${c} failed: ${r(R)}`,R)}}async fillEmptyBinding(d,c,R){let D=await this.withEmptyBindingCleanup(d,c,async()=>{if(!R.complete)throw new ne(Z("discovery_incomplete","Device discovery was incomplete for an empty binding."));let P=await this.findAdoptionCandidate(d,R.devices);if(c.platform!==d.request.platform)await this.assertCreatable(d);return P});if(c.platform!==d.request.platform)c=await this.emptyOnRequestedPlatform(d,c);let k=su(d);if(D)return await this.creation.replaceOrphan(k,c,D);return await this.createAndCommit(k,c,"created")}async findAdoptionCandidate(d,c){let{request:R}=d,D=Io(R.key),k=R.priorDeviceHint?.stableId,P=c.filter((C)=>C.platform===R.platform).map((C)=>({device:C,stableId:fe(C)})).filter((C)=>!!C.stableId).sort((C,M)=>Number(M.stableId===k)-Number(C.stableId===k)||C.stableId.localeCompare(M.stableId));for(let{device:C,stableId:M}of P){if(!uc(C.name)||!C.name.slice(C.name.indexOf("-")+1).startsWith(D))continue;if(await this.deps.registry.findDeviceHolder(R.platform,M)||this.sessionsOn(C).length>0||(await this.deps.claims.describe(C)).kind!=="free")continue;if(await this.deps.matcher.matches(C,R.requestedSpec)==="match")return C}return}async existingSpec(d){let c=await this.deps.provisioner.readExistingSpec(d);if(!c)throw new ne(Z("discovery_incomplete",`The configuration of device '${d.name}' could not be read.`));return c}async createAndCommit(d,c,R,{replacing:D,...k}={}){return this.creation.createAndCommit(d,c,R,{replacing:D,...k})}async withEmptyBindingCleanup(d,c,R){return this.creation.withEmptyBindingCleanup(d,c,R)}async replaceAssigned(d,c,R,D){return this.creation.replaceAssigned(d,c,R,D)}async assertCreatable(d){return this.creation.assertCreatable(d)}sessionsOn(d){return this.deps.claims.sessionsOn?.(d)??[]}async releaseStaleSessions(d,c){let R=this.sessionsOn(c);if(R.length===0)return new Set;this.assertNoLiveExecutionOn(d,c,R);try{await Promise.all(R.map((D)=>this.deps.provisioner.releaseSession(D)))}catch(D){throw e.warn(`[Bindings] releasing stale session(s) on '${c.name}' failed: ${r(D)}`,D),new ne(Z("stale_session",`An earlier execution's session on '${c.name}' could not be released: ${r(D)}`))}return d.evidence.releasedStaleSessions=R,new Set(R)}assertNoLiveExecutionOn(d,c,R=this.sessionsOn(c)){let D=R.find((k)=>this.deps.claims.isLiveExecution?.(k));if(D!==void 0)throw new ne(Z("binding_in_use",`Binding ${d.request.key.bindingIndex} is held by live session ${D} on '${c.name}'.`))}async provisionExisting(d,c){let{request:R}=d,D=await this.releaseStaleSessions(d,c),k;try{k=await this.deps.provisioner.provision({platform:R.platform,name:c.name,...R.platform!=="android"&&c.deviceId?{deviceId:c.deviceId}:{},spec:ei(R.requestedSpec),mode:"adopt",deadlineMs:R.deadlineMs,signal:R.signal})}catch(P){throw new ne(Tt(P))}if(D.has(k.sessionUuid))throw await this.releaseSession(k.sessionUuid),new ne(Z("stale_session",`Provisioning '${c.name}' returned earlier session ${k.sessionUuid}.`));if(!N4(R.platform,k))throw await this.releaseSession(k.sessionUuid),new ne(Z("readiness_incomplete",`Device '${c.name}' did not reach ${Fq(R.platform)}.`));return k}async releaseSession(d){try{await this.deps.provisioner.releaseSession(d)}catch(c){e.warn(`[Bindings] releasing unpublished session ${d} failed: ${r(c)}`,c)}}checkBudget(d){if(d.signal?.aborted)throw new ne(Z("cancelled","Binding preparation was cancelled."));if(this.deps.timer.now()>=d.deadlineMs)throw new ne(Z("timeout","Binding preparation deadline passed."))}async claimAndReady(d,c,R,{provisioned:D,reservation:k}){let{owner:P,key:C}=d.request;if(!P)return this.ready(d,c,R,D);let M=await this.deps.registry.claimExecution(C,Te(R),{...P,sessionUuid:D.sessionUuid},k?{supersedesSessionUuid:k}:{});if(M.kind!=="claimed")throw await this.releaseSession(D.sessionUuid),new ne(Oe(M,"execution claim"));return this.ready(d,c,M.assignment,D)}async readyOrReleaseOnBusy(d,c){let R=!1,D=async()=>{if(!R)R=!0,await this.releaseSession(d.sessionUuid)};try{return await c(D)}catch(k){if(Qa(k)==="retryable"||k instanceof tn)await D();throw k}}ready(d,c,R,D){return{outcome:"ready",disposition:c,assignment:R,device:D.device,sessionUuid:D.sessionUuid,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:d.fingerprint,readiness:D.readiness,...D.lifecycle!==void 0?{lifecycle:D.lifecycle}:{},evidence:d.evidence}}}var ab={registry_schema_unsupported:"Upgrade this daemon and every daemon sharing the registry to the build that migrated it, restarting older daemons; nothing was changed.",scope_invalidated:"This runner incarnation was reset; launch with the current runnerIncarnation.",scope_transition_pending:"Wait for the previous runner incarnation's executions and cleanup to settle, then retry.",execution_policy_failed:"Retry; the session could not be held for the execution.",liveness_owner_conflict:"Retry; another owner claimed the binding's session.",timeout:"Retry with a longer preparationTimeoutMs.",cancelled:"The preparation was cancelled; retry when needed."};function Je(d,c,R){return{code:d,retryable:R,message:c,nextAction:ab[d]??"Retry."}}function cb(d,c){return c!==void 0&&c>0?{createDeadlineMs:d-c}:{}}var lb=5000;class Bo{deps;closed=!1;closeController=new AbortController;backOutSessionReleases=new WeakMap;backOutOwnerReads=new WeakMap;backOutOwnerClears=new WeakMap;pacing;backOutCleanups=new Map;background=new Set;warnedBackOutCleanups=new WeakSet;constructor(d){this.deps=d;this.pacing=new Me({timer:d.timer,backoff:d.backOutRetryBackoff})}close(){this.closed=!0,this.closeController.abort(),this.pacing.close()}async whenIdle(){while(this.background.size>0)await Promise.allSettled([...this.background])}pendingBackOutCleanups(){return[...this.backOutCleanups.values()].map(({cleanup:d})=>({...d,key:{...d.key},ageMs:this.deps.timer.now()-d.owedSinceMs}))}async acquire(d,c){let R={managedHostScope:d.managedHostScope,runnerNamespace:d.runnerNamespace,runnerIncarnation:d.runnerIncarnation},D=(U,K)=>({contractVersion:1,scope:{...R,scopeKey:U,...K?{revived:K}:{}}}),k;try{k=vq(d.idleTimeoutMs)}catch(U){return{...D(null),outcome:"failed",bindings:[],failure:Je("binding_config_invalid",r(U),!1)}}let P=this.deps.timer.now()+(d.preparationTimeoutMs??ao),C,M;try{C=await this.deps.registry(),M=await this.admitScope(C,R)}catch(U){if(U instanceof tn)return e.warn(`[Bindings] Registry schema unsupported: ${r(U)}`,U),{...D(null),outcome:"failed",bindings:[],failure:Je(U.code,r(U),U.retryable)};if(Qa(U)!=="retryable"&&!(U instanceof ss))throw U;return{...D(Qd(R)),outcome:"failed",bindings:[],failure:Z("discovery_incomplete",r(U))}}if(M.kind==="failed")return{...D(Qd(R)),outcome:"failed",bindings:[],failure:M.failure};let{bindings:F,failure:q}=await this.acquireBindings(C,M.scopeKey,d.requests,{deadlineMs:P,...cb(P,d.createRetryReserveMs),idleTimeoutMs:k,livenessOwnerToken:c.livenessOwnerToken,signal:c.signal});return{...D(M.scopeKey,M.revived),outcome:q?"failed":"ready",idleTimeoutMs:k,bindings:F,...q?{failure:q}:{}}}async acquireBindings(d,c,R,D){let k=[],P=[],C;for(let M of R){let F={scopeKey:c,bindingIndex:M.bindingIndex},q=await this.acquireBinding(d,F,M,D);if(k.push(q),q.failure){C=q.failure;break}P.push({key:F,sessionUuid:q.sessionUuid})}if(!C&&D.signal?.aborted)C=Je("cancelled","The binding acquisition was cancelled.",!0);if(C){await Promise.all(P.map(({key:M,sessionUuid:F})=>this.backOut(d,M,F)));for(let M of k)if(!M.failure)M.sessionUuid=null}return{bindings:k,failure:C}}async admitScope(d,c){let R=await d.ensureScope(c);switch(R.kind){case"ready":return{kind:"ready",scopeKey:R.scope.scopeKey,revived:R.revived};case"scope_invalidated":return{kind:"failed",failure:Je("scope_invalidated",`Runner incarnation '${c.runnerIncarnation}' of namespace '${c.runnerNamespace}' was reset and no longer accepts work.`,!1)};case"incarnation_conflict":return{kind:"failed",failure:Je("scope_transition_pending",`Runner incarnation '${R.current.runnerIncarnation}' is still being retired.`,!0)}}}async acquireBinding(d,c,R,D){let k;try{k=await this.deps.reconcile(d,{key:c,role:R.role,platform:R.platform,requestedSpec:R.requestedSpec,...R.priorDeviceHint?{priorDeviceHint:R.priorDeviceHint}:{},deadlineMs:D.deadlineMs,...D.createDeadlineMs===void 0?{}:{createDeadlineMs:D.createDeadlineMs},signal:D.signal,owner:this.deps.owner()})}catch(M){if(!(M instanceof tn))throw M;return{bindingIndex:R.bindingIndex,role:R.role,platform:R.platform,assignmentGeneration:null,device:null,sessionUuid:null,requestedSpec:R.requestedSpec,resolvedSpec:null,specFingerprint:null,disposition:null,readiness:null,lifecycle:null,failure:Je(M.code,r(M),M.retryable)}}if(k.outcome==="failed")return{bindingIndex:R.bindingIndex,role:R.role,platform:R.platform,assignmentGeneration:k.assignment?.generation??null,device:null,sessionUuid:null,requestedSpec:R.requestedSpec,resolvedSpec:k.assignment?.resolvedSpec??null,specFingerprint:null,disposition:null,readiness:null,lifecycle:{evidence:k.evidence},failure:k.failure};let P={bindingIndex:R.bindingIndex,role:R.role,platform:R.platform,assignmentGeneration:k.assignment.generation,device:k.device,sessionUuid:k.sessionUuid,requestedSpec:k.requestedSpec,resolvedSpec:k.resolvedSpec,specFingerprint:k.specFingerprint,disposition:k.disposition,readiness:k.readiness,lifecycle:{...k.lifecycle!==void 0?{provision:k.lifecycle}:{},evidence:k.evidence}},C=await this.handOff(k.sessionUuid,D);if(C)return await this.backOut(d,c,k.sessionUuid),{...P,sessionUuid:null,failure:C};return P}async handOff(d,c){try{let R=await this.deps.sessions.claimLivenessOwnership(d,c.livenessOwnerToken);if(R!=="claimed")return Je("liveness_owner_conflict",`Session ${d} could not be claimed for this execution (${R}).`,!0);await this.deps.sessions.adoptManagedExecutionLivenessPolicy(d,{idleTimeoutMs:c.idleTimeoutMs});return}catch(R){return e.warn(`[Bindings] Holding session ${d} on the ${ni} policy failed: ${r(R)}`,R),Je("execution_policy_failed",r(R),!0)}}async backOut(d,c,R){let D=this.deps.timer.now(),k={key:{...c},sessionUuid:R,attempts:0,owedSinceMs:this.deps.timer.now(),ageMs:0,ownerClearOwed:!1,sessionReleaseOwed:!1,lastError:""};try{await d.releaseExecution(c,R)}catch(P){if(k.owedSinceMs=this.deps.timer.now(),k.ownerClearOwed=!0,k.lastError=r(P),!this.closed)e.info(`[Bindings] Clearing binding ${c.scopeKey}/${c.bindingIndex}'s owner ${R} failed: ${k.lastError}; cleanup continues in the background`,P)}try{await this.deps.sessions.releaseSession(R)}catch(P){if(!k.ownerClearOwed)k.owedSinceMs=this.deps.timer.now();if(k.sessionReleaseOwed=!0,k.lastError=r(P),!this.closed)e.info(`[Bindings] Releasing backed-out session ${R} for binding ${c.scopeKey}/${c.bindingIndex} failed: ${k.lastError}; cleanup continues in the background`,P)}if(k.ownerClearOwed||k.sessionReleaseOwed)this.retainBackOutCleanup(d,k),this.pacing.noteBlocked(D)}retainBackOutCleanup(d,c){let R=JSON.stringify([c.key.scopeKey,c.key.bindingIndex,c.sessionUuid]);if(this.closed)return;let D=this.backOutCleanups.get(R);if(D){D.cleanup.ownerClearOwed||=c.ownerClearOwed,D.cleanup.sessionReleaseOwed||=c.sessionReleaseOwed,D.cleanup.lastError=c.lastError;return}this.backOutCleanups.set(R,{registry:d,cleanup:c}),this.startBackOutRetry(R,d,c)}startBackOutRetry(d,c,R){let D=this.retryBackOutCleanup(d,c,R).catch((k)=>{if(!this.closed)R.lastError=r(k),e.warn(`${this.backOutCleanupLabel(R)} retry stopped; no task remains: ${R.lastError}`,k)}).finally(()=>this.background.delete(D));this.background.add(D)}async retryBackOutCleanup(d,c,R){for(let D=1;!this.closed;D++){if(await this.pacing.wait(this.pacing.delay(D)),this.closed)return;if(await this.pacing.run(()=>(R.attempts=D,this.retryBackOutOnce(c,R)),(P)=>P)){if(this.backOutCleanups.delete(d),!this.closed)e.info(`${this.backOutCleanupLabel(R)} landed after ${this.deps.timer.now()-R.owedSinceMs} ms (${R.attempts} retries)`);return}if(this.closed)return}}async retryBackOutOnce(d,c){let R=this.deps.timer.now()+Ee;try{if(c.sessionReleaseOwed){if(await this.retryBackOutStep(c,this.backOutSessionReleases,()=>this.deps.sessions.releaseSession(c.sessionUuid),{step:"session release",deadlineMs:R}),this.closed)return!1;c.sessionReleaseOwed=!1}if(c.ownerClearOwed){if(await this.retryBackOutOwnerClear(d,c,R),this.closed)return!1;c.ownerClearOwed=!1}return!0}catch(D){if(!this.closed)c.lastError=r(D),this.logBackOutRetryFailure(c,D);return!1}}async retryBackOutStep(d,c,R,{step:D,deadlineMs:k}){let P=k-this.deps.timer.now();if(P<=0)throw Error(`${this.backOutCleanupLabel(d)} ${D} attempt deadline reached`);let C=await l(()=>{let M=c.get(d);if(!M)M=R().then(void 0,(F)=>{throw c.delete(d),F}),c.set(d,M);return M},{timer:this.deps.timer,timeoutMs:P,signal:this.closeController.signal,label:`${this.backOutCleanupLabel(d)} ${D}`});return c.delete(d),C}async retryBackOutOwnerClear(d,c,R){let D=()=>this.retryBackOutStep(c,this.backOutOwnerClears,()=>d.releaseExecution(c.key,c.sessionUuid),{step:"owner clear",deadlineMs:R});if(this.backOutOwnerClears.has(c)){await D();return}let k=()=>this.retryBackOutStep(c,this.backOutOwnerReads,()=>d.getAssignment(c.key),{step:"ownership read",deadlineMs:R});if(this.backOutOwnerReads.has(c))await k();let P=(await k())?.execOwner;if(!this.closed&&P&&this.isBackedOutOwner(P,c.sessionUuid))await D()}logBackOutRetryFailure(d,c){let R=`${this.backOutCleanupLabel(d)} retry failed: ${d.lastError}`;e.debug(R,c);let D=this.deps.timer.now()-d.owedSinceMs;if(D>lb&&!this.warnedBackOutCleanups.has(d))this.warnedBackOutCleanups.add(d),e.warn(`${this.backOutCleanupLabel(d)} owed for ${D} ms (${d.attempts} retries): ${d.lastError}; retries continue with waits capped at 5 s`,c)}isBackedOutOwner(d,c){let R=this.deps.owner(),D=d.processGenerationToken??void 0,k=R.processGenerationToken??void 0;return d.sessionUuid===c&&d.pid===R.pid&&(D===void 0||k===void 0||D===k)}backOutCleanupLabel(d){return`[Bindings] Back-out cleanup for binding ${d.key.scopeKey}/${d.key.bindingIndex} session ${d.sessionUuid}`}}class Oo{deviceManager;watches;constructor(d,c){this.deviceManager=d;this.watches=c}async listImages(d,c){if(d!=="watchos")return await this.deviceManager.listDeviceImages(d,c);if(!this.watches)throw new Dp("Apple Watch simulators are listed only on macOS hosts.");return await this.watches.listWatchSimulators(c)}async runtimeDeviceId(d,c){return d.deviceId??this.bootedRuntimeId(d,c,"replacement runtime")}async probeRunning(d,c){return await this.bootedRuntimeId(d,c,"running state")!==void 0}async bootedRuntimeId(d,c,R){try{let D=await this.deviceManager.getBootedDevicesDetailed?.(d.platform,{signal:c.signal,bypassAndroidDeviceListCache:!0,skipForeignEnrichment:!0});if(c.signal?.throwIfAborted(),!D?.succeededPlatforms.has(d.platform))return;return D.devices.find((k)=>!k.foreignOwned&&k.platform===d.platform&&k.name===d.name&&ae(k.deviceId))?.deviceId}catch(D){c.signal?.throwIfAborted(),e.warn(`[Bindings] cannot resolve ${R}: ${r(D)}`,D);return}}async list(d,c){try{return{complete:!0,devices:await this.listImages(d,c.signal)}}catch(R){if(c.signal?.throwIfAborted(),d==="android"&&R instanceof Yk||d!=="android"&&R instanceof Dp)return e.debug(`[Bindings] ${d} toolchain not installed: ${r(R)}`),{complete:!1,devices:[],toolchain:"not_installed"};return e.warn(`[Bindings] ${d} device inventory failed: ${r(R)}`,R),{complete:!1,devices:[]}}}}class ii extends Error{}var ub=2000,xo=fc+ub;class Fo{timer;assertAvailable;reserveCapacity;constructor(d,c=(D,k)=>jS(D,{signal:k}),R=jq){this.timer=d;this.assertAvailable=c;this.reserveCapacity=R}async reserve(d,c){let R=new AbortController,D=c.signal?AbortSignal.any([c.signal,R.signal]):R.signal,k=this.timer.now()+c.timeoutMs,P=()=>Math.max(0,k-this.timer.now()),C=(q)=>l(q,{timer:this.timer,timeoutMs:Math.min(P(),xo),signal:c.signal,label:`Reserving ${d} boot capacity`,onTimeout:()=>R.abort(),timeoutError:()=>new ii(`Timed out reserving ${d} boot capacity.`)}),M=!1,F;try{let q=c.resolveReplacingDeviceId,U=q?await C(()=>q({signal:D})):c.replacingDeviceId;D.throwIfAborted();let K=await C(async()=>{if(F=await this.reserveCapacity(d,{...c,replacingDeviceId:U,timeoutMs:Math.max(1,P()),signal:D}),D.aborted)F.release(),D.throwIfAborted();return F});return M=!0,{kind:"available",reservation:K}}catch(q){return this.refusal(d,q)}finally{if(!M)R.abort(),F?.release()}}async check(d,c){let R=Math.min(c.timeoutMs??xo,xo),D=new AbortController,k=c.signal?AbortSignal.any([c.signal,D.signal]):D.signal;try{return await l(()=>this.assertAvailable(d,k),{timer:this.timer,timeoutMs:R,signal:c.signal,label:`Checking ${d} boot capacity`,onTimeout:()=>D.abort(),timeoutError:()=>new ii(`Timed out after ${R}ms checking ${d} boot capacity.`)}),{kind:"available"}}catch(P){return this.refusal(d,P)}finally{D.abort()}}refusal(d,c){if(c instanceof $n){let{externalDevices:R,heldDevices:D,ownershipUnknown:k}=c.details;return{kind:"exhausted",limit:c.limit,booted:c.booted,retryAfterMs:c.retryAfterMs,...R&&R.length>0?{externalDevices:R}:{},...D&&D.length>0?{heldDevices:D}:{},...k?{ownershipUnknown:!0}:{}}}if(c instanceof ze||c instanceof ss||c instanceof ii)return e.warn(`[Bindings] ${d} boot capacity is unknown: ${r(c)}`,c),{kind:"unknown",message:r(c)};throw c}}class No{pool;executions;constructor(d,c){this.pool=d;this.executions=c}isLiveExecution(d){return this.executions?.isLiveManagedExecutionSession(d)??!1}async describe(d){let c=this.runtimesOf(d),R=c.find((D)=>O(D)!==null);if(R)return{kind:"held",reason:`session ${O(R)} holds ${R.id}`};if(d.isRunningStateKnown===!1&&c.length===0)return{kind:"unknown",reason:"its running state could not be determined"};if(d.platform==="android"&&this.hasUnresolvedSessionRuntime())return{kind:"unknown",reason:"a session holds an emulator whose AVD is unresolved"};for(let D of c)try{await this.pool.assertNotClaimedByForeignDaemon(D.id,d.platform)}catch(k){return{kind:"held",reason:r(k)}}return{kind:"free"}}sessionsOn(d){return this.runtimesOf(d).flatMap((c)=>O(c)?[O(c)]:[])}hasUnresolvedSessionRuntime(){return this.pool.getAllDevices().some((d)=>d.platform==="android"&&O(d)!==null&&!d.avdName&&d.name.startsWith("Unknown ("))}runtimesOf(d){let c=fe(d);return this.pool.getAllDevices().filter((R)=>R.platform===d.platform&&(d.platform==="android"?(R.avdName??R.name)===c:R.id===c))}}function hu(d,c){let{runtime:R,deviceType:D}=d.spec;if(D===void 0)throw new Ue("unsupported",`Apple Watch binding '${d.name}' has no device type to provision.`);return{device:{platform:"watchos",name:d.name,...d.deviceId?{deviceId:d.deviceId}:{},spec:{runtime:R,deviceType:D}},boot:!0,readiness:"none",timeoutMs:c}}function gu(d){if(d.isAvailable===!1||!d.runtime||!d.deviceType)return null;return{runtime:d.runtime,deviceType:d.deviceType,displayCutout:"unknown"}}function ri(d){let c=d??{};if(c.structuredContent&&typeof c.structuredContent==="object")return{isError:c.isError===!0,payload:c.structuredContent};let R=c.content?.find((k)=>typeof k.text==="string")?.text,D={};if(R!==void 0)try{let k=JSON.parse(R);D=k&&typeof k==="object"?k:{}}catch(k){e.debug(`[Bindings] tool response text is not JSON: ${r(k)}`),D={message:R}}return{isError:c.isError===!0,payload:D}}function we(d){return typeof d==="string"&&d.length>0?d:void 0}function $o(d){return typeof d==="number"&&Number.isFinite(d)?d:void 0}function vu(d){return Array.isArray(d)?d.filter((c)=>typeof c==="string"):[]}function yu(d){return d!==null&&typeof d==="object"&&!Array.isArray(d)}function mb(d){let c=d.lifecycle;if(!yu(c)||!yu(c.device))return{};let R=c.device,D=we(R.name),k=[we(R.stableId),we(R.runtimeDeviceId)].find((C)=>C!==void 0&&C!==D),P=c.state==="created_not_ready"&&c.phase==="readiness"&&R.platform==="ios"&&k&&D?{platform:"ios",stableId:k,name:D}:void 0;return P?{retainedDevice:P}:{}}function fb(d,c){let R=d.error??{},D=we(R.code)??"platform_command_failed",k=we(R.message)??we(d.message)??c,P=typeof R.retryable==="boolean"?R.retryable:void 0,C=$o(R.limit),M=$o(R.booted),F=$o(R.retryAfterMs),q=vu(R.externalDevices),U=vu(R.heldDevices);return new Ue(D,k,P,{...mb(d),...F!==void 0?{retryAfterMs:F}:{},...C!==void 0&&M!==void 0?{capacity:{limit:C,booted:M,...q.length>0?{externalDevices:q}:{},...U.length>0?{heldDevices:U}:{}}}:{}})}function hb(d,c){let R=d.device??{},D=d.readiness??{},k=we(R.identity?.stableId);if(!k)throw new Ue("platform_command_failed",`provisionDevice '${c}' returned no stable device identity.`);return{device:{stableId:k,transportId:we(R.runtime?.deviceId)??null,name:we(R.name)??c},created:d.created===!0,sessionUuid:we(d.sessionId)??"",readiness:{mode:we(D.mode)??"none",status:we(D.status)??"unknown"},lifecycle:vb(d)}}function vb(d){let c={lifecycleState:d.lifecycleState};for(let R of["lifecycle","resources","timing"])if(d[R]!==void 0)c[R]=d[R];return c}function yb(d,c){return Math.max(1,Math.min(c,Math.floor(d)))}class Uo{deps;constructor(d){this.deps=d}async readExistingSpec(d){if(d.platform==="watchos")return gu(d);if(d.platform==="ios"){if(d.isAvailable===!1||!d.runtime||!d.deviceType)return null;return{runtime:d.runtime,deviceType:d.deviceType,displayCutout:Ow("ios",d.deviceType)}}return this.readExistingAndroidSpec(d.name)}async readExistingAndroidSpec(d){try{let c=await this.deps.androidConfigReader.readConfig(d);if(!c?.systemImagePackage)return null;return{runtime:c.systemImagePackage,...c.deviceName?{deviceType:c.deviceName,displayCutout:Ow("android",c.deviceName)}:{},configuration:{...c.hardware,...c.ramSizeMb!==void 0?{memoryMb:c.ramSizeMb}:{},...c.screenWidth!==void 0?{screenWidth:c.screenWidth}:{},...c.screenHeight!==void 0?{screenHeight:c.screenHeight}:{},...c.screenDensity!==void 0?{screenDensity:c.screenDensity}:{}}}}catch(c){return e.warn(`[Bindings] cannot resolve AVD config for '${d}': ${r(c)}`,c),null}}async provision(d){let c=yb(d.deadlineMs-this.deps.timer.now(),yR),R=d.platform,D=R==="watchos"?hu(d,c):{...await this.exactProvisionArgs({...d,platform:R},c)},k=await this.deps.invokeTool("provisionDevice",D,d.signal),{isError:P,payload:C}=ri(k);if(P)throw fb(C,`provisionDevice '${d.name}' failed`);return hb(C,d.name)}async exactProvisionArgs(d,c){let R={...d.spec,deviceType:d.spec.deviceType??await this.existingModel(d)};return{device:{platform:d.platform,name:d.name,...d.platform==="ios"&&d.deviceId?{deviceId:d.deviceId}:{},spec:R},boot:!0,readiness:"automation",...d.platform==="android"&&this.deps.discardAndroidSnapshotOnExit?.()===!0?{discardSnapshotOnExit:!0}:{},...d.platform==="ios"&&d.mode==="create"?{rollbackOnRetryableReadiness:!1}:{},timeoutMs:c}}releaseSession(d){return this.deps.releaseSession(d)}async existingModel(d){if(d.platform==="android"){let R=(await this.deps.androidConfigReader.readConfig(d.name))?.deviceName;if(R)return R}else{let R=(await this.deps.deviceManager.listDeviceImages("ios",d.signal)).find((D)=>d.deviceId?D.deviceId===d.deviceId:D.name===d.name)?.deviceType;if(R)return R}throw new Ue("discovery_incomplete",`The model of ${d.platform} device '${d.name}' could not be read.`)}}var Sb=100,wb=5000;class Go{journal;timer;intervalMs;stopped=!1;running;stopping;controller=new AbortController;cancelWait;constructor(d,c,R=wb){this.journal=d;this.timer=c;this.intervalMs=R}start(){if(!this.stopped)this.running??=this.loop()}stop(d=Sb){return this.stopped=!0,this.controller.abort(),this.cancelWait?.(),this.stopping??=this.join(d),this.stopping}async join(d){try{return await l(this.running??Promise.resolve(),{timer:this.timer,timeoutMs:d,label:"journal redrive stop"}),"stopped"}catch(c){return e.warn(`[BindingJournal] redrive stop failed: ${r(c)}`,c),"timed_out"}}wait(){return new Promise((d)=>{let c=this.timer.setTimeout(()=>{this.cancelWait=void 0,d()},this.intervalMs);this.cancelWait=()=>{this.timer.clearTimeout(c),this.cancelWait=void 0,d()}})}async loop(){while(!this.stopped){try{await this.journal.runPass({signal:this.controller.signal})}catch(d){e.warn(`[BindingJournal] redrive pass failed: ${r(d)}`,d)}if(this.stopped)return;await this.wait()}}}var Rb={listInstalledPackages:async(d)=>(await Hu(void 0,void 0,d)).map((c)=>c.packageName)},Db={listProfileIds:async(d)=>(await eP(void 0,d)).map((c)=>c.id)};function kb(d={},c){let R=process.platform==="darwin"?new wa(new L(null)):void 0;return{deviceManager:d.deviceManager??(c?new Xn().withForeignAndroidSerialSource(c):new Xn),androidConfigReader:d.androidConfigReader??new Nr,androidImageCatalog:d.androidImageCatalog??Rb,androidProfileCatalog:d.androidProfileCatalog??Db,iosRuntimeCatalog:d.iosRuntimeCatalog??(process.platform==="darwin"?new L(null):void 0),watchInventory:d.watchInventory??R,watchCatalog:d.watchCatalog??R,checkBootCapacity:d.checkBootCapacity,reserveBootCapacity:d.reserveBootCapacity}}var si=async(d,c,R)=>await ch().callInternal(d,c,{signal:R});function Su(d){let c=(M)=>xl(d.pool,M),R=d.invokeTool??si,D=new WeakMap,k=new WeakMap,P=(M)=>{let F=D.get(M);if(!F){let q=kb(d.tooling,d.pool.foreignSerials?{foreignSerials:(J,X)=>d.pool.foreignSerials(J,X)}:void 0),{deviceManager:U,androidConfigReader:K}=q,W=new Oo(U,q.watchInventory),V=new No(d.pool,d.executions),z=d.resourceBudgetPolicy?new so({registry:async()=>M,policy:d.resourceBudgetPolicy,inventory:W,timer:d.timer}):void 0;F=new Eo({registry:M,inventory:W,...z?{resourceBudget:z}:{},isBusy:c,matcher:new zi(K),resolver:new Ji(q.iosRuntimeCatalog,{androidImageCatalog:q.androidImageCatalog,androidProfileCatalog:q.androidProfileCatalog,watchCatalog:q.watchCatalog}),provisioner:d.tooling?.provisioner??new Uo({invokeTool:R,deviceManager:U,androidConfigReader:K,timer:d.timer,releaseSession:(J)=>d.sessions.releaseSession(J),discardAndroidSnapshotOnExit:d.discardAndroidSnapshotOnExit}),deleter:d.tooling?.deleter??new co(d.timer),claims:V,...d.executions?{isExecOwnerLive:Hq(mc,d.executions)}:{},capacity:new Fo(d.timer,q.checkBootCapacity,q.reserveBootCapacity),timer:d.timer,journal:{owner:d.journal.owner,inFlight:d.journal.inFlight}}),D.set(M,F)}return F};return{acquisition:new Bo({registry:d.registry,reconcile:(M,F)=>y0(F.key,()=>P(M).reconcile(F)),sessions:d.sessions,owner:d.owner,timer:d.timer}),startJournalRedrive:(M)=>{let F=k.get(M);if(!F)F=new Go(P(M).journal,d.timer),k.set(M,F),F.start();return F},journalFor:(M)=>P(M).journal}}var Wo="watchos-keep-booted-unsupported: a watch session has no mutation journal, pool-entry app baseline or CtrlProxy health probe, so keep-booted cleaning cannot prove it clean",bu="watchos-minimal-unsupported: the session's installed watch apps are not journaled and the minimal appearance, content-size, pasteboard and Files-fixture steps have no watchOS equivalent; minimal mode never erases, so the watch is destroyed";class Jo{dependencies;constructor(d){this.dependencies=d}async resetWithTiming(d,c,R,D={}){Ab(d,c);let k=this.dependencies.policy;switch(k.mode){case"erase":return this.erase(d,c,R,{...D,mode:"erase"});case"keep-booted":if(k.fallback==="destroy")return e.info(`[SessionBroker] watch ${d.deviceId} keep-booted release destroys: ${Wo}`),{outcome:"pending",mode:"keep-booted",phases:{},fallbackReason:Wo};return this.erase(d,c,R,{...D,mode:"keep-booted",fallbackReason:Wo});case"minimal":return e.info(`[SessionBroker] watch ${d.deviceId} minimal release destroys: ${bu}`),{outcome:"pending",mode:"minimal",phases:{},fallbackReason:bu}}}async erase(d,c,R,{signal:D,runResetBoot:k,mode:P,fallbackReason:C}){let M={},F=async()=>{D?.throwIfAborted(),await R(),D?.throwIfAborted()};try{await F();let q=()=>this.reservedEraseAndBoot(d,c,F,{phases:M,signal:D});await(k?k(q):q()),await F()}catch(q){throw new Ci(r(q),{outcome:"pending",mode:P,phases:M,fallbackReason:r(q)},{cause:q})}return P==="erase"?{outcome:"clean",mode:P,phases:M}:{outcome:"fallback:erase",mode:P,phases:M,...C?{fallbackReason:C}:{}}}async reservedEraseAndBoot(d,c,R,D){let k=await this.dependencies.reserveBoot?.({replacingDeviceId:d.deviceId,timeoutMs:Ve,reason:"reset",signal:D.signal}),P=()=>this.eraseAndBoot(d,c,R,D);try{await(k?k.run(P):P())}finally{k?.release()}}async eraseAndBoot(d,c,R,{phases:D,signal:k}){if((await this.expectedWatch(d,c,k,"start watch reset")).isRunning)await R(),await this.measure(D,"stop",()=>this.dependencies.stopDevice(d));let C=await this.expectedWatch(d,c,k,"erase watch");if(C.state!=="Shutdown")throw new t(`Cannot erase Apple Watch simulator '${d.deviceId}': it is ${C.state}, not Shutdown`);if(await R(),await this.measure(D,"erase",()=>this.dependencies.simctl.eraseSimulator(d.deviceId)),await R(),await this.measure(D,"boot",()=>this.dependencies.lifecycle.boot(C,{timeoutMs:Ve,signal:k})),!(await this.expectedWatch(d,c,k,"confirm erased watch")).isRunning)throw new t(`Apple Watch simulator '${d.deviceId}' did not report Booted after its erase`)}async expectedWatch(d,c,R,D){let k=await this.dependencies.lifecycle.findWatch({deviceId:d.deviceId},R);if(k.runtimeId!==c.runtime||k.deviceType!==c.deviceType)throw new t(`Cannot ${D}: Apple Watch simulator '${d.deviceId}' is ${k.deviceType??"an unknown device type"} on ${k.runtimeId??"an unknown runtime"}, not ${c.deviceType} on ${c.runtime}`);return k}async measure(d,c,R){let D=this.dependencies.timer.now();try{return await R()}finally{d[c]=this.dependencies.timer.now()-D}}}function Ab(d,c){if(d.platform!=="watchos"||!d.deviceId.trim())throw new t("A watch reset requires an exact Apple Watch simulator UDID");if(!c.runtime.trim()||!c.deviceType.trim())throw new t("A watch reset requires the watch's exact runtime and device type")}function Pb(d){let c=m0(d);switch(c.mode){case"off":return;case"erase":return{mode:"erase"};case"keep-booted":return{mode:"keep-booted",fallback:c.fallback};case"minimal":return{mode:"minimal"}}}function Ib(d,c=Xo){let R=c.iosBootInstrumentation();return R.reserveBoot?R.reserveBoot(d):Promise.resolve({run:(D)=>D(),markReplacedDeviceGone:()=>{},release:()=>{}})}function wu(d,c){let R=Pb(d);if(!R)return;let D=new L(null),k=new Jo({policy:R,timer:c,simctl:D,lifecycle:new tP(D,new wa(D),{run:(P,C)=>Xo.iosBootInstrumentation().run(P,C)}),reserveBoot:Ib,stopDevice:async(P)=>{let C=ri(await si("killDevice",{device:P},void 0));if(C.isError||C.payload.success===!1)throw new t("Provider watch shutdown did not confirm a clean teardown")}});return(P,C,M,F)=>k.resetWithTiming(P,C,M,F)}function Ye(d){if((d.platform==="android"?[d.resourceId,d.stableDeviceId,...d.bootId===null?[]:[d.bootId]]:[d.scopeKey,d.stableDeviceId]).some((R)=>typeof R!=="string"||!R.trim())||d.platform==="ios"&&(!Number.isSafeInteger(d.allocationIndex)||d.allocationIndex<0))throw new t("Mutation incarnation requires non-empty identities and a safe non-negative allocation index");return JSON.stringify(d.platform==="android"?[d.resourceId,d.stableDeviceId,d.bootId]:[d.scopeKey,d.allocationIndex,d.stableDeviceId])}function Xi(d){let{resource:c,stableDeviceId:R}=d;if(d.platform!=="ios"&&(!c.resourceId.trim()||d.assignmentGeneration===null||!Number.isSafeInteger(d.assignmentGeneration)||d.assignmentGeneration<0))throw new t("Broker mutation recording requires an exact resource and assignment generation");return d.platform==="ios"?{sessionUuid:d.sessionUuid,deviceId:R,incarnation:Ye({platform:"ios",scopeKey:c.scopeKey,allocationIndex:c.allocationIndex,stableDeviceId:R})}:{sessionUuid:d.sessionUuid,deviceId:d.transportId??R,incarnation:Ye({platform:"android",resourceId:c.resourceId,stableDeviceId:R,bootId:d.bootId??null})}}class jo{journal;scope;constructor(d,c){this.journal=d;du(c,c.sessionUuid),this.scope=Object.freeze({...c})}record(d){return this.journal.record(this.scope,d)}async markUnrecorded(d){try{await this.record({kind:"opaque",key:Bn("recording-failed",d),priorValue:{state:"unobservable"},toolName:d})}catch(c){e.warn("Cannot persist device mutation recording failure marker",c)}}async missingMutations(d){let c=await this.journal.list(this.scope),R=new Set(c.map((D)=>JSON.stringify([D.kind,D.key])));return d.filter((D)=>!R.has(JSON.stringify([D.kind,D.key])))}readBaseline(){return this.journal.getBaseline(this.scope)}async baselinePrior(d,c){let R=await this.journal.getBaseline(this.scope);if(!R?.completeKinds.includes(d)||R.unobservable.includes(d))return{state:"unobservable"};return R.observations.find((D)=>D.kind===d&&D.key===c)?.value??{state:"absent"}}}var Ru=en(()=>g({name:y(),durationMs:T().finite().nonnegative(),children:Du.optional()})),Du=en(()=>Le([j(Ru),Dt(y(),Ru)])),Cb=g({provision:g({timing:Du.nullable().optional()})});function ku(d){let c=Cb.safeParse(d);if(!c.success||!c.data.provision.timing)return;let R={},D=(k)=>{for(let P of Object.values(k)){if(P.name==="provisionExactDevice")R.createMs=P.durationMs;if(P.name==="bootDevice")R.bootMs=P.durationMs;if(P.name==="ensureCtrlProxy iOS"||P.name==="ensureAccessibilityService")R.automationReadyMs=P.durationMs;if(P.children)D(P.children)}};return D(c.data.provision.timing),R}class zo{dependencies;managesResetBootSlots=!0;androidDevices=new Map;scope;scopeKey;isExecOwnerLive;constructor(d){this.dependencies=d;this.scope={...d.scope},this.scopeKey=Qd(this.scope),this.isExecOwnerLive=d.isExecOwnerLive??mc}async prepare(d,c){if(this.assertResource(d,"reserved"),!d.requestId)throw new t("A broker device reservation must belong to a session request");let R=Ln(d),D=this.requestedDevice(R),k=this.dependencies.timer??i,P=k.now()+(c.preparationTimeoutMs??ao),C=(W,V=0)=>{let z=this.bindingConfig(d,D,{...c,preparationTimeoutMs:Math.max(1,W)});return this.dependencies.brokerDeviceAcquisition.acquire(V>0?{...z,createRetryReserveMs:V}:z,{livenessOwnerToken:c.livenessOwnerToken,...c.signal?{signal:c.signal}:{}})},M=P-k.now(),F=R.platform==="ios"?Math.min(M/3,ga):0,q=await C(M,F);if(this.canRetryReadiness(q,d,R)&&!this.preparationStopped(P,c.signal)){if(await this.waitForRetry(Math.min(P-k.now(),25),c.signal),!this.preparationStopped(P,c.signal))q=await C(P-k.now())}let U=await this.readySessionId(q,d,R);await this.captureBaselinesHoldingLease(d,q,R,{sessionId:U,signal:c.signal,deadlineMs:P,deviceProfileOptions:c});let K=q.bindings.find((W)=>W.bindingIndex===d.allocationIndex);return{sessionId:U,profile:await KZ(R,K,this.dependencies.androidConfigReader),timing:ku(K?.lifecycle)}}async applyDeviceProfile(d,c,R,D){let k=D.deviceProfile;if(!k)return;let P=this.androidDevices.get(d.resourceId)?.device??Tb(c),M=await(this.dependencies.manufacturerProfileApplier??n1).apply(P,k,R,D.signal);if(M.status==="route_to_real_device")throw new t(M.message);e.info(`[SessionBroker] ${M.message}`)}async captureBaselinesHoldingLease(d,c,R,D){let{sessionId:k}=D,P=this.dependencies.leaseKeepalive?.hold({taskId:d.requestId,ownerKey:"session-broker",sessionUuid:k});try{if(await this.captureAndroidBaseline(d,c,R,D),R.platform==="ios"&&this.dependencies.captureIosBaseline)await this.capturePoolEntryBaseline(d,k,D);await this.applyDeviceProfile(d,c,k,D.deviceProfileOptions)}finally{P?.()}}async captureAndroidBaseline(d,c,R,D){let{sessionId:k}=D,P=this.dependencies.resetBaseline?.android;if(R.platform!=="android"||!P||!P.canCapture)return;this.androidDevices.delete(d.resourceId);try{let C=c.bindings[0],M=C?.device;if(!M?.transportId||typeof C?.assignmentGeneration!=="number")throw new t("Android reset baseline requires the acquired emulator serial");let F={platform:"android",name:M.name,deviceId:M.transportId};this.androidDevices.set(d.resourceId,{device:F,generation:C.assignmentGeneration,stableDeviceId:M.stableId});let q=await y0(this.key(d),()=>P.capture(d.resourceId,F,R,{sessionId:k,fresh:C.disposition==="created"||C.disposition==="replaced",signal:D.signal,timeoutMs:Math.max(0,D.deadlineMs-(this.dependencies.timer??i).now()),timer:this.dependencies.timer??i,stableDeviceId:M.stableId,assertOwned:async()=>{D.signal?.throwIfAborted();let U=await this.dependencies.registry.getAssignment(this.key(d));if(!U||!el(U,{generation:C.assignmentGeneration,stableDeviceId:M.stableId})||U.state!=="ready"||U.deviceName!==F.name||U.execOwner?.sessionUuid!==k||U.settler!==null||await this.hasOpenJournal(this.key(d)))throw new t("Android baseline capture lost exclusive binding ownership")}}));if(q)this.bindSessionMutationRecorder(C,d,R,q.bootId)}catch(C){await this.handleAndroidBaselineCaptureFailure(d.resourceId,P,D,C)}}async handleAndroidBaselineCaptureFailure(d,c,R,D){if(await c.forget(d),this.androidDevices.delete(d),R.signal?.throwIfAborted(),this.preparationStopped(R.deadlineMs,R.signal))throw new t("Android reset baseline capture exceeded preparation deadline");e.warn(`Android reset baseline unavailable; device will be destroyed on release: ${r(D)}`,D)}async capturePoolEntryBaseline(d,c,R){let D=this.dependencies.timer??i,k=new AbortController,P=He(k.signal,R.signal)??k.signal,C;try{if(P.throwIfAborted(),this.preparationStopped(R.deadlineMs,P))throw new t("iOS reset baseline capture exceeded preparation deadline");let M=this.key(d),F=await this.dependencies.registry.getAssignment(M);if(!F?.stableDeviceId||F.execOwner?.sessionUuid!==c)throw new t("iOS baseline capture requires the acquired execution binding");let q=async()=>{if(P.throwIfAborted(),this.preparationStopped(R.deadlineMs,P))throw new t("iOS reset baseline capture exceeded preparation deadline");let U=await this.dependencies.registry.getAssignment(M);if(!U||!el(U,F)||U.state!=="ready"||U.execOwner?.sessionUuid!==c||U.settler!==null||await this.hasOpenJournal(M))throw new t("iOS baseline capture lost execution binding ownership")};C=q,await l(()=>this.dependencies.captureIosBaseline({scope:{...this.mutationScope(d,F),sessionUuid:c},assertOwned:q,signal:P}),{timer:D,signal:P,timeoutMs:Math.max(0,R.deadlineMs-D.now()),label:"iOS pool-entry baseline capture",timeoutError:()=>new DOMException("iOS reset baseline capture exceeded preparation deadline","TimeoutError"),onTimeout:()=>k.abort(new DOMException("iOS baseline preparation deadline","TimeoutError"))}),await q()}catch(M){if(e.warn(`Skipping iOS pool-entry baseline; release erases if app baseline is unavailable: ${r(M)}`,M),R.signal?.throwIfAborted(),this.preparationStopped(R.deadlineMs,R.signal))throw u(M,"iOS reset baseline capture exceeded preparation deadline");if(!C)throw u(M,"Cannot capture iOS pool-entry baseline after ownership loss");await C()}}preparationStopped(d,c){return c?.aborted===!0||(this.dependencies.timer??i).now()>=d}canRetryReadiness(d,c,R){let D=d.bindings.find((C)=>C.bindingIndex===c.allocationIndex);if(!D?.failure)return!1;let k=D.failure,P=k.code==="readiness_incomplete"||k.code==="timeout"||k.code==="provision_failed"&&k.provision?.code==="timeout";return[R.platform==="ios",d.outcome==="failed",d.scope.scopeKey===this.scopeKey,d.bindings.length===1,D.sessionUuid===null,k.retryable,k.retainedDevice?.platform==="ios",P].every(Boolean)}async waitForRetry(d,c){let R=this.dependencies.timer??i,D;try{await l(()=>new Promise((k)=>{D=R.setTimeout(k,d)}),{timer:R,signal:c,label:"Managed device readiness retry"})}catch(k){throw new xa({code:c?.aborted?"cancelled":"session_preparation_failed",retryable:c?.aborted===!0,message:c?.aborted?"The binding acquisition was cancelled.":r(k)})}finally{if(D!==void 0)R.clearTimeout(D)}}async readySessionId(d,c,R){let D=d.bindings.find((q)=>q.bindingIndex===c.allocationIndex);if([d.outcome==="ready",d.scope.scopeKey===this.scopeKey,d.bindings.length===1].every(Boolean)&&this.isReadyBinding(D,R))return this.bindSessionMutationRecorder(D,c,R),D.sessionUuid;let P=D===void 0?null:D.sessionUuid;if(typeof P==="string"&&P.length>0)await this.dependencies.brokerExecutionRelease.releaseExecution(P);let{code:C,retryable:M,message:F}=d.failure??D?.failure??{code:"session_preparation_failed",retryable:!1,message:"Managed device preparation did not return an automation-ready session"};throw new xa({code:C,retryable:M,message:F})}bindSessionMutationRecorder(d,c,R,D=null){if(!this.dependencies.bindMutationRecorder||R.platform==="watchos")return;try{this.dependencies.bindMutationRecorder(Xi({platform:R.platform,sessionUuid:d.sessionUuid,resource:c,stableDeviceId:d.device.stableId,transportId:d.device.transportId,assignmentGeneration:d.assignmentGeneration,bootId:D}))}catch(k){e.warn("Failed to bind broker device mutation recorder; acquiring without recording",k)}}isReadyBinding(d,c){if(d===void 0||d.readiness===null)return!1;if(typeof d.sessionUuid!=="string"||d.sessionUuid.length===0)return!1;let R=c.platform==="watchos"?o_:{mode:"automation",status:"automation_ready"};return[d.platform===c.platform,d.failure===void 0,d.device!==null,d.readiness.mode===R.mode,d.readiness.status===R.status].every(Boolean)}async release(d){if(!d.trim())throw new t("A managed execution session UUID must be non-empty");let c=await this.dependencies.brokerExecutionRelease.releaseExecution(d);return{settled:c.outcome==="reusable_for_this_binding"&&c.settlement==="confirmed"&&c.bindingFailures.length===0}}async reset(d,c,R){this.assertResource(d,"resetting");let D=Ln(d),k=this.dependencies.resetBaseline?.ios,P=this.dependencies.resetBaseline?.android,C=this.dependencies.resetBaseline?.watch,M=this.dependencies.isCurrentReset;if(!M||!this.hasReset(D.platform))return"pending";let F=this.key(d),q=await this.dependencies.registry.getAssignment(F);if(!q?.stableDeviceId||!q.deviceName)throw new t("Reset requires a current bound native device");let U=q.deviceName,K={generation:q.generation,stableDeviceId:q.stableDeviceId},W=async()=>{if(c?.throwIfAborted(),!await M(d))throw new t("Clean reset no longer owns its durable resource revision");let z=await this.dependencies.registry.getAssignment(F);if(!(z&&el(z,K)&&z.state==="ready"&&z.execOwner===null&&z.settler===null&&z.deviceName===U&&this.belongsToResource(z,D,this.requestedSpec(D)))||await this.hasOpenJournal(F))throw new t("Clean reset lost exclusive native binding ownership")};await W();let V=await y0(F,async()=>{if(D.platform==="watchos"&&C)return C({platform:"watchos",deviceId:K.stableDeviceId,name:U},D,W,{signal:c,runResetBoot:R});if(D.platform==="ios"&&k)return k({platform:"ios",deviceId:K.stableDeviceId,name:U},D,W,{signal:c,context:{resource:d,scope:this.mutationScope(d,q),runResetBoot:R}});if(!P||D.platform!=="android")throw new t("Android reset dispatch requires an Android reset implementation and profile");if(!P.canCapture)throw new t("Android reset is destruction-only: no androidResetMode reset strategy is configured");let z=this.androidResetTarget(d,q,U);return P.reset(d.resourceId,z,D,{assertOwned:W,signal:c})});return await W(),V}hasReset(d){let c=this.dependencies.resetBaseline;switch(d){case"ios":return c?.ios!==void 0;case"android":return c?.android!==void 0;case"watchos":return c?.watch!==void 0}}androidResetTarget(d,c,R){let D=this.androidDevices.get(d.resourceId);if(!D)throw new t("Android reset baseline was not captured at acquisition");let k=[];if(!this.sameReleasedBinding(c,D))k.push("generation");if(D.stableDeviceId!==c.stableDeviceId)k.push("stableDeviceId");if(D.device.name!==R)k.push("deviceName");if(c.stableDeviceId!==R)k.push("avdName");if(k.length>0)throw e.warn(`Android reset acquired transport identity mismatch: ${k.join(", ")}`,{resourceId:d.resourceId,fields:k,acquired:{generation:D.generation,stableDeviceId:D.stableDeviceId,deviceName:D.device.name},expected:{generation:c.generation,stableDeviceId:c.stableDeviceId,deviceName:R}}),new t(`Android reset lacks its original acquired transport identity (mismatched: ${k.join(", ")})`);return D.device}mutationScope(d,c){if(!c.stableDeviceId)throw new t("iOS mutation scope requires an exact bound device");return{deviceId:c.stableDeviceId,incarnation:Ye({platform:"ios",scopeKey:d.scopeKey,allocationIndex:d.allocationIndex,stableDeviceId:c.stableDeviceId})}}async destroy(d,c){c?.throwIfAborted(),this.assertResource(d,"destroying");let R=Ln(d);if(R.platform==="android")await this.dependencies.resetBaseline?.android?.forget(d.resourceId),this.androidDevices.delete(d.resourceId);let D=this.requestedSpec(R),k=this.key(d);if(await this.redriveOpenJournal(k,c)==="pending")return"pending";c?.throwIfAborted();let P=await this.destroyableAssignment(k,R,D);if(typeof P==="string")return P;c?.throwIfAborted();let C=await this.drainAssignment(k,P,R,D);return c?.throwIfAborted(),typeof C==="string"?C:this.deleteAssignment(k,C,c)}async destroyableAssignment(d,c,R){let D=await this.dependencies.registry.getAssignment(d);if(!D||D.stableDeviceId===null)return this.confirmNoBinding(d);return this.belongsToResource(D,c,R)?D:"pending"}async drainAssignment(d,c,R,D){if(!c.execOwner)return c;if(!jc(c.execOwner,this.dependencies.bindingJournal.owner))return this.isExecOwnerLive(c.execOwner)?"pending":c;if(!(await this.release(c.execOwner.sessionUuid)).settled)return"pending";let P=await this.dependencies.registry.getAssignment(d);if(!P)return this.confirmNoBinding(d);return[this.sameReleasedBinding(P,c),P.state==="ready",P.settler===null,P.execOwner===null,this.belongsToResource(P,R,D)].every(Boolean)?P:"pending"}sameReleasedBinding(d,c){return el(d,c)||el(d,{...c,generation:c.generation+1})}async deleteAssignment(d,c,R){if(c.stableDeviceId===null)return this.confirmNoBinding(d);let D=c.stableDeviceId;R?.throwIfAborted();let k=await this.dependencies.registry.openBindingJournal(d,{kind:"replace",phase:"deleting",owner:this.dependencies.bindingJournal.owner,target:{oldStableId:D,oldName:c.deviceName,newName:null,newStableId:null,requestedSpec:c.requestedSpec,resolvedSpec:c.resolvedSpec,specFingerprint:c.specFingerprint},assignment:{kind:"state",expected:{generation:c.generation,stableDeviceId:D},state:"replacing"}});if(k.kind!=="opened"&&k.kind!=="journal_open")return"pending";R?.throwIfAborted();let P=await this.dependencies.bindingJournal.redriveBinding(d,{signal:R});if(R?.throwIfAborted(),P.kind==="blocked"||await this.hasOpenJournal(d))return"pending";let C=await this.dependencies.registry.getAssignment(d);return!C||C.stableDeviceId===null?"absent":"pending"}async confirmNoBinding(d){let c=await this.dependencies.registry.getAssignment(d);if(c!==null&&(c.stableDeviceId!==null||c.execOwner!==null||c.settler!==null))return"pending";return await this.hasOpenJournal(d)?"pending":"absent"}assertResource(d,c){if(!d.resourceId.trim())throw new t("A broker resource identity must be non-empty");if(!Number.isSafeInteger(d.allocationIndex)||d.allocationIndex<0||d.scopeKey!==this.scopeKey)throw new t("Broker resource does not belong to this provider-owned scope");if(d.state!==c)throw new t(`Broker resource '${d.resourceId}' must be ${c}, not ${d.state}`)}key(d){return{scopeKey:this.scopeKey,bindingIndex:d.allocationIndex}}bindingConfig(d,c,R){return{contractVersion:1,...this.scope,localBindingCapacity:1,requests:[{bindingIndex:d.allocationIndex,role:fh,...c}],...R.preparationTimeoutMs===void 0?{}:{preparationTimeoutMs:R.preparationTimeoutMs},...R.idleTimeoutMs===void 0?{}:{idleTimeoutMs:R.idleTimeoutMs},...R.executionOwnerPid===void 0?{}:{executionOwnerPid:R.executionOwnerPid}}}requestedSpec(d){return this.requestedDevice(d).requestedSpec}requestedDevice(d){if(d.platform==="watchos")return{platform:"watchos",requestedSpec:{runtime:d.runtime,deviceType:d.deviceType}};if(d.platform==="ios")return{platform:"ios",requestedSpec:{runtime:d.runtimeId,deviceType:d.simulatorDeviceTypeIdentifier}};let c=nn(d.systemImagePackage);if(!c||c.apiLevel!==d.apiLevel||c.abi!==d.abi||c.tag!==d.flavor)throw new t("Stored Android profile does not agree with its exact system-image package");return{platform:"android",requestedSpec:{runtime:c.systemImagePackage,deviceType:d.profileId,...d.memoryMb===void 0?{}:{configuration:{memoryMb:d.memoryMb}}}}}belongsToResource(d,c,R){if(d.scopeKey!==this.scopeKey||d.role!==fh||d.platform!==c.platform)return!1;let D=d.requestedSpec;if(!D||typeof D!=="object")return!1;let k=D;return k.runtime===R.runtime&&k.deviceType===R.deviceType&&k.configuration?.memoryMb===("configuration"in R?R.configuration?.memoryMb:void 0)}async redriveOpenJournal(d,c){if(!await this.hasOpenJournal(d))return"clear";c?.throwIfAborted();let R=await this.dependencies.bindingJournal.redriveBinding(d,{signal:c});return c?.throwIfAborted(),R.kind==="clear"&&!await this.hasOpenJournal(d)?"clear":"pending"}async hasOpenJournal(d){return(await this.dependencies.registry.listOpenBindingJournal(d)).length>0}}function Tb(d){let c=d.bindings[0]?.device;if(!c?.transportId)throw new t("A manufacturer profile requires the acquired emulator serial");return{platform:"android",name:c.name,deviceId:c.transportId}}function Mt(d,c){if(d.platform!=="ios"||!d.deviceId.trim())throw new t("iOS baseline reset requires an exact iOS simulator UDID");if(c.platform!=="ios"||!c.simulatorDeviceTypeIdentifier.trim()||!c.runtimeId.trim()||!c.osVersion.trim())throw new t("iOS baseline reset requires a complete exact iOS profile")}async function ai(d,c,R,{state:D,action:k,timeoutMs:P,signal:C}){let M;try{M=P!==void 0?await d.readSimulatorTarget(c,P,C):await d.readSimulatorTarget(c)}catch(q){throw u(q,`Cannot ${k}: fresh iOS simulator inventory failed`)}if(!M||M.udid!==c)throw new t(`Cannot ${k}: fresh iOS simulator inventory did not prove one exact target '${c}'`);let F=ED(M.runtime,M.os_version);if(![M.isAvailable===!0,M.deviceTypeIdentifier===R.simulatorDeviceTypeIdentifier,M.runtime===R.runtimeId,uB(F,R.osVersion)===0,M.state===D].every(Boolean))throw new t(`Cannot ${k}: simulator '${c}' lacks authoritative ${D} identity, runtime, type, OS, or availability evidence`)}var Mb=60000;class Qo{dependencies;timer;deferredBoots=new Set;constructor(d,c=i){this.dependencies=d;this.timer=c}async reset(d,c,R,D){return await this.runReset(d,c,R,{phases:{},signal:D}),"clean"}async resetWithTiming(d,c,R,D){let k={};try{return await this.runReset(d,c,R,{phases:k,signal:D})}catch(P){throw new Ci(r(P),{outcome:"pending",mode:"erase",phases:k,fallbackReason:r(P)},{cause:P})}}async runReset(d,c,R,{phases:D,signal:k}){let P=async()=>{k?.throwIfAborted(),await R(),k?.throwIfAborted()};Mt(d,c);let C=this.deferredBoots.delete(d.deviceId);await this.readExpectedTarget(d.deviceId,c,C?"Shutdown":"Booted","start reset"),await P();let M;try{M=await this.reserveResetBoot(d.deviceId,P,k)}catch(q){if(C)this.deferredBoots.add(d.deviceId);throw u(q,"Cannot reserve iOS reset boot slot")}let F=()=>this.eraseAndBoot(d,c,P,{phases:D,deferredBoot:C,signal:k});try{return await(M?M.run(F):F())}finally{M?.release()}}async reserveResetBoot(d,c,R){let D=this.timer.now(),k=D+Ve,P=Q({initialDelayMs:1000,maxDelayMs:8000}),C=0,M=0;for(;;){R?.throwIfAborted();let F=this.timer.now();try{return await this.dependencies.iosBootInstrumentation.reserveBoot?.({replacingDeviceId:d,timeoutMs:k-this.timer.now(),reason:"reset",signal:R})}catch(q){if(q instanceof $n){await this.waitResetCapacity({error:q,deviceId:d,startedAt:D,owned:c,delayMs:P.delayForAttempt(++M)}),k+=this.timer.now()-F;continue}let U=P.delayForAttempt(++C);if(!(q instanceof ze)||k-this.timer.now()<=U)throw u(q,"Cannot reserve iOS reset boot slot");if(await this.timer.sleep(U),await c(),this.timer.now()>=k)throw u(q,"Cannot reserve iOS reset boot slot")}}}async waitResetCapacity(d){let{error:c,deviceId:R,startedAt:D,owned:k,delayMs:P}=d,C=D+Mb;if(this.timer.now()+P>C||this.timer.now()>=C)throw new i_(R,this.timer.now()-D,c);if(await this.timer.sleep(P),await k(),this.timer.now()>=C)throw new i_(R,this.timer.now()-D,c)}async eraseAndBoot(d,c,R,{phases:D,deferredBoot:k,signal:P}){if(this.dependencies.iosBootInstrumentation.reserveBoot)await R();if(!k)await this.measureStep(d.deviceId,"stop",D,()=>this.dependencies.stopDevice(d));await this.readExpectedTarget(d.deviceId,c,"Shutdown","erase simulator"),await R(),await this.measureStep(d.deviceId,"erase",D,()=>this.dependencies.simctl.eraseSimulator(d.deviceId));let C=await this.measureStep(d.deviceId,"boot",D,()=>this.bootAdmitted(d.deviceId,c,R,P));if(C.platform!=="ios"||C.deviceId!==d.deviceId)throw new t(`iOS baseline reset booted a different target instead of simulator '${d.deviceId}'`);return await this.readExpectedTarget(d.deviceId,c,"Booted","confirm clean baseline"),await R(),{outcome:"clean",mode:"erase",phases:D}}async bootAdmitted(d,c,R,D){let k=!1;try{return await this.dependencies.iosBootInstrumentation.run({udid:d,runtime:c.runtimeId,timeoutMs:Ve,reason:"reset",signal:D},async()=>(k=!0,await R(),this.dependencies.simctl.bootSimulator(d)))}catch(P){if(P instanceof $n||!k&&P instanceof ze)this.deferredBoots.add(d);throw u(P,"Cannot boot erased iOS simulator")}}async measureStep(d,c,R,D){let k=this.timer.now(),P=!1;e.info(`[SessionBroker] iOS baseline reset ${c} started for ${d}`);try{let C=await D();return P=!0,C}finally{R[c]=this.timer.now()-k,e.info(`[SessionBroker] iOS baseline reset ${c} ${P?"completed":"failed"} for ${d} after ${this.timer.now()-k}ms`)}}async readExpectedTarget(d,c,R,D){await ai(this.dependencies.simctl,d,c,{state:R,action:D})}}function Zi(d){let c=d.kind==="installed-app"&&d.priorValue.state==="absent",R=d.kind==="clipboard"&&(d.priorValue.state==="absent"||d.priorValue.state==="present"&&(d.priorValue.value===""||d.priorValue.value===null));return c||R?{kind:d.kind,key:d.key,priorValue:d.priorValue,toolName:"baseline-diff"}:null}function es(d,c,R){let D=new Set(HS),k=[...c.dirty],P=[...d].sort((C,M)=>M.sequence-C.sequence).map((C)=>({source:"journal",mutation:C}));for(let C of c.changes.filter((M)=>!M.journaled)){let M=R.baselineRevert?.(C,c.changes)??Zi(C);if(M){if(!P.some((F)=>F.mutation.kind===M.kind&&F.mutation.key===M.key))P.push({source:"baseline",mutation:M})}else k.push(`Unjournaled ${C.kind}:${C.key}`)}for(let C of P){if(C.mutation.priorValue.state==="unobservable"){k.push(`Unobservable prior value ${C.mutation.kind}:${C.mutation.key}`);continue}if(!D.has(C.mutation.kind)||!R.canRevert(C.mutation))k.push(`Unsupported ${C.mutation.kind}:${C.mutation.key}`)}return k.length>0?{status:"non_revertible",reasons:k}:{status:"revertible",steps:P}}class ts{dependencies;budgetTimeouts=new WeakSet;pending=new Map;eraseReasons=new Map;constructor(d){this.dependencies=d;if(!Number.isSafeInteger(d.maxUses)||d.maxUses<1)throw new t("iOS keep-booted reset maxUses must be a positive safe integer")}async resetWithTiming(d,c,R,{scope:D,...k}){let{reuseCount:P,signal:C,runResetBoot:M}=k;this.assertInput(d,c,D,P);let F={},q=async()=>{C?.throwIfAborted(),await R(),C?.throwIfAborted()};await q(),await this.assertSettled(D,q,C);let U=JSON.stringify([D.deviceId,D.incarnation,D.sessionUuid]),K=this.eraseReasons.get(U)??"maxUses reached";if(!this.eraseReasons.has(U)&&(P+1)%this.dependencies.maxUses!==0){let W={scope:D,signal:C??new AbortController().signal,assertOwned:async()=>{W.signal.throwIfAborted(),await q(),W.signal.throwIfAborted()},recordPhase:(J,X)=>{F[J]=(F[J]??0)+X}},V=(J,X)=>this.cleaningStep(W,C,J,{phases:F,operation:X}),z=await this.loadJournal(W,V,F);try{if(this.assertCompleteRecording(D.sessionUuid),await V("inventory",()=>ai(this.dependencies.simctl,d.deviceId,c,{state:"Booted",action:"start keep-booted reset",signal:W.signal,timeoutMs:this.innerReadTimeoutMs()})),!W.baseline?.completeKinds.includes("installed-app"))throw new t("iOS reset requires a captured app baseline; erase required");let J=z.find(qS);if(J)throw new t(`iOS opaque journaled mutation (${J.toolName}) cannot be journal-reverted; erase required`);let X=await this.dependencies.journal.listStrayIncarnations(W.scope);if(X.length>0)throw new t(`iOS journaled mutations recorded under a different incarnation (${X.length}) cannot be journal-reverted; erase required`);await this.replayJournal(z,W,V),await V("sanitize",()=>this.dependencies.mutations.sanitize(W)),await q(),await this.checkHealth(d,c,W,{phases:F,signal:C})}catch(J){e.warn(`iOS keep-booted cleaning failed: ${r(J)}`,J),await q(),K=this.fallbackReason(J),e.warn(`iOS erase fallback: ${K}`,J),this.eraseReasons.set(U,K)}if(!this.eraseReasons.has(U))return await q(),await this.dependencies.journal.deleteSession(D),await q(),{outcome:"clean",mode:"keep-booted",phases:F}}return await q(),await this.assertSettled(D,q,C),this.nonCleanOutcome({device:d,profile:c,scope:D,assertOwned:q,phases:F,signal:C},K,M)}nonCleanOutcome(d,c,R){return this.dependencies.fallback==="destroy"?Promise.resolve(this.destroyFallback(d.phases,c)):this.eraseFallback(d,c,R)}destroyFallback(d,c){return{outcome:"pending",mode:"keep-booted",phases:d,fallbackReason:c}}async eraseFallback(d,c,R){let{device:D,profile:k,scope:P,assertOwned:C,phases:M,signal:F}=d;try{let q=()=>this.dependencies.erase.resetWithTiming(D,k,C,F),U=await(R?R(q):q());if(await C(),U.outcome!=="clean")throw new t("iOS erase fallback did not confirm a clean baseline");return await this.dependencies.journal.deleteSession(P),await C(),this.dependencies.recordingGaps?.clear(P.sessionUuid),this.eraseReasons.delete(JSON.stringify([P.deviceId,P.incarnation,P.sessionUuid])),{outcome:"fallback:erase",mode:"erase",phases:{...M,...U.phases},fallbackReason:c}}catch(q){throw e.warn(`iOS erase fallback failed: ${r(q)}`,q),new Ci(r(q),{outcome:"pending",mode:"erase",phases:{...M,...q instanceof Ci?q.reset.phases:{}},fallbackReason:`${c}; erase: ${r(q)}`},{cause:q instanceof Ci?q.cause:q})}}async loadJournal(d,c,R){try{return await c("journal",async()=>(d.baseline=await this.dependencies.journal.getBaseline(d.scope)??void 0,this.dependencies.journal.list(d.scope)))}catch(D){throw new Ci(r(D),{outcome:"pending",mode:"keep-booted",phases:R,fallbackReason:r(D)},{cause:D})}}async replayJournal(d,c,R){let D=[...d].sort((k,P)=>P.sequence-k.sequence).map((k)=>({entry:k,plan:es([k],{dirty:[],changes:[]},this.dependencies.mutations)}));for(let{entry:k,plan:P}of D)if(!["installed-app","app-group"].includes(k.kind)&&P.status==="non_revertible"&&!this.sanitizeCovers(k,c))throw new t(`iOS journaled mutation ${k.kind}:${k.key} (${k.toolName}) cannot be journal-reverted or sanitized; erase required`);for(let{entry:k,plan:P}of D){if(["installed-app","app-group"].includes(k.kind)){e.warn(`iOS reset handles ${k.kind}:${k.key} through app inventory cleaning`);continue}if(P.status==="non_revertible"){e.warn(`iOS reset skipped journal revert: ${P.reasons.join("; ")}`);continue}await R(`revert:${k.kind}:${k.key}`,()=>this.dependencies.mutations.revert(k,c))}}assertCompleteRecording(d){let c=this.dependencies.recordingGaps?.reasonFor(d);if(c!==void 0)throw new t(`iOS device mutation recording failed (${c}); journal is incomplete; erase required`)}sanitizeCovers(d,c){if(d.kind==="opaque")return!qS(d);if(d.kind==="preference")return $H(d,c.baseline);return this.dependencies.mutations.sanitizeCovers(d,c)}innerReadTimeoutMs(){return Math.max(this.dependencies.budgetMs??30000,this.dependencies.budgetCeilingMs??120000)}fallbackReason(d){return this.isBudgetTimeout(d)?`budget-driven: ${r(d)}`:r(d)}isBudgetTimeout(d){return typeof d==="object"&&d!==null&&this.budgetTimeouts.has(d)}async cleaningStep(d,c,R,{phases:D,operation:k}){let P=Gz({baseMs:this.dependencies.budgetMs??30000,ceilingMs:this.dependencies.budgetCeilingMs??120000},this.dependencies.hostLoad??Kz());try{return await this.cleaningAttempt(d,c,R,{phases:D,operation:k,first:P,timeoutMs:P.budgetMs})}catch(C){if(!this.isBudgetTimeout(C)||c?.aborted)throw C;return e.warn(`Retrying iOS reset ${R}: ${r(C)}`,C),await this.waitForAbandonedStep(d.scope.deviceId,CD(P),C,c),this.cleaningAttempt(d,c,R,{phases:D,operation:k,first:P,timeoutMs:CD(P)})}}async cleaningAttempt(d,c,R,{phases:D,operation:k,first:P,timeoutMs:C}){let M=new AbortController;d.signal=He(M.signal,c)??M.signal;let F=new DOMException(`iOS reset ${R} timed out after ${C}ms (${Yz(P)})`,"TimeoutError");return l(()=>this.measure(d.scope.deviceId,R,D,async()=>{await d.assertOwned();let q=await k();return await d.assertOwned(),q}),{timer:this.dependencies.timer,timeoutMs:C,signal:c,label:`iOS reset ${R}`,timeoutError:()=>F,onTimeout:()=>{this.budgetTimeouts.add(F),M.abort(F)}})}async waitForAbandonedStep(d,c,R,D){await l(Promise.allSettled([...this.pending.get(d)??[]]),{timer:this.dependencies.timer,timeoutMs:c,signal:D,label:"iOS reset abandoned step settlement",timeoutError:()=>R})}async checkHealth(d,c,R,{phases:D,signal:k}){let P=this.dependencies.timer.now();try{await this.cleaningStep(R,k,"health-probe",{phases:D,operation:async()=>{if(await ai(this.dependencies.simctl,d.deviceId,c,{state:"Booted",action:"confirm keep-booted health",signal:R.signal,timeoutMs:this.innerReadTimeoutMs()}),await R.assertOwned(),!await this.dependencies.health.probe(d,R.signal))throw new t("iOS keep-booted automation server is unhealthy")}})}finally{D.health=(D.health??0)+this.dependencies.timer.now()-P}}async measure(d,c,R,D){let k=this.dependencies.timer.now(),P=Promise.resolve().then(D),C=this.pending.get(d)??new Set;this.pending.set(d,C),C.add(P);try{return await P}finally{if(C.delete(P),C.size===0)this.pending.delete(d);R[c]=(R[c]??0)+this.dependencies.timer.now()-k}}assertInput(d,c,R,D){if(Mt(d,c),du(R,R.sessionUuid),d.deviceId!==R.deviceId||!Number.isSafeInteger(D)||D<0)throw new t("iOS keep-booted reset requires the exact mutation scope and durable use count")}async assertSettled(d,c,R){try{if(this.pending.has(d.deviceId))throw new DOMException("iOS reset still has an unsettled native step","TimeoutError");await this.dependencies.mutations.assertSettled({scope:d,assertOwned:c,signal:R??new AbortController().signal})}catch(D){throw new Ci(r(D),{outcome:"pending",mode:"keep-booted",phases:{}},{cause:D})}}}var Eb="light",Bb="large",xb={kind:"clipboard",key:"pasteboard",priorValue:{state:"present",value:""},toolName:"minimal-reset"},_b=30000,Fb=1e4;class is{dependencies;failures=new Map;constructor(d){this.dependencies=d;if(!Number.isSafeInteger(d.maxUses)||d.maxUses<1)throw new t("iOS minimal reset maxUses must be a positive safe integer")}async resetWithTiming(d,c,R,{scope:D,reuseCount:k,signal:P}){if(Mt(d,c),du(D,D.sessionUuid),d.deviceId!==D.deviceId||!Number.isSafeInteger(k)||k<0)throw new t("iOS minimal reset requires the exact mutation scope and durable use count");let C={},M=JSON.stringify([D.deviceId,D.incarnation,D.sessionUuid]),F=this.failures.get(M);if(F!==void 0)return this.pending(C,F);if((k+1)%this.dependencies.maxUses===0)return this.pending(C,"maxUses reached");try{await this.clean(D,R,C,P)}catch(q){if(P?.aborted)throw q;await R();let U=r(q);return e.warn(`iOS minimal cleaning failed; simulator will be destroyed: ${U}`,q),this.failures.set(M,U),this.pending(C,U)}return await R(),await this.dependencies.journal.deleteSession(D),await R(),this.dependencies.recordingGaps?.clear(D.sessionUuid),{outcome:"clean",mode:"minimal",phases:C}}pending(d,c){return{outcome:"pending",mode:"minimal",phases:d,fallbackReason:c}}async clean(d,c,R,D){let k=this.dependencies.recordingGaps?.reasonFor(d.sessionUuid);if(k!==void 0)throw new t(`iOS device mutation recording failed (${k}); the session's apps are unknown`);let P=[...await this.dependencies.journal.list(d)].sort((F,q)=>q.sequence-F.sequence),C=d.deviceId,M=(F,q)=>this.step({scope:d,assertOwned:c,phases:R,callerSignal:D},F,q);for(let F of P.filter((q)=>q.kind==="installed-app"))await M(`uninstall:${F.key}`,(q)=>this.dependencies.mutations.revert(F,q));if(P.some((F)=>F.kind==="shared-file"&&O7(F.key)))await M("files-fixture",(F)=>this.simctl(["uninstall",C,iI],F));await M("keychain",(F)=>this.simctl(["keychain",C,"reset"],F)),await M("privacy",(F)=>this.simctl(["privacy",C,"reset","all"],F)),await M("appearance",(F)=>this.simctl(["ui",C,"appearance",Eb],F)),await M("content-size",(F)=>this.simctl(["ui",C,"content_size",Bb],F)),await M("pasteboard",(F)=>this.dependencies.mutations.revert(xb,F))}async simctl(d,c){let R=await this.dependencies.simctl.executeCommandArgs(d,Fb,c.signal);if(R.error){if(d[0]==="uninstall"&&/\b(?:app|application)\b[^\n]*\bis not installed\b/i.test(`${R.error}
22
+ ${R.stderr}`)){e.debug("iOS minimal reset Files fixture already absent",R.error);return}throw new t(`iOS minimal reset ${d[0]} failed: ${R.error}`)}}async step({scope:d,assertOwned:c,phases:R,callerSignal:D},k,P){let C=new AbortController,M=He(C.signal,D)??C.signal,F=this.dependencies.budgetMs??_b,q={scope:d,signal:M,assertOwned:async()=>{M.throwIfAborted(),await c(),M.throwIfAborted()},recordPhase:(U,K)=>{R[U]=(R[U]??0)+K}};await l(async()=>{await q.assertOwned(),await P(q),await q.assertOwned()},{timer:this.dependencies.timer,timeoutMs:F,signal:D,label:`iOS minimal reset ${k}`,timeoutError:()=>new DOMException(`iOS minimal reset ${k} timed out after ${F}ms`,"TimeoutError"),onTimeout:()=>C.abort()})}}import{realpath as zb,rm as Yb}from"fs/promises";import{homedir as Xb}from"os";import{posix as $b}from"path";function ns(d){if(d.key!=="device"||d.priorValue.state!=="present")return;let c=d.priorValue.value;return c==="enrolled"?!0:c==="not_enrolled"?!1:void 0}function Au(d,c){let R=L$;return["spawn",d,"notifyutil","-1",R,"-s",R,c?"1":"0","-g",R,"-p",R]}import{isDeepStrictEqual as Nb}from"util";var ds=["media","shared-file","keyboard","accessibility"],as={photos:{kind:"media",key:"dcim"},documents:{kind:"shared-file",key:"documents"},safariDocuments:{kind:"shared-file",key:"safari-documents"},keyboard:{kind:"keyboard",key:"defaults"},accessibility:{kind:"accessibility",key:"defaults"}};function Mu(d){return Object.keys(as).map((c)=>({...as[c],value:{state:"present",value:d[c]}}))}function Eu(d){return ds.every((c)=>d?.completeKinds.includes(c))}function li(d,c){let{kind:R,key:D}=as[c],k=d.observations.find((P)=>P.kind===R&&P.key===D);return k?.value.state==="present"?k.value.value:void 0}function rs(d){return Array.isArray(d)?d.filter((c)=>typeof c==="string"):[]}function Iu(d){let c={};if(d!==null&&typeof d==="object"&&!Array.isArray(d)){for(let[R,D]of Object.entries(d))if(typeof D==="boolean"||typeof D==="number"||typeof D==="string")c[R]=D}return c}function Bu(d){return{photos:rs(li(d,"photos")),documents:rs(li(d,"documents")),safariDocuments:rs(li(d,"safariDocuments")),keyboard:Iu(li(d,"keyboard")),accessibility:Iu(li(d,"accessibility"))}}function rn(d,c){return d.filter((R)=>!c.includes(R))}function ls(d,c){let R=[],D=rn(c.photos,d.photos).length,k=rn(d.photos,c.photos).length;if(D>0)R.push(`iOS reset cannot revert ${D} added photo(s)`);if(k>0)R.push(`iOS reset cannot restore ${k} removed photo(s)`);let P=[];for(let[C,M,F,q]of[["documents","Documents",d.documents,c.documents],["safari-documents","Safari Documents",d.safariDocuments,c.safariDocuments]]){let U=rn(F,q).length;if(U>0)R.push(`iOS reset cannot restore ${U} removed ${M} file(s)`);let K=rn(q,F);if(K.length>0)P.push({area:C,names:K})}return{unrevertible:R,removals:P,keyboard:Tu(d.keyboard,c.keyboard),accessibility:Tu(d.accessibility,c.accessibility)}}function Tu(d,c){return[...new Set([...Object.keys(d),...Object.keys(c)])].sort().filter((R)=>!Nb(d[R],c[R])).map((R)=>({key:R,prior:d[R]}))}function us(d){return d.unrevertible.length===0&&d.removals.length===0&&d.keyboard.length===0&&d.accessibility.length===0}var Ne={appearance:p(["light","dark"]),nightMode:p(["light","dark"]),"content-size":p(["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"]),"increase-contrast":p(["enabled","disabled"]),reduceMotion:p(["0","1"]),boldText:p(["0","1"]),locale:n().min(1),language:S(n().min(1)).min(1),calendarSystem:n().min(1),"force-24-hour-time":m(),"force-12-hour-time":m()},Hb=s({AppleLocale:Ne.locale.optional(),AppleLanguages:Ne.language.optional(),AppleCalendar:Ne.calendarSystem.optional(),AppleICUForce24HourTime:Ne["force-24-hour-time"].optional(),AppleICUForce12HourTime:Ne["force-12-hour-time"].optional()}),on={locale:"AppleLocale",language:"AppleLanguages",calendarSystem:"AppleCalendar","force-24-hour-time":"AppleICUForce24HourTime","force-12-hour-time":"AppleICUForce12HourTime"},qb={"app-group":"simctl lists app-owned group paths, not complete shared/orphan container contents.","keep-awake":"simctl cannot inventory the simulator's effective idle-timer assertions.",rotation:"simctl has no complete orientation readback and restoration API.","screen-reader":"simctl cannot read back effective VoiceOver state.",notification:"simctl cannot inventory or remove all delivered and pending notifications.",contact:"simctl cannot inventory and restore the complete Contacts store.",calendar:"simctl cannot inventory and restore the complete Calendar store.",clock:"simctl cannot observe all effective clock and automatic time-zone state.","network-condition":"simctl cannot inventory effective simulator and host network shaping.","biometric-enrollment":"simctl cannot read back complete biometric enrollment state.",profile:"simctl cannot inventory and restore all configuration profiles.",certificate:"simctl cannot inventory and restore complete certificate trust settings.","opened-url":"simctl cannot inventory persistent effects of arbitrary URL handlers.",preference:"simctl cannot inventory every app's arbitrary preferences and live caches.",account:"simctl cannot inventory and restore all provider and system accounts."},Ou={contentSize:"content-size",increaseContrast:"increase-contrast"},Kb={reduceMotion:"ReduceMotionEnabled",boldText:"EnhancedTextLegibilityEnabled"};function fs(d){return Object.hasOwn(Ou,d)?Ou[d]:d}function Lu(d){return Object.entries(Kb).find(([c])=>c===d)?.[1]}function Gb(d,c,R){return["spawn",d,"defaults",R===void 0?"delete":"write","com.apple.Accessibility",c,...R===void 0?[]:["-bool",R==="1"?"YES":"NO"]]}function $u(d){return Object.entries(on).find(([c])=>c===d)?.[1]}async function Wb(d){let c=await Hp(d);if(!(c instanceof Map))throw new t("iOS global settings export is not a dictionary");let R=Hb.parse(Object.fromEntries(c));return Object.entries(on).map(([D,k])=>{let P=R[k];return{kind:"device-setting",key:D,value:P===void 0?{state:"absent"}:{state:"present",value:P}}})}function Vb(d){let c=d.priorValue;if(c.state!=="present")return c.state==="absent"&&($u(d.key)!==void 0||Lu(d.key)!==void 0);let R=fs(d.key);return Object.entries(Ne).find(([k])=>k===R)?.[1]?.safeParse(c.value).success??!1}var xu=["keychain","permission","location","status-bar","clipboard"];function Jb(d,c){let R=MH(d.key);return d.kind==="shared-file"&&R!==void 0&&c?.baseline?.completeKinds.includes("installed-app")===!0&&!c.baseline.observations.some((D)=>D.kind==="installed-app"&&D.key.toLowerCase()===R.toLowerCase())}class hs{dependencies;timer;constructor(d,c){this.dependencies=d;this.timer=c}canRevert(d){let c=d.priorValue;if(c.state==="unobservable")return!1;if(["installed-app","app-group","keychain","permission","location","status-bar"].includes(d.kind))return c.state==="absent";switch(d.kind){case"clipboard":return c.state==="absent"||typeof c.value==="string";case"device-setting":return Vb(d);case"biometric-enrollment":return ns(d)!==void 0;case"preference":return d.key.split(":").length===2&&d.key.split(":").every(Boolean)&&(c.state==="absent"||["string","boolean","number"].includes(typeof c.value));default:return!1}}baselineRevert(d){let c={kind:d.kind,key:d.key,priorValue:d.priorValue,toolName:"baseline-diff"};return d.kind==="device-setting"&&this.canRevert(c)?c:null}async assertSettled(d){await d.assertOwned(),this.dependencies.pasteboard.assertSettled(d.scope.deviceId)}async capture(d){try{return await this.captureObservable(d)}catch(c){if(e.warn(`iOS baseline inventory is unobservable: ${r(c)}`,c),d.signal.throwIfAborted(),await d.assertOwned(),$S(c)==="retryable")throw u(c,"iOS baseline inventory is temporarily unavailable");throw u(c,"iOS baseline app inventory is unavailable")}}async captureObservable(d){await this.assertSettled(d),await d.assertOwned();let c=await this.dependencies.simctl.listAppsOrThrow(d.scope.deviceId,{signal:d.signal,timeoutMs:1e4});await d.assertOwned();let R=c.map((k)=>{let P=pn(k);if(!P)throw new t("iOS baseline app inventory contains an unidentified bundle");return{kind:"installed-app",key:P,value:{state:"present",value:Yp().parse(k)}}}),D=["installed-app"];try{let k=await this.captureSettings(d);R.push(...k),D.push("device-setting")}catch(k){await this.inventoryFailure(k,d,"device-setting")}try{R.push(...Mu(await this.dependencies.residue.read(d.scope.deviceId,d.signal))),D.push(...ds)}catch(k){await this.inventoryFailure(k,d,"out-of-band residue")}return{observations:R,completeKinds:D,unobservable:HS.filter((k)=>(k in qb)||!D.includes(k))}}async inventoryFailure(d,c,R){if(e.warn(`iOS ${R} inventory is unobservable: ${r(d)}`,d),c.signal.throwIfAborted(),await c.assertOwned(),$S(d)==="retryable")throw u(d,`iOS ${R} inventory is temporarily unavailable`)}async captureSettings(d){let c=d.scope.deviceId,R=Ne.appearance.parse((await this.command(d,["ui",c,"appearance"])).stdout.trim()),D=Ne["content-size"].parse((await this.command(d,["ui",c,"content_size"])).stdout.trim()),k=Ne["increase-contrast"].parse((await this.command(d,["ui",c,"increase_contrast"])).stdout.trim()),P=await this.command(d,["spawn",c,"defaults","export","-g","-"]);return[...["appearance","nightMode"].map((C)=>({kind:"device-setting",key:C,value:{state:"present",value:R}})),{kind:"device-setting",key:"content-size",value:{state:"present",value:D}},{kind:"device-setting",key:"increase-contrast",value:{state:"present",value:k}},...await Wb(P.stdout)]}async revert(d,c){if(!this.canRevert(d))throw new t(`Unsupported iOS reset mutation ${d.kind}:${d.key}`);let R=c.scope.deviceId,D=d.priorValue.state==="present"?d.priorValue.value:void 0;switch(d.kind){case"installed-app":await this.terminate(d.key,c),await this.clearAppGroups(d.key,c),await this.command(c,["uninstall",R,d.key]);break;case"app-group":await this.terminate(d.key,c),await this.clearAppGroups(d.key,c);break;case"clipboard":{await c.assertOwned();let k=this.timer.now();try{await this.dependencies.pasteboard.write(R,typeof D==="string"?D:"",c.signal)}finally{c.recordPhase?.("simctl:pbcopy",this.timer.now()-k)}await c.assertOwned();break}case"biometric-enrollment":await this.revertBiometricEnrollment(d,c);break;default:await this.revertByCommand(d,c)}}async revertByCommand(d,c){let R=this.revertCommand(d,c.scope.deviceId);try{await this.command(c,R)}catch(D){if(R[0]!=="spawn"||R[3]!=="delete"||!_S(D))throw u(D,"iOS reset command failed");e.debug(`iOS reset preference already absent: ${r(D)}`),c.signal.throwIfAborted(),await c.assertOwned()}}async revertBiometricEnrollment(d,c){let R=ns(d);if(R===void 0)throw new t("iOS cannot restore an unreadable biometric enrollment");let D=await this.command(c,Au(c.scope.deviceId,R));if(lP(D.stdout)!==R)throw new t("iOS biometric enrollment did not read back as restored")}revertCommand(d,c){switch(d.kind){case"keychain":return["keychain",c,"reset"];case"permission":return["privacy",c,"reset","all",...d.key==="device"?[]:[d.key]];case"location":return["location",c,"clear"];case"status-bar":return["status_bar",c,"clear"];case"device-setting":return this.settingCommand(d,c);case"preference":return this.preferenceCommand(d,c);default:throw new t(`Unsupported iOS reset command ${d.kind}`)}}settingCommand(d,c){let R=d.priorValue.state==="present"?d.priorValue.value:void 0,D=fs(d.key);if(["appearance","nightMode","content-size","increase-contrast"].includes(D))return["ui",c,D==="content-size"?"content_size":D==="increase-contrast"?"increase_contrast":"appearance",String(R)];let k=Lu(d.key);if(k)return Gb(c,k,R);let P=$u(d.key);if(!P)throw new t(`Unsupported iOS setting ${d.key}`);return["spawn",c,"defaults",R===void 0?"delete":"write",".GlobalPreferences",P,...R===void 0?[]:Array.isArray(R)?["-array",...R.map(String)]:typeof R==="boolean"?["-bool",String(R)]:["-string",String(R)]]}preferenceCommand(d,c){let R=d.priorValue.state==="present"?d.priorValue.value:void 0,[D,k]=d.key.split(":");return["spawn",c,"defaults",R===void 0?"delete":"write",D,k,...R===void 0?[]:[typeof R==="boolean"?"-bool":typeof R==="number"?Number.isInteger(R)?"-int":"-float":"-string",String(R)]]}sanitizeCovers(d,c){if(d.kind==="shared-file")return Jb(d,c);if(["installed-app","app-group",...xu,"certificate","media"].includes(d.kind))return!0;return d.kind==="device-setting"&&(["appearance","nightMode","content-size","increase-contrast"].includes(fs(d.key))||Object.hasOwn(on,d.key))}async sanitize(d){if(await d.assertOwned(),!d.baseline?.completeKinds.includes("installed-app"))throw new t("iOS reset requires a captured app baseline; erase required");let c=this.timer.now(),R=await this.dependencies.simctl.listAppsOrThrow(d.scope.deviceId,{signal:d.signal,timeoutMs:1e4}).finally(()=>d.recordPhase?.("app-inventory",this.timer.now()-c));await d.assertOwned();let D=new Set(d.baseline?.observations.filter((C)=>C.kind==="installed-app"&&C.value.state==="present").map((C)=>C.key)),k=R.filter((C)=>C.ApplicationType==="User").filter((C)=>{let M=pn(C);if(!M)throw new t("iOS reset app inventory contains an unidentified bundle");return!D.has(M)}),P=k.length>0?await this.appGroupCleanup(d):void 0;for(let C of k){let M=pn(C);await this.terminate(M,d),await this.clearAppGroups(M,d,P),await this.command(d,["uninstall",d.scope.deviceId,M])}for(let C of xu)await this.revert({kind:C,key:"device",priorValue:{state:"absent"},toolName:"baseline-reset"},d);await this.resetSurvivingPrivacyGrants(d),await this.assertNoUserTrustedCertificates(d),await this.restoreSettings(d),await this.sanitizeResidue(d)}async sanitizeResidue(d){if(await d.assertOwned(),!Eu(d.baseline)||!d.baseline)throw new t("iOS reset requires a residue baseline; erase required");let c=Bu(d.baseline),R=async(k)=>{let P=this.timer.now();try{let C=await this.dependencies.residue.read(d.scope.deviceId,d.signal);return await d.assertOwned(),C}finally{d.recordPhase?.(k,this.timer.now()-P)}},D=ls(c,await R("residue:inspect"));if(D.unrevertible.length>0)throw new t(`${D.unrevertible.join("; ")}; erase required`);if(us(D))return;for(let{area:k,names:P}of D.removals)await d.assertOwned(),await this.dependencies.residue.removeEntries(d.scope.deviceId,k,P,d.signal);for(let[k,P]of[[NY,D.keyboard],[FY,D.accessibility]])for(let{key:C,prior:M}of P)await this.revert({kind:"preference",key:`${k}:${C}`,priorValue:M===void 0?{state:"absent"}:{state:"present",value:M},toolName:"baseline-reset"},d);if(!us(ls(c,await R("residue:verify"))))throw new t("iOS out-of-band residue survived reset; erase required")}async assertNoUserTrustedCertificates(d){await d.assertOwned(),d.signal.throwIfAborted();let c=this.timer.now();try{let R=await this.dependencies.trustStore.readUserTrustedCertificates(d.scope.deviceId,d.signal);if(await d.assertOwned(),d.signal.throwIfAborted(),R.length>0)throw new t(`iOS reset cannot remove ${R.length} user-trusted root certificate(s); erase required`)}finally{d.recordPhase?.("trust-store:verify",this.timer.now()-c)}}async resetSurvivingPrivacyGrants(d){let c=d.scope.deviceId,R=async()=>{await d.assertOwned(),d.signal.throwIfAborted();let C=this.timer.now();try{return await this.dependencies.privacyGrants.readServiceRows(c,Ane,d.signal)}catch(M){throw u(M,"iOS privacy grant verification failed")}finally{d.recordPhase?.("tcc:privacy-verify",this.timer.now()-C)}},D=await R();if(await d.assertOwned(),d.signal.throwIfAborted(),D.length===0)return;let k=[...new Set(D.map((C)=>C.client))].sort();e.warn(`iOS privacy grants survived global reset; resetting clients: ${k.join(", ")}`);for(let C of k)await this.command(d,["privacy",c,"reset","all",C]);let P=await R();if(await d.assertOwned(),d.signal.throwIfAborted(),P.length>0)throw new t("iOS privacy grants survived reset: "+P.map((C)=>`${C.service}:${C.client}`).join(", "))}async restoreSettings(d){let c={appearance:{state:"present",value:"light"},"content-size":{state:"present",value:"large"},"increase-contrast":{state:"present",value:"disabled"},...Object.fromEntries(Object.keys(on).map((R)=>[R,{state:"absent"}]))};for(let[R,D]of Object.entries(c)){let k=d.baseline?.observations.find((C)=>C.kind==="device-setting"&&C.key===R)??(R==="appearance"?d.baseline?.observations.find((C)=>C.kind==="device-setting"&&C.key==="nightMode"):void 0),P={kind:"device-setting",key:R,priorValue:k?.value??D,toolName:"baseline-reset"};if(!this.canRevert(P))e.warn(`iOS reset using simulator default for unsupported baseline setting ${R}`),P.priorValue=D;await this.revert(P,d)}}async command(d,c){let R=this.timer.now();try{d.signal.throwIfAborted(),await d.assertOwned();let D=await this.dependencies.simctl.executeCommandArgs(c,1e4,d.signal);if(D.error)throw new t(`iOS reset ${c[0]} failed: ${D.error}`);return await d.assertOwned(),d.signal.throwIfAborted(),D}finally{d.recordPhase?.(`simctl:${c[0]}`,this.timer.now()-R),d.recordPhase?.(`simctl:${c[0]}:${c.slice(2,c[0]==="spawn"?6:3).join(":")}`,this.timer.now()-R)}}async clearAppGroups(d,c,R){let D=await this.appGroups(d,c);if(Object.keys(D).length===0)return;let k=R??await this.appGroupCleanup(c);this.excludeSharedGroups(D,k);for(let P of Object.values(D)){if(await c.assertOwned(),k.removedPaths.has(P))continue;let{isAbsolute:C,normalize:M,sep:F}=$b,q=`${F}${c.scope.deviceId}${F}data${F}Containers${F}Shared${F}AppGroup${F}`;if(!C(P)||M(P)!==P||!P.includes(q)||P.slice(P.indexOf(q)+q.length).includes(F)||P.endsWith(F)||await this.dependencies.files.realpath(P)!==P)throw new t("iOS reset refused an unproven app-group container path");await c.assertOwned();let U=this.timer.now();try{await this.dependencies.files.remove(P),k.removedPaths.add(P)}finally{c.recordPhase?.("app-group-remove",this.timer.now()-U)}await c.assertOwned()}}async appGroupCleanup(d){let c={baselineIds:new Set,baselinePaths:new Set,removedPaths:new Set};for(let R of d.baseline?.observations.filter((D)=>D.kind==="installed-app"&&D.value.state==="present"&&D.value.value!==null&&typeof D.value.value==="object"&&!Array.isArray(D.value.value)&&D.value.value.ApplicationType==="User")??[]){let D=await this.appGroups(R.key,d);for(let[k,P]of Object.entries(D))c.baselineIds.add(k),c.baselinePaths.add(P)}return c}excludeSharedGroups(d,c){for(let[R,D]of Object.entries(d))if(R.startsWith("group.com.apple.")||c.baselineIds.has(R)||c.baselinePaths.has(D))e.warn(`iOS reset retained protected or baseline-shared app-group ${R}`),delete d[R]}async terminate(d,c){try{await this.command(c,["terminate",c.scope.deviceId,d])}catch(R){if(!bf(r(R)))throw u(R,"iOS reset could not terminate app");e.debug(`iOS reset app already terminated: ${r(R)}`),await c.assertOwned()}}async appGroups(d,c){let R=await this.command(c,["get_app_container",c.scope.deviceId,d,"groups"]),D={};for(let k of R.stdout.split(`
23
+ `).filter((P)=>P.trim()!=="")){let P=k.split("\t");if(P.length!==2||!P[0]||!P[1]||Object.hasOwn(D,P[0]))throw new t("iOS reset received invalid app-group inventory");D[P[0]]=P[1]}return D}}function gs(d,c){let R=new Set,D=new fR({timer:c});return new hs({simctl:d,privacyGrants:D,trustStore:D,residue:new LY({simctl:d,files:mj,deviceSetRoot:Og(Xb())}),files:{realpath:zb,remove:(k)=>Yb(k,{recursive:!0,force:!1})},pasteboard:{assertSettled:(k)=>{if(R.has(k))throw u(new DOMException("iOS pasteboard child teardown remains unconfirmed","TimeoutError"),"Cannot redrive iOS reset")},write:async(k,P,C)=>{C.throwIfAborted();let M=await d.startCommandArgs(["pbcopy",k],{stdio:["pipe","ignore","pipe"]}),F=Ug(M,[]);R.add(k),M.once("exit",()=>R.delete(k));let q=()=>{M.kill("SIGTERM")},U=(W)=>{q(),K=W},K;C.addEventListener("abort",q,{once:!0}),M.stdin?.on("error",U);try{if(C.aborted||!M.stdin)q();else M.stdin.end(P);if(await un(M,F.exitPromise,{timer:c,signal:null,timeoutMs:1e4,forceKillTimeoutMs:1000}),C.throwIfAborted(),K||!M.stdin||F.exitState.exitCode!==0)throw new t("iOS reset could not restore the pasteboard",{cause:K})}catch(W){if(W instanceof $p)throw u(new DOMException(r(W),"TimeoutError"),"iOS pasteboard teardown remains unconfirmed");throw u(W,"iOS reset pasteboard command failed")}finally{if([M.exitCode!==null,M.signalCode!==null,M.pid===void 0].some(Boolean))R.delete(k);C.removeEventListener("abort",q),M.stdin?.off("error",U)}}}},c)}function qu(d){return{probe:async(c,R)=>{let D=ve.registry.peek(c.deviceId);if(!D)return!1;return new zk(void 0,d,{deviceId:c.deviceId,useRemoteRunner:()=>!1,getHost:()=>"127.0.0.1"}).checkHealthEndpointOnPortForDevice(D.getServicePort(),c.deviceId,5000,{signal:R,requireDeviceId:!0})}}}async function sn(d,c,R){if(R.signal.throwIfAborted(),await R.assertOwned(),await d.getBaseline(R.scope))return;let D=await c.capture(R);if(await R.assertOwned(),R.signal.throwIfAborted(),D.completeKinds.length===0&&D.observations.length===0)throw new t("Device baseline capture returned no observable inventory");await d.captureBaseline(R.scope,D)}var Uu=4,dn=2000,vs=2000,Qb=Q({initialDelayMs:250,multiplier:2,maxDelayMs:2000});function lt(d,c,R=Uu){return Math.min(d,Math.max(dn,Math.floor(d/2**(R-c+2))))}function bs(d){if(!(d instanceof Error)||d.name==="AbortError")return!1;return d instanceof ht||/timed out after \d+ms/.test(d.message)}function mn(d,c){let R=d.now(),D=c-R;return R+Math.min(D,Math.max(dn,Math.floor(D/4)))}async function Ku(d,c){await d.timer.sleep(Math.min(Qb.delayForAttempt(c),Math.max(0,d.deadlineMs-d.timer.now()))),d.signal?.throwIfAborted()}async function Et(d,c){let R=c.attempts??Uu;for(let D=1;;D++){c.signal?.throwIfAborted();let k=c.deadlineMs-c.timer.now();if(k<=0)throw new t(`${c.label} exceeded the reset budget`);let P=Math.min(k,Math.max(c.minAttemptMs??0,lt(k,D,R)));try{let C=await d(P);return c.signal?.throwIfAborted(),C}catch(C){if(c.signal?.throwIfAborted(),!bs(C)||D>=R||c.timer.now()>=c.deadlineMs)throw C;e.warn(`${c.label} timed out; retrying (attempt ${D+1})`,C)}await Ku(c,D)}}async function fn(d,c){for(let R=1;;R++){c.signal?.throwIfAborted();let D=c.deadlineMs-c.timer.now();if(D<=0)return!1;let k=await d(lt(D,Math.min(R,2)));if(c.signal?.throwIfAborted(),c.timer.now()>=c.deadlineMs)return!1;if(k)return!0;await Ku(c,R)}}var ws=600000,Gu=3;function Wu(d,c){return d.fullBaseline?!c.madeHostSideChanges():c.canReset()}function Zb(d){return bs(d)}function Vu(d,c){let R=!0,D=!1,k=!1,P=d.onSessionExecutionEnded((C,M)=>{if(C.includes(c)&&M.admitted)R=!1,D||=uee(M.toolName),k||=lee(M.toolName)});return{canReset:()=>R,madeOpaquePersistentChanges:()=>D,madeHostSideChanges:()=>k,close:P}}class ks{dependencies;baselines=new Map;constructor(d){this.dependencies=d}get canCapture(){return this.dependencies.strategy!==void 0}async capture(d,c,R,D){let{sessionId:k}=D;if(this.closeBaseline(d),!this.dependencies.strategy)return;let P=this.dependencies.watchSession(k),C=D.timer??i,M=C.now()+(D.timeoutMs??2000),F=new AbortController,q=D.signal?AbortSignal.any([D.signal,F.signal]):F.signal,U=(W,V,z)=>{q.throwIfAborted();let J=M-C.now();if(J<=0)throw new t("Android reset baseline capture exceeded preparation deadline");return l(async()=>{await D.assertOwned?.(),q.throwIfAborted();let X=await W(z===void 0?Math.min(2000,J):Math.min(J,Math.max(2000,Math.floor(J/z))));return q.throwIfAborted(),await D.assertOwned?.(),X},{timer:C,timeoutMs:J,signal:q,label:V,timeoutError:()=>new t("Android reset baseline capture exceeded preparation deadline"),onTimeout:()=>F.abort(new t("Android reset baseline capture exceeded preparation deadline"))})},K=async(W,V,z=!1)=>{for(let J=1;;J++)try{let X=z?Gu-J+1:void 0;return await U(W,V,X)}catch(X){if(!(J<Gu&&!q.aborted&&M-C.now()>0&&Zb(X)))throw X;e.warn(`${V} timed out; retrying (attempt ${J+1})`)}};try{await K((J)=>this.assertTarget(c,R,q,{timeoutMs:J}),"Android reset baseline target verification",!0);let W=await K((J)=>this.packages(c,q,J),"Android reset baseline package inventory"),V=this.dependencies.strategy.handlesSessionMutations?await K((J)=>this.bootIdentity(c,q,J),"Android reset boot identity"):void 0,z=Ye({platform:"android",resourceId:d,stableDeviceId:D.stableDeviceId,bootId:V??null});if(this.dependencies.strategy.capture){if(this.dependencies.strategy.fullBaseline&&!D.assertOwned)throw new t("Android snapshot capture requires exclusive binding ownership");await this.dependencies.strategy.capture(c,{fresh:D.fresh,resourceId:d,sessionId:k,incarnation:z,signal:q,timeoutMs:Math.max(0,M-C.now()),assertOwned:async()=>{if(await D.assertOwned?.(),await this.assertTarget(c,R,q,{timeoutMs:Math.max(1,M-C.now()),allowPendingName:!0}),V)await this.assertBootIdentity(c,V,q);await D.assertOwned?.()}})}return this.baselines.set(d,{device:{...c},profile:{...R},packages:W,activity:P,sessionId:k,incarnation:z,stableDeviceId:D.stableDeviceId,bootId:V,timer:C}),{bootId:V??null}}catch(W){throw P.close(),await this.forget(d),u(W,"Cannot capture Android reset baseline")}}async forget(d,c=!0){if(this.closeBaseline(d),c)try{await this.dependencies.strategy?.forget?.(d)}catch(R){e.warn("Android reset baseline pruning failed; continuing teardown",R)}}closeBaseline(d){this.baselines.get(d)?.activity.close(),this.baselines.delete(d)}async reset(d,c,R,{assertOwned:D,signal:k}){let P={outcome:"pending",mode:"none",phases:{}},C=this.dependencies.timer??this.baselines.get(d)?.timer??i,M=this.dependencies.resetTimeoutMs??ws;if(!Number.isSafeInteger(M)||M<=0)throw new t("Android reset timeout must be a positive integer in milliseconds");let F=C.now()+M,q=new AbortController,U=k?AbortSignal.any([k,q.signal]):q.signal,K=async()=>{U.throwIfAborted(),await D(),U.throwIfAborted()};try{return await l(()=>this.resetWithinDeadline(d,c,R,{assertOwned:K,signal:U,deadlineMs:F,timing:P,timer:C}),{timer:C,timeoutMs:M,signal:U,label:"Android baseline reset",onTimeout:()=>q.abort(new t("Android baseline reset deadline exceeded"))})}catch(W){if(q.abort(W),W instanceof Ci)throw W;throw new Ci(u(W,"Android baseline reset failed").message,{...P,outcome:"pending"},{cause:W})}finally{this.closeBaseline(d)}}async restoreFoldPosture(d,c,R,D){if(c.archetype==="foldable"){if(D.throwIfAborted(),await R(),!this.dependencies.postureReset)throw new t(`Cannot restore Android device '${d.deviceId}' to opened posture: posture reset is unavailable`);await this.dependencies.postureReset.restore(d,D),D.throwIfAborted(),await R()}}requireBaseline(d,c,R){let D=this.baselines.get(d);if(!D||D.device.deviceId!==c.deviceId||D.device.name!==c.name||D.profile.systemImagePackage!==R.systemImagePackage||D.profile.profileId!==R.profileId||D.profile.memoryMb!==R.memoryMb)throw new t("Android reset lacks the original session baseline");return D}async resetWithinDeadline(d,c,R,{assertOwned:D,signal:k,deadlineMs:P,timing:C,timer:M}){let F=this.dependencies.strategy;if(!F)throw await this.forget(d),new t("Android reset cannot prove restoration of unobservable state");let q=this.requireBaseline(d,c,R),U={deadlineMs:P,timer:M,assertOwned:D},K=async()=>{if(await D(),!F.handlesSessionMutations&&!Wu(F,q.activity))throw new t("Android session mutations cannot be restored by this reset");if(await this.assertTarget(c,R,k,{timeoutMs:Math.max(1,P-M.now()),requireBoot:!F.handlesSessionMutations,allowPendingName:!0,budget:U}),q.bootId)await this.assertBootIdentity(c,q.bootId,k,U);await D()};try{if(await K(),!F.fullBaseline&&!F.handlesSessionMutations)await this.assertPackagesMatch(c,q.packages,"Android reset detected untracked package inventory changes",{signal:k,budget:U});let W=(z)=>this.healthCheck(c,R,z?.signal??k,nw(U,z)),V=await F.reset(c,q.packages,F.fullBaseline?async()=>{if(await D(),!F.handlesSessionMutations&&!Wu(F,q.activity))throw new t("Android session mutations cannot be restored by this reset")}:K,{resourceId:d,sessionId:q.sessionId,incarnation:q.incarnation,opaquePersistentChanges:q.activity.madeOpaquePersistentChanges(),foldPostureRestored:R.archetype==="foldable"&&this.dependencies.postureReset!==void 0,signal:k,timeoutMs:P-M.now(),deadlineMs:P,assertOwned:D,assertBindingOwned:D,rebindIncarnation:async()=>{await D(),await this.assertTarget(c,R,k,{timeoutMs:Math.max(1,P-M.now()),allowPendingName:!0,budget:U});let z=await this.bootIdentity(c,k,void 0,U);return await D(),q.bootId=z,q.incarnation=Ye({platform:"android",resourceId:d,stableDeviceId:q.stableDeviceId,bootId:z??null}),q.incarnation},healthCheck:W,resetTiming:C});if(Object.assign(C,V),await K(),await this.restoreFoldPosture(c,R,D,k),await K(),!F.handlesSessionMutations)await this.assertPackagesMatch(c,q.packages,"Android reset did not restore the original package inventory",{signal:k,budget:U});return await W(),await K(),V??"clean"}finally{this.closeBaseline(d)}}async healthCheck(d,c,R,D){if(await D.assertOwned(),await this.assertTarget(d,c,R,{timeoutMs:Math.max(1,D.deadlineMs-D.timer.now()),allowPendingName:!0,budget:D}),await D.assertOwned(),await this.packages(d,R,void 0,D),await D.assertOwned(),!await this.checkCtrlProxy(d,D,R))throw new t("Android reset CtrlProxy health check failed");await D.assertOwned()}async assertTarget(d,c,R,{timeoutMs:D=2000,requireBoot:k=!0,allowPendingName:P=!1,budget:C}={}){let M=nn(c.systemImagePackage);if(![d.platform==="android",/^emulator-\d+$/.test(d.deviceId),d.name.trim().length>0,M?.apiLevel===c.apiLevel,M?.abi===c.abi,M?.tag===c.flavor].every(Boolean))throw new t("Android reset requires an exact emulator and system-image profile");let q=await this.readWithinBudget((U)=>this.dependencies.inventory({signal:R,timeoutMs:U,targetDeviceId:d.deviceId}),R,D,C);if(R?.throwIfAborted(),!tw(q,d,c,P))throw new t("Fresh Android inventory did not prove the exact online reset target");if(k)await this.assertBoot(d,R,rw(D,C),C)}async assertBoot(d,c,R=2000,D){let k=await this.readWithinBudget((P)=>this.dependencies.adb(d).executeCommand("shell getprop sys.boot_completed",{timeoutMs:P,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,D);if(k.stdout.trim()!=="1"||je(k.stdout,k.stderr))throw new t("Android reset target has not completed boot")}async bootIdentity(d,c,R=2000,D){c?.throwIfAborted();let k=await this.readWithinBudget((C)=>this.dependencies.adb(d).executeCommand("shell cat /proc/sys/kernel/random/boot_id",{signal:c,timeoutMs:C,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,D);c?.throwIfAborted();let P=k.stdout.trim();if(k.error||k.stderr.trim()||!/^[a-f\d]{8}-(?:[a-f\d]{4}-){3}[a-f\d]{12}$/i.test(P))throw new t("Android reset cannot read emulator boot identity");return P}async assertBootIdentity(d,c,R,D){if(await this.bootIdentity(d,R,void 0,D)!==c)throw new t("Android reset target changed emulator boot identity")}async checkCtrlProxy(d,c,R){let D=new AbortController,k=R?AbortSignal.any([R,D.signal]):D.signal,P=mn(c.timer,c.deadlineMs),C=()=>new t("Android reset CtrlProxy health check failed");return l(()=>fn(async(M)=>{await c.assertOwned();let F=await this.dependencies.ctrlProxyReady(d,{signal:k,timeoutMs:M,noRetry:!0});return await c.assertOwned(),F},{timer:c.timer,deadlineMs:P,signal:k,label:"Android reset CtrlProxy health check"}),{timer:c.timer,timeoutMs:Math.max(0,P-c.timer.now()),signal:R,label:"Android reset CtrlProxy health check",timeoutError:C,onTimeout:()=>D.abort(C())})}readWithinBudget(d,c,R,D){if(!D)return d(R);return Et(async(k)=>{await D.assertOwned(),c?.throwIfAborted();let P=await d(k);return await D.assertOwned(),P},{timer:D.timer,deadlineMs:D.deadlineMs,signal:c,label:"Android reset adb"})}async assertPackagesMatch(d,c,R,{signal:D,budget:k}={}){let P=await this.packages(d,D,void 0,k);if(P.size!==c.size||[...c].some((C)=>!P.has(C)))throw new t(R)}async packages(d,c,R=2000,D){let k=await this.readWithinBudget((M)=>this.dependencies.adb(d).executeCommand("shell pm path android",{timeoutMs:M,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,D);if(c?.throwIfAborted(),!k.stdout.trim().startsWith("package:")||k.stderr.trim())throw new t("Android reset package manager is not responsive");let P=await this.readWithinBudget((M)=>this.dependencies.adb(d).executeCommand("shell pm list packages -3",{timeoutMs:M,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,D);if(c?.throwIfAborted(),P.stderr.trim()||je(P.stdout,P.stderr))throw new t("Android reset package manager is not responsive");let C=new Set;for(let M of P.stdout.split(`
24
+ `)){let F=M.trim();if(!F)continue;if(!/^package:[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/.test(F))throw new t("Android reset received an invalid package inventory");C.add(F.slice(8))}return C}}function ew(d,c,R,D){return[d.platform==="android",d.deviceId===c.deviceId,D||d.name===c.name,d.isRunning===!0,d.isRunningStateKnown!==!1,D||d.runtimeId===R.systemImagePackage,D||d.deviceType===R.profileId,D||d.apiLevel===R.apiLevel].every(Boolean)}function tw(d,c,R,D){let k=d.filter((M)=>M.deviceId===c.deviceId||M.name===c.name),P=k[0];if(k.length!==1||!P)return!1;let C=D&&Sa(P.name,c.deviceId);return ew(P,c,R,C)}function nw(d,c){return{...d,deadlineMs:Math.min(d.deadlineMs,c?.deadlineMs??d.deadlineMs),assertOwned:c?.assertOwned??d.assertOwned}}function rw(d,c){return c?d:Math.min(2000,d)}import{isDeepStrictEqual as gn}from"util";import{createHash as Ju}from"crypto";var hn=["device-setting","account"],ow={"installed-app":"Package membership is observed for all users; package identities are captured only for third-party apps, not system app updates",permission:"Runtime grants and flags are observed for third-party packages and users; system grants, AppOps and other permission stores are not fully inventoried","shared-file":"Public roots are hashed; other roots, directories, symlinks and secondary-user storage are not fully observed or restorable",clock:"Timezone is observed; wall clock and alarm state are not fully observable"},sw=["global","secure","system"],As=["/sdcard/Download","/sdcard/DCIM","/sdcard/Pictures","/sdcard/Movies","/sdcard/Documents"],Is="/sdcard/Download",Cs="download-entries";function Qe(d){return d.startsWith("/sdcard/")&&!d.split("/").slice(1).some((c)=>c==="."||c===".."||c==="")&&!/[\x00-\x1f\x7f\\]/.test(d)}async function ju(d){let c=[],R=(P,C,M)=>{c.push({kind:P,key:C,value:M===null?{state:"absent"}:{state:"present",value:M}})},D=await Os(d);await uw(d,R,D),await aw(d,R,D),await dw(d,R),R("device-setting","locale",await d("shell getprop persist.sys.locale")),R("clock","timezone",await d("shell getprop persist.sys.timezone"));for(let[P,C]of Ms(await d("shell dumpsys account"),D))R("account",Ts(P),C);await cw(d,R);let k=HS.filter((P)=>!hn.some((C)=>C===P));return{completeKinds:[...hn],observations:c,unobservable:k,unobservableReasons:Object.fromEntries(k.map((P)=>[P,ow[P]??"No complete Android observation and restoration contract is available"]))}}function Ts(d){return`user:${d}`}function Ms(d,c){let R=d.split(/\r?\n/),D=new Map;for(let k of c){let P=R.findIndex((F)=>new RegExp(`^User UserInfo\\{${k}:[^\\n]*\\}:\\s*$`).test(F)),C=/^\s*Accounts: (\d+)\s*$/.exec(R[P+1]??"")?.[1];if(P<0||C===void 0)throw new t(`Android account inventory is unreadable for user ${k}`);let M=R.slice(P+2,P+2+Number(C)).map((F)=>F.trim());if(M.length!==Number(C)||M.some((F)=>!/^Account \{.+\}$/.test(F)))throw new t(`Android account inventory is malformed for user ${k}`);D.set(k,Es(M))}return D}function Es(d){return Ju("sha256").update(JSON.stringify([...d].sort())).digest("hex")}async function aw(d,c,R){for(let D of sw)for(let k of D==="global"?[0]:R){let P=await d(`shell settings --user ${k} list ${D}`);Bs(P,D,k,c)}}function Bs(d,c,R,D){let k=new Set;for(let P of d.split(`
25
+ `).filter(Boolean)){let C=P.indexOf("="),M=P.slice(0,C);if(C<1||!/^[A-Za-z0-9_]\S*$/.test(M)||k.has(M))throw new t(`Android baseline ${c} settings inventory is malformed`);k.add(M),D("device-setting",R===0?`${c}:${M}`:`${c}:user:${R}:${M}`,P.slice(C+1))}}async function dw(d,c){c("device-setting","display:density",mi(await d("shell wm density"),"density")),c("device-setting","display:size",mi(await d("shell wm size"),"size")),c("device-setting","display:night-mode",xs(await d("shell cmd uimode night")))}async function cw(d,c){let D=(await d("shell find /sdcard/ -mindepth 1 -maxdepth 1 -print")).split(`
26
+ `).filter(Boolean).sort();if(new Set(D).size!==D.length||D.some((k)=>!Qe(k)||k.slice(8).includes("/")))throw new t("Android baseline shared-storage root inventory is malformed");c("shared-file","roots",Ju("sha256").update(JSON.stringify(D)).digest("hex")),await lw(d,c);for(let k of As){let P=`if [ -d ${b(k)} ]; then find ${b(k)} -type f -exec sha256sum {} \\;; elif [ -e ${b(k)} ]; then exit 1; fi`,C=await d(`shell sh -c ${b(P)}`,30000);for(let M of C.split(`
27
+ `).filter(Boolean)){let F=/^([a-fA-F0-9]{64}) (.+)$/.exec(M),q=F?.[2];if(!F?.[1]||!q||!q.startsWith(`${k}/`)||!Qe(q))throw new t("Android baseline shared-file inventory is malformed");c("shared-file",q,F[1].toLowerCase())}}}async function lw(d,c){let R=Is,D=`if [ -d ${b(R)} ]; then find ${b(R)} -mindepth 1 -maxdepth 1 -print; elif [ -e ${b(R)} ]; then exit 1; fi`,k=(await d(`shell sh -c ${b(D)}`)).split(`
28
+ `).filter(Boolean).sort();if(new Set(k).size!==k.length||k.some((P)=>!P.startsWith(`${R}/`)||!Qe(P)||P.slice(R.length+1).includes("/")))throw new t("Android baseline Downloads entry inventory is malformed");c("shared-file",Cs,JSON.stringify(k))}async function Os(d){let c=await d("shell pm list users"),R=Uz(c).map((k)=>k.userId),D=c.split(`
29
+ `).filter((k)=>k.trim());if(D[0]?.trim()!=="Users:"||D.length!==R.length+1||!R.includes(0)||R.some((k)=>!Number.isSafeInteger(k))||new Set(R).size!==R.length||D.slice(1).some((k)=>!/^\s*UserInfo\{\d+:[^:]+:[a-fA-F0-9]+\}(?: running)?\s*$/.test(k)))throw new t("Android baseline user inventory is malformed");return R.sort((k,P)=>k-P)}function ui(d){let c=d.split(`
30
+ `).filter((R)=>R.trim()).map((R)=>{let D=/^package:([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)$/.exec(R.trim());if(!D?.[1])throw new t("Android baseline package inventory is malformed");return D[1]});if(new Set(c).size!==c.length)throw new t("Android baseline package inventory has duplicates");return c.sort()}async function uw(d,c,R){let D=new Map;if(!new Set(ui(await d("shell pm list packages -s -u"))).has("android"))throw new t("Android baseline system package inventory is incomplete");let P=new Set;for(let C of R){c("installed-app",`users:${C}`,!0);let M=ui(await d(`shell pm list packages --user ${C}`)),F=ui(await d(`shell pm list packages -3 --user ${C}`));if(!M.includes("android")||F.some((q)=>!M.includes(q)))throw new t("Android baseline package inventory is incomplete");D.set(C,M);for(let q of M)c("installed-app",`user:${C}:${q}`,!0);for(let q of F)P.add(q)}for(let C of[...P].sort())await pw(d,c,C,R.filter((M)=>D.get(M)?.includes(C)))}async function pw(d,c,R,D){let k=await d(`shell dumpsys package ${b(R)}`),P=new RegExp(`^\\s*Package \\[${R.replaceAll(".","\\.")}\\] \\([^\\n]+\\):\\s*$`,"m").exec(k),C=P?k.slice(P.index+P[0].length).split(/^\s*Package \[/m)[0]:"",M=/^\s*lastUpdateTime=(.+)$/m.exec(C)?.[1],F=/^\s*versionCode=(\d+)\b/m.exec(C)?.[1],q=/^\s*codePath=(.+)$/m.exec(C)?.[1];if(!M||!F||!q)throw new t(`Android baseline cannot read package identity for ${R}`);c("installed-app",`identity:${R}`,JSON.stringify([M,F,q]));for(let U of D){let K=wn(k,R,U);if(!K||!new RegExp(`^\\s*User ${U}:.*\\binstalled=true\\b`,"m").test(C))throw new t(`Android baseline cannot read permissions for ${R} user ${U}`);for(let[W,V]of K.runtimePermissions)c("permission",`runtime:${U}:${R}:${W}`,V.state==="granted"),c("permission",`runtime-flags:${U}:${R}:${W}`,JSON.stringify(V.raw))}}function mi(d,c){let R=d.split(`
31
+ `),D=c==="density"?"[0-9]+":"[0-9]+x[0-9]+",k=new RegExp(`^Physical ${c}: ${D}$`),P=new RegExp(`^Override ${c}: (${D})$`);if(!R[0]||!k.test(R[0])||R.length>2)throw new t(`Android baseline display ${c} is unreadable`);if(R.length===1)return null;let C=P.exec(R[1]);if(!C?.[1])throw new t(`Android baseline display ${c} is unreadable`);return C[1]}function xs(d){let c=/^Night mode: (yes|no|auto|custom)$/.exec(d);if(!c?.[1])throw new t("Android baseline night mode is unreadable");return c[1]}function Fs(d){return/^(?:global|secure):(?:user:\d+:)?(?:adb_enabled|adb_wifi_enabled|development_settings_enabled|airplane_mode_on|wifi_on|mobile_data|enabled_accessibility_services|accessibility_enabled)$/.test(d)}function Ns(d){if(["installed-app","clipboard","rotation","screen-reader","keep-awake","opened-url"].includes(d.kind))return!0;let c=/^(?:global|secure|system):/.test(d.key);return d.kind==="device-setting"&&(c||d.key.startsWith("display:")||d.key===PS||["density","nightMode"].includes(d.key))}function mw(d){let c=d.observations.find((R)=>R.kind==="shared-file"&&R.key===Cs);if(c?.value.state!=="present"||typeof c.value.value!=="string")return;try{let R=JSON.parse(c.value.value);return Array.isArray(R)&&R.every((D)=>typeof D==="string")?new Set(R):void 0}catch(R){e.debug("Android baseline Downloads inventory is not JSON",R);return}}function fw(d){let c=d.observations.filter((R)=>R.kind==="installed-app"&&R.key.startsWith("users:")&&R.value.state==="present").map((R)=>R.key);return c.length===1&&c[0]==="users:0"}function hw(d){let c;try{c=JSON.parse(d.key)}catch(D){e.debug("Android journal file key is not JSON; not a user_files scope",D);return}let R=d.kind==="media"?5:d.kind==="shared-file"?6:-1;return Array.isArray(c)&&c.length===R&&c[0]==="user_files"&&c[1]===null&&c[2]===null&&typeof c[3]==="string"&&(R===5||typeof c[5]==="string")?{namespace:c[3],user:c[4]}:void 0}function gw(d){let c=d.trim(),R=`${Is}/${c}`;return c.length>0&&!/[/\\]/.test(c)&&Qe(R)?R:void 0}function Yu(d,c){let R=c?hw(d):void 0;if(!c||!R)return;let D=gw(R.namespace),k=mw(c);return(R.user===0||R.user==="default"&&fw(c))&&D!==void 0&&k!==void 0&&!k.has(D)&&!c.observations.some((P)=>P.kind==="shared-file"&&P.key.startsWith(`${D}/`))?D:void 0}function Xu(d,c){if(!c||d.kind!=="shared-file"&&d.kind!=="media")return!1;let R=d.kind==="shared-file"?MH(d.key):void 0;return R!==void 0?!hA(c,R):Yu(d,c)!==void 0}var zu={rotation:["system:accelerometer_rotation","system:user_rotation"],"screen-reader":["secure:enabled_accessibility_services","secure:accessibility_enabled"],"keep-awake":["global:stay_on_while_plugged_in","system:screen_off_timeout"]};function vw(d){let c=new Set(d.filter((k)=>k.kind==="device-setting"&&k.priorValue.state==="absent"&&/^(?:global|system|secure):/.test(k.key)).map((k)=>k.key)),R=new Set(d.flatMap((k)=>(k.kind in zu)?[k.kind]:[])),D=new Set([...R].flatMap((k)=>zu[k]??[]));return(k)=>c.has(k)||D.has(k.replace(/^(\w+):user:\d+:/,"$1:"))}var yw=/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/,Sw=["android","com.android.bluetooth","com.android.externalstorage","com.android.inputmethod","com.android.keychain","com.android.launcher3","com.android.location.fused","com.android.networkstack","com.android.nfc","com.android.packageinstaller","com.android.permissioncontroller","com.android.phone","com.android.providers","com.android.se","com.android.server.telecom","com.android.shell","com.android.systemui","com.android.vending","com.google.android.apps.nexuslauncher","com.google.android.ext.services","com.google.android.gms","com.google.android.gsf","com.google.android.inputmethod","com.google.android.networkstack","com.google.android.packageinstaller","com.google.android.permissioncontroller","dev.jasonpearson.automobile"];function bw(d){return Sw.some((c)=>d===c||d.startsWith(`${c}.`))}function ww(d,c,R){return d.get(`installed-app:user:${c}:${R}`)?.state==="present"&&!d.has(`installed-app:identity:${R}`)}function Rw(d){let c=d.split(`
32
+ `).map((R)=>R.trim()).filter(Boolean);if(c.length===1&&c[0]==="No activities found")return[];if(c.length===0)throw new t("Android cleaning read an empty URL handler inventory");return c.map((R)=>{let D=/^([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)\/[A-Za-z0-9_.$]+$/.exec(R);if(!D?.[1])throw new t("Android cleaning cannot read the URL handler inventory");return D[1]})}async function Qu(d,c,R,{revert:D,journalEntries:k=[]}){let P=new Set(k.flatMap((C)=>Yu(C,d)??[]));await new tp(d,c,R,{revert:D,journal:{sessionCreated:vw(k),userFilesNamespaces:[...P].sort(),launches:Dw(k)}}).clean()}function Dw(d){let c=new Set,R=new Set;for(let D of d){let k=B7(D);if(k===null)throw new t("Android cleaning cannot read a journaled app launch");let P=D.kind==="opened-url"?D.key.trim():"";if(k!==void 0)c.add(k);else if(P.startsWith("package:"))c.add(P.slice(8));else if(P)R.add(P)}return{packages:c,urls:R}}class tp{baseline;context;command;prior;revert;journal;constructor(d,c,R,{revert:D,journal:k}){this.baseline=d;this.context=c;this.command=R;this.revert=D,this.journal=k,this.prior=new Map(d.observations.map((P)=>[`${P.kind}:${P.key}`,P.value]))}restore(d,c,R){return this.revert({kind:d,key:c,priorValue:R,toolName:"keep-booted-cleaning"})}async clean(){let d=await Os(this.command),c=await this.sessionStartedPreinstalledApps(d);await this.cleanPackages(d);for(let[R,D]of c)await this.restore("preference",`app-data:${R}:${D}`,{state:"absent"});await this.cleanDisplay();for(let R of["global","system","secure"])for(let D of R==="global"?[0]:d)await this.cleanSettings(R,D);await this.cleanFiles();for(let R of this.journal.userFilesNamespaces)await this.removeNamespaceDirectory(R);await this.cleanTimezone(),await this.verifyLocale(),await this.verifyAccounts(d)}baselineString(d,c){let R=this.prior.get(`${d}:${c}`);return R?.state==="present"&&typeof R.value==="string"?R.value:void 0}async cleanTimezone(){let d=this.baselineString("clock","timezone");if(await this.command("shell getprop persist.sys.timezone")===d)return;if(!d)throw new t("Android cleaning cannot restore a time zone the baseline lacks");await this.restore("clock","timezone",{state:"present",value:d})}async verifyLocale(){let d=this.baselineString("device-setting","locale");if(d===void 0||await this.command("shell getprop persist.sys.locale")!==d)throw new t("Android cleaning found a changed device locale")}async verifyAccounts(d){let c=this.baseline.observations.filter((P)=>P.kind==="account"&&/^user:\d+$/.test(P.key)).map((P)=>Number(P.key.slice(5)));if(c.length===0)throw new t("Android baseline has no per-user account inventory");let R=Ms(await this.command("shell dumpsys account"),d),D=Es([]),k=[...new Set([...c,...d])].sort((P,C)=>P-C).filter((P)=>(this.baselineString("account",Ts(P))??D)!==(R.get(P)??D));if(k.length>0)throw new t(`Android cleaning found changed accounts for user ${k.join(", ")}; accounts cannot be restored in place`)}async sessionStartedPreinstalledApps(d){let c=[];for(let R of d){let D=new Set(this.journal.launches.packages);for(let C of this.journal.launches.urls){let M=await this.command(`shell cmd package query-activities --components --user ${R} -a android.intent.action.VIEW -d ${b(C)}`);for(let F of Rw(M))D.add(F)}let k=[...D].filter((C)=>yw.test(C)&&ww(this.prior,R,C)).sort(),P=k.find(bw);if(P)throw new t(`Android cleaning cannot clear data of core package ${P} the session started`);c.push(...k.map((C)=>[R,C]))}return c}async removeNamespaceDirectory(d){let c=b(d),R=b(d.slice(7)),D=`root=$(readlink -f /sdcard) && [ -n "$root" ] && if [ -e ${c} ] || [ -L ${c} ]; then [ ! -L ${c} ] && [ -d ${c} ] && [ "$(readlink -f ${c})" = "$root"${R} ] && find ${c} -depth -type d -exec rmdir {} +; fi && [ ! -e ${c} ] && [ ! -L ${c} ]`;await this.command(`shell sh -c ${b(D)}`)}async readDisplay(){let d=mi(await this.command("shell wm density"),"density"),c=mi(await this.command("shell wm size"),"size"),R=xs(await this.command("shell cmd uimode night"));return new Map([["display:density",d===null?{state:"absent"}:{state:"present",value:d}],["display:size",c===null?{state:"absent"}:{state:"present",value:c}],["display:night-mode",{state:"present",value:R}]])}async cleanDisplay(){let d=await this.readDisplay();for(let[R,D]of d){let k=this.prior.get(`device-setting:${R}`);if(k&&!gn(D,k))await this.restore("device-setting",R,k)}let c=[...await this.readDisplay()].filter(([R,D])=>{let k=this.prior.get(`device-setting:${R}`);return k&&!gn(D,k)}).map(([R])=>R);if(c.length>0)throw new t(`Android cleaning did not restore live display state: ${c.join(", ")}`)}async cleanPackages(d){for(let c of d){let R=ui(await this.command(`shell pm list packages -3 --user ${c}`));for(let D of R)await this.cleanPackage(c,D)}}async cleanPackage(d,c){let R=`user:${d}:${c}`;if(this.prior.get(`installed-app:${R}`)?.state!=="present"){await this.restore("installed-app",R,{state:"absent"});return}let D=await this.command(`shell dumpsys package ${b(c)}`),k=wn(D,c,d);if(!k)throw new t(`Android cleaning cannot read runtime permissions for ${R}`);for(let[P,C]of k.runtimePermissions){let M=`runtime:${d}:${c}:${P}`,F=this.prior.get(`permission:${M}`);if(C.state==="granted"&&!(F?.state==="present"&&F.value===!0))await this.restore("permission",M,{state:"present",value:!1})}}async readSettings(d,c){let R=new Map;return Bs(await this.command(`shell settings --user ${c} list ${d}`),d,c,(D,k,P)=>{R.set(k,P===null?{state:"absent"}:{state:"present",value:P})}),R}async cleanSettings(d,c){let R=await this.readSettings(d,c),D=new Map,k=c===0?`${d}:`:`${d}:user:${c}:`,P=this.baseline.observations.filter((M)=>M.kind==="device-setting"&&M.key.startsWith(k)&&(c!==0||!M.key.startsWith(`${d}:user:`))),C=0;for(let M of new Set([...R.keys(),...P.map((F)=>F.key)])){let F=this.prior.get(`device-setting:${M}`),q=F??{state:"absent"};if(gn(R.get(M)??{state:"absent"},q))continue;if(!F&&!this.journal.sessionCreated(M)){C++;continue}try{await this.restore("device-setting",M,q)}catch(U){if(e.warn(`Android cleaning could not restore setting ${M}`,U),await this.context.assertOwned(),this.context.signal.throwIfAborted(),D.set(M,q),Fs(M))throw U}}if(D.size>0){let M=await this.readSettings(d,c),F=[...D].filter(([q,U])=>!gn(M.get(q)??{state:"absent"},U)).map(([q])=>q);if(F.length>0)throw new t(`Android cleaning settings remain dirty after failed restore: ${F.join(", ")}`)}}async cleanFiles(){for(let d of As){let c=`if [ -d ${b(d)} ]; then find ${b(d)} -type f -print; elif [ -e ${b(d)} ]; then exit 1; fi`,R=(await this.command(`shell sh -c ${b(c)}`)).split(`
33
+ `).filter(Boolean);for(let D of R){if(!D.startsWith(`${d}/`)||!Qe(D))throw new t("Android cleaning shared-file inventory is malformed");if(this.prior.get(`shared-file:${D}`)?.state!=="present")await this.restore("shared-file",D,{state:"absent"})}}}}var kw=s({store:_("preference"),scope:_("systemProperty"),appId:TP(),suite:TP(),userId:TP(),key:n()}),Aw=s({value:n()}),Pw=/^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,255}$/;function Iw(d){return d.startsWith("ro.")||d.startsWith("ctl.")||d==="sys.powerctl"}function vn(d){let c;try{c=JSON.parse(d)}catch(k){return e.debug("Preference journal key is not a JSON identity",k),null}let R=kw.safeParse(c);if(!R.success)return null;let D=R.data.key;return Pw.test(D)&&!Iw(D)?D:null}function ip(d){if(d.state==="absent")return"";if(d.state!=="present")return null;let c=Aw.safeParse(d.value);return c.success&&!/[\r\n\0]/.test(c.data.value)?c.data.value:null}class Ls{dependencies;handlesSessionMutations=!0;sessions=new Map;maxUses;budgetMs;fallbackBudgetMs;constructor(d){this.dependencies=d;if(this.maxUses=d.maxUses??20,this.budgetMs=d.budgetMs,this.fallbackBudgetMs=d.fallbackBudgetMs,!Number.isSafeInteger(this.maxUses)||this.maxUses<=0||[this.budgetMs,this.fallbackBudgetMs].some((c)=>c!==void 0&&(!Number.isFinite(c)||c<=0||c>Ur)))throw new t("Android keep-booted requires positive, bounded reset limits")}async capture(d,c){if(!Number.isFinite(c.timeoutMs)||c.timeoutMs<=0||c.timeoutMs>Ur)throw new t("Android keep-booted capture requires a bounded preparation budget");let R=new AbortController,D=AbortSignal.any([c.signal,R.signal]),k=async()=>{D.throwIfAborted(),await c.assertOwned(),D.throwIfAborted()};try{await l(()=>this.captureSession(d,{...c,signal:D,assertOwned:k}),{timer:this.dependencies.timer,signal:D,timeoutMs:c.timeoutMs,label:"Android keep-booted baseline capture",onTimeout:()=>R.abort(new t("Android keep-booted capture budget exceeded"))})}catch(P){throw R.abort(P),await this.forget(c.resourceId),u(P,"Android keep-booted baseline capture failed")}}async captureSession(d,c){if(!c.sessionId)throw new t("Android keep-booted capture requires a session identity");let R=this.dependencies.timer.now()+c.timeoutMs,D=this.sessions.get(c.resourceId),k=c.incarnation??c.resourceId;if(D&&(D.scope.deviceId!==d.deviceId||D.scope.incarnation!==k))throw new t("Android keep-booted resource changed emulator identity");let P={deviceId:d.deviceId,incarnation:k,sessionUuid:c.sessionId},C=await this.dependencies.journal.getBaseline(P),M=this.dependencies.port(d);if(this.sessions.set(c.resourceId,this.nextSession(P,D,C!==null)),!C){let F=new AbortController,q=AbortSignal.any([c.signal,F.signal]),U=Math.min(c.timeoutMs,this.budgetMs??c.timeoutMs);await l(()=>this.captureBaseline(M,P,{...c,signal:q,timeoutMs:U,assertOwned:async()=>{q.throwIfAborted(),await c.assertOwned(),q.throwIfAborted()}}),{timer:this.dependencies.timer,signal:q,timeoutMs:U,label:"Android keep-booted journal capture",onTimeout:()=>F.abort(new t("Android keep-booted capture budget exceeded"))})}if(await c.assertOwned(),c.signal.throwIfAborted(),!this.sessions.get(c.resourceId)?.retired)await this.dependencies.fallback?.capture?.(d,{...c,timeoutMs:R-this.dependencies.timer.now()});await c.assertOwned(),c.signal.throwIfAborted()}async captureBaseline(d,c,R){await sn(this.dependencies.journal,d,{scope:c,signal:R.signal,assertOwned:R.assertOwned})}nextSession(d,c,R){return{scope:d,uses:c?.scope.sessionUuid===d.sessionUuid?c.uses:(c?.uses??0)+1,retired:c?.retired??R}}async forget(d){try{await this.dependencies.journal.deleteResource(d)}catch(c){e.warn("Android keep-booted journal pruning failed; continuing teardown",c)}this.sessions.delete(d),await this.dependencies.fallback?.forget?.(d)}resetSession(d,c){let R=this.sessions.get(c.resourceId);if(!R||R.scope.sessionUuid!==c.sessionId||R.scope.deviceId!==d.deviceId||R.scope.incarnation!==(c.incarnation??c.resourceId))throw new t("Android keep-booted lacks the fenced session baseline");if(R.retired)throw new t("Android keep-booted restart requires incarnation retirement");return R}async reset(d,c,R,D){let k=D.deadlineMs??this.dependencies.timer.now()+(D.timeoutMs??1/0),P=this.resetSession(d,D),C=this.dependencies.port(d),M=new AbortController,F=D.signal?AbortSignal.any([D.signal,M.signal]):M.signal,q=async()=>{F.throwIfAborted();let z=me(F);try{await H(z,R)}catch(J){if(!z?.aborted)M.abort(J);throw u(J,"Android keep-booted ownership fence failed")}F.throwIfAborted()},U={},K,W,V={scope:P.scope,deadlineMs:k,signal:F,assertOwned:q};try{await q();let z=await this.whyEscalate(P,C,V,{context:D,phases:U});if(await q(),z){W=z;let J=this.dependencies.fallback;if(!J)throw new t(`Android keep-booted is non-clean (${z}); baseline fallback or destruction is required`);e.warn(`Android keep-booted escalating to baseline (${z})`);let X=Math.min(this.fallbackBudgetMs??Ur,k-this.dependencies.timer.now()-vs-1);if(X<=0)throw new t("Android keep-booted has no remaining fallback settlement budget");K={outcome:"pending",mode:"snapshot",phases:{}};let te;try{await l(()=>(te=this.measure("fallback",U,async()=>{let ie=J.fullBaseline?D.assertBindingOwned:q;if(!ie||J.fullBaseline&&!D.rebindIncarnation)throw new t("Android snapshot fallback requires incarnation rebinding");let oe=await J.reset(d,c,ie,{...D,signal:F,timeoutMs:X,assertOwned:ie,deadlineMs:this.dependencies.timer.now()+X,resetTiming:K});if(oe)K=oe;if(oe?.outcome==="pending")throw new t("Android snapshot fallback did not prove a clean reset");for(let[pe,de]of Object.entries(K.phases))U[`snapshot:${pe}`]=de;if(J.fullBaseline){let pe=await D.rebindIncarnation();await this.dependencies.journal.deleteResource(D.resourceId),P.scope={...P.scope,incarnation:pe},V.scope=P.scope,await this.captureBaseline(C,P.scope,{...D,incarnation:pe,signal:F,timeoutMs:X,assertOwned:q})}await q(),await this.measure("health",U,()=>D.healthCheck?.(V)??Promise.resolve()),await q()}),te),{timer:this.dependencies.timer,signal:F,timeoutMs:X,label:"Android keep-booted fallback",onTimeout:()=>M.abort(new t("Android keep-booted fallback budget exceeded"))})}catch(ie){throw M.abort(ie),ie}finally{await this.drainOperation(te)}await q(),this.dependencies.recordingGaps?.clear(V.scope.sessionUuid),P.uses=0;let re=K.mode;return{outcome:re==="wipe-data"?"fallback:wipe-data":"fallback:snapshot",mode:re,phases:U,fallbackReason:[z,K.fallbackReason].filter(Boolean).join("; ")}}return await q(),{outcome:"clean",mode:"keep-booted",phases:U}}catch(z){throw M.abort(z),e.warn(`Android keep-booted reset failed: ${r(z)}`,z),this.resetFailure(z,U,K,W)}}async whyEscalate(d,c,R,{context:D,phases:k}){if(d.uses>=this.maxUses)return"maxUses retirement";if(D.opaquePersistentChanges)return"opaque persistent changes (deviceSnapshot) cannot be journal-reverted";let P=this.dependencies.recordingGaps?.reasonFor(R.scope.sessionUuid);if(P!==void 0)return`device mutation recording failed (${P}); journal is incomplete`;let C=await this.dependencies.journal.listStrayIncarnations(R.scope);if(C.length>0)return`journaled mutations recorded under a different incarnation (${C.length}) cannot be journal-reverted`;let M=await this.dependencies.journal.list(R.scope),F=M.find((U)=>qS(U)&&!(D.foldPostureRestored&&U.key===Bn(...$7)));if(F)return`opaque journaled mutation (${F.toolName}) cannot be journal-reverted`;let q=M.filter((U)=>U.kind==="preference"&&!z6.includes(U.key)&&!np(U,c));if(q.length>0){let U;try{U=await this.dependencies.journal.getBaseline(R.scope)}catch(W){return e.warn("Android app-state baseline is unreadable; baseline fallback required",W),"journaled app state has an unreadable baseline"}let K=q.find((W)=>!$H(W,U));if(K)return`journaled ${K.kind} (${K.toolName}) cannot be baseline-cleaned`}return await this.unrevertibleReason(M,c,R.scope)??this.cleanWithDeadline(c,R,D,k)}async unrevertibleReason(d,c,R){let D=d.filter((C)=>C.kind!=="opaque"&&C.kind!=="preference"&&!Ns(C)&&!c.canRevert(C)),k=null;if(D.some((C)=>C.kind==="shared-file"||C.kind==="media"))try{k=await this.dependencies.journal.getBaseline(R)}catch(C){return e.warn("Android file baseline is unreadable; baseline fallback required",C),"journaled files have an unreadable baseline"}let P=D.find((C)=>!Xu(C,k));return P?`journaled mutation ${P.kind}:${P.key} (${P.toolName}) cannot be journal-reverted`:void 0}resetFailure(d,c,R,D){if(d instanceof Ci)R=d.reset;for(let[k,P]of Object.entries(R?.phases??{}))c[`snapshot:${k}`]=P;return new Ci(u(d,"Android keep-booted requires baseline fallback or destruction").message,{outcome:"pending",mode:R?.mode??"keep-booted",phases:c,fallbackReason:[D,R?.fallbackReason].filter(Boolean).join("; ")||void 0},{cause:d instanceof Ci?d.cause:d})}async measure(d,c,R){let D=this.dependencies.timer.now();try{await R()}finally{c[d]=this.dependencies.timer.now()-D}}async cleanWithDeadline(d,c,R,D){let k=(R.deadlineMs??this.dependencies.timer.now()+(R.timeoutMs??Ur))-this.dependencies.timer.now(),P=this.dependencies.fallback?Math.floor(k/3):k,C=Math.min(k,Ur,this.budgetMs??Math.max(dn,P));if(C<=0)return"Android keep-booted cleaning budget exceeded";let M=new AbortController,F=AbortSignal.any([c.signal,M.signal]),q={...c,deadlineMs:this.dependencies.timer.now()+C,signal:F,assertOwned:async()=>{F.throwIfAborted(),await H(F,c.assertOwned),F.throwIfAborted()}},U;try{await l(()=>(U=this.clean(d,q,R,D),U),{timer:this.dependencies.timer,signal:F,timeoutMs:C,label:"Android keep-booted cleaning",onTimeout:()=>M.abort(new t("Android keep-booted cleaning budget exceeded"))});return}catch(K){return M.abort(K),e.warn("Android keep-booted cleaning failed",K),r(K)}finally{await this.drainOperation(U)}}async drainOperation(d){await l(Promise.allSettled(d?[d]:[]),{timer:this.dependencies.timer,timeoutMs:vs,label:"Android keep-booted command settlement"})}async clean(d,c,R,D){let k=await this.dependencies.journal.getBaseline(c.scope);if(!k)throw new t("Android keep-booted baseline is missing");await c.assertOwned();let P=[];await this.measure("journal",D,async()=>{P=await this.dependencies.journal.list(c.scope),await this.replayJournal(d,c,k,P)}),await this.measure("clean",D,()=>d.cleanBaseline(k,c,P)),await c.assertOwned(),await this.measure("health",D,()=>R.healthCheck?.(c)??Promise.resolve()),await c.assertOwned()}async replayJournal(d,c,R,D){for(let k of[...D].sort((P,C)=>C.sequence-P.sequence)){await c.assertOwned();let P=k.kind==="installed-app"&&k.priorValue.state==="absent"&&R.observations.some((C)=>C.kind===k.kind&&C.key===k.key&&C.value.state==="present");if(!Cw(k,d)||P){e.warn(`Android keep-booted skipped journal revert ${k.kind}:${k.key}`);continue}try{await d.revert(k,c)}catch(C){if(e.warn(`Android keep-booted journal revert failed ${k.kind}:${k.key}`,C),await c.assertOwned(),k.kind!=="device-setting"||!Ns(k)||Fs(k.key)||pA(k.key)!==null)throw C}}}}function Cw(d,c){return d.kind==="preference"?np(d,c):c.canRevert(d)}function np(d,c){return d.kind==="preference"&&vn(d.key)!==null&&c.canRevert(d)}function fi(d){return d.priorValue.state==="present"?d.priorValue.value:void 0}var Hs=(d)=>d?"enable":"disable",rp={airplaneMode:(d)=>`shell cmd connectivity airplane-mode ${Hs(d)}`,wifiEnabled:(d)=>`shell svc wifi ${Hs(d)}`,bluetoothEnabled:(d)=>`shell svc bluetooth ${Hs(d)}`,locationEnabled:(d)=>`shell cmd location set-location-enabled ${d}`},Tw=p(["off","none","priority","alarms"]),op=s({level:a().int().min(0).max(100),charging:p(gO),faked:m()}),sp=s({status:a().int().min(0).max(6),override:m()});function Mw(d){if(d==="none")return["shell dumpsys battery unplug","shell dumpsys battery set status 3"];return[...["ac","usb","wireless"].map((c)=>`shell dumpsys battery set ${c} ${c===d?1:0}`),"shell dumpsys battery set status 2"]}function Ew(d){let c=op.safeParse(d);if(!c.success)return null;let{level:R,charging:D,faked:k}=c.data;return(k?[...Mw(D),`shell dumpsys battery set level ${R}`]:["shell dumpsys battery reset"]).map((P)=>({command:P}))}function Bw(d){let c=p(sE).safeParse(d);if(!c.success)return null;return[{command:"shell dumpsys deviceidle unforce",wakeSleptScreen:!0},...c.data==="off"?[]:[{command:`shell dumpsys deviceidle force-idle ${c.data}`}]]}function xw(d){let c=sp.safeParse(d);if(!c.success)return null;return[{command:c.data.override?`shell cmd thermalservice override-status ${c.data.status}`:"shell cmd thermalservice reset"}]}function _w(d,c){if(d.priorValue.state==="absent")return[{command:"shell settings delete global low_power"}];return typeof c==="boolean"?[{command:`shell settings put global low_power ${c?1:0}`}]:null}function Fw(d,c){if(d.field==="inactive")return typeof c==="boolean"?[{command:`shell am set-inactive ${b(d.appId)} ${c}`}]:null;let R=p(yO).safeParse(c);return R.success?[{command:`shell am set-standby-bucket ${b(d.appId)} ${R.data}`}]:null}function dp(d,c){let R=fi(c);switch(d.field){case"battery":return Ew(R);case"doze":return Bw(R);case"thermal":return xw(R);case"dataSaver":return typeof R==="boolean"?[{command:`shell cmd netpolicy set restrict-background ${R}`}]:null;case"batterySaver":return _w(c,R);case"standby":case"inactive":return Fw(d,R)}}function Lw(d){let c=op.parse(d);return async(R)=>{let D=await R.readBattery();return(c.faked?D.level===c.level&&D.charging===c.charging:!D.faked)?null:"battery differs from its prior state"}}function $w(d){let c=sp.parse(d);return async(R)=>{let D=await R.readThermal();return(c.override?D.override&&D.status===c.status:!D.override)?null:"thermal override differs from its prior state"}}function Hw(d){let c=p(sE).parse(d);return async(R,D)=>{let k,P=await aE({readDoze:async()=>{try{return await R.readDoze()}catch(C){throw k=u(C,"Android reset could not read back device state"),k}}},c,{...D,reading:await R.readDoze()});if(k)throw k;return P.settled?null:`Doze is ${P.reading.mode}, expected ${c}`}}function qw(d,c){switch(d.field){case"battery":return Lw(c);case"thermal":return $w(c);case"doze":return Hw(c);case"dataSaver":return async(R)=>await R.readDataSaver()===c?null:"Data Saver differs from its prior state";case"batterySaver":return async(R)=>{let D=await R.readBatterySaver();return(c===void 0?(D??!1)===!1:D===c)?null:"battery saver differs from its prior state"};case"standby":return async(R)=>await R.readStandbyBucket(d.appId)===c?null:"standby bucket differs from its prior state";case"inactive":return async(R)=>await R.readInactive(d.appId)===c?null:"inactive state differs from its prior state"}}function cp(d){if(d.kind!=="device-setting")return null;let c=pA(d.key);return c&&dp(c,d)!==null?qw(c,fi(d)):null}function lp(d){let c=fi(d);if(Object.hasOwn(rp,d.key))return typeof c==="boolean"?[{command:rp[d.key](c)}]:null;if(d.key==="doNotDisturb"){let D=Tw.safeParse(c);return D.success?[{command:`shell cmd notification set_dnd ${D.data}`}]:null}let R=pA(d.key);return R?dp(R,d):null}var Kw=s({delayMs:a().min(0).optional(),downloadKbps:a().min(0).optional(),uploadKbps:a().min(0).optional()});function mp(d){let c=Kw.safeParse(fi(d));if(d.key!=="device"||!c.success)return null;let{delayMs:R=0,downloadKbps:D=0,uploadKbps:k=0}=c.data,P=R>0?`${R}:${R}`:"none",C=D>0||k>0?`${k}:${D}`:"full";return[{command:`emu network delay ${P}`,success:"OK"},{command:`emu network speed ${C}`,success:"OK"},{command:"emu gsm data on",success:"OK"},{command:"shell svc wifi enable"}]}var Gw=s({instant:n().refine((d)=>Number.isFinite(Date.parse(d))),automaticTime:m()});function fp(d,c){let R=Gw.safeParse(fi(d));if(d.key!=="device"||!R.success)return null;let D=Math.floor(c/1000),k=Math.ceil(Fl/1000),P=[`cur=$(date +%s); diff=$((cur - ${D}))`,`if [ "$diff" -gt ${k} ] || [ "$diff" -lt -${k} ]; then settings put global auto_time 0 && date -u @${D}; fi`,`settings put global auto_time ${R.data.automaticTime?1:0}`].join("; ");return[{command:`shell sh -c ${b(P)}`}]}var hp={fontScale:["system:font_scale"],timeFormat:["system:time_12_24"],textDirection:["global:debug.force_rtl","global:force_rtl"],increaseContrast:["secure:high_text_contrast_enabled"],reduceMotion:HN.map((d)=>`global:${d}`),boldText:["secure:font_weight_adjustment"],colorInversion:["secure:accessibility_display_inversion_enabled"],colorCorrection:["secure:accessibility_display_daltonizer_enabled","secure:accessibility_display_daltonizer"],magnification:["secure:accessibility_display_magnification_enabled"],magnificationScale:["secure:accessibility_display_magnification_scale"],extraDim:["secure:reduce_bright_colors_activated"]},Ww=/^[+]?(?:\d+(?:\.\d*)?|\.\d+)$/;function jw(d){if(d==="default")return[null];return typeof d==="number"&&Number.isFinite(d)&&d>0?[String(d)]:null}function zw(d,c){if(typeof d!=="string")return null;let R=d.split(",");return R.length===c&&R.every((D)=>D==="null"||Ww.test(D))?R.map((D)=>D==="null"?null:D):null}function Xw(d,c,R){if(c.state==="absent")return Array.from({length:R},()=>null);if(c.state!=="present")return null;if(d==="fontScale")return jw(c.value);if(d==="timeFormat")return c.value==="12"||c.value==="24"?[c.value]:null;return zw(c.value,R)}function gp(d){if(!Object.hasOwn(hp,d.key))return null;let c=hp[d.key],R=Xw(d.key,d.priorValue,c.length);return R?c.map((D,k)=>{let P=R[k];return{kind:"device-setting",key:D,priorValue:P===null?{state:"absent"}:{state:"present",value:P},toolName:d.toolName}}):null}var vp="posted-notifications-cancelled",eR=1e4,hi=/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/;class Us{adb;timer;dozeBackoff;certifiableKinds=hn;adapters={"installed-app":(d)=>this.packageCommands(d),permission:(d)=>this.runtimePermissionCommands(d)??this.appOpsCommands(d),"device-setting":(d)=>this.settingCommands(d)??this.displayOverrideCommands(d)??this.nightModeCommands(d)??this.screenStateCommands(d)??this.volumeCommands(d)??this.settingsBackedCommands(d)??this.appLocaleCommands(d)??lp(d),clock:(d)=>this.timezoneCommands(d)??this.settingCommands(d)??fp(d,this.timer.now()),"network-condition":(d)=>mp(d),rotation:(d)=>this.settingCommands(d),"keep-awake":(d)=>this.settingCommands(d),"screen-reader":(d)=>this.settingCommands(d),keyboard:(d)=>this.settingCommands(d),clipboard:(d)=>this.clipboardCommands(d),location:(d)=>this.locationCommands(d),preference:(d)=>this.appDataCommands(d)??this.systemPropertyCommands(d),"shared-file":(d)=>this.fileCommands(d),"status-bar":(d)=>this.statusBarCommands(d),notification:(d)=>this.postedNotificationCommands(d)??this.notificationChannelCommands(d)};constructor(d,c=i,R=Q({initialDelayMs:250,multiplier:2,maxDelayMs:1000})){this.adb=d;this.timer=c;this.dozeBackoff=R}canRevert(d){return this.commands(d)!==null}baselineRevert(d,c){let R=d.kind==="permission"?/^runtime(?:-flags)?:(\d+):([^:]+):/.exec(d.key):null,D=d.kind==="installed-app"&&d.key.startsWith("identity:")?d.key.slice(9):R?.[2];if(d.priorValue.state==="absent"&&D){let P=c.find((C)=>C.kind==="installed-app"&&C.priorValue.state==="absent"&&/^user:\d+:/.test(C.key)&&(!R||C.key.startsWith(`user:${R[1]}:`))&&C.key.endsWith(`:${D}`));if(P)return{kind:P.kind,key:P.key,priorValue:P.priorValue,toolName:"baseline-diff"}}let k={kind:d.kind,key:d.key,priorValue:d.priorValue,toolName:"baseline-diff"};return["installed-app","permission","device-setting","shared-file"].includes(d.kind)&&this.canRevert(k)?k:Zi(d)}capture(d){return ju((c,R)=>this.execute(c,d,{timeoutMs:R}))}async cleanBaseline(d,c,R=[]){await Qu(d,c,(k,P)=>this.execute(k,c,{timeoutMs:P}),{revert:(k)=>this.revert(k,c),journalEntries:R});let D=await this.execute("shell cmd clipboard clear",c,{optionalClipboard:!0});if(this.unsupportedClipboard(D))e.warn("Android cleaning skipped unsupported clipboard clear");else if(this.failedOutput(D))throw new t("Android clipboard cleaning command failed")}unsupportedClipboard(d){return/Unknown command:|Can't find service:|No shell command implementation|Service .* not found/i.test(d)}failedOutput(d){return je(d,"")||/^(?:Failure \[.*\]|Error:.*|Unknown command:.*|Unknown option:.*|Permission Denial:.*|usage:.*|Can't find service:.*)\s*$/im.test(d.trim())}async revert(d,c){let R=this.commands(d);if(!R)throw new t(`Android cannot restore ${d.kind}:${d.key}`);if(d.kind==="installed-app"&&d.priorValue.state==="absent"&&await this.packageAbsent(d.key,c))return;for(let{command:D,success:k,confirms:P,timeoutMs:C,retryable:M,wakeSleptScreen:F}of R){let q=await this.execute(D,c,{timeoutMs:C,optionalClipboard:d.kind==="clipboard",retryable:M});if(d.kind==="clipboard"&&this.unsupportedClipboard(q)){e.warn("Android cleaning skipped unsupported journal clipboard clear");continue}if(!this.confirmed(q,{success:k,confirms:P}))throw new t("Android reset command failed to confirm success");if(F)await this.wakeBeforeReadBack(c)}await this.verifyPower(d,c)}confirmed(d,{success:c,confirms:R}){return(c===void 0||d===c)&&(R===void 0||R(d))&&!this.failedOutput(d)}powerClient(d){return new iE({execute:async(c)=>Nz(await this.execute(c.map(Zo).join(" "),d),""),isScreenOn:async()=>/mWakefulness=Awake/.test(await this.execute("shell dumpsys power | grep mWakefulness=",d))})}async wakeBeforeReadBack(d){try{await pq({screenSlept:!0},this.powerClient(d))}catch(c){d.signal.throwIfAborted(),e.warn(`Android reset could not wake the screen before the Doze read-back: ${r(c)}`,c)}}async verifyPower(d,c){let R=cp(d);if(!R)return;let D=this.powerClient(c),k;try{k=await H(c.signal,()=>R(D,{timer:this.timer,backoff:this.dozeBackoff,budgetMs:c.deadlineMs===void 0?3000:Math.max(0,Math.min(3000,c.deadlineMs-this.timer.now()))}))}catch(P){throw u(P,"Android reset could not read back device state")}if(k!==null)throw new t(`Android reset could not confirm ${d.key} was restored: ${k}`)}async packageAbsent(d,c){let R=/^user:(\d+):(.+)$/.exec(d);if(!R)throw new t("Android reset requires a user-scoped package key");let D=await this.execute(`shell pm list packages --user ${R[1]}`,c);if(!Gi(D,"android")||D.split(`
34
+ `).some((k)=>!/^package:[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/.test(k.trim())))throw new t("Android reset cannot confirm package absence");return!Gi(D,R[2])}async execute(d,c,{timeoutMs:R=2000,optionalClipboard:D=!1,retryable:k=!0}={}){try{let P=async(M)=>(await c.assertOwned(),c.signal.throwIfAborted(),this.adb.executeCommand(d,{signal:c.signal,timeoutMs:M,maxBuffer:4194304,noRetry:!0,waitForProcessSettlementAfterAbort:!0})),C=c.deadlineMs===void 0?await P(R):await Et((M)=>P(k?M:Math.min(c.deadlineMs-this.timer.now(),Math.max(R,lt(c.deadlineMs-this.timer.now(),3)))),{timer:this.timer,deadlineMs:c.deadlineMs,signal:c.signal,label:"Android reset command",minAttemptMs:R,attempts:k?void 0:1});if(c.signal.throwIfAborted(),await c.assertOwned(),D&&this.unsupportedClipboard(`${C.stdout}
35
+ ${C.stderr}`))return`${C.stdout}
36
+ ${C.stderr}`;if(C.error||C.stderr.trim())throw new t("Android reset command failed");return C.stdout.replace(/\r?\n$/,"")}catch(P){throw u(P,"Android reset command failed")}}commands(d){return(Object.hasOwn(this.adapters,d.kind)?this.adapters[d.kind]:void 0)?.(d)??null}packageCommands({key:d,priorValue:c}){let R=/^user:(\d+):(.+)$/.exec(d);return c.state==="absent"&&R&&hi.test(R[2])?[{command:`shell am force-stop --user ${R[1]} ${b(R[2])}`},{command:`shell pm uninstall --user ${R[1]} ${b(R[2])}`,retryable:!1,success:"Success",timeoutMs:1e4}]:null}runtimePermissionCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0,D=/^runtime:(\d+):([A-Za-z0-9_.]+):([A-Za-z0-9_.]+)$/.exec(d);return D&&hi.test(D[2])&&typeof R==="boolean"?[{command:`shell pm ${R?"grant":"revoke"} --user ${D[1]} ${b(D[2])} ${b(D[3])}`}]:null}appOpsCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0,D=c.state==="absent",k=/^appops:(\d+):([A-Za-z0-9_.]+):([A-Za-z0-9_]+)$/.exec(d);return k&&hi.test(k[2])&&(D||typeof R==="string"&&["allow","ignore","deny","default","foreground"].includes(R))?[{command:`shell cmd appops set --user ${k[1]} ${b(k[2])} ${b(k[3])} ${D?"default":R}`}]:null}settingCommands(d){let{key:c,priorValue:R}=d,D=R.state==="present"?R.value:void 0,k=R.state==="absent",P=/^(global|secure|system):(?:(?:user:(\d+)):)?(?!user:)([A-Za-z0-9_][A-Za-z0-9_.:-]*)$/.exec(c);if(!P||!k&&typeof D!=="string")return null;if(["global:airplane_mode_on","global:wifi_on","global:mobile_data","global:zen_mode"].includes(c)&&!k)return this.connectivityCommands(d);return[{command:k?`shell settings --user ${P[2]??"0"} delete ${P[1]} ${P[3]}`:`shell settings --user ${P[2]??"0"} put ${P[1]} ${P[3]} ${b(D)}`}]}settingsBackedCommands(d){let c=gp(d);if(!c)return null;let R=c.map((D)=>this.settingCommands(D));return R.every((D)=>D!==null)?R.flat():null}appLocaleCommands({key:d,priorValue:c}){let R=NH(d),D=M7(c);if(R===null||!hi.test(R)||!D)return null;let{userId:k,locales:P}=D;return[{command:`shell cmd locale set-app-locales ${b(R)} --user ${k} --locales ${b(P)}`,success:""},{command:`shell cmd locale get-app-locales ${b(R)} --user ${k}`,success:`Locales for ${R} for user ${k} are [${P}]`}]}connectivityCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0;if(typeof R!=="string")return null;if(d==="global:zen_mode"){let k={"0":"off","1":"priority","2":"none","3":"alarms"};return Object.hasOwn(k,R)?[{command:`shell cmd notification set_dnd ${k[R]}`}]:null}if(R!=="0"&&R!=="1")return null;return[{command:d==="global:airplane_mode_on"?`shell cmd connectivity airplane-mode ${R==="1"?"enable":"disable"}`:`shell svc ${d==="global:wifi_on"?"wifi":"data"} ${R==="1"?"enable":"disable"}`}]}displayOverrideCommands({key:d,priorValue:c}){if(d!=="display:density"&&d!=="display:size")return null;let R=d.slice(8),D=c.state==="present"?c.value:void 0,k=c.state==="absent";return k||typeof D==="string"&&(R==="density"?/^\d+$/:/^\d+x\d+$/).test(D)?[{command:`shell wm ${R} ${k?"reset":D}`}]:null}screenStateCommands({key:d,priorValue:c}){return d===PS&&F7(c)?[{command:"shell input keyevent KEYCODE_WAKEUP"},{command:"shell wm dismiss-keyguard"}]:null}volumeCommands({key:d,priorValue:c}){let R=L7(d,c);return R===null?null:[{command:`shell sh -c ${b(R)}`,success:V6,timeoutMs:eR}]}nightModeCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0;return d==="display:night-mode"&&typeof R==="string"&&["yes","no","auto"].includes(R)?[{command:`shell cmd uimode night ${R}`}]:null}timezoneCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0;return d==="timezone"&&typeof R==="string"&&R.length>0?[{command:`shell cmd alarm set-timezone ${b(R)}`},{command:"shell getprop persist.sys.timezone",success:R}]:null}clipboardCommands({priorValue:d}){let c=d.state==="present"?d.value:void 0;return d.state==="absent"||c===""||c===null?[{command:"shell cmd clipboard clear"}]:null}locationCommands({key:d,priorValue:c}){return c.state==="absent"&&/^provider:(gps|network|fused)$/.test(d)?[{command:`shell cmd location providers remove-test-provider ${d.slice(9)}`}]:null}appDataCommands({key:d,priorValue:c}){let R=/^app-data:(\d+):([A-Za-z0-9_.]+)$/.exec(d);return c.state==="absent"&&R&&hi.test(R[2])?[{command:`shell am force-stop --user ${R[1]} ${b(R[2])}`},{command:`shell pm clear --user ${R[1]} ${b(R[2])}`,retryable:!1,success:"Success"}]:null}systemPropertyCommands({key:d,priorValue:c}){let R=vn(d),D=ip(c);return R===null||D===null?null:[{command:`shell setprop ${R} ${b(D)}`,success:""},{command:`shell getprop ${R}`,success:D}]}statusBarCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0;if(d!=="device"||c.state!=="absent"&&typeof R!=="string")return null;return[{command:"shell am broadcast -a com.android.systemui.demo -e command exit"},{command:c.state==="absent"?"shell settings delete global sysui_demo_allowed":`shell settings put global sysui_demo_allowed ${b(R)}`}]}postedNotificationCommands({key:d}){let c=N7(d);if(c===void 0)return null;let R=["out=$(cmd notification list) || exit 1",`if printf '%s\\n' "$out" | grep -Ev -e '^$' -e '^-?[0-9]+[|]' | grep -q .; then exit 1; fi`,`if printf '%s\\n' "$out" | grep -qF ${b(`|${c}|`)}; then exit 1; fi`,`echo ${vp}`].join("; ");return[{command:`shell am force-stop ${b(c)}`},{command:`shell sh -c ${b(R)}`,success:vp}]}notificationChannelCommands({key:d,priorValue:c}){let R=_I(d);if(R===void 0||c.state!=="absent")return null;let D=(k)=>FH(k)==="absent";return[{command:RN(R,"delete"),confirms:D},{command:RN(R,"query"),confirms:D},{command:`shell am force-stop ${b(R.appId)}`}]}fileCommands({key:d,priorValue:c}){if(c.state!=="absent"||!Qe(d))return null;let R=`root=$(readlink -f /sdcard) && [ -n "$root" ] && target=$(readlink -f ${b(d)}) && [ "$target" = "$root"${b(d.slice(7))} ] && [ ! -L ${b(d)} ] && rm -f -- ${b(d)}`;return[{command:`shell sh -c ${b(R)}`},{command:`shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d ${b(`file://${d}`)}`}]}}import{readFile as oR,rm as sR}from"fs/promises";import{resolve as Sp}from"path";class Ks{port;timer;incarnation;fullBaseline=!0;baselines=new Map;constructor(d,c,R){this.port=d;this.timer=c;this.incarnation=R}forget(d){this.baselines.delete(d)}capture(d,c){return this.bounded(c,async(R)=>{let D=await R("identity",(P)=>this.port.identity(d,P)),k=this.baselines.get(c.resourceId);if(k?.deviceId===d.deviceId&&this.matches(k.identity,D))return;if(c.fresh!==!0)throw new t("Android baseline capture requires a freshly created emulator, not unqualified adoption");if(this.forget(c.resourceId),k)await R("invalidate",(P)=>this.port.snapshot("delete",d,P));await this.save(d,c.resourceId,D,R)})}reset(d,c,R,D){let k=D.resetTiming??{outcome:"pending",mode:"snapshot",phases:{}};return k.mode="snapshot",this.bounded({...D,assertOwned:R,resetTiming:k},async(P)=>{let C=this.baselines.get(D.resourceId);try{if(D.opaquePersistentChanges)throw new t("Android session made opaque persistent changes a snapshot load cannot revert");let F=await P("identity",(q)=>this.port.identity(d,q));if(!C||C.deviceId!==d.deviceId||!this.matches(C.identity,F))throw new t("Android snapshot baseline is missing or incompatible");return await this.changeIncarnation(d,P,async(q)=>{await P("load",(K)=>this.port.snapshot("load",d,K)),await q(),await P("restore readiness",(K)=>this.port.waitForRestore(d,K)),await P("health",(K)=>this.port.health(d,K));let U=await P("restored identity",(K)=>this.port.identity(d,K));if(!this.matches(F,U))throw new t("Android snapshot restored an incompatible identity")}),k.outcome="clean",k}catch(F){e.warn("Android snapshot reset unavailable; attempting wipe-data replacement",F),k.mode="wipe-data",k.fallbackReason=r(F)}if(this.forget(D.resourceId),C)try{await P("invalidate",(F)=>this.port.snapshot("delete",d,F))}catch(F){e.warn("Android baseline invalidation failed; never reload it, require wipe-data",F)}let M;try{if(await P("reserve replacement boot",async(q)=>{M=await this.port.reserveBoot({replacingDeviceId:d.deviceId,signal:q.signal,timeoutMs:q.timeoutMs});try{await q.assertOwned()}catch(U){throw M.release(),u(U,"Android replacement boot lost ownership")}}),!M)throw new t("Android replacement boot was not reserved");let F=M;await F.run(()=>this.replace(d,D.resourceId,P,F))}finally{M?.release()}return k.outcome="fallback:wipe-data",k})}replace(d,c,R,D){return this.changeIncarnation(d,R,async(k)=>{await R("stop",(C)=>this.port.stop(d,C)),await k(),D.markReplacedDeviceGone(),await R("wipe-data launch",(C)=>this.port.launchWiped(d,C)),await R("readiness",(C)=>this.port.ready(d,C)),await R("wipe-data health",(C)=>this.port.health(d,C));let P=await R("wipe-data identity",(C)=>this.port.identity(d,C));await this.save(d,c,P,R)})}async changeIncarnation(d,c,R){let D=!1,k=!1,P=!1,C=async()=>{if(!P)P=!0,await this.incarnation.invalidate(d)};try{await c("prepare incarnation",async()=>{D=!0,await this.incarnation.prepareForIncarnationChange(d)}),await R(C),k=!0}finally{if(D)try{await C()}finally{await this.incarnation.settleIncarnationChange(d,{ready:k})}}}async save(d,c,R,D){await D("save",(P)=>this.port.snapshot("save",d,P));let k=await D("saved identity",(P)=>this.port.identity(d,P));if(!this.matches(R,k))throw new t("Android baseline identity changed during snapshot capture");this.baselines.set(c,{deviceId:d.deviceId,identity:{...R}})}matches(d,c){return d.avdName===c.avdName&&d.systemImage===c.systemImage&&d.emulatorVersion===c.emulatorVersion&&d.ctrlProxyVersion===c.ctrlProxyVersion}async bounded(d,c){let R=d.resetTiming,D=new AbortController,k=d.signal?AbortSignal.any([D.signal,d.signal]):D.signal,P=d.timeoutMs??0,C=this.timer.now()+P,M=async()=>{k.throwIfAborted(),await d.assertOwned?.(),k.throwIfAborted()},F=async(q,U)=>{let K=this.timer.now();try{let W=C-this.timer.now();if(W<=0)throw new t("Android snapshot reset deadline exceeded");return await l(async()=>{await M();let V=await U({signal:k,timeoutMs:W,assertOwned:M});return await M(),V},{timer:this.timer,timeoutMs:W,signal:k,label:`Android snapshot ${q}`,timeoutError:()=>new t("Android snapshot reset deadline exceeded"),onTimeout:()=>D.abort(new t("Android snapshot reset deadline exceeded"))})}finally{if(R)R.phases[q]=(R.phases[q]??0)+this.timer.now()-K}};try{if(!Number.isFinite(P)||P<=0||!d.assertOwned)throw new t("Android snapshot reset requires a finite positive deadline");return await c(F)}catch(q){if(D.abort(q),R)throw new Ci(u(q,"Android snapshot baseline reset failed; destroy required").message,{...R,outcome:"pending"},{cause:q});throw u(q,"Android snapshot baseline reset failed; destroy required")}}}var tR=2,nR=Q({initialDelayMs:500,multiplier:2,maxDelayMs:2000});async function yp(d,c){let{stopper:R,timer:D,signal:k,deadlineMs:P,assertOwned:C}=c,M=0;for(let F=1;;F++){await l(D.sleep(nR.delayForAttempt(F)),{timer:D,signal:k,label:"Android emulator liveness watch"}),await C();try{let q=await R.identify(d,{signal:k,deadlineMs:P});M=q.kind==="absent"||q.kind==="mismatch"?M+1:0}catch(q){k.throwIfAborted(),e.debug(`Android emulator liveness probe failed: ${r(q)}`),M=0}if(M>=tR)throw new t(`Android emulator process for ${d.serial} (${d.avdName}) exited during snapshot restore`)}}import{createHash as rR}from"crypto";class Gs{dependencies;constructor(d){this.dependencies=d}reserveBoot(d){return this.dependencies.capacity.reserveBoot(d)}async identity(d,c){c=this.remainingStep(c),await this.assertTarget(d,c);let R=await this.dependencies.config.readConfig(d.name);if(await c.assertOwned(),!R?.systemImagePackage||!R.systemImagePath)throw new t("Android baseline lacks system-image metadata");let D=await this.dependencies.imageMetadata(R.systemImagePath,c.signal);await c.assertOwned();let k=await this.retryStep(c,async(C)=>(await c.assertOwned(),this.dependencies.emulator.executeCommand(["-version"],C,c.signal)));if(await c.assertOwned(),k.error||!k.stdout.trim())throw new t("Android baseline lacks emulator version");let P=await this.dependencies.readiness.ctrlProxyIdentity(d,c.signal);return await c.assertOwned(),{avdName:d.name,systemImage:`${R.systemImagePackage}:${rR("sha256").update(D).update(JSON.stringify(R.hardware??{})).digest("hex")}`,emulatorVersion:k.stdout.trim(),ctrlProxyVersion:P}}async snapshot(d,c,R){R=this.remainingStep(R),await this.dependencies.console.runExclusive(c.deviceId,async()=>{let D=await this.dependencies.adb.create(c).execute(ry(d,i5).split(" "),{timeoutMs:R.timeoutMs,signal:R.signal,noRetry:!0,waitForProcessSettlementAfterAbort:!0,beforeDispatch:()=>this.assertTarget(c,R,!0)});R.signal.throwIfAborted();let k=ny(d,i5,D);if(!k.ok&&!(d==="delete"&&M$(k.errorMessage)))throw new t(k.errorMessage??"Android baseline snapshot failed")})}async health(d,c){c=this.remainingStep(c);let R=this.dependencies.timer.now()+c.timeoutMs;await this.assertTarget(d,c);let k=await this.fencedAdb(d,c).executeCommand("shell getprop sys.boot_completed");if(k.stdout.trim()!=="1"||je(k.stdout,k.stderr))throw new t("Android snapshot target has not completed boot");if(!(await this.dependencies.clockRegistry.runExclusive(d.deviceId,async(C,M)=>{await this.assertTarget(d,c);let F=AbortSignal.any([c.signal,M]),q=new zp(this.fencedAdb(d,{...c,signal:F,timeoutMs:R-this.dependencies.timer.now()}),F),U=await q.ensureRoot();if(!U.success)throw new t(U.error);return hO(d,q,{initialAutomaticTime:1,clockChangedByUs:!0,rootedByUs:U.rootedByUs},{hostClock:this.dependencies.timer,invalidate:this.dependencies.invalidate,mutationSignal:F})})).verified)throw new t("Android snapshot clock resync did not verify");if(await c.assertOwned(),!await this.checkCtrlProxy(d,c,R))throw new t("Android snapshot CtrlProxy health check failed");await this.assertTarget(d,c)}checkCtrlProxy(d,c,R){let D=this.dependencies.timer,k=mn(D,R),P=new AbortController,C=AbortSignal.any([c.signal,P.signal]),M=()=>new t("Android snapshot CtrlProxy health check failed");return l(()=>fn(async(F)=>{await c.assertOwned();let q=await this.dependencies.ctrlProxyReady(d,{signal:C,timeoutMs:F,noRetry:!0});return await c.assertOwned(),q},{timer:D,deadlineMs:k,signal:C,label:"Android snapshot CtrlProxy health check"}),{timer:D,signal:c.signal,timeoutMs:Math.max(0,k-D.now()),label:"Android snapshot CtrlProxy health check",timeoutError:M,onTimeout:()=>P.abort(M())})}async stop(d,c){c=this.remainingStep(c);let R=this.dependencies.timer.now()+c.timeoutMs;await this.assertTarget(d,c);let D=await this.dependencies.processStopper.identify({serial:d.deviceId,avdName:d.name},{signal:c.signal,deadlineMs:R});if(await c.assertOwned(),D.kind!=="match")throw new t("Android reset cannot prove the owned emulator process exists");await this.dependencies.emulator.killDevice(d,{force:!0,beforeDispatch:()=>this.assertTarget(d,c),signal:c.signal,timeoutMs:c.timeoutMs,processStop:{stopper:this.dependencies.processStopper,expectedAvdName:d.name}});let k,P=()=>lt(R-this.dependencies.timer.now(),2),C=()=>{if(this.dependencies.timer.now()>=R)throw new t("Android reset emulator process did not exit before the deadline"+(k===void 0?"":`: ${r(k)}`))};for(;;){await c.assertOwned(),c.signal.throwIfAborted(),C();let M=!1;try{if(!(await this.dependencies.inventory({signal:c.signal,timeoutMs:P(),targetDeviceId:d.deviceId})).some((q)=>q.deviceId===d.deviceId||q.name===d.name)&&this.dependencies.timer.now()<R)M=!(await this.dependencies.emulator.getListedNonDeviceStatesAmong([d.deviceId],{signal:c.signal,timeoutMs:P()})).has(d.deviceId)}catch(F){c.signal.throwIfAborted(),e.debug("Android reset exit inventory poll failed; continuing to wait",F),k=F}if(await c.assertOwned(),c.signal.throwIfAborted(),C(),M&&await this.processExited(d,c,R))return;C(),await this.dependencies.timer.sleep(Math.min(100,R-this.dependencies.timer.now()))}}async processExited(d,c,R){let D=await this.dependencies.processStopper.identify({serial:d.deviceId,avdName:d.name},{signal:c.signal,deadlineMs:R});if(await c.assertOwned(),D.kind==="absent")return await this.dependencies.clearQuickBoot(d,c),await c.assertOwned(),!0;if(D.kind!=="match")throw new t("Android reset cannot prove the owned emulator process exited");return!1}async launchWiped(d,c){await c.assertOwned();let R=await this.dependencies.emulator.launchEmulator({avdName:d.name,deviceId:d.deviceId,signal:c.signal,extraArgs:["-wipe-data","-no-snapshot-load","-no-snapshot-save"],admitColdBoot:()=>this.dependencies.admitColdBoot(d,c)});if(R.outcome!=="launched"||!R.process||R.targetDeviceId!==d.deviceId)throw R.dispose(),new t("Android wipe-data reset did not launch the exact reserved emulator");R.release(),await c.assertOwned(),await this.dependencies.emulator.waitForEmulatorReady(d.name,c.timeoutMs,R.process,{targetDeviceId:d.deviceId,signal:c.signal,options:{freshProvision:!0}})}async waitForRestore(d,c){await c.assertOwned();let{timer:R,processStopper:D}=this.dependencies,k=new AbortController,P=AbortSignal.any([c.signal,k.signal]),C=R.now()+c.timeoutMs;try{await l([this.dependencies.emulator.waitForEmulatorReady(d.name,c.timeoutMs,null,{targetDeviceId:d.deviceId,signal:P,options:{skipWakeAndUnlock:!0}}),yp({serial:d.deviceId,avdName:d.name},{stopper:D,timer:R,signal:P,deadlineMs:C,assertOwned:c.assertOwned})],{timer:R,signal:c.signal,label:"Android snapshot restore readiness"})}finally{k.abort()}}ready(d,c){return this.dependencies.readiness.ready(d,c)}fencedAdb(d,c){let R=this.dependencies.adb.create(d);return c=this.remainingStep(c),{executeCommand:(D,k)=>{let P=D.startsWith("shell date -u @");return this.retryStep(c,async(C)=>{await c.assertOwned(),c.signal.throwIfAborted();let M=c.timeoutMs,F=await R.executeCommand(D,{...k,timeoutMs:P?Math.min(M,Math.max(k?.timeoutMs??0,lt(M,3))):C,signal:c.signal,noRetry:!0,beforeDispatch:()=>c.assertOwned()});return await c.assertOwned(),F},{minAttemptMs:k?.timeoutMs,attempts:P?1:void 0})}}}remainingStep(d){let c=this.dependencies.timer,R=c.now()+d.timeoutMs;return{...d,get timeoutMs(){return R-c.now()}}}retryStep(d,c,R={}){return Et(c,{timer:this.dependencies.timer,deadlineMs:this.dependencies.timer.now()+d.timeoutMs,signal:d.signal,label:"Android snapshot reset adb",...R})}async assertTarget(d,c,R=!1){await c.assertOwned();let D=await this.retryStep(c,async(k)=>(await c.assertOwned(),this.dependencies.emulator.resolveAvdNameForSerial(d.deviceId,{signal:c.signal,timeoutMs:k,consoleExclusiveOwner:R,throwOnTimeout:!0})));if(await c.assertOwned(),D!==d.name)throw new t("Android snapshot reset serial no longer hosts its owned AVD")}}function dR(d){return{recordingGaps:d.recordingGaps??new ro,lock:d.hostLock??Dl(d.owner)}}async function bp(d){let{recordingGaps:c,lock:R}=dR(d);R.acquire();let D;try{let k=Qd(sv);await OR(d.registry,k),await BR(d,k);let P=await d.registry.ensureScope(sv);if(P.kind!=="ready")throw new t(`Session broker's private ownership scope is unavailable: ${P.kind}`);let C=d.registry.sessionBrokerStore(k),M=m0(d.config),F=d.registry.deviceMutationJournal(),q=wR(d.config,d.androidReset,d.timer,{journal:F,recordingGaps:c}),U=q?.ios,K=U?(te,re,ie,{signal:oe,context:pe}={})=>{let de=()=>U.resetWithTiming(te,re,ie,oe);return pe?.runResetBoot?pe.runResetBoot(de):de()}:void 0,W;if(U)({resetIosBaseline:K,captureIosBaseline:W}=hR(d,M,{erase:U,journal:F,recordingGaps:c,store:C},K));let V=d.mutationSessions?(te)=>{let re=d.mutationSessions.peekSession(te.sessionUuid);if(!re||re.sessionId!==te.sessionUuid||re.assignedDevice!==te.deviceId)throw new t("Broker mutation scope must match the live native session and device");re.mutationRecorder=new jo(F,te)}:void 0,z=new zo({androidConfigReader:new Nr,scope:sv,timer:d.timer,leaseKeepalive:NR(d),brokerDeviceAcquisition:d.acquisition,brokerExecutionRelease:d.release,registry:d.registry,bindingJournal:d.journal,bindMutationRecorder:V,...q?{resetBaseline:{ios:K,android:q.android,watch:q.watch},captureIosBaseline:W,isCurrentReset:(te)=>MR(C,te)}:{}});D=new v4({store:C,devices:z,timer:d.timer,owner:d.owner,limits:d.config.limits,catalog:d.catalog??Ol(d.config),defaults:(te)=>{let re=d.config.defaults[te];if(!re)throw new t(`Session-broker execution is not configured for ${te} on this host`);return re},sessionDisposition:d.sessionDisposition,reuseCleanDevices:M.mode!=="off",reuseAndroidCleanDevices:d.config.reuseAndroidCleanDevices,idleTtlMs:{android:d.config.androidIdleTtlMs}}),await D.recoverReceipts();let J=(te)=>mR(d,C,k,{bindMutationRecorder:V,sessionUuid:te});await lR(C,J,c);let X=new wp(D,k,R,{timer:d.timer,avdSnapshotCleanup:io(d.avdSnapshotCleanup,d.registry,d.timer),mutations:{recordingGaps:c,recorderFor:J}});if(!d.deferStart)X.start();return X}catch(k){throw await cR(D,R),u(k,"Session broker startup failed")}}async function cR(d,c){try{await d?.close()}catch(R){e.warn("Failed to close broker after startup failure",R)}finally{c.release()}}async function lR(d,c,R){let D;try{D=await d.listRecoverableRequests()}catch(k){e.warn("Cannot list recoverable session requests for mutation recorder recovery",k);return}for(let k of D){if(k.state!=="active"||!k.sessionId)continue;try{await c(k.sessionId)}catch(P){R.mark(k.sessionId,`recorder recovery: ${r(P)}`),e.warn(`Cannot recover mutation recorder for session ${k.sessionId}`,P)}}}async function uR(d,c){let R=await d.getSession(c);if(R?.state!=="active"||!R.resourceId)return"not-recordable";let D=await d.getResource(R.resourceId);return D&&Ln(D).platform==="watchos"?"not-recordable":D}async function mR(d,c,R,{bindMutationRecorder:D,sessionUuid:k}){if(!D||!d.mutationSessions)return;let P=d.mutationSessions.peekSession(k);if(!P)return;let C=await uR(c,k);if(C==="not-recordable")return;let M=C?await d.registry.getAssignment({scopeKey:R,bindingIndex:C.allocationIndex}):null;bR(M,k,P.stableDeviceId??P.assignedDevice),D(SR(k,P.assignedDevice,C,M));let F=d.mutationSessions.peekSession(k)?.mutationRecorder;if(!F)throw new t("Broker mutation recorder recovery did not attach a recorder to the active session");return F}function hR(d,c,R,D){let{erase:k,journal:P,recordingGaps:C,store:M}=R;if(c.mode==="keep-booted")return gR(d,c,k,{journal:P,recordingGaps:C,store:M});if(c.mode==="minimal")return{resetIosBaseline:vR(d,c.maxUses,P,{recordingGaps:C,store:M}),captureIosBaseline:void 0};return{resetIosBaseline:D,captureIosBaseline:void 0}}function gR(d,c,R,{journal:D,recordingGaps:k,store:P}){let C=gs(new L(null),d.timer),M=new ts({recordingGaps:k,journal:D,mutations:C,simctl:new L(null),timer:d.timer,health:qu(d.timer),erase:R,maxUses:c.maxUses,fallback:c.fallback,budgetMs:Zs(h.IOS_RESET_STEP_BUDGET_MS),budgetCeilingMs:Zs(h.IOS_RESET_STEP_BUDGET_MAX_MS)});return{captureIosBaseline:(F)=>sn(D,C,F),resetIosBaseline:async(F,q,U,{signal:K,context:W}={})=>{let V=W?.resource.requestId?await P.getRequest(W.resource.requestId):void 0;if(!W||!V?.sessionId)throw new t("iOS keep-booted reset requires its durable released session identity");return M.resetWithTiming(F,q,U,{scope:{...W.scope,sessionUuid:V.sessionId},reuseCount:W.resource.reuseCount??0,signal:K,runResetBoot:W.runResetBoot})}}}function vR(d,c,R,{recordingGaps:D,store:k}){let P=new L(null),C=new is({recordingGaps:D,journal:R,mutations:gs(P,d.timer),simctl:P,timer:d.timer,maxUses:c,budgetMs:Zs(h.IOS_RESET_STEP_BUDGET_MS)});return async(M,F,q,{signal:U,context:K}={})=>{let W=K?.resource.requestId?await k.getRequest(K.resource.requestId):void 0;if(!K||!W?.sessionId)throw new t("iOS minimal reset requires its durable released session identity");return C.resetWithTiming(M,F,q,{scope:{...K.scope,sessionUuid:W.sessionId},reuseCount:K.resource.reuseCount??0,signal:U})}}function SR(d,c,R,D){if(!R)throw new t("Recovered broker session has no resource");return Xi({platform:Ln(R).platform,sessionUuid:d,resource:R,stableDeviceId:D.stableDeviceId??c,transportId:c,assignmentGeneration:D.generation,bootId:null})}function bR(d,c,R){if(!d||d.state!=="ready"||d.execOwner?.sessionUuid!==c||d.stableDeviceId!==R)throw new t("Cannot recover broker mutation recording without the exact native assignment")}function wR(d,c,R,{journal:D,recordingGaps:k}){if(d.reuseAndroidCleanDevices&&d.defaults.android&&!c)throw new t("Android baseline reset requires the daemon readiness ports");let P=m0(d).mode!=="off";return P||d.reuseAndroidCleanDevices?{ios:P?RR():void 0,watch:wu(d,R),android:d.reuseAndroidCleanDevices&&d.defaults.android?kR(c,R,d,{journal:D,recordingGaps:k}):void 0}:void 0}function RR(){return new Qo({simctl:new L(null),iosBootInstrumentation:Xo.iosBootInstrumentation(),stopDevice:async(d)=>{let c=ri(await si("killDevice",{device:d},void 0));if(c.isError||c.payload.success===!1)throw new t("Provider device shutdown did not confirm a clean controller teardown")}})}function kR(d,c,R,{journal:D,recordingGaps:k}){let P=new Nr,C=TR(d.inventory,c),M;if(R.androidResetMode==="snapshot"||R.androidResetMode==="keep-booted"&&R.androidKeepBootedFallback==="snapshot"){if(!d.snapshot)throw new t("Android snapshot reset requires daemon readiness and identity ports");M=new Ks(new Gs({emulator:new pi({timer:c}),adb:v,config:P,console:qs,clockRegistry:kf,processStopper:nh(c),clearQuickBoot:async(q,U)=>{let K=await P.resolveAvdDirectory(q.name);if(await U.assertOwned(),!K)throw new t("Android reset cannot locate its owned AVD to remove dirty quick-boot state");await sR(Sp(K,Jw,Am),{recursive:!0,force:!0}),await U.assertOwned()},capacity:{reserveBoot:(q)=>{if(!Xo.androidColdBootAdmitter())throw new t("Android snapshot replacement requires boot admission before stopping");return jq("android",q)}},admitColdBoot:async(q,U)=>{let K=Xo.androidColdBootAdmitter();if(!K)throw new t("Android snapshot wipe-data reset requires boot admission wiring");return await U.assertOwned(),K.admit({avdName:q.name,timeoutMs:U.timeoutMs,signal:U.signal})},readiness:d.snapshot,inventory:C,ctrlProxyReady:d.ctrlProxyReady,imageMetadata:async(q,U)=>{let K=Pl();if(!K)throw new t("Android snapshot reset requires installed system-image metadata");return oR(Sp(K.androidHome,q,"source.properties"),{encoding:"utf8",signal:U})},timer:c,invalidate:(q)=>Js(q,"Android broker baseline reset")}),c,rH)}let F=CR(R,{recordingGaps:k,journal:D,timer:c,snapshot:M,port:(q)=>new Us(v.create(q))});return new ks({postureReset:new no(v),timer:c,resetTimeoutMs:R.androidResetTimeoutMs,inventory:async(q)=>{let U=await C(q);return Promise.all(U.map(async(K)=>{q?.signal?.throwIfAborted();let W=await P.readConfig(K.name);return q?.signal?.throwIfAborted(),{...K,isRunning:!0,runtimeId:W?.systemImagePackage,deviceType:W?.deviceName,apiLevel:W?.apiLevel}}))},adb:(q)=>v.create(q),watchSession:(q)=>Vu(G,q),ctrlProxyReady:d.ctrlProxyReady,strategy:F})}function CR(d,{snapshot:c,...R}){return d.androidResetMode==="keep-booted"?new Ls({...R,maxUses:d.androidKeepBootedMaxUses,fallback:c,fallbackBudgetMs:c?d.androidResetTimeoutMs??ws:void 0}):c}function TR(d,c){return(R)=>{R.signal?.throwIfAborted();let D=new AbortController,k=R.signal?AbortSignal.any([R.signal,D.signal]):D.signal;return l(()=>d({...R,signal:k}),{timer:c,timeoutMs:R.timeoutMs,signal:R.signal,label:"Android baseline reset inventory",onTimeout:()=>D.abort()})}}async function MR(d,c){let R=await d.getResource(c.resourceId);return R?.state==="resetting"&&R.revision===c.revision&&R.requestId===c.requestId&&R.scopeKey===c.scopeKey}async function BR(d,c){let R=d.liveSessionIds?.()??[];if(R.length===0)return;let D=await d.registry.sessionBrokerStore(c).listRequests(),k=new Set(D.flatMap((P)=>P.sessionId?[P.sessionId]:[]));for(let P of await d.registry.snapshotManagedDevices())if(P.scopeKey===c&&P.execSessionUuid)k.add(P.execSessionUuid);if(R.some((P)=>!k.has(P)))throw new t("Session-broker mode requires prior generic sessions to be drained before startup")}async function OR(d,c){let R=await d.sessionBrokerStore(c).listLiveResources(),D=new Set(R.filter((C)=>C.state!=="destroyed").map((C)=>C.allocationIndex)),k=(await d.snapshotManagedDevices()).some((C)=>C.scopeKey!==c||C.holder!=="session_broker"||C.bindingIndex===null||!D.has(C.bindingIndex)),P=(await d.listOpenBindingJournal()).some((C)=>C.scopeKey!==c||!D.has(C.bindingIndex));if(k||P)throw new t("Session-broker mode requires prior or unaccounted managed allocations to be drained; existing inventory remains untouched")}var FR=3600000;class wp{broker;scopeKey;lock;avdSnapshotCleanup;stopped=!1;lastPruneAtMs;running;closing;wake;timer;mutations;constructor(d,c,R,{timer:D,mutations:k,avdSnapshotCleanup:P}){this.broker=d;this.scopeKey=c;this.lock=R;this.timer=D,this.mutations=k,this.avdSnapshotCleanup=io(P)}markMutationUnrecorded(d,c){this.mutations.recordingGaps.mark(d,c)}async recoverMutationRecorder(d){try{if(this.stopped)throw new t("Cannot recover mutation recording from a stopped session broker");return await this.mutations.recorderFor?.(d)}catch(c){this.markMutationUnrecorded(d,`recorder recovery: ${r(c)}`),e.warn(`Cannot recover mutation recorder for session ${d}; proceeding without recording`,c);return}}start(){if(this.stopped)return;this.running??=this.loop()}close(){return this.closing??=this.stop(),this.closing}async stop(){this.stopped=!0,this.wake?.();try{await this.broker.markRestartHandoff()}catch(d){e.warn(`Session broker restart handoff failed: ${r(d)}`,d)}await this.running,await this.broker.close(),this.lock.release()}async loop(){let d=!0;while(!this.stopped){if(!d)await this.wait();if(this.stopped)return;try{await this.broker.recoverReceipts(),await this.broker.recoverCleanup()}catch(c){e.warn(`Session broker recovery remains pending: ${r(c)}`)}if(await this.expireIdlePool(),this.stopped)return;if(!d)await this.pruneIfDue();d=!1}}async expireIdlePool(){if(this.stopped)return;try{await this.broker.expireIdlePool()}catch(d){e.warn(`Session broker idle expiry failed: ${r(d)}`,d)}}async pruneIfDue(){let d=this.timer.now();if(this.lastPruneAtMs!==void 0&&d-this.lastPruneAtMs<FR)return;this.lastPruneAtMs=d;try{if(await this.broker.pruneReceipts()>=y4)this.lastPruneAtMs=void 0}catch(c){e.warn(`Session broker receipt retention failed: ${r(c)}`,c)}}wait(){return new Promise((d)=>{let c=()=>{this.wake=void 0,d()},R=this.timer.setTimeout(c,GZ);this.wake=()=>{this.timer.clearTimeout(R),c()}})}}function NR(d){let{mutationSessions:c,timer:R}=d;return c?new II({sessions:()=>c,timer:R}):void 0}var kp=Ee+ll,Pp=kp+kp,LR=wt,$R=Rt,HR=Pt,qR=5000,Ip=60000,UR=3;class Ws{deps;recovering=new Map;recoveredSessions=new Set;ownership=new Map;attempts=new Map;registryOpens=new Map;ownerReads=new Map;ownerClaims=new Map;background=new Map;retryExpedites=new Map;closing=new AbortController;releaseHolds=new Map;episodes=new Map;pacing;closed=!1;constructor(d){this.deps=d;this.pacing=new Me({timer:d.timer??i,initialDelayMs:LR,maxDelayMs:$R,maxBlockedWaitMs:HR,backoff:d.retryBackoff})}async reown(d,c){if(this.closed||d.length===0||this.deps.registryExists?.()===!1)return[];if(this.pruneReleasedSessions(),c?.rehydrated)this.markUnconfirmed(d.filter((D)=>!this.recoveredSessions.has(D)));let R=[];for(let D of d)R.push(...await this.reownInline(D));return R}noteRecovering(d,c){if(this.closed||this.deps.registryExists?.()===!1||this.recovering.has(d))return;this.isPresent(d),this.resetEpisode(d),this.recovering.set(d,c),this.recoveredSessions.add(d),this.ownership.set(d,"unconfirmed"),this.episode(d),c.then(()=>{if(this.recovering.delete(d),this.isHeld(d))this.reown([d],{rehydrated:!0})},(R)=>{if(!this.closed)e.debug(`[Bindings] Recovery of ${d} failed before re-owning`,R);this.recovering.delete(d),this.isPresent(d)})}ownershipState(d){return this.isPresent(d)?this.ownership.get(d):void 0}releaseDeviceHold(d){if(this.deps.isSessionPresent&&!this.isPresent(d))return;let c=this.ownership.get(d);if(c==="lost")return{skipDeviceWrites:!0};if(c!=="unconfirmed")return;if(this.closed)return this.warnDroppedState(d,this.deps.deviceOf?.(d)??"unknown device"),{skipDeviceWrites:!0};let R=this.releaseHolds.get(d);if(!R){let D=Promise.withResolvers(),k=this.deps.timer??i;R={settled:D.promise,resolve:D.resolve,device:this.deps.deviceOf?.(d)??"unknown device",timeout:k.setTimeout(()=>this.resolveUnknownHold(d),Pp)},this.releaseHolds.set(d,R),this.expediteRetry(d)}return{settled:R.settled,capMs:Pp}}expediteRetry(d){if(this.canAttempt(d))this.retryExpedites.get(d)?.abort()}isReleaseHeld(d){return this.releaseHolds.has(d)}confirmOwnership(d){this.settleOwnership(d,"confirmed")}loseOwnership(d){this.settleOwnership(d,"lost")}resolveHold(d,c){let R=this.releaseHolds.get(d);if(!R)return;(this.deps.timer??i).clearTimeout(R.timeout),this.releaseHolds.delete(d),R.resolve(c)}resolveUnknownHold(d){let c=this.releaseHolds.get(d);if(!c)return;this.warnDroppedState(d,c.device),this.resolveHold(d,"skip-device-writes")}warnDroppedState(d,c){e.warn(`[Bindings] Session ${d} on device ${c}: saved device state was dropped because ownership could not be confirmed.`)}episode(d){let c=this.episodes.get(d);if(!c)c={attempts:0,inFlight:!1,warned:!1,sinceMs:(this.deps.timer??i).now(),stop:new AbortController},this.episodes.set(d,c);return c}startDeadline(d){let c=this.episode(d);if(c.deadline!==void 0)return;let R=this.deps.timer??i;c.deadline=R.setTimeout(()=>{this.canAttempt(d)},Math.max(0,Ip-(R.now()-c.sinceMs)))}clearDeadline(d){let c=this.episodes.get(d);if(c?.deadline!==void 0)(this.deps.timer??i).clearTimeout(c.deadline),c.deadline=void 0}resetEpisode(d){this.clearDeadline(d),this.episodes.get(d)?.stop.abort(),this.episodes.delete(d)}logUnconfirmed(d,c,R){if(this.closed)return;let D=this.episode(d);e.debug(c,R);let k=(this.deps.timer??i).now()-D.sinceMs;if(this.ownership.get(d)==="unconfirmed"&&!D.warned&&k>qR)D.warned=!0,e.warn(`[Bindings] Session ${d} ownership unconfirmed for ${k} ms (${D.attempts} attempts): ${r(R)}; retries continue`,R)}markUnconfirmed(d){for(let c of d)if(this.isPresent(c)&&!this.ownership.has(c)){if(this.ownership.set(c,"unconfirmed"),this.episode(c).attempts>0)this.startDeadline(c)}}async reownInline(d){if(!this.canAttempt(d)||this.ownership.get(d)==="lost")return[];let c=this.episode(d);try{let R=await this.attempt(d);if(!this.acceptResult(d,R.outcome,c.stop.signal))return[];if(this.settleOwnership(d,R.outcome),R.outcome==="retry")this.logRetry(d,R.error),this.retryInBackground(d);return R.assignments}catch(R){if(!this.canAttempt(d,c.stop.signal)){if(!this.closed)e.debug(`[Bindings] Re-owning managed execution ${d} failed after resolution`,R);return[]}return this.logUnconfirmed(d,`[Bindings] Re-owning managed execution ${d} failed: ${r(R)}`,R),this.retryInBackground(d),[]}}isAdmitted(d,c){return!this.closed&&!c?.aborted&&!this.recovering.has(d)&&this.isHeld(d)}acceptResult(d,c,R){return c==="confirmed"?this.isAdmitted(d,R):this.canAttempt(d,R)}canAttempt(d,c){if(!this.isAdmitted(d,c))return!1;let R=this.episodes.get(d);if(this.ownership.get(d)==="unconfirmed"&&R&&!R.inFlight&&R.attempts>=UR&&(this.deps.timer??i).now()-R.sinceMs>=Ip)return this.settleOwnership(d,"lost"),!1;return!0}automationRefusal(d){switch(this.ownershipState(d)){case"unconfirmed":{let c=this.episode(d);return new MA(d,c.attempts===0?0:(this.deps.timer??i).now()-c.sinceMs)}case"lost":return new Dq(d);default:return}}close(){this.closed=!0;for(let d of this.releaseHolds.keys())this.resolveUnknownHold(d);for(let[d,c]of this.episodes)this.clearDeadline(d),c.stop.abort();this.closing.abort(),this.pacing.close(),this.registryOpens.clear(),this.ownerReads.clear(),this.ownerClaims.clear()}async whenIdle(){this.pruneReleasedSessions();while(this.background.size>0||this.attempts.size>0||this.releaseHolds.size>0)await Promise.allSettled([...this.background.values(),...this.attempts.values(),...Array.from(this.releaseHolds.values(),(d)=>d.settled)])}isHeld(d){let c=this.isPresent(d)&&(this.releaseHolds.has(d)||this.deps.isSessionHeld?.(d)!==!1);if(!c)this.clearDeadline(d);return c}isPresent(d){if(this.releaseHolds.has(d)||this.recovering.has(d))return!0;if((this.deps.isSessionPresent??this.deps.isSessionHeld)?.(d)!==!1)return!0;return this.ownership.delete(d),this.recoveredSessions.delete(d),this.clearDeadline(d),this.episodes.get(d)?.stop.abort(),this.episodes.delete(d),this.forgetRegistrySteps(d),!1}forgetRegistrySteps(d){this.registryOpens.delete(d),this.ownerReads.delete(d),this.ownerClaims.delete(d)}pruneReleasedSessions(){for(let d of new Set([...this.ownership.keys(),...this.recoveredSessions,...this.episodes.keys()]))this.isPresent(d)}settleOwnership(d,c){if(this.closed||!this.isPresent(d))return;let R=this.episode(d);if(c!=="retry")this.resetEpisode(d);if(this.ownership.get(d)!=="unconfirmed")return;if(c==="confirmed")this.forgetRegistrySteps(d),this.ownership.delete(d),e.info(`[Bindings] Session ${d} ownership confirmed after ${(this.deps.timer??i).now()-R.sinceMs} ms (${R.attempts} attempts); re-owned by daemon ${this.deps.owner().daemonId}.`),this.resolveHold(d,"teardown"),this.notifyOwnership(d,"confirmed");if(c==="lost")this.forgetRegistrySteps(d),this.ownership.set(d,"lost"),e.warn(`[Bindings] Session '${d}' no longer owns its broker binding; acquire a new session.`),this.resolveHold(d,"skip-device-writes"),this.notifyOwnership(d,"lost")}notifyOwnership(d,c){let R=c==="confirmed"?this.deps.onOwnershipConfirmed:this.deps.onOwnershipLost;try{R?.(d)}catch(D){e.warn(`[Bindings] Ownership-${c} hook failed for ${d}`,D)}}needsRetry(d){return this.canAttempt(d)&&this.ownership.get(d)==="unconfirmed"}logRetry(d,c=Error("binding ownership unconfirmed")){this.logUnconfirmed(d,`[Bindings] Re-owning managed execution ${d} failed; retrying: ${r(c)}`,c)}retryInBackground(d){if(!this.needsRetry(d)||this.background.has(d))return;let c=this.retryLoop(d).finally(()=>{this.background.delete(d)});this.background.set(d,c)}async retryLoop(d){let c=this.episode(d).stop.signal;for(let R=1;this.needsRetry(d);R++){let D=new AbortController;this.retryExpedites.set(d,D);try{if(await this.pacing.wait(this.pacing.delay(R),c,D.signal),!this.needsRetry(d))return;let k=await this.attempt(d,D.signal);if(!this.acceptResult(d,k.outcome,c))return;if(this.settleOwnership(d,k.outcome),k.outcome==="retry")this.logRetry(d,k.error)}catch(k){let P=this.canAttempt(d,c);if(!P&&!this.closed&&!c.aborted)e.debug(`[Bindings] Re-own retry no longer admitted for ${d}: ${r(k)}`);if(!P)return;this.logRetry(d,k)}finally{this.retryExpedites.delete(d)}}}attempt(d,c){let R=this.attempts.get(d);if(R)return R;let D=this.episode(d),k=this.pacing.run(async()=>{if(this.retryExpedites.delete(d),!this.canAttempt(d,D.stop.signal))return{assignments:[],outcome:"retry"};if(D.attempts===0){if(D.sinceMs=(this.deps.timer??i).now(),this.ownership.get(d)==="unconfirmed")this.startDeadline(d)}D.attempts++,D.inFlight=!0;try{return await this.boundedAttempt(d,D.stop.signal)}finally{D.inFlight=!1}},(P)=>P.outcome!=="retry",D.stop.signal,c).finally(()=>{this.attempts.delete(d)});return this.attempts.set(d,k),k}async boundedAttempt(d,c){let R=new AbortController,D=AbortSignal.any([this.closing.signal,c,R.signal]);try{return await l(()=>this.reownSession(d,D,c),{timer:this.deps.timer??i,timeoutMs:Ee,signal:D,onTimeout:()=>R.abort(Error(`Re-owning session ${d} attempt timed out`)),label:`Re-owning session ${d}`})}finally{R.abort()}}async registryStep(d,c,R,D){let k=!1;try{return await l(()=>{let P=c.get(d);if(!P)P=R(),c.set(d,P);return P.then((C)=>(k=!D.aborted,C),(C)=>{throw k=!D.aborted,C})},{timer:this.deps.timer??i,signal:D,label:`Re-owning session ${d} registry step`})}finally{if(k)c.delete(d)}}async readCurrentAssignments(d,c,R){let D=this.ownerClaims.get(d);if(D){let P=await this.registryStep(d,this.ownerClaims,()=>D,R);if(!this.closed)e.debug(`[Bindings] Session ${d} retained claim completed (${P.kind}); checking current ownership`)}let k=()=>this.registryStep(d,this.ownerReads,()=>c.findExecutionAssignments(d),R);if(this.ownerReads.has(d)){if(await k(),!this.closed)e.debug(`[Bindings] Session ${d} retained ownership read completed; checking current ownership`)}return await k()}async reownSession(d,c,R){let D={assignments:[],outcome:"retry"},k=await this.registryStep(d,this.registryOpens,()=>this.deps.registry(),c);if(!this.isAdmitted(d,c))return D;let P=await this.readCurrentAssignments(d,k,c);if(!this.isAdmitted(d,c))return D;if(D.outcome="confirmed",P.length===0)D.outcome="lost";let C=this.deps.owner();for(let M of P){if(!this.isAdmitted(d,c))return{...D,outcome:"retry"};if(M.execOwner&&jc(M.execOwner,C))continue;let F;try{F=await this.registryStep(d,this.ownerClaims,()=>k.claimExecution({scopeKey:M.scopeKey,bindingIndex:M.bindingIndex},{generation:M.generation,stableDeviceId:M.stableDeviceId},{...C,sessionUuid:d},{supersedesSessionUuid:d}),c)}catch(q){if(this.isAdmitted(d,R))this.markUnconfirmed([d]);throw q}if(!this.isAdmitted(d,c))return{...D,outcome:"retry"};if(F.kind==="claimed")D.assignments.push(F.assignment);else this.markUnconfirmed([d]),this.recordRefusal(D,F.kind,M,d)}return D}recordRefusal(d,c,R,D){if(c==="binding_in_use"||c==="scope_not_valid"||c==="binding_missing"||c==="device_assigned_elsewhere"){if(d.outcome="lost",c==="binding_in_use"&&this.ownership.has(D))return}else if(d.outcome!=="lost")d.outcome="retry";d.error=Error(`Binding ${R.bindingIndex} of ${R.scopeKey} was not re-owned for session ${D}: ${c}`)}}class Vs{options;constructor(d){this.options=d}async retire(d){let{timer:c,devices:R,isOwnerLive:D}=this.options,k=new AbortController,P=this.options.signal?AbortSignal.any([k.signal,this.options.signal]):k.signal;try{await d.withLegacyRows(async(C,M)=>{await l(async()=>{this.assertOwnersDead(C,D);let F=new Map(C.devices.map((q)=>[JSON.stringify(q),q]));for(let q of F.values()){P.throwIfAborted(),this.assertOwnersDead(C,D);let U=await R.inspect(q,P);if(P.throwIfAborted(),!U)continue;if(!uc(U.name))throw new t(`Refusing to retire non-product device '${U.name}'; reconcile its legacy registry row manually.`);if(U.isRunningStateKnown===!1)throw new t(`Running state of legacy device '${U.name}' is unconfirmed`);if(U.isRunning){this.assertOwnersDead(C,D),await R.stop(U,P),P.throwIfAborted();let K=await R.inspect(q,P);if(K&&(K.isRunning||K.isRunningStateKnown===!1))throw new t(`Shutdown of legacy device '${U.name}' is unconfirmed`)}}P.throwIfAborted(),this.assertOwnersDead(C,D)},{timer:c,signal:P,timeoutMs:this.options.timeoutMs??30000,label:"Legacy slot device retirement",onTimeout:()=>k.abort()}),P.throwIfAborted(),await M()})}catch(C){throw(this.options.warn??e.warn)(`[Daemon] Legacy slot device retirement deferred: ${r(C)}`,C),u(C,"Legacy slot devices must be retired first; retry daemon startup after resolving the cause")}}assertOwnersDead(d,c){if(d.owners.some((R)=>c(R)))throw new t("A live execution or cleanup owner still holds legacy slot devices; let it exit and retry daemon startup")}}async function Cp(d){if(!d.brokerConfigured&&!d.registryExists)return;try{await d.open()}catch(c){if((d.warn??e.warn)(`[Daemon] Binding registry upgrade deferred: ${r(c)}`,c),d.brokerConfigured)throw u(c,"Session broker cannot start until legacy slot retirement and registry upgrade complete")}}class js{manager;android;constructor(d,c){this.manager=d;this.android=c}async inspect(d,c){if(d.platform==="watchos")throw new t(`Legacy slot retirement cannot confirm Apple Watch simulator '${d.stableId??d.name}'; legacy slots never held watches.`);let R=await this.manager.getDeviceImagesDetailed(d.platform,{signal:c,bypassIosDeviceListCache:!0}),D=await this.manager.getBootedDevicesDetailed(d.platform,{signal:c,bypassAndroidDeviceListCache:!0,bypassIosDeviceListCache:!0,skipPhysicalIosDiscovery:!0});this.assertComplete(d,R,D);let k=(F)=>d.stableId?(d.platform==="android"?F.name:F.deviceId)===d.stableId:F.name===d.name,P=R.devices.find(k),C=D.devices.find((F)=>k(F)&&(d.platform!=="android"||ae(F.deviceId)));if(D.transitionalSimulators?.some((F)=>k(F.device)))throw new t("Legacy simulator is transitioning; retry retirement after it settles");if(d.platform==="android"&&!C&&P?.isRunningStateKnown===!1)throw new t("Legacy Android running state is unconfirmed");if(d.platform==="android"&&!C)await this.assertAndroidStopped(d,c);return this.currentDevice(d,P,C)}currentDevice(d,c,R){let D=R??c;if(!D)return;return{...c,...R,name:D.name,platform:d.platform,isRunning:R!==void 0||c?.isRunning===!0,isRunningStateKnown:c?.isRunningStateKnown}}assertComplete(d,c,R){let D=d.platform==="ios"?R.succeededSources?.has("ios-simulator"):R.succeededPlatforms.has("android");if(!c.succeededPlatforms.has(d.platform)||!D)throw new t(`Cannot confirm legacy ${d.platform} device inventory; retry with the platform tooling available`);if(d.platform==="android"&&R.devices.some(Cn))throw new t("Cannot confirm legacy shutdown while an Android runtime has unresolved identity")}async assertAndroidStopped(d,c){let R=await this.android.readStates(c),D=await this.android.processes.read({signal:c});if(!D.value)throw new t(`Cannot confirm legacy emulator process absence: ${D.error??"process table unavailable"}`);for(let k of R){if(!ae(k.deviceId)||k.state==="device")continue;let P=db(k.deviceId),C=D.value.filter(Cu).map((M)=>md(M.command)).filter((M)=>M.port===P);if(C.length!==1||!C[0].avdName||uc(C[0].avdName))throw new t("Cannot confirm legacy shutdown while an Android emulator is offline or unauthorized")}if(D.value.some((k)=>this.mayBeTargetProcess(k,d)))throw new t("Legacy emulator process is still running; retry retirement after it exits")}mayBeTargetProcess(d,c){if(!Cu(d))return!1;let{avdName:R}=md(d.command);return!R||R===(c.stableId??c.name)}async stop(d,c){if(!d.deviceId)throw new t(`Legacy device '${d.name}' has no confirmed runtime id`);await this.manager.killDevice({...d,deviceId:d.deviceId},{signal:c,timeoutMs:30000})}}async function Mp(d,c){if(c.isLive(d))return"live";try{let R=await c.getSession(d),D=c.timer.now();return R&&R.status==="released"&&R.release_reason&&bo(R.release_reason)&&R.released_at_ms!==null&&Qy(R,D)===void 0&&JN(R,D)?"recoverable-handoff":"gone"}catch(R){return e.warn(`Session ${d} disposition lookup failed: ${r(R)}`,R),"recoverable-handoff"}}class zs{open;options;controller=new AbortController;backoff;task;retryWait;constructor(d,c){this.open=d;this.options=c;this.backoff=c.backoff??Q({initialDelayMs:5000,maxDelayMs:300000})}start(){if(this.controller.signal.aborted)return;this.task??=this.run().catch((d)=>{if(d instanceof tn)return e.debug(`[Daemon] Registry upgrade skipped until restart: ${r(d)}`),!1;return e.warn(`[Daemon] Binding registry upgrade stopped: ${r(d)}`,d),!1})}async run(){for(let d=1;!this.controller.signal.aborted;d++){let c=this.backoff.delayForAttempt(d);if(await this.tryOpen(d,c))return!0;if(!this.controller.signal.aborted)await new Promise((R)=>{let D=this.options.timer.setTimeout(()=>{this.retryWait=void 0,R()},c);this.retryWait={handle:D,resolve:R}})}return!1}async tryOpen(d,c){try{return await this.open(this.controller.signal),!0}catch(R){if(R instanceof tn)throw R;if(!this.controller.signal.aborted)e.warn(`[Daemon] Binding registry upgrade deferred: ${r(R)} (attempt ${d}; retry delay ${c}ms)`,R);return!1}}async close(){if(this.controller.abort(),this.retryWait)this.options.timer.clearTimeout(this.retryWait.handle),this.retryWait.resolve(),this.retryWait=void 0;await this.task}}function KR(d){return{inventory:(c)=>d().listBootedAndroidDevices({signal:c.signal,androidTargetDeviceId:c.targetDeviceId,skipAndroidProfileEnrichment:!0}),ctrlProxyReady:(c,R)=>d().verifyAndroidCtrlProxyServiceReady(c,R),snapshot:{ctrlProxyIdentity:(c,R)=>d().readAndroidCtrlProxySnapshotIdentity(c,R),ready:async(c,R)=>{await R.assertOwned(),await d().verifyDevice(c.deviceId,"android",{signal:R.signal,readiness:"automationReady"},c),await R.assertOwned()}}}}class Ys{host;brokerExecutionRelease;sessionBrokerService;sessionBrokerConfig;bindingExecOwnerLiveness;bindingJournalInFlight=new Qt;bindingRedrive;maintainedRegistries=new WeakSet;registryClosing=!1;unsupportedRegistrySchema;constructor(d){this.host=d}installManagedExecutionRelease(){let d=new jr({registry:()=>this.host.openBindingRegistry(),journal:{inFlight:this.bindingJournalInFlight},work:G,sessions:qi(this.host.services.sessionManager(),VN(()=>this.host.services.devicePool())),timer:this.host.services.timer(),settler:this.bindingJournalOwner(),isExecOwnerLive:this.bindingOwnerLiveness(),ownership:{isReleaseHeld:(c)=>this.host.lifecycle.managedExecutionReowner()?.isReleaseHeld(c)??!1,confirmOwnership:(c)=>this.host.lifecycle.managedExecutionReowner()?.confirmOwnership(c),loseOwnership:(c)=>this.host.lifecycle.managedExecutionReowner()?.loseOwnership(c)}});this.brokerExecutionRelease=d,this.host.services.sessionManager().onSessionRelease((c,R,D,{snapshot:k,...P})=>d.onSessionReleased(k,P))}bindingOwnerLiveness(){return this.bindingExecOwnerLiveness??=Hq(mc,this.host.services.sessionManager()),this.bindingExecOwnerLiveness}async reownRehydratedManagedExecutions(d){let c=d.filter((R)=>this.host.services.sessionManager().isLiveManagedExecutionSession(R));await this.host.lifecycle.managedExecutionReowner()?.reown(c,{rehydrated:!0})}bindingRegistryExists(){return this.host.bindingRegistry()!==void 0||hh()}bindingJournalOwner(){return{daemonId:this.host.identity.daemonSessionId(),...qq(()=>this.host.identity.processGenerationToken())}}installBrokerDeviceAcquisition(){let d=qi(this.host.services.sessionManager(),VN(()=>this.host.services.devicePool())),c=Su({registry:()=>this.host.openBindingRegistry(),discardAndroidSnapshotOnExit:()=>WZ(this.sessionBrokerConfig),resourceBudgetPolicy:{limit:()=>this.sessionBrokerConfig?.limits.totalDeviceCap??null},sessions:{claimLivenessOwnership:(R,D)=>this.host.services.sessionManager().claimLivenessOwnership(R,D),adoptManagedExecutionLivenessPolicy:(R,D)=>this.host.services.sessionManager().adoptManagedExecutionLivenessPolicy(R,D),releaseSession:async(R)=>{await d.releaseSession(R)}},pool:this.host.services.devicePool(),executions:this.host.services.sessionManager(),owner:()=>this.bindingJournalOwner(),timer:this.host.services.timer(),journal:{owner:this.bindingJournalOwner(),inFlight:this.bindingJournalInFlight}});this.host.setBrokerDeviceAcquisition(c),this.host.lifecycle.setManagedExecutionReowner(new Ws({registry:()=>this.host.openBindingRegistry(),registryExists:()=>this.bindingRegistryExists(),owner:()=>this.bindingJournalOwner(),timer:this.host.services.timer(),isSessionHeld:(R)=>this.host.services.sessionManager().isLiveManagedExecutionSession(R),isSessionPresent:(R)=>this.host.services.sessionManager().hasSession(R)||this.host.services.sessionManager().getReleasingSession(R)!==null,deviceOf:(R)=>this.host.services.sessionManager().getHeldDeviceSessions().find((D)=>D.sessionId===R)?.deviceId??null,onOwnershipLost:(R)=>{this.host.cancelAndReleaseSession(R,"binding-ownership-lost",{cutCallsLearnRelease:!0}).catch((D)=>{e.warn(`[Daemon] Lost managed execution ${R} release failed`,D)})},onOwnershipConfirmed:(R)=>{this.warmConfirmedManagedExecution(R).catch((D)=>{e.warn(`[Daemon] Confirmed managed execution ${R} iOS warm-up failed`,D)})}})),this.host.services.daemonState().setBrokerExecutionReowner(this.host.lifecycle.managedExecutionReowner()),this.host.services.sessionManager().setReleaseDeviceHold((R)=>this.host.lifecycle.managedExecutionReowner()?.releaseDeviceHold(R))}startBackgroundRegistryUpgrade(){if(this.registryClosing||this.host.lifecycle.shutdownInProgress())return!1;if(this.host.lifecycle.sessionBrokerConfigPath())return!0;if(!this.host.identity.socketBindCommitted())return!1;if(!this.host.lifecycle.backgroundRegistryUpgrade()){let d=new zs((c)=>this.host.openBindingRegistry(c),{timer:this.host.services.timer()});this.host.lifecycle.setBackgroundRegistryUpgrade(d),d.start()}return!0}openBindingRegistry(d,c){if(this.unsupportedRegistrySchema)return Promise.reject(this.unsupportedRegistrySchema);let R=this.host.bindingRegistry();if(R)return c?.quiet?R:R.then((k)=>(this.startBindingRegistryMaintenance(k),k));let D=WS({writerVersion:di,migrate:this.host.lifecycle.sessionBrokerConfigPath()!==void 0||this.host.identity.socketBindCommitted(),timer:this.host.services.timer(),isExecOwnerLive:this.bindingOwnerLiveness(),legacyDeviceRetirement:new Vs({signal:d,timer:this.host.services.timer(),isOwnerLive:mc,devices:new js(new Xn,{processes:new lu(new ee,{timer:this.host.services.timer(),processTableSupported:process.platform!=="win32",procFs:process.platform==="linux"?ap:void 0}),readStates:async(k)=>{let P=v.create(null),C=P.getDeviceStates;if(!C)throw new t("Android device-state discovery is unavailable for legacy retirement");return C.call(P,{signal:k,throwOnMissingAdb:!0})}})})});return this.host.setBindingRegistry(D),D.then((k)=>{if(!this.registryClosing)this.host.services.daemonState().setBindingRegistrySchemaProbe(k);if(this.host.deviceClaimMirrors().registryOpened(k.deviceClaims()),!c?.quiet)this.startBindingRegistryMaintenance(k)},()=>{return}),D.catch((k)=>{if(k instanceof tn)this.host.deviceClaimMirrors().skip(),this.unsupportedRegistrySchema=k;if(e.debug(`[Daemon] Binding registry open failed: ${r(k)}`),this.host.bindingRegistry()===D)this.host.setBindingRegistry(void 0)}),D}startBindingRegistryMaintenance(d){if(this.maintainedRegistries.has(d))return;this.maintainedRegistries.add(d),this.brokerExecutionRelease?.recoverSettledBindings();let c=this.host.brokerDeviceAcquisition();if(c&&!this.host.lifecycle.sessionBrokerConfigPath()&&!this.bindingRedrive&&I(Y.NODE_ENV)!=="test")this.bindingRedrive=c.startJournalRedrive(d)}async closeManagedExecutionRelease(){this.registryClosing=!0,this.host.services.daemonState().setBindingRegistrySchemaProbe(void 0),await this.host.lifecycle.backgroundRegistryUpgrade()?.close(),this.host.lifecycle.setBackgroundRegistryUpgrade(void 0),await this.sessionBrokerService?.close(),this.sessionBrokerService=void 0,this.host.services.daemonState().setSessionBrokerService(void 0),this.brokerExecutionRelease?.close(),this.host.lifecycle.managedExecutionReowner()?.close();try{await this.bindingRedrive?.stop()}catch(c){e.warn(`[Daemon] Stopping journal redrive failed: ${r(c)}`,c)}this.bindingRedrive=void 0,this.host.brokerDeviceAcquisition()?.acquisition.close(),this.host.setBrokerDeviceAcquisition(void 0);let d=this.host.bindingRegistry();this.host.setBindingRegistry(void 0),this.host.deviceClaimMirrors().dispose(),await this.host.deviceClaimMirrors().idle();try{await this.host.deviceClaimMirrors().releaseOwnedClaims((await d)?.deviceClaims())}catch(c){e.warn(`[Daemon] Withdrawing this daemon's device claims failed: ${r(c)}`,c)}try{await(await d)?.close()}catch(c){e.warn(`[Daemon] Closing the binding registry failed: ${r(c)}`,c)}}async installSessionBroker(){if(!this.host.lifecycle.sessionBrokerConfigPath()||this.sessionBrokerService)return this.sessionBrokerService;let d=this.host.brokerDeviceAcquisition(),c=this.brokerExecutionRelease;if(!d||!c)throw new t("Session broker requires the provider's native ownership and cleanup machinery");let R=await this.host.openBindingRegistry(),D=await VZ(this.host.lifecycle.sessionBrokerConfigPath());if(this.sessionBrokerConfig=D,this.sessionBrokerService=await bp({deferStart:!0,config:D,registry:R,acquisition:d.acquisition,release:c,journal:d.journalFor(R),mutationSessions:this.host.services.sessionManager(),owner:this.bindingJournalOwner(),timer:this.host.services.timer(),sessionDisposition:(k)=>Mp(k,{isLive:(P)=>this.host.services.sessionManager().peekSession(P)!==null,getSession:(P)=>this.host.readPersistedSession(P),timer:this.host.services.timer()}),liveSessionIds:()=>this.host.services.sessionManager().getAllSessions().map((k)=>this.host.services.sessionManager().ownershipSessionUuid(k.sessionId)),androidReset:KR(()=>this.host.services.deviceReadiness())}),this.host.services.daemonState().setSessionBrokerService(this.sessionBrokerService),!this.bindingRedrive&&I(Y.NODE_ENV)!=="test")this.bindingRedrive=d.startJournalRedrive(R);return this.sessionBrokerService}async warmConfirmedManagedExecution(d){return this.host.warmConfirmedManagedExecution(d)}get testHooks(){return{startBackgroundRegistryUpgrade:()=>this.startBackgroundRegistryUpgrade(),openBindingRegistry:(...d)=>this.host.openBindingRegistry(...d),closeManagedExecutionRelease:()=>this.closeManagedExecutionRelease(),bindingJournalOwner:()=>this.bindingJournalOwner(),setBindingRegistry:(d)=>{this.host.setBindingRegistry(d)}}}}var GR=3,WR=[1000,5000,30000,120000,300000],VR=2000;class Xs{options;intents=new Map;inFlight=new Map;generationOf;retryDelays;versions=0;disposed=!1;skipped=!1;registryOpeningHandled=!1;constructor(d){this.options=d;this.generationOf=d.generationOf??((c)=>kt.current(c)),this.retryDelays=d.retryDelaysMs??WR}skip(){this.skipped=!0;for(let d of this.intents.values())this.clearRetry(d);this.intents.clear()}claimed(d,c,R,D){if(this.skipped)return;let k=this.intents.get(d),P=k?.kind==="claim"&&k.owner.pid===c.pid&&k.owner.ownerToken===c.ownerToken;this.record(d,{kind:"claim",owner:c,claimedAtMs:P?k.claimedAtMs:this.options.timer.now(),...R===void 0?{}:{stillHeld:R},...D===void 0?{}:{isLiveForeignOwner:D}})}released(d,c){if(this.skipped)return;this.record(d,{kind:"release",owner:c,claimedAtMs:this.options.timer.now()})}async acquire(d,c,R){let D=this.skipped?void 0:await this.readStore();if(!D||this.skipped||this.disposed)return{outcome:"unavailable"};try{for(let P=0;P<GR;P++){let C=await this.acquireOnce(D,d,c,R);if(C)return C}let k=await D.get(this.options.platform,d);return k?{outcome:"refused",ownerPid:k.pid}:{outcome:"unavailable"}}catch(k){return e.warn(`[DeviceClaims] Cannot claim ${d} in the host-wide table; the claim files decide: ${r(k)}`,k),{outcome:"unavailable"}}}async acquireOnce(d,c,R,D){let k=await d.get(this.options.platform,c),P=k?.pid===R.pid&&k.ownerToken===R.ownerToken;if(k&&!P&&await this.isLiveOwner(k,D))return{outcome:"refused",ownerPid:k.pid};let C=P?k.claimedAtMs:this.options.timer.now();if(!await d.replaceIf(k,this.claimRow(c,R,C)))return;return this.recordAcquired(c,R,C),{outcome:"claimed"}}async isLiveOwner(d,c){if(d.processGenerationToken!==void 0&&this.generationVerdict(d)==="different")return!1;return c(d)}generationVerdict(d){return this.options.generationVerdict?.(d.pid,d.processGenerationToken)??kt.compare(d.pid,d.processGenerationToken)}recordAcquired(d,c,R){let D=this.intents.get(d);if(D)this.clearRetry(D);this.intents.set(d,{kind:"claim",acquired:!0,owner:c,claimedAtMs:R,version:++this.versions,synced:!0,attempts:0})}async read(d){if(this.skipped)return;let c=await this.readStore();if(this.skipped)return;let R=await c?.get(this.options.platform,d);if(this.skipped||!R)return;if(R.processGenerationToken!==void 0&&this.generationVerdict(R)==="different")return;return R}async readStore(){let d;try{d=this.options.store()??(this.options.whenOpen?await l(this.options.whenOpen,{timer:this.options.timer,timeoutMs:VR,label:"Device claim registry open"}):void 0)}catch(c){if(!this.skipped)throw c;e.debug(`[DeviceClaims] Ignoring skipped registry open: ${r(c)}`);return}return d}reconcile(d){if(this.skipped)return;for(let[c,R]of this.intents)R.synced=!1,R.attempts=0,R.version=++this.versions,this.clearRetry(R),this.write(c,d)}dispose(){this.disposed=!0;for(let d of this.intents.values())this.clearRetry(d)}async idle(){while(this.inFlight.size>0)await Promise.all([...this.inFlight.values()])}async releaseOwnedClaims(d){if(this.skipped)return;let c=new Map;for(let R of this.intents.values())c.set(`${R.owner.pid}:${R.owner.ownerToken}`,R.owner);for(let R of c.values()){if(this.skipped)return;await d.releaseOwnedBy(R)}}record(d,c){if(this.disposed||this.skipped)return;let R=this.intents.get(d);if(R)this.clearRetry(R);this.intents.set(d,{...c,version:++this.versions,synced:!1,attempts:0}),this.write(d)}write(d,c){let R=this.intents.get(d);if(!R||this.disposed||this.skipped||this.inFlight.has(d))return;if(R.kind==="claim"&&this.isGone(R)){this.clearRetry(R),this.intents.delete(d);return}let D=c??this.options.store();if(!D){this.probeRegistry(),this.scheduleRetry(d,R);return}let k=R.version,P=this.issue(D,d,R).then(()=>{if(this.intents.get(d)?.version===k)this.confirm(d,R)},(C)=>{if(e.warn(`[DeviceClaims] Cannot ${R.kind==="claim"?"record":"remove"} the claim on ${d} in the host-wide table: ${r(C)}`,C),this.intents.get(d)?.version===k)this.scheduleRetry(d,R)}).finally(()=>{this.inFlight.delete(d);let C=this.intents.get(d);if(C&&C.version!==k)this.write(d)});this.inFlight.set(d,P)}probeRegistry(){if(this.registryOpeningHandled||!this.options.openRegistry)return;try{if(this.options.registryFileExists?.())this.registryOpeningHandled=this.options.openRegistry()}catch(d){e.warn(`[DeviceClaims] Cannot start registry opening: ${r(d)}`,d)}}isGone(d){try{return d.stillHeld?.()===!1}catch(c){return e.debug(`[DeviceClaims] Cannot re-check a claim file: ${r(c)}`),!1}}async issue(d,c,R){if(R.kind==="release")return d.release(this.options.platform,c,R.owner);let D=await d.get(this.options.platform,c),k=D?.pid===R.owner.pid&&D.ownerToken===R.owner.ownerToken;if(R.acquired){if(D&&!k||!await d.replaceIf(D,this.claimRowFor(c,R,D)))this.dropIntent(c,R);return}if(D&&!k&&await this.heldByLiveForeignOwner(D,R))throw Error(`the row names live owner pid ${D.pid}; the claim file decides this claim until it is gone`);if(!await d.replaceIf(D,this.claimRowFor(c,R,D)))throw Error("the row changed while it was being written")}claimRowFor(d,c,R){let D=R?.pid===c.owner.pid&&R.ownerToken===c.owner.ownerToken;return this.claimRow(d,c.owner,D?R.claimedAtMs:c.claimedAtMs)}async heldByLiveForeignOwner(d,c){return c.isLiveForeignOwner!==void 0&&this.isLiveOwner(d,c.isLiveForeignOwner)}dropIntent(d,c){if(this.intents.get(d)===c)this.intents.delete(d)}claimRow(d,c,R){let D=this.generationOf(c.pid);return{platform:this.options.platform,deviceId:d,kind:"allocation",...this.options.daemonSessionId===void 0?{}:{daemonSessionId:this.options.daemonSessionId},pid:c.pid,ownerToken:c.ownerToken,...D===void 0?{}:{processGenerationToken:D},...c.metadata===void 0?{}:{metadata:c.metadata},claimedAtMs:R,updatedAtMs:this.options.timer.now()}}confirm(d,c){if(c.kind==="release"){this.intents.delete(d);return}c.synced=!0,c.attempts=0}scheduleRetry(d,c){if(this.disposed||this.skipped||c.retry!==void 0)return;let R=this.retryDelays[c.attempts];if(R===void 0)return;c.attempts++,c.retry=this.options.timer.setTimeout(()=>{if(c.retry=void 0,this.intents.get(d)===c&&!c.synced)this.write(d)},R)}clearRetry(d){if(d.retry!==void 0)this.options.timer.clearTimeout(d.retry),d.retry=void 0}}function Ep(d){let c,R;return()=>{let D=d();if(D!==c)c=D,R=void 0,D?.then((k)=>{if(c===D)R=k.deviceClaims()},()=>{return});return R}}function Bp(d,c={}){let R=c.registry??MM,D=c.controllerFor??d1,k=c.timer??i,P=async(M,F,q)=>{if(q.aborted){e.warn(`[statusBar] Release cap expired before the status bar clear for session ${M} on ${F} could start; left the override in place`);return}let U=R.takeOwnedBy(F,M),K=U?D(U.device):null;if(!K)return;await Xe(()=>K.clear(q))},C=(M,F,q)=>{let U=R.hasDeviceWork(F);if(!U&&R.get(F)?.sessionId!==M)return;if(q?.deviceIdentityReplaced){if(e.debug(`[statusBar] Cleanup for session ${M} on replaced serial ${F}: skipped status bar clear`),R.takeOwnedBy(F,M),U)R.runOnDevice(F,async()=>{R.takeOwnedBy(F,M)});return}let K=new AbortController,W=l(()=>R.runOnDevice(F,()=>P(M,F,K.signal)),{timer:k,timeoutMs:wr,unref:!0,label:"Status bar clear",onTimeout:()=>K.abort()}).catch((V)=>{e.warn(`[statusBar] Failed to clear status bar override on ${F}: ${r(V)}`,V)});d.registerPendingDeviceCleanup(F,W,{name:"clear status bar override",leftover:"the released session's status bar override"})};d.onSessionRelease((M,F,q,U)=>{if(U?.upgradeOnly)return;C(M,F,U)}),d.onSessionDeviceUnbound(C)}function Op(d,c=MM){c.forget(d)}function xp(d,c={}){let R=c.registry??Gl,D=c.shellFor??JE,k=c.timer??i,P=(C,M,F)=>{let q=R.takeOwnedBy(M,C);if(!q)return;if(F?.deviceIdentityReplaced){e.debug(`Kill-profile restore for session ${C} on replaced serial ${M}: skipped device writes`);return}d.registerPendingDeviceCleanup(M,TJ(q,D,k),{name:"restore kill profile",leftover:"the released session's battery, Doze, standby-bucket and appop changes"})};d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;P(C,M,q)}),d.onSessionDeviceUnbound(P)}function _p(d,c={}){let R=c.registry??fS,D=c.consoleFor??q1,k=c.timer??i,P=(C,M,F)=>{let q=R.takeOwnedBy(M,C);if(!q)return;if(F?.deviceIdentityReplaced){e.debug(`Sensor restore for session ${C} on replaced serial ${M}: skipped emulator sensor writes`);return}d.registerPendingDeviceCleanup(M,mX(q,D,k),{name:"restore emulator sensors",leftover:"the released session's emulator sensor values"})};d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;P(C,M,q)}),d.onSessionDeviceUnbound(P)}function Fp(d,c=Zf){let R=(D,k,P)=>{let C=c.stopOwnedBy(k,D);if(!C)return;if(P?.deviceIdentityReplaced){e.debug(`Audio injections for session ${D} on replaced serial ${k} stopped`);return}d.registerPendingDeviceCleanup(k,C,{name:"stop emulator audio injection",leftover:"audio the released session was injecting into the emulator microphone"})};d.onSessionRelease((D,k,P,C)=>{if(C?.upgradeOnly)return;R(D,k,C)}),d.onSessionDeviceUnbound(R)}function Np(d,c=Zf,R=i){return(D)=>{let k=c.stopOwnerless(D);if(!k)return;CS(d,D,k,{timer:R,capMs:wr,label:"stop sessionless emulator audio injection"})}}var jR=5000;async function zR(d,c,R,D=Js){let k=c(d.device),P=[];for(let C of d.actions)try{await Xe(()=>l(()=>Q6(k,C),{timer:R,timeoutMs:jR,label:`Restore display-profile ${C.facet}`}))}catch(M){P.push(C.facet),e.warn(`Failed to restore display-profile ${C.facet} on ${d.device.deviceId}: ${r(M)}`,M)}if(d.actions.some((C)=>["screenSize","cutout","navigationMode"].includes(C.facet)))D(d.device.deviceId,"Display geometry restored");return P}function qp(d,c={}){let R=c.registry??tu,D=c.portsFor??XE,k=c.timer??i,P=c.invalidate??Js,C=(M,F,q)=>{let U=R.takeOwnedBy(F,M);if(!U)return;if(q?.deviceIdentityReplaced){e.debug(`Display-profile restore for session ${M} on replaced serial ${F}: skipped device writes`);return}d.registerPendingDeviceCleanup(F,zR(U,D,k,P),{name:"restore display profile",leftover:"the released session's screen size, display, overlay, force-dark and posture changes"})};d.onSessionRelease((M,F,q,U)=>{if(U?.upgradeOnly)return;C(M,F,U)}),d.onSessionDeviceUnbound(C)}function Up(d,c={}){let R=c.registry??Kf,D=c.clientFor??gJ,k=c.timer??i,P=(C,M,F)=>{let q=R.takeOwnedBy(M,C);if(!q)return;if(F?.deviceIdentityReplaced){e.debug(`Keyboard-profile restore for session ${C} on replaced serial ${M}: skipped device writes`);return}d.registerPendingDeviceCleanup(M,yJ(q,D,k),{name:"restore keyboard profile",leftover:"the released session's AutoMobile keyboard behaviour profile"})};d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;P(C,M,q)}),d.onSessionDeviceUnbound(P)}function Kp(d,c=t1){d.onSessionRelease((R,D)=>{let k={deviceId:D,sessionUuid:R};if(!c.hasActiveConditions(k))return;d.registerPendingDeviceCleanup(D,c.restore(k),{name:"restore device condition",leftover:"the released session's device-condition fixtures"})}),d.onSessionDeviceUnbound((R,D)=>{let k={deviceId:D,sessionUuid:R};if(!c.hasActiveConditions(k))return;d.registerPendingDeviceCleanup(D,c.restore(k),{name:"restore device condition",leftover:"the unbound session's device-condition fixtures"})})}function Wp(d,c=Lb){d.onSessionRelease((R,D,k,P)=>{if(!P.upgradeOnly)c.clear(D)}),d.onSessionDeviceUnbound((R,D)=>c.clear(D))}function Vp(d,c=Cy){let R=(D,k,P,C)=>{if(C){c.forgetOwnerOnDevice(D,k);return}if(!c.hasOwnedMappings(D,k))return;d.registerPendingDeviceCleanup(k,c.releaseOwnerOnDevice(D,k),{name:"remove adb reverse mappings",leftover:P})};d.onSessionRelease((D,k,P,C)=>{if(C.upgradeOnly)return;R(D,k,"the released session's adb reverse mappings",C.deviceIdentityReplaced)}),d.onSessionDeviceUnbound((D,k,P)=>R(D,k,"the unbound session's adb reverse mappings",P?.deviceIdentityReplaced))}function Jp(d,c=hS){let R=(D,k)=>{d.registerPendingDeviceCleanup(D,k,{name:"stop BLE peripherals",leftover:"the released session's Bumble sidecars"})};d.onSessionRelease((D,k,P,C)=>{if(!C.upgradeOnly)R(k,c.releaseSession(D))}),d.onSessionDeviceUnbound((D,k)=>R(k,c.unbindSession(D)))}function Xp(d,c=vJ){let R=(D,k,P)=>{let C=c();if(!C?.holdsHostPortFor(k))return;let M=d.getSessionForDevice(k);if(M!==null){e.info(`[AndroidAuto] keeping the Desktop Head Unit for ${k}: session ${M} still holds it after ${D} left it`);return}if(P?.deviceIdentityReplaced){jp(C,k,{deviceStopped:!0});return}d.registerPendingDeviceCleanup(k,jp(C,k,{releaseRedirect:!0}),{name:"stop the Android Auto Desktop Head Unit",leftover:"the released session's Desktop Head Unit and its host port 5277 redirect"})};d.onSessionRelease((D,k,P,C)=>{if(C.upgradeOnly)return;R(D,k,C)}),d.onSessionDeviceUnbound(R)}async function jp(d,c,R){try{await Xe(async()=>await d.stopDesktopHeadUnit(c,R))}catch(D){e.warn(`[AndroidAuto] stopping the Desktop Head Unit for ${c} after its session ended failed: ${r(D)}`,D)}}function Qp(d,c,R=G){let D=new Set,k=async(C,M)=>{let F=M==="cli-idle-timeout"?d.getTerminalReleaseSnapshot(C.baseSessionId)?.cliIdleTimeoutMs:void 0;VI(R,C,new lc(C.sessionId,M,F)).catch((q)=>{e.warn(`[DeviceLabelMap] Failed to cancel executions of ${C.sessionId}`,q)}),await Ds({manager:d,pool:c},C.deviceId,C.sessionId,{reason:M})},P=async(C,M,F)=>{let q=d.getSession(M);if(!q)return;let U={sessionId:M,baseSessionId:C,deviceId:q.assignedDevice,excludeExecutionId:Fe()?.execution?.executionId};try{if(ir(F))await k(U,F);else await _A(d,c,U,R);e.info(`[DeviceLabelMap] Released label session ${M} with its base ${C}`)}catch(K){e.warn(`[DeviceLabelMap] Failed to release label session ${M} with its base ${C}`,K)}};return d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;let U=d.takeDerivedLabelSessions(C,F);if(U.length===0)return;let K=Promise.resolve().then(()=>Promise.all(U.map((W)=>P(C,W,F)))).then(()=>{return});D.add(K),K.finally(()=>D.delete(K))}),{settled:async()=>{while(D.size>0)await Promise.all(D)}}}function Zp(d,c,R,{shutdown:D,snapshot:k,upgradeOnly:P}){let C=d.takeRecordingIds(c);if(D.fallbacks?.has(c))return;if(R==="daemon-shutdown")D.announced?.add(c);let M={...C.length>0?{recordingIds:C}:{},...P?{upgradeOnly:!0}:{}};d.emit(c,R,k,Object.keys(M).length>0?M:void 0)}var YR=Ie([n(),a(),TP()]),XR=s({settingDefaults:s({name:n(),sessionId:n(),values:hce(p(xS),YR)})});class Qs{db;constructor({db:d}={}){this.db=d}getDb(){return this.db??_e()}async get(d){let c=await this.getDb().selectFrom("device_configs").select(["platform","config_json"]).where("device_id","=",d).executeTakeFirst();if(!c)return null;let R;try{R=XR.parse(JSON.parse(c.config_json))}catch(D){return e.warn(`Ignoring unreadable device setting defaults for ${d}: ${r(D)}`,D),null}return{platform:c.platform,...R.settingDefaults}}async put(d,c){let R={device_id:d,platform:c.platform,config_json:JSON.stringify({settingDefaults:{name:c.name,sessionId:c.sessionId,values:c.values}})};await this.getDb().insertInto("device_configs").values(R).onConflict((D)=>D.column("device_id").doUpdateSet({platform:R.platform,config_json:R.config_json,updated_at:f`(datetime('now'))`})).execute()}async delete(d){await this.getDb().deleteFrom("device_configs").where("device_id","=",d).execute()}}function em(d,c={}){let R=(D,k)=>{(c.monitor?.()??Fc()).stopMonitoring(k)};d.onSessionRelease((D,k,P,C)=>{if(!C?.upgradeOnly)R(D,k)}),d.onSessionDeviceUnbound(R)}var QR=(d)=>new i1(v.create(d));function nm(d,c={}){let R=c.registry??ZE,D=c.appLinksFor??QR,k=(P,C,M)=>{let F=R.takeOwnedBy(C,P);if(F.length===0)return;if(M?.deviceIdentityReplaced){e.debug(`[appLinks] Restore for session ${P} on replaced serial ${C}: skipped pm writes`);return}d.registerPendingDeviceCleanup(C,OJ(F,D),{name:"restore App Links state",leftover:"the released session's App Links verification and user selections"})};d.onSessionRelease((P,C,M,F)=>{if(F?.upgradeOnly)return;k(P,C,F)}),d.onSessionDeviceUnbound(k)}function rm(d,c={}){let R=c.registry??O1,D=c.adbFor??((P)=>v.create(P)),k=(P,C,M)=>{let F=R.takeOwnedBy(C,P);if(F.traces.length===0&&F.deviceFiles.length===0)return;if(M?.deviceIdentityReplaced){e.info(`[profiling] Session ${P}'s ${C} was replaced; not cleaning up`);return}let q={name:C,platform:"android",deviceId:C},U=Xe(async()=>M1(C,F,D(q),{timer:c.timer??i})).catch((K)=>(e.warn(`[profiling] Cleaning up session ${P}'s profiling state threw: ${r(K)}`,K),{deviceId:C,stoppedTraces:[],removedFiles:[],errors:[r(K)]}));d.registerPendingDeviceCleanup(C,U,{name:"stop released session's trace recorders and remove profiling files",leftover:"a perfetto recorder or a heap dump file the released session started"})};d.onSessionRelease((P,C,M,F)=>{if(!F?.upgradeOnly)k(P,C,F)}),d.onSessionDeviceUnbound(k)}function sm(d,c={}){let R=c.registry??Ly,D=(k,P)=>{R.clearOwnedBy(P,k)};d.onSessionRelease((k,P,C,M)=>{if(!M?.upgradeOnly)D(k,P)}),d.onSessionDeviceUnbound(D)}var ZR={sync:(d)=>dG(d),resolveSessionKey:(d)=>u_(d)};function am(d,c,R=ZR){let D=(k,P)=>{if(!c.passiveWorkPolicy().allows("android","appearance-sync",P))return;let C=c.devicePool().getDevice(P);if(C?.platform!=="android")return;R.sync({deviceId:C.id,name:C.id,platform:"android",incarnation:C.incarnation,sessionKey:R.resolveSessionKey(k)})};d.onSessionCreated((k)=>{D(k.sessionId,k.assignedDevice)}),d.onDeviceOwnershipChange((k,P)=>{if(P!=="full")return;let C=d.getSessionForDevice(k);if(C)D(C,k)})}function eD(d,c,R){let D=new Set([R,d.ownershipSessionUuid(R),d.getBaseSessionOfDerivedLabel(R)].filter((k)=>k!==void 0));return(k)=>{for(let P of D)c.markMutationUnrecorded(P,k)}}function dm(d,c,R){Gie(d),Ec(d,{timer:c,gapMarkerFor:(F)=>eD(d,R,F)}),Bp(d),nm(d),xp(d),_p(d),Fp(d),qp(d),Up(d),Kp(d),Wp(d),Vp(d),Jp(d),Xp(d),em(d),IZ(d),_Z(d),rm(d),sm(d),Nc(d,{...St,markDeviceNeedsRecorderRecovery:Oc(d)}),d.onDeviceOwnershipChange((F,q)=>{if(q==="full")R.deviceDataStreamServer()?.invalidateDeviceFrames(F);else R.deviceDataStreamServer()?.invalidateInitialDeviceFrames(F)}),d.setManagedExecutionRecoveryListener((F,q)=>R.managedExecutionReowner()?.noteRecovering(F,q)),d.setLateRehydrationListener((F)=>R.reownRehydratedManagedExecutions(F)),d.setActiveSessionExecutionChecker((F,q)=>R.hasActiveSessionExecution(F,q)),d.setSessionExecutionDeadlineLookup((F,q)=>R.latestSessionExecutionDeadlineMs(F,{onSessionClock:!0,...q})),G.setSessionClockOffsetProvider(()=>d.sessionNow()-c.now()),d.setExpiryReleaseExecutionCanceller((F,q,U,K)=>R.cancelExecutionsForExpiryRelease(F,q,U,K));let D=_c(d),k=Bc(d,{timer:c}),P=Np(d),C=new d4(new Qs,new kA,(F)=>d.getSessionForDevice(F),{timer:c});SZ(C),RZ(C);let M=wZ(d,C,c);d.setDeviceAcquisitionExecutionCanceller((F,q)=>{G.cancelSessionlessDeviceUse(F,{excludeExecutionId:Fe()?.execution?.executionId}),R.socketServer()?.liftSessionlessStrokesOn(F),D(F,q),k(F),P(F),M(F,q)}),d.onSessionCreated((F)=>{he.clearReleasedSession(F.sessionId),R.setupNavigationGraphUpdateListener(he.getInstanceForSession(F.sessionId))}),am(d,R),d.onSessionRelease((F,q,U,K)=>{if(K?.upgradeOnly)return;R.deviceReadiness().clearExplicitDevicePin(q);let W=he.findInstanceForSession(F);if(W)R.navigationGraphListenerManagers.delete(W);he.releaseSession(F),xe.clearCache(q),Rs.invalidate(q),E.getExistingInstance(q)?.releaseSessionBinding(F),x.getExistingInstance(q)?.releaseSessionBinding(F)}),Qp(d,VN(()=>R.devicePool())),d.onSessionDeviceUnbound((F,q)=>{R.socketServer()?.liftStrokesHeldByOn(F,q),R.deviceReadiness().clearExplicitDevicePin(q);let U=he.getInstanceForSession(F);he.resetSession(F),R.navigationGraphListenerManagers.delete(U),R.setupNavigationGraphUpdateListener(he.getInstanceForSession(F)),xe.clearCache(q),Rs.invalidate(q),E.getExistingInstance(q)?.releaseSessionBinding(F),x.getExistingInstance(q)?.releaseSessionBinding(F)}),d.onSessionRelease((F,q,U,{snapshot:K,...W})=>{if(Zp({takeRecordingIds:xc,emit:(...V)=>Ai.emit(...V)},F,U,{shutdown:{fallbacks:R.shutdownFallbackReleaseNotifications(),announced:R.shutdownReleaseNotifications()},snapshot:K,upgradeOnly:W?.upgradeOnly}),R.shutdownFallbackReleaseNotifications()?.has(F))return;if(K.terminal)Kq(F).catch((V)=>{e.warn(`[Appearance] Failed to drop config of released session ${F}`,V)})})}function cm(d,c,R){return d.onSessionExecutionEnded((D,{admitted:k})=>{let P=new Set(D.map((C)=>at(C,c)??C));for(let C of P)c.recordToolCallEnded(C,{admitted:k});R.sessionExecutionsEnded(new Set([...D,...P]))})}function ta({tracker:d,sessionManager:c,devicePool:R},D,k){let{recoveryOnly:P,...C}=k??{};if(P)return R.isSessionRecoveryInFlight(D);let M=at(D,c)??D;return C.sessionClockStartedAtOrBefore===void 0&&R.isSessionRecoveryInFlight(D)||d.hasActiveSessionUuidExecutions(D,C)||d.hasActiveAutolockSessionExecutions(D,C)||M!==D&&(d.hasActiveSessionUuidExecutions(M,C)||d.hasActiveAutolockSessionExecutions(M,C))}function ra({tracker:d,sessionManager:c,devicePool:R},D,k={}){if(R.isSessionRecoveryInFlight(D))return Number.POSITIVE_INFINITY;let P=at(D,c)??D,C=d.getLatestSessionExecutionDeadlineMs(D,k);if(P===D)return C;let M=d.getLatestSessionExecutionDeadlineMs(P,k);if(C===void 0||M===void 0)return C??M;return Math.max(C,M)}function lm(d,c,R,D={}){let k=D.excludeReads?{excludeReads:!0}:{};return{hasActiveExecutions:(P)=>ta({tracker:d,sessionManager:c,devicePool:R},P,k),latestExecutionDeadlineMs:(P)=>ra({tracker:d,sessionManager:c,devicePool:R},P,{onSessionClock:!0,...k})}}function um(d,c,R){return d.getAllDevices().filter((D)=>D.platform==="android"&&c.allows("android","appearance-sync",D.id)).map((D)=>({deviceId:D.id,name:D.id,platform:"android",incarnation:D.incarnation,sessionKey:u_(R.getSessionForDevice(D.id)??void 0)}))}var yn=1000;function tD(d,c){return d.attachClaimMirror(c),d}class oa{host;unsubscribeSessionExecutionEnded=null;constructor(d){this.host=d}createDevicePool(d,c){let R=new aH(this.sessionExecutionProbe({excludeReads:!0}),this.host.services.timer(),sH,()=>this.host.services.sessionManager().sessionNow()),D=Ep(()=>this.host.bindingRegistry()),k=(C)=>this.host.deviceClaimMirrors().register(new Xs({platform:C,store:D,whenOpen:async()=>(await this.host.bindingRegistry())?.deviceClaims(),registryFileExists:hh,openRegistry:()=>this.host.startBackgroundRegistryUpgrade(),timer:this.host.services.timer(),daemonSessionId:this.host.identity.daemonSessionId()})),P=k("android");return pH.create({deviceClaimMirrors:{android:P,ios:k("ios")},sessionManager:this.host.services.sessionManager(),daemonSessionId:this.host.identity.daemonSessionId(),timer:this.host.services.timer(),bindingExclusion:this.host.bindingExclusionFactory()(this.host.services.timer()),...this.host.foreignCtrlProxyForwardEvidence()?{foreignDeviceOwnership:tD(new gh(void 0,void 0,void 0,{timer:this.host.services.timer(),forwardEvidence:this.host.foreignCtrlProxyForwardEvidence()}),P)}:{},managedExecutionOwnership:()=>this.host.lifecycle.managedExecutionReowner(),missingDeviceMisses:this.host.lifecycle.deviceDisconnectMisses(),installedAppsRepository:this.host.services.installedAppsRepository(),deviceSessionRepository:this.host.services.deviceSessionRepository(),releaseSessionForDisconnectedDevice:(C,M,F,{shouldCommit:q,releaseOptions:U}={})=>this.host.cancelAndReleaseSession(C,F,{shouldCommit:q,deferFailureFallback:!0,releaseOptions:U}),ownerDisconnect:{release:async(C,M)=>{let F=R.keeps(C);if(F)return F;await this.host.cancelAndReleaseSession(C.sessionId,M,{expectedSession:C,cutCallsLearnRelease:!0})}},onDeviceReady:(C)=>this.host.onDeviceReadyForSessionRegistry(C),recoveryPolicy:d,onDeviceFramesInvalidated:(C)=>{this.host.lifecycle.deviceDataStreamServer()?.invalidateDeviceFrames(C),ma().deviceIdentityChanged(C)},onDeviceIncarnationAssigned:(C)=>this.host.lifecycle.recorderDeviceIncarnationListener()?.(C),onDeviceRemoved:(C,M)=>{if(ma().deviceRemoved(C),Kie(C),tE.retireDevice(C),Op(C),ln.getInstance().retireDevice(C),ZE.retireDevice(C),Gl.retireDevice(C),fS.retireDevice(C),tu.retireDevice(C),YP.retireDevice(C),Ly.retireDevice(C),Kf.retireDevice(C),Rs.invalidate(C),this.host.services.deviceReadiness().clearExplicitDevicePin(C),this.host.services.deviceSessionRegistry().onDeviceDisconnected(C),this.host.lifecycle.deviceDataStreamServer()?.removeDeviceFrames(C),M==="android")E.evictAfterDeviceRemoval(C).catch((F)=>{e.warn(`[Daemon] Failed to stop Android CtrlProxy for removed device ${C}: ${r(F)}`,F)});if(M==="ios")ve.evictAfterDeviceRemoval(C).catch((F)=>{e.warn(`[Daemon] Failed to stop iOS CtrlProxy for removed device ${C}: ${r(F)}`)})},onDeviceStateChanged:this.host.deviceStateChangeNotifier(),emulatorLossIncidentStore:new wM({timer:this.host.services.timer(),idGenerator:this.host.services.idGenerator()}),ambientExecutionIdReader:e1,cancelDeviceSessionExecutions:Object.assign((C,M,F)=>this.cancelAndDrainDeviceSessionExecutions(C,M,F),{cancelDeviceExecutions:(C,M,F)=>this.cancelAndDrainDeviceExecutions(C,M,F)}),idGenerator:this.host.services.idGenerator(),deviceSessionContinuityEnabled:LF(c)})}stopSessionTimers(){this.host.deviceStateChangeNotifier().dispose(),this.host.services.sessionManager().stopCleanupTimer(),this.host.observerSessionRegistry().dispose(),this.unsubscribeSessionExecutionEnded?.(),this.unsubscribeSessionExecutionEnded=null}subscribeToolCallEndActivity(){this.unsubscribeSessionExecutionEnded?.(),this.unsubscribeSessionExecutionEnded=cm(G,this.host.services.sessionManager(),this.host.services.devicePool())}configureSessionLifecycleCallbacks(){dm(this.host.services.sessionManager(),this.host.services.timer(),{markMutationUnrecorded:(d,c)=>this.host.services.daemonState().getSessionBrokerService()?.markMutationUnrecorded(d,c),deviceDataStreamServer:()=>this.host.lifecycle.deviceDataStreamServer(),socketServer:()=>this.host.lifecycle.socketServer(),managedExecutionReowner:()=>this.host.lifecycle.managedExecutionReowner(),deviceReadiness:()=>this.host.services.deviceReadiness(),devicePool:()=>this.host.services.devicePool(),passiveWorkPolicy:()=>this.host.services.passiveWorkPolicy(),navigationGraphListenerManagers:this.host.lifecycle.navigationGraphBridge().listenerManagers,shutdownReleaseNotifications:()=>this.host.lifecycle.shutdownReleaseNotifications(),shutdownFallbackReleaseNotifications:()=>this.host.lifecycle.shutdownFallbackReleaseNotifications(),setupNavigationGraphUpdateListener:(d)=>this.host.lifecycle.navigationGraphBridge().attach(d),reownRehydratedManagedExecutions:(d)=>this.host.reownRehydratedManagedExecutions(d),hasActiveSessionExecution:(d,c)=>this.hasActiveSessionExecution(d,c),latestSessionExecutionDeadlineMs:(d,c)=>this.latestSessionExecutionDeadlineMs(d,c),cancelExecutionsForExpiryRelease:(d,c,R,D)=>this.cancelExecutionsForExpiryRelease(d,c,R,D)})}getAppearanceSyncTargets(){return um(this.host.services.devicePool(),this.host.services.passiveWorkPolicy(),this.host.services.sessionManager())}hasActiveSessionExecution(d,c){return ta({tracker:G,sessionManager:this.host.services.sessionManager(),devicePool:this.host.services.devicePool()},d,c)}sessionExecutionProbe(d={}){let c={isSessionRecoveryInFlight:(R)=>this.host.services.devicePool().isSessionRecoveryInFlight(R)};return lm(G,this.host.services.sessionManager(),c,d)}latestSessionExecutionDeadlineMs(d,c={}){return ra({tracker:G,sessionManager:this.host.services.sessionManager(),devicePool:this.host.services.devicePool()},d,c)}cancelExecutionsForExpiryRelease(d,c,R,D){VI(G,{sessionId:d,baseSessionId:at(d,this.host.services.sessionManager()),deviceId:D,excludeExecutionId:R.excludeExecutionId},c).catch((k)=>{e.warn(`[Daemon] Failed to cancel executions of released session ${d}: ${r(k)}`,k)})}async cancelAndReleaseSession(d,c="explicit-release",R){let{allowExpired:D=!1,expectedSession:k,shouldCommit:P}=R??{},C=async(M)=>{if(P?.()===!1)return!1;let F=k?.assignedDevice??this.host.services.devicePool().getAllDevices().find((K)=>O(K)===d)?.id??null,q=null,U=!1;if(await Ds({manager:this.host.services.sessionManager(),pool:this.host.services.devicePool()},F,d,{deferFailureFallback:R?.deferFailureFallback,release:async()=>{if(k)q=await this.host.services.sessionManager().releaseSession(d,c,{expectedOwner:{session:k,deviceId:k.assignedDevice}});else if(P){let K=await this.host.services.sessionManager().releaseSessionUnlessSuperseded(d,c,{commitFence:P,allowExpired:D,...R?.releaseOptions});if(K.superseded)return e.info(`Kept session ${d}: a newer identity confirmation superseded its release (reason=${c})`),U=!0,null;q=K.deviceId}else q=await this.host.services.sessionManager().releaseSession(d,c,{allowExpired:D,...R?.releaseOptions});if(!this.isSessionDeviceAssigned(q,d))q=null;return q}}),U)return!1;if(!q||this.isSessionDeviceAssigned(q,d))return e.info(`Cancelled session ${d} (${M} executions); no device freed (reason=${c})`),!1;return e.info(`Cancelled session ${d} (${M} executions) and released device ${q} (reason=${c})`),!0};if(R?.cutCallsLearnRelease){let M=G.getActiveDeviceSessionExecutionCount(d);return this.host.services.sessionManager().cancelExecutionsCutByRelease(d,c),C(M)}return EZ(d,c,C)}isSessionDeviceAssigned(d,c){return d!==null&&O(this.host.services.devicePool().getDevice(d))===c}async cancelAndDrainDeviceExecutions(d,c,R){let D=await G.cancelDeviceExecutions(d,c,R);if(D===0)return 0;if(!await G.waitForDeviceExecutionsToEnd(d,yn,R))e.warn(`[Daemon] Timed out after ${yn}ms draining cancelled executions for device ${d}`);return D}async cancelAndDrainDeviceSessionExecutions(d,c,R){let D=await G.cancelDeviceSessionExecutions(d,c,R);if(D===0)return 0;if(!await G.waitForDeviceSessionExecutionsToEnd(d,yn,R))e.warn(`[Daemon] Timed out after ${yn}ms draining cancelled executions for device session ${d}`);return D}}async function pm(d,c,R,D=gQ){if(d.timedOut)return e.info("[Appearance] Startup rehydration timed out; keeping per-session appearance rows"),[];let k=new Set(d.skipped.filter(({reason:P})=>P!=="not-recoverable").map(({sessionUuid:P})=>P));try{let P=[...R.liveDaemonSessionIds].some((M)=>M!==R.ownDaemonSessionId),C=await D(async(M)=>k.has(M)||nD(c.findSession(M))||await iD(M,R,P));if(C.length>0)e.info(`[Appearance] Dropped ${C.length} stale per-session appearance rows`);return C}catch(P){return e.warn(`[Appearance] Startup appearance-row sweep failed: ${r(P)}`,P),[]}}async function iD(d,c,R){try{let D=await c.getPersistedSession(d);if(D===void 0)return R;return D.status==="active"}catch(D){return e.warn(`[Appearance] Could not read session ${d} during startup sweep; keeping its row: ${r(D)}`,D),!0}}function nD(d){return d!==null&&d!==void 0}import{createServer as oA}from"http";import{AsyncLocalStorage as rD}from"async_hooks";var gm=new rD;function vm(d,c){return gm.run(d,c)}function ym(){return gm.getStore()}var oD=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,sD=/^(?:[a-z][a-z0-9_*/-]{0,255}|[a-z0-9][a-z0-9_*/-]{0,240}@[a-z][a-z0-9_*/-]{0,13})$/,aD=/^[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]$/,fm=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,dD=/^(?:[\x21\x23-\x24\x26-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]|%[0-9a-fA-F]{2})*$/;function Sn(d){return d.replace(/^[ \t]+|[ \t]+$/g,"")}function cD(d){if(typeof d!=="string"||d.length>512||/[^\x20-\x7e\t]/.test(d))return;let c=d.split(",");if(c.length>32)return;let R=new Set;for(let D of c){let k=Sn(D);if(k==="")continue;let P=k.indexOf("="),C=k.slice(0,P),M=k.slice(P+1);if(P<0||!sD.test(C)||!aD.test(M)||R.has(C))return;R.add(C)}return d}function lD(d,c){let R=d.indexOf("=");if(R<0)return c&&fm.test(Sn(d));return fm.test(Sn(d.slice(0,R)))&&dD.test(Sn(d.slice(R+1)))}function uD(d){if(typeof d!=="string"||d.length>8192||/[^\x20-\x7e\t]/.test(d))return;let c=d.split(",");if(c.length>180)return;return c.every((D)=>D.split(";").every((k,P)=>lD(k,P>0)))?d:void 0}function Sm(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d,R=c[PV];if(typeof R!=="string"||R.length!==55)return;let D=oD.exec(R);if(!D||/^0+$/.test(D[1])||/^0+$/.test(D[2]))return;return Object.freeze({traceparent:R,traceId:D[1],parentId:D[2],traceFlags:D[3],tracestate:cD(c[AV]),baggage:uD(c[TV])})}var sa=600000,wm=15000;class aa{deps;maintenanceAdmissionToken;maintenanceAdmissionExpiresAt;maintenanceAdmissionExpiryTimer;maintenanceAdmissionAbortController;maintenanceRestartConsumed=!1;acceptanceRestartAdmissionToken;acceptanceRestartAdmissionOwnerSessionId;acceptanceRestartAdmissionCommitted=!1;acceptanceRestartAdmissionExpiresAt;acceptanceRestartAdmissionExpiryTimer;constructor(d){this.deps=d}releaseAll(){this.releaseDaemonMaintenanceAdmission(this.maintenanceAdmissionToken),this.releaseAcceptanceRestartAdmission(this.acceptanceRestartAdmissionToken)}prepareDaemonRestart(d){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};let c=G.prepareForDaemonRestart();if(c!=="accepted")return{accepted:!1,reason:c};if(!this.deps.onRestartAccepted)return G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"};try{return this.deps.onRestartAccepted(),{accepted:!0}}catch(R){return e.warn("Failed to initiate an admitted daemon restart",R),G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"}}}prepareDaemonMaintenance(d){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};this.expireDaemonMaintenanceAdmission();let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"sessions_unavailable"};let R=c.length,D=G.prepareForDaemonMaintenance(R);if(D!=="accepted")return{accepted:!1,reason:D};let k=this.deps.idGenerator.next();return this.maintenanceAdmissionToken=k,this.maintenanceAdmissionExpiresAt=this.deps.timer.now()+sa,this.maintenanceAdmissionExpiryTimer=this.deps.timer.setTimeout(()=>this.releaseDaemonMaintenanceAdmission(k),sa),this.maintenanceAdmissionAbortController=new AbortController,this.maintenanceRestartConsumed=!1,{accepted:!0,maintenanceToken:k}}completeDaemonMaintenance(d){if(!this.deps.generationMatches(d)||!this.daemonMaintenanceAdmissionMatches(d.maintenanceToken))return{completed:!1};return this.releaseDaemonMaintenanceAdmission(d.maintenanceToken),{completed:!0}}daemonMaintenanceAdmissionMatches(d){return this.expireDaemonMaintenanceAdmission(),typeof d==="string"&&this.maintenanceAdmissionToken!==void 0&&d===this.maintenanceAdmissionToken}expireDaemonMaintenanceAdmission(){if(this.maintenanceAdmissionToken!==void 0&&this.maintenanceAdmissionExpiresAt!==void 0&&this.maintenanceAdmissionExpiresAt<=this.deps.timer.now())this.releaseDaemonMaintenanceAdmission(this.maintenanceAdmissionToken)}releaseDaemonMaintenanceAdmission(d){if(typeof d!=="string"||this.maintenanceAdmissionToken===void 0||d!==this.maintenanceAdmissionToken)return;if(this.maintenanceAdmissionExpiryTimer!==void 0)this.deps.timer.clearTimeout(this.maintenanceAdmissionExpiryTimer);this.maintenanceAdmissionAbortController?.abort(Error("Daemon maintenance admission expired or was released")),G.clearDaemonMaintenancePreparation(),this.maintenanceAdmissionToken=void 0,this.maintenanceAdmissionExpiresAt=void 0,this.maintenanceAdmissionExpiryTimer=void 0,this.maintenanceAdmissionAbortController=void 0,this.maintenanceRestartConsumed=!1}restartAdmittedDaemon(d){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};if(!this.daemonMaintenanceAdmissionMatches(d.maintenanceToken))return{accepted:!1,reason:"maintenance_token_invalid"};if(this.maintenanceRestartConsumed)return{accepted:!1,reason:"maintenance_token_consumed"};let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"sessions_unavailable"};if(c.length>0)return{accepted:!1,reason:"active_sessions"};let R=G.prepareForAdmittedDaemonRestart();if(R!=="accepted")return{accepted:!1,reason:R};if(!this.deps.onRestartAccepted)return G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"};this.maintenanceRestartConsumed=!0;try{return this.deps.onRestartAccepted(),{accepted:!0}}catch(D){return e.warn("Failed to initiate a maintenance-admitted daemon restart",D),G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"}}}restartAcceptanceSession(d,c){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};if(c===void 0)return{accepted:!1,reason:"restart_pending"};this.expireAcceptanceRestartAdmission();let R=this.acceptanceSessionRestartScope(d.scope);if(!R)return{accepted:!1,reason:"scope_invalid"};if(R.expiresAt<=this.deps.timer.now())return{accepted:!1,reason:"scope_expired"};let D=this.deps.currentIdentity();if(!TZ(this.deps.liveAcceptanceStartupSecret,D,R,d.acceptanceCapability))return{accepted:!1,reason:"acceptance_capability_invalid"};let k=this.acceptanceRestartSessionRefusal(R);if(k)return k;let P=G.prepareForDaemonRestart();if(P!=="accepted")return{accepted:!1,reason:P==="active_operations"?"active_operations":"restart_pending"};let C=this.deps.idGenerator.next(),M=Math.min(wm,R.expiresAt-this.deps.timer.now());return this.acceptanceRestartAdmissionToken=C,this.acceptanceRestartAdmissionOwnerSessionId=c,this.acceptanceRestartAdmissionCommitted=!1,this.acceptanceRestartAdmissionExpiresAt=this.deps.timer.now()+M,this.acceptanceRestartAdmissionExpiryTimer=this.deps.timer.setTimeout(()=>this.releaseAcceptanceRestartAdmission(C),M),{accepted:!0,restartToken:C}}acceptanceRestartSessionRefusal(d){let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"session_not_found"};let R=c.find((D)=>D.sessionId===d.sessionUuid);if(!R)return{accepted:!1,reason:"session_not_found"};if(R.platform!==d.platform||R.stableDeviceId!==d.stableDeviceId||c.length!==1)return{accepted:!1,reason:c.length!==1&&c.some((D)=>D.sessionId!==d.sessionUuid)?"unrelated_sessions":"session_identity_mismatch"};return}releaseAcceptanceRestart(d,c){if(!this.deps.generationMatches(d)||!this.acceptanceRestartAdmissionMatches(d.restartToken,c))return{released:!1};return this.releaseAcceptanceRestartAdmission(d.restartToken),{released:!0}}commitAcceptanceRestart(d,c){if(!this.deps.generationMatches(d)||!this.acceptanceRestartAdmissionMatches(d.restartToken,c))return{committed:!1};return this.acceptanceRestartAdmissionCommitted=!0,{committed:!0}}acceptanceRestartAdmissionMatches(d,c){return this.expireAcceptanceRestartAdmission(),typeof d==="string"&&c!==void 0&&d===this.acceptanceRestartAdmissionToken&&c===this.acceptanceRestartAdmissionOwnerSessionId}expireAcceptanceRestartAdmission(){if(this.acceptanceRestartAdmissionToken!==void 0&&this.acceptanceRestartAdmissionExpiresAt!==void 0&&this.acceptanceRestartAdmissionExpiresAt<=this.deps.timer.now())this.releaseAcceptanceRestartAdmission(this.acceptanceRestartAdmissionToken)}releaseAcceptanceRestartAdmissionForOwner(d){if(this.acceptanceRestartAdmissionCommitted||d!==this.acceptanceRestartAdmissionOwnerSessionId)return;this.releaseAcceptanceRestartAdmission(this.acceptanceRestartAdmissionToken)}releaseAcceptanceRestartAdmission(d){if(typeof d!=="string"||d!==this.acceptanceRestartAdmissionToken)return;if(this.acceptanceRestartAdmissionExpiryTimer!==void 0)this.deps.timer.clearTimeout(this.acceptanceRestartAdmissionExpiryTimer);G.clearDaemonRestartPreparation(),this.acceptanceRestartAdmissionToken=void 0,this.acceptanceRestartAdmissionOwnerSessionId=void 0,this.acceptanceRestartAdmissionCommitted=!1,this.acceptanceRestartAdmissionExpiresAt=void 0,this.acceptanceRestartAdmissionExpiryTimer=void 0}acceptanceSessionRestartScope(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d,R=c.controls;if(typeof c.sessionUuid!=="string"||c.sessionUuid.length===0||c.platform!=="android"&&c.platform!=="ios"||typeof c.stableDeviceId!=="string"||c.stableDeviceId.length===0||!mD(c.expiresAt)||!pD(R))return;return{sessionUuid:c.sessionUuid,platform:c.platform,stableDeviceId:c.stableDeviceId,controls:{androidSiblingAvdName:R.androidSiblingAvdName,androidDuplicateSerial:R.androidDuplicateSerial,iosSameNameSiblingUdid:R.iosSameNameSiblingUdid},expiresAt:c.expiresAt}}}function pD(d){return!(!d||typeof d!=="object"||typeof d.androidSiblingAvdName!=="string"||typeof d.androidDuplicateSerial!=="string"||typeof d.iosSameNameSiblingUdid!=="string")}function mD(d){return typeof d==="number"&&Number.isFinite(d)}function Dm(d,c){let R=c?.aborted?c.reason:d instanceof Mr?d:void 0;if(R===void 0)return;return{name:R instanceof Error?R.name:"Error",message:r(R)}}var Rm=-32602;function fD(d){if(!(d instanceof Error)||!("toPayload"in d))return;let{toPayload:c}=d;if(typeof c!=="function")return;let R=c.call(d);if(R===null||typeof R!=="object"||Array.isArray(R))return;let D=Object.fromEntries(Object.entries(R));return typeof D.code==="string"&&typeof D.retryable==="boolean"?D:void 0}function hD(d){if(!(d instanceof Error))return;let c=(P)=>Reflect.get(d,P),R=c("sessionUuid");if(typeof R!=="string")return;let D=c("remainingMs");if(d.name==="SessionSuspectError"&&typeof D==="number")return{code:mu,retryable:!0,details:{sessionUuid:R,remainingMs:D}};let k=c("release");if(d.name!=="TerminalSessionError"||k===null||typeof k!=="object")return;return{code:Ho,retryable:!1,nextAction:ci,details:{sessionUuid:R,...gD(k)}}}function gD(d){let c=Reflect.get(d,"releaseReason"),R=typeof c==="string"?c:void 0,D=Reflect.get(d,"ownerPid"),k=Reflect.get(d,"cliIdleTimeoutMs");return{...R===void 0?{}:{reason:R},...bi(R),...cu(R,typeof k==="number"?k:void 0),...typeof D==="number"?{ownerPid:D}:{}}}function Pm(d){let{code:c}=Im(d);return c===mu||c===Ho}function Im(d){let c=hD(d);if(c)return c;let R=$I(d);if(R)return{code:Ho,retryable:!1,nextAction:ci,details:Y6(R)};let D=fD(d);if(!D)return mm(d)??{};let{code:k,retryable:P,retryAfterMs:C,nextAction:M,...F}=D;return{...typeof k==="string"?{code:k}:{},...typeof P==="boolean"?{retryable:P}:{},...typeof C==="number"?{retryAfterMs:C}:{},...typeof M==="string"?{nextAction:M}:{},...Object.keys(F).length>0?{details:F}:{}}}function SD(d){let c=J8(d);return c===void 0?{}:{code:Tm,details:{toolName:c}}}function gi(d,c){return{...Im(d),...d instanceof ia?{overloadFailure:d.failure}:{},...d instanceof Mr&&d.code?{code:d.code}:{},...d instanceof Mr&&d.code===up?{retryable:!0}:{},...d instanceof ye&&"code"in d&&d.code===Rm?{code:Rm}:{},...Y8(d)?{code:pp}:{},...SD(d),...X8(d)?{code:km}:{},...c?{requestFailureCause:c}:{}}}class _t{deps;bySocket=new Map;constructor(d){this.deps=d}static key(d,c){return`${d}::${c}`}get ownerCount(){return this.bySocket.size}async onStartAcked(d,c,R,{holderSessionId:D,admissionStillHolds:k=!0}={}){if(!k||!this.deps.isSocketLive(d))return await this.cancelOne(c,R,d),"cancelled";let P=this.bySocket.get(d)??new Map;return P.set(_t.key(c.deviceId,R),{targetDevice:c,gestureId:R,...D!==void 0?{holderSessionId:D}:{}}),this.bySocket.set(d,P),"owned"}onEndAcked(d,c,R){let D=this.bySocket.get(d);if(!D)return;if(D.delete(_t.key(c,R)),D.size===0)this.bySocket.delete(d)}async cancelAllFor(d){let c=this.bySocket.get(d);if(this.bySocket.delete(d),!c)return;for(let{targetDevice:R,gestureId:D}of c.values())await this.cancelOne(R,D,d)}async cancelAllHeldBy(d){await this.cancelAllMatching((c)=>c.holderSessionId===d)}async cancelAllHeldByOn(d,c){await this.cancelAllMatching((R)=>R.holderSessionId===d&&R.targetDevice.deviceId===c)}async cancelAllUnheldOn(d){await this.cancelAllMatching((c)=>c.holderSessionId===void 0&&c.targetDevice.deviceId===d)}async cancelAllMatching(d){let c=[];for(let[R,D]of this.bySocket){for(let[k,P]of D)if(d(P))D.delete(k),c.push({...P,socketSessionId:R});if(D.size===0)this.bySocket.delete(R)}await Promise.all(c.map(({targetDevice:R,gestureId:D,socketSessionId:k})=>this.cancelOne(R,D,k)))}async cancelIfDeviceChangedHands(d,c,R,D){let k=this.bySocket.get(d)?.get(_t.key(c,R));if(!k||k.holderSessionId===D)return!1;return this.onEndAcked(d,c,R),await this.cancelOne(k.targetDevice,R,d),!0}async cancelOne(d,c,R){try{await this.deps.cancelGesture(d,c)}catch(D){e.warn(`Failed to cancel orphaned gesture ${c} on ${d.deviceId} owned by socket ${R}: ${r(D)}`)}}}class da{pending=new Set;get size(){return this.pending.size}add(d){this.pending.add(d)}delete(d){this.pending.delete(d)}deleteForSocket(d){for(let c of this.pending)if(c.socket===d)this.pending.delete(c)}hasLiveRequest(d,c){for(let R of this.pending)if(R.socket===d&&R.idleDeadline&&R.idleDeadline.value>=c)return!0;return!1}[Symbol.iterator](){return this.pending[Symbol.iterator]()}}import{AsyncResource as AD}from"async_hooks";function bD(d){return wee(JSON.parse(JSON.stringify(d)))}class Rn{inner;enter;constructor(d,c){this.inner=d;this.enter=c}get onclose(){return this.inner.onclose}set onclose(d){this.inner.onclose=d}get onerror(){return this.inner.onerror}set onerror(d){this.inner.onerror=d}get onmessage(){return this.inner.onmessage}set onmessage(d){this.inner.onmessage=d}start(){return this.inner.start()}send(d,c){let R=bD(d);return this.enter(()=>this.inner.send(R,c))}close(){return this.inner.close()}}var wD=/^[\t\n\r ]+|[\t\n\r ]+$/g;function RD(d,c){let R=d[c];return typeof R==="string"?R:void 0}function DD(d){return d?d.replace(wD,""):void 0}function ca(d){return d!==void 0&&d.trim().length>0}function Dn(d){let c=kD(d),R=c(tne,"boundSessionUuid"),D=c(nne,"releasedSessionUuid"),k=c(rne,"toolSelectionProfileUuid"),P=D!==void 0&&D.trim()===R?.trim();return{...ca(R)&&!P?{initialSessionToolBinding:R}:{},...ca(D)?{initialReleasedSession:D}:{},...ca(k)?{initialToolSelectionProfile:k}:{}}}function kD(d){if("headers"in d){let{headers:c}=d;return(R)=>RD(c,R)}return(c,R)=>DD(d[R])}function An(d,c,R){return pG({...d,...R.era!==void 0&&{era:R.era},...R.taskOwnerKey!==void 0&&{taskOwnerKey:R.taskOwnerKey},sessionContext:{...c,sessionId:R.requestScopeId},daemonMode:!0,requestMcpSessionId:R.requestMcpSessionId,...R.trustedForwarder===!0&&{trustForwardedMcpSessionId:!0},stateless:!0,taskLeaseKeepalive:Z8()})}var PD=ad("MCP client relay",()=>import("./chunk-a9ps00a1.js"));function la(d){let c=new AD(d);return{run:(R)=>c.runInAsyncScope(R)}}class Cm{deps;root;inFlight=new Map;accepting=!0;constructor(d){this.deps=d;this.root=d.serverScope??la("auto-mobile-mcp-forward-root");let c=d.refreshResources;if(c)this.refreshResources=()=>this.root.run(c)}refreshResources;get inFlightCount(){return this.inFlight.size}stopAccepting(){this.accepting=!1}inFlightForwards(){return Array.from(this.inFlight.values(),(d)=>({requestScopeId:d.requestScopeId,close:()=>d.close()}))}async connect(d){let c=this.deps.clientModule??PD,{LoopbackMcpClient:R}=c.loaded()??await c.load();if(!this.accepting)throw new Ia(aS);let D={requestScopeId:this.deps.idGenerator.next(),requestMcpSessionId:d.sessionKey,trustedForwarder:!0,...d.taskOwnerKey!==void 0&&{taskOwnerKey:d.taskOwnerKey}},k=(W)=>this.root.run(W),P=k(()=>this.deps.createServer(Dn(d),D)),[C,M]=xee.createLinkedPair(),F=new R({name:"auto-mobile-daemon-client",version:"1.0.0"},{capabilities:{}}),q=F.close.bind(F),U,K={requestScopeId:D.requestScopeId,close:(W)=>(U??=this.closeForward(K,D,P,{closeClient:q,reason:W}),U)};F.close=()=>K.close(),this.inFlight.set(D.requestScopeId,K);try{await k(()=>P.connect(new Rn(M,(W)=>W()))),await F.connect(new Rn(C,k))}catch(W){throw await K.close(),W}return F}async closeForward(d,c,R,{closeClient:D,reason:k}){try{await this.deps.cancelScopeExecutions(c.requestScopeId,k??this.deps.closeReason())}finally{if(this.inFlight.get(c.requestScopeId)===d)this.inFlight.delete(c.requestScopeId);let P=await Promise.allSettled([D(),R.close()]);for(let C of P)if(C.status==="rejected")e.warn(`In-process MCP forward ${c.requestScopeId} teardown failed: ${im(C.reason)}`);if(c.requestMcpSessionId===void 0)this.deps.forgetScopeBindings(c.requestScopeId)}}}var ua="mcp_forward_closed";function Pn(d){return new Cm({idGenerator:d.idGenerator??B,refreshResources:jU,createServer:(c,R)=>An(d.base(),c,R),cancelScopeExecutions:(c,R)=>G.cancelSessionExecutions(c,R),forgetScopeBindings:(c)=>FE(c),closeReason:d.closeReason??(()=>ua)})}class ut extends t{}var Mm=2000,pa=100,fa=3,Em=250;function Bm(d){if(d===null||typeof d!=="object"||Array.isArray(d))return null;let c=d.id;return typeof c==="string"?c:null}function Om(d,c){return d?.aborted===!0&&(c?.message==="Daemon MCP client disconnected"||d.reason instanceof ut)}function xm(d){if(d)e.error(`Original MCP request failure cause: ${d.name}: ${d.message}`)}function _m(d,c){return d===void 0?c.now():d}function Fm(d){return structuredClone(d??{})}var Nm=new Set(["getAndroid","getApple","startDevice","provisionDevice"]),Lm=1000,ha=1000,$m=1000;function ID(d,c){let R=`${d}.bind.lock`;return{acquire:()=>ti(R,{ownerToken:c,ownerGeneration:kt}),release:()=>Wn(R,process.pid,c)}}var TD={getOwnerStatus(){let d=_o();if(!d||d.pid===process.pid)return"unknown";return st(d.pid,{debugLog:e.debug})?"live":"dead"}};function Hm(d,c,R){return{reachability:d.reachability??new ER,ownerLiveness:d.ownerLiveness??TD,bindLock:d.bindLock??ID(c,R)}}var qm=(d,c)=>ch().getRegisteredTool(d)?.isDeviceReadOnlyCall?.(c)===!0,Um=":read",va="device:",ya=900000,Ze=(d)=>typeof d==="string"&&d.trim().length>0;function Km(d,c){return d instanceof ut||c&&d instanceof Error&&d.message==="Daemon MCP client disconnected"}function qe(d){d?.throwIfAborted()}class ba{callbacks;shapeToolCallError;inboundFrameLimit;server=null;serverClosePromise=null;closing=!1;acceptingRequests=!1;requestTimeoutEnv;get maxInboundFrameBytes(){return this.inboundFrameLimit()}lifecycleGeneration=0;socketFileIdentity=null;adbClientFactory;sessions=new Map;clientSockets=new Map;acceptedClientConnections=0;controlConnections=new WeakMap;activeRequestHandlers=new Set;pendingSocketRequests=new da;notificationSubscribers=new Set;resourceSubscriptions=new Map;inputTargetOwners=new WeakMap;resourceUpdatedUnsubscribe=null;pendingSessionReleaseWrites=new Set;listChangedUnsubscribe=null;sessionReleaseUnsubscribe=null;sessionDeviceReboundUnsubscribe=null;socketPath;daemonState;clearConnectionDevicePin;boundMcpClientKeysBySocketSession=new Map;mcpForwardTails=new Map;mcpForwardIdleCloseKeys=new Map;forwardKeyIdleTimers=new Map;timer;onFrameTrace;idGenerator;forwardedCallKeys=new WeakMap;socketReachability;socketOwnerLiveness;socketReclaimLock;featureFlagService;handshakeEnforced;daemonIdentity;identityStartedAt;processGenerationToken;startupOptions;onRepublishIdentity;identityDbPath;identityPidFilePath;startupCompletion;startupCompleted=!1;identitySockets;identityProcessStartedAt;identityRepublishInFlight;onRestartAccepted;liveAcceptanceStartupSecret;acceptanceDiscoveryCapability;restartAdmission;sessionToolSelectionService;mcpDispatcher;mcpRequestAbortControllers=new Map;deviceReadToolCallClassifier=qm;mcpClientFactory=(d,c,R)=>this.callbacks().createMcpClient(d,c,R);releaseToolCallRecording=mN;forgetSessionToolBindings=(d)=>FE(d);appendTextFactory=(d)=>this.callbacks().createSocketAppendTextInput(d);appendTextInputs=new Map;confirmedLegacyScaleDevices=new Set;ownedGestures=new _t({isSocketLive:(d)=>this.clientSockets.has(d),cancelGesture:(d,c)=>this.callbacks().cancelGestureOnDevice(d,c)});constructor(d,c,R,D){this.callbacks=c;this.shapeToolCallError=R;this.inboundFrameLimit=D;let[k=Bt,P=w.daemonState(),C=i,M=null,F={},q=B,U={},K=v]=d;this.socketPath=k,this.daemonState=P,this.clearConnectionDevicePin=F.clearConnectionDevicePin,this.timer=C,this.requestTimeoutEnv=F.requestTimeoutEnv,this.onFrameTrace=F.onFrameTrace,this.mcpDispatcher=F.mcpDispatcher??Pn({base:()=>({acceptanceDiscoveryCapability:F.acceptanceDiscoveryCapability})}),this.idGenerator=q;let W=Hm(U,k,B.next());this.socketReachability=W.reachability,this.socketOwnerLiveness=W.ownerLiveness,this.socketReclaimLock=W.bindLock,this.adbClientFactory=K,this.featureFlagService=M,this.handshakeEnforced=F.enforce??sne,this.sessionToolSelectionService=F.sessionToolSelectionService,this.daemonIdentity=F.identity??dV(),this.identityStartedAt=_m(F.identityStartedAt,this.timer),this.processGenerationToken=F.processGenerationToken,this.startupOptions=Fm(F.startupOptions),this.onRepublishIdentity=F.onRepublishIdentity,this.identityDbPath=F.dbPath,this.identityPidFilePath=F.pidFilePath,this.startupCompletion=F.startupCompletion,this.observeStartupCompletion(),this.identitySockets=F.sockets,this.identityProcessStartedAt=F.processStartedAt,this.onRestartAccepted=F.onRestartAccepted,this.liveAcceptanceStartupSecret=F.liveAcceptanceStartupSecret,this.acceptanceDiscoveryCapability=F.acceptanceDiscoveryCapability,this.restartAdmission=new aa({timer:this.timer,idGenerator:this.idGenerator,generationMatches:(V)=>this.callbacks().daemonGenerationMatches(V),currentIdentity:()=>this.callbacks().currentGenerationIdentity(),getAllSessions:()=>this.daemonState.getSessionManager().getAllSessions?.(),onRestartAccepted:this.onRestartAccepted,liveAcceptanceStartupSecret:this.liveAcceptanceStartupSecret}),e.info(`UnixSocketServer initialized with in-process MCP dispatcher: "${k}"`)}observeStartupCompletion(){this.startupCompletion?.then(()=>{this.startupCompleted=!0},(d)=>{e.debug(`Daemon startup completion rejected: ${r(d)}`)})}}import{createServer as MD}from"net";import{unlink as OD}from"fs/promises";import{existsSync as xD}from"fs";import FD from"path";class Ra{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async start(){if(this.callbacks.beginAccepting(),!Sl())await bl();if(await Fu(FD.dirname(this.state.socketPath)),!this.state.socketReclaimLock.acquire())throw new t(`Refusing to bind: another AutoMobile process is currently reclaiming or binding the daemon socket ${this.state.socketPath}. Two concurrent launches cannot bind the same socket; let the in-flight one finish, then re-observe, or run \`--daemon restart\`.`);try{if(xD(this.state.socketPath))await this.callbacks.reclaimExistingSocketBeforeBind();this.state.server=MD(this.callbacks.connectionHandlerWithFanOut()),await new Promise((d,c)=>{this.state.server.listen(this.state.socketPath,()=>{this.state.socketFileIdentity=kz(this.state.socketPath),e.info(`Unix socket server listening on ${this.state.socketPath}`),XB(this.state.socketPath).then(d).catch(c)}),this.state.server.on("error",(R)=>{e.error(`Unix socket server error: ${R}`),c(R)})})}finally{this.state.socketReclaimLock.release()}}startDetached(){return this.callbacks.beginAccepting(),this.callbacks.connectionHandlerWithFanOut()}stopAcceptingAndFanOut(){this.state.closing=!0,this.state.acceptingRequests=!1,this.state.listChangedUnsubscribe?.(),this.state.listChangedUnsubscribe=null,this.state.resourceUpdatedUnsubscribe?.(),this.state.resourceUpdatedUnsubscribe=null,this.state.sessionReleaseUnsubscribe?.(),this.state.sessionReleaseUnsubscribe=null,this.state.sessionDeviceReboundUnsubscribe?.(),this.state.sessionDeviceReboundUnsubscribe=null}beginAccepting(){this.state.closing=!1,this.state.acceptingRequests=!0,this.state.serverClosePromise=null,this.state.lifecycleGeneration+=1}connectionHandlerWithFanOut(){return this.state.listChangedUnsubscribe?.(),this.state.listChangedUnsubscribe=_r.subscribe((d)=>{this.callbacks.broadcastListChanged(d)}),this.state.resourceUpdatedUnsubscribe?.(),this.state.resourceUpdatedUnsubscribe=Uw.subscribe((d)=>{this.callbacks.broadcastResourceUpdated(d)}),this.state.sessionReleaseUnsubscribe?.(),this.state.sessionReleaseUnsubscribe=Ai.subscribe((d,c,R,D)=>{this.callbacks.clearBoundMcpClientsForReleasedSession(d),this.callbacks.liftStrokesHeldBy(d),this.callbacks.broadcastSessionReleased(d,c,R,D?.recordingIds)}),this.state.sessionDeviceReboundUnsubscribe?.(),this.state.sessionDeviceReboundUnsubscribe=Iq.subscribe((d)=>this.callbacks.broadcastSessionDeviceRebound(d)),(d)=>this.callbacks.handleConnection(d)}async reclaimExistingSocketBeforeBind(){let d=await this.state.socketReachability.probe(this.state.socketPath,$m);if(d!=="absent"||this.state.socketOwnerLiveness.getOwnerStatus()!=="dead")throw new t((d==="unknown"?`Refusing to bind: the AutoMobile daemon socket ${this.state.socketPath} probe is inconclusive; the socket could not be verified as dead. `:`Refusing to bind: the AutoMobile daemon socket ${this.state.socketPath} is still reachable or its former owner is not positively known to be dead. `)+"A startup lock and an inconclusive liveness probe do not authorize unlinking a socket that may still be live. Stop the running daemon or run `--daemon restart` to replace it.");await OD(this.state.socketPath)}isListening(){return this.state.server!==null&&this.state.server.listening}getClientConnectionCount(){return this.state.clientSockets.size}getAcceptedClientConnectionCount(){return this.state.acceptedClientConnections}async quiesce(){this.state.acceptingRequests=!1,this.callbacks.closeListeningServer(aR(this.state.socketFileIdentity,this.state.socketPath));for(let[d,c]of this.state.clientSockets)if(!this.state.notificationSubscribers.has(d)&&!c.destroyed)c.end();await this.callbacks.drainActiveRequestHandlers()}async drainSessionReleaseNotifications(){let d=Array.from(this.state.pendingSessionReleaseWrites);if(d.length===0)return;let c=Symbol("notification drain timeout"),R=!0;try{await l(Promise.allSettled(d),{timer:this.state.timer,timeoutMs:ha,label:"Session release notification drain",timeoutError:()=>c})}catch(D){if(D!==c)throw D;R=!1}if(!R)e.warn(`Timed out waiting for ${d.length} session-release notification(s) to flush during shutdown`)}async close(){e.info("Closing Unix socket server..."),this.callbacks.stopAcceptingAndFanOut(),this.state.lifecycleGeneration+=1,this.state.restartAdmission.releaseAll();let d=Array.from(this.state.clientSockets.values()),c=aR(this.state.socketFileIdentity,this.state.socketPath),R=this.callbacks.closeListeningServer(c);for(let k of this.state.pendingSocketRequests)if(!k.admitted)this.callbacks.writeShutdownSocketResponse(k);await this.callbacks.drainActiveRequestHandlers();for(let k of this.state.pendingSocketRequests)this.callbacks.writeShutdownSocketResponse(k);this.callbacks.destroyClientSockets(d),await R,this.state.sessions.clear(),this.state.clientSockets.clear(),this.state.notificationSubscribers.clear(),this.state.resourceSubscriptions.clear(),this.state.server=null,this.state.boundMcpClientKeysBySocketSession.clear();for(let k of this.state.forwardKeyIdleTimers.values())this.state.timer.clearTimeout(k);this.state.forwardKeyIdleTimers.clear(),this.state.mcpForwardTails.clear(),this.state.mcpForwardIdleCloseKeys.clear(),this.state.appendTextInputs.clear(),this.state.socketFileIdentity=null}writeShutdownSocketResponse(d){this.callbacks.writeTerminalSocketResponse(d,{id:d.id,type:"mcp_response",success:!1,error:kg,...z0(W0(d.admitted))})}closeListeningServer(d){if(this.state.serverClosePromise)return this.state.serverClosePromise;if(!this.state.server)return Promise.resolve();if(d==="replaced")return e.warn(`Unix socket path ${this.state.socketPath} no longer belongs to this server; leaving listener for process teardown`),this.state.server.unref(),Promise.resolve();return this.state.serverClosePromise=new Promise((c)=>{this.state.server.close(()=>{e.info("Unix socket server closed"),c()})}),this.state.serverClosePromise}destroyClientSockets(d){for(let c of d)if(!c.destroyed){let R=this.state.timer.setTimeout(()=>c.destroy(),ha);c.once("close",()=>this.state.timer.clearTimeout(R)),c.end()}}async drainActiveRequestHandlers(){let d=Array.from(this.state.activeRequestHandlers);if(d.length===0)return;let c=Symbol("request handler drain timeout"),R=!0;try{await l(Promise.allSettled(d),{timer:this.state.timer,timeoutMs:Lm,label:"Unix socket request drain",timeoutError:()=>c})}catch(D){if(D!==c)throw D;R=!1}if(!R)e.warn(`Timed out waiting for ${d.length} in-flight Unix socket request handler(s) to finish during shutdown`)}}var ND="input/";function LD(d){return d.startsWith(ND)}function Gm(d,c){return LD(d)||c.has(d)}async function Wm(d,c,R,{socketSessionId:D,input:k}){return c.handler==="gesture"?await d.gesture(R,c.gestureKind,D,k):await d[c.handler](R,D,k)}var $D=new Map([["tools/list",async(d)=>await d.admitted(d.request.params,()=>d.mcpClient.listTools(void 0,d.options))],["resources/list",async(d)=>await d.admitted(d.request.params,()=>d.mcpClient.listResources(void 0,d.options))],["resources/read",async(d)=>{if(!d.request.params?.uri)throw Error("resources/read requires params.uri");let c=d.request.params.uri;return await d.admitted(d.readAdmissionArgs(d.request),()=>d.mcpClient.readResource({uri:c,...d.request.params._meta!==void 0&&{_meta:d.request.params._meta}},d.options))}],["resources/list-templates",async(d)=>await d.admitted(d.request.params,()=>d.mcpClient.listResourceTemplates(void 0,d.options))],["ide/getNavigationGraph",async(d)=>{let c={...d.request.params??{},[Rp]:d.timeoutMs};return await d.mcpClient.callTool({name:"getNavigationGraph",arguments:c},d.options)}]]);function Vm(d){return $D.get(d.request.method)?.(d)}var Jm=new WeakMap;function jm(d){let c="result"in d?d.result:void 0,R=c&&typeof c==="object"?Jm.get(c):void 0;if(R===void 0)return JSON.stringify(d)+`
37
+ `;return"{"+Object.entries(d).flatMap(([D,k])=>{let P=D==="result"?R:JSON.stringify(k);return P===void 0?[]:[`${JSON.stringify(D)}:${P}`]}).join(",")+`}
38
+ `}function HD(d){if(d==="tools/list")return"tools";return d==="resources/list"?"resources":void 0}class Mn{refreshResources;timer;entries=new Map;inFlightRefresh;constructor(d,c){this.refreshResources=d;this.timer=c}static MAX_ENTRIES=128;forgetSocket(d){for(let[c,R]of this.entries)if(R.socketSessionId===d)this.entries.delete(c)}async read(d,c){let R=HD(d.request.method);if(!R)return await c();d.signal?.throwIfAborted();let{route:D}=d,k=JSON.stringify([R,d.socketSessionId,D.clientKey,D.sessionUuid,D.toolSelectionProfileUuid,D.releasedSessionUuid]),P=this.entries.get(k);if(R==="resources"&&P?.generation===_r.generation(R)){if(!await this.awaitWarmRefresh(d))return P.result;d.signal?.throwIfAborted()}let C=_r.generation(R);if(P?.generation===C)return this.entries.delete(k),this.entries.set(k,P),P.result;this.entries.delete(k);let M=await c();return d.signal?.throwIfAborted(),this.retain(R,k,C,{result:M,socketSessionId:d.socketSessionId}),M}async awaitWarmRefresh(d){let c=this.inFlightRefresh??=this.refreshResources().finally(()=>{this.inFlightRefresh=void 0}),R=Error("warm resources/list refresh passed the MCP deadline");try{return await l(c,{timer:this.timer,signal:d.signal,timeoutMs:Math.max(0,d.deadline.value-this.timer.now()),label:"Warm resources/list refresh",timeoutError:()=>R}),!0}catch(D){if(D!==R)throw D;return e.debug(`[DiscoveryCache] ${R.message}; the refresh keeps running.`),!1}}retain(d,c,R,{result:D,socketSessionId:k}){if(R!==_r.generation(d)||!D||typeof D!=="object")return;if(Jm.set(D,JSON.stringify(D)),this.entries.set(c,{generation:R,result:D,socketSessionId:k}),this.entries.size>Mn.MAX_ENTRIES){let P=this.entries.keys().next().value;if(P!==void 0)this.entries.delete(P)}}}function zm(d,c,R){let D={type:"daemon_notification",method:A3[R]};for(let k of d)if(c.hasSocket(k))c.write(k,D)}function Xm(d,c,R){for(let[D,k]of d){if(!c.hasSocket(D))continue;for(let P of R(k))c.write(D,{type:"daemon_notification",method:KC,uri:P})}}function Qm(d,c,R){let D=R.params?.uri;if(typeof D!=="string"||D.length===0)return{id:R.id,type:"mcp_response",success:!1,error:"Resource subscription requires params.uri"};if(R.method===XA){let k=d.get(c)??new Set;k.add(D),d.set(c,k)}else{let k=d.get(c);if(k?.delete(D),k?.size===0)d.delete(c)}return{id:R.id,type:"mcp_response",success:!0,result:{}}}function Zm(d,c,R,D){let{releasedSessionId:k,reason:P,release:C,recordingIds:M}=D,F={type:"daemon_notification",method:QB,sessionId:k,...P!==void 0?{reason:P}:{},...bi(P),...C!==void 0?{release:C}:{},...M&&M.length>0?{recordingIds:M}:{}};for(let q of d){if(!c.hasSocket(q))continue;let U=Promise.withResolvers();R.add(U.promise),c.write(q,F,()=>{R.delete(U.promise),U.resolve()})}}function ef(d,c,R){let{requestId:D,progressToken:k,progress:P,total:C,message:M}=R;if(!d.hasSocket(c))return;d.write(c,{type:"daemon_notification",method:iw,requestId:D,progressToken:k,progress:P,...C!==void 0?{total:C}:{},...M!==void 0?{message:M}:{}})}function tf(d,c,R,D){let k={type:"daemon_notification",method:d0,...D};for(let P of d){if(!c.hasSocket(P))continue;let C=Promise.withResolvers();R.add(C.promise),c.write(P,k,()=>{R.delete(C.promise),C.resolve()})}}class nf{#t;get signal(){return this.#t}adopt(d){this.#t=d}}function En(d,c,R,D=process.env){let k=Z0(d,D),P=new AbortController;return{id:d.id,socketSessionId:c,receivedAtMs:R,totalTimeoutMs:k,deadline:new xh(R,k),signal:P.signal,cancellation:P,owner:new nf}}var UD=0,Da=0;function ka(){return++UD}function of(){return Da}class Aa{pending=[];runningLanes=new Set;runningCount=0;barrierRunning=!1;get pendingCount(){return this.pending.length}run(d,c,R){return new Promise((D,k)=>{let P=d!==void 0&&(this.runningLanes.has(d)||this.pending.some((K)=>K.lane===d)),C,M=()=>{if(C!==void 0)R?.timer.clearTimeout(C);R?.signal.removeEventListener("abort",q)},F=(K)=>{let W=this.pending.indexOf(U);if(W<0)return;this.pending.splice(W,1),M(),k(K),this.pump()},q=()=>F(R?.signal.reason),U={lane:d,run:()=>{if(M(),R&&R.timer.now()>=R.deadlineMs)return k(R.timeoutError(P)),Promise.resolve();return c().then(D,k)}};if(this.pending.push(U),R){if(R.signal.addEventListener("abort",q,{once:!0}),R.signal.aborted){q();return}let K=R.deadlineMs-R.timer.now();if(K<=0){F(R.timeoutError(P));return}C=R.timer.setTimeout(()=>F(R.timeoutError(P)),K)}this.pump()})}pump(){if(this.barrierRunning)return;let d=new Set,c=0;while(c<this.pending.length){let R=this.pending[c];if(R.lane===void 0){if(c===0&&this.runningCount===0)this.start(this.pending.shift());return}if(this.runningLanes.has(R.lane)||d.has(R.lane)){d.add(R.lane),c++;continue}this.start(this.pending.splice(c,1)[0])}}start(d){if(this.runningCount++,d.lane===void 0)this.barrierRunning=!0;else if(d.lane!=="host:inventory")this.runningLanes.add(d.lane);d.run().finally(()=>{if(this.runningCount--,d.lane===void 0)Da=Math.max(Da,ka()),this.barrierRunning=!1;else this.runningLanes.delete(d.lane);this.pump()})}}var KD=new Set(["getAndroid","getApple","startDevice","provisionDevice","setActiveDevice","setToolEnabled"]),sf=["sessionUuid","device",Ko,rf,_u];function Pa(d){let c=d.params?.name;if(d.method!=="tools/call"||typeof c!=="string"||KD.has(c))return;let R=VD(d.params?.arguments);if(R!==void 0)return`device:${R}`;if(et(c,d.params?.arguments))return"host:inventory";return}function et(d,c){return J0(d)&&WD(c)}function WD(d){return d===void 0||typeof d==="object"&&d!==null&&!Array.isArray(d)&&!("deviceId"in d)&&!sf.some((c)=>(c in d))}function VD(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c="deviceId"in d?d.deviceId:void 0;if(typeof c!=="string"||c.length===0)return;return sf.some((R)=>(R in d))?void 0:c}var JD=g({id:y(),type:A(["mcp_request","daemon_request"]),method:y(),params:yr().optional()}).passthrough();function af(d){return JD.safeParse(d).success}var jD=g({platform:A(["android","ios"])}).passthrough();function df(d){let c=jD.safeParse(d);return c.success?c.data.platform:void 0}var Ca=16777216;class Ta{admitted=0;headEnd=0;drainedAtSample=0;watchdog;socket;timer;onStalled;maxQueuedBytes;stallTimeoutMs;constructor(d,c,R,{maxQueuedBytes:D=16777216,stallTimeoutMs:k=60000}={}){this.socket=d,this.timer=c,this.onStalled=R,this.maxQueuedBytes=D,this.stallTimeoutMs=k}admit(d){let c=this.socket.writableLength;if(c===0)this.headEnd=this.admitted+d;else if(this.bytesBehindHead(c)+d>this.maxQueuedBytes)return c+d;this.admitted+=d;return}written(){if(this.socket.writableLength===0)this.clearWatchdog();else if(!this.watchdog&&this.socket.writableLength>this.stallWatchMinBytes)this.armWatchdog()}flushed(){if(this.socket.writableLength===0)this.clearWatchdog()}dispose(){this.clearWatchdog()}get stallWatchMinBytes(){return Math.min(1048576,this.maxQueuedBytes)}bytesBehindHead(d){return Math.min(d,Math.max(0,this.admitted-this.headEnd))}armWatchdog(){this.drainedAtSample=this.admitted-this.socket.writableLength,this.watchdog=this.timer.setTimeout(()=>this.checkProgress(),this.stallTimeoutMs)}checkProgress(){this.watchdog=void 0;let d=this.socket.writableLength;if(d===0)return;if(this.admitted-d>this.drainedAtSample){if(d>this.stallWatchMinBytes)this.armWatchdog();return}this.onStalled({queuedBytes:d,stalledMs:this.stallTimeoutMs})}clearWatchdog(){if(this.watchdog)this.timer.clearTimeout(this.watchdog),this.watchdog=void 0}}var zD=new Set(["EPIPE","ECONNRESET","ERR_STREAM_DESTROYED","ECONNABORTED"]);function YD(d){return"code"in d&&typeof d.code==="string"&&zD.has(d.code)}class Ma{socket;sessionId;timer;maxInboundFrameBytes;guard;idleTimeout;peerEndGrace;started=!1;handlers;constructor(d,c,R,D){this.socket=d;this.sessionId=c;this.timer=R;this.maxInboundFrameBytes=D}outboundWriteGuard(){if(!this.guard)this.guard=new Ta(this.socket,this.timer,(d)=>{e.warn(`Daemon RPC socket ${this.sessionId} reader stalled: no queued bytes freed for ${d.stalledMs}ms with ${d.queuedBytes} bytes queued; destroying`),this.socket.destroy()});return this.guard}startBackpressureIdle(){if(!this.started||this.idleTimeout||this.socket.destroyed)return;this.socket.setTimeout(0),this.idleTimeout=this.armIdleTimeout()}refreshIdle(){if(!this.started||!this.idleTimeout||this.socket.destroyed)return;this.timer.clearTimeout(this.idleTimeout),this.idleTimeout=this.armIdleTimeout()}responseFlushed(){if(!this.started||this.socket.destroyed)return;if(this.idleTimeout){if(this.socket.writableLength===0)this.refreshIdle()}else this.socket.setTimeout(_D)}start(d){let{socket:c,sessionId:R,timer:D}=this;if(this.started=!0,this.handlers=d,c.setTimeout(_D),c.on("timeout",()=>this.onIdleTimeout(d)),c.on("drain",()=>this.refreshIdle()),c.on("drain",()=>this.guard?.flushed()),d.trace){let C=d.trace.bind(d);c.on("drain",()=>C("socket_drain")),c.on("pause",()=>C("socket_pause")),c.on("end",()=>C("socket_end")),c.on("finish",()=>C("socket_finish"))}let k=D.now(),P=new dd(this.maxInboundFrameBytes,{onLine:(C)=>d.onLine(C,k),onOverflow:()=>d.onOverflow()});c.on("data",(C)=>{if(P.hasOverflowed)return;this.refreshIdle(),k=D.now(),P.push(C)}),c.on("end",()=>{if(c.destroyed||this.peerEndGrace)return;this.peerEndGrace=D.setTimeout(()=>{if(!c.destroyed)e.debug(`Daemon RPC socket ${R} peer closed with ${c.writableLength} bytes unflushed; destroying`),c.destroy()},Qre)}),c.on("close",(C)=>{if(this.peerEndGrace)D.clearTimeout(this.peerEndGrace);if(this.idleTimeout)D.clearTimeout(this.idleTimeout);this.started=!1,this.guard?.dispose(),d.trace?.("socket_close",{hadError:C}),d.onClose(C)}),c.on("error",(C)=>{if(YD(C))e.debug(`Socket peer closed for ${R}: ${r(C)}`);else e.error(`Socket error for ${R}:`,C);if(d.onError(C),!c.destroyed)c.destroy()})}armIdleTimeout(){return this.timer.setTimeout(()=>this.onIdleTimeout(this.handlers),_D)}onIdleTimeout(d){if(this.socket.writableLength===0&&d?.hasLiveRequest()){if(this.socket.setTimeout(0),this.idleTimeout)this.timer.clearTimeout(this.idleTimeout);this.idleTimeout=this.armIdleTimeout();return}e.warn(`Daemon RPC socket ${this.sessionId} idle timeout after ${_D}ms, destroying`),this.socket.destroy()}}class On extends Error{queuedBytes;limitBytes;reason="queue_overflow";constructor(d,c){super(`Daemon RPC socket queued bytes exceeded ${c}`);this.queuedBytes=d;this.limitBytes=c;this.name="DaemonSocketQueueOverflowError"}}class Ea{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}handleConnection(d){if(!this.state.acceptingRequests){d.end();return}let c=this.state.idGenerator.next(),R={sessionId:c,createdAt:this.state.timer.now(),requestQueue:new Aa,requestCancellations:new Map};this.state.sessions.set(c,R),this.state.clientSockets.set(c,d),this.state.acceptedClientConnections++,e.info(`New client connection: ${c}`),this.callbacks.connectionFor(d,c).start({onLine:(D,k)=>{if(D.trim())this.callbacks.trackRequestHandler(this.callbacks.processSocketRequestLine(c,d,D,k))},onOverflow:()=>this.callbacks.rejectOversizedFrame(c,d),hasLiveRequest:()=>this.callbacks.hasLiveSocketRequest(d),trace:this.state.onFrameTrace?(D,k)=>this.callbacks.traceFrame(D,"*",{details:k}):void 0,onClose:()=>{this.state.controlConnections.delete(d),e.info(`Client disconnected: ${c}`),this.state.pendingSocketRequests.deleteForSocket(d),this.callbacks.releaseSocketSession(c,d)},onError:()=>this.callbacks.releaseSocketSession(c,d)})}connectionFor(d,c){let R=this.state.controlConnections.get(d);if(!R)R=new Ma(d,c,this.state.timer,this.state.maxInboundFrameBytes),this.state.controlConnections.set(d,R);return R}rejectOversizedFrame(d,c){e.warn(`Daemon RPC socket ${d} sent a frame over ${this.state.maxInboundFrameBytes} bytes; rejecting`);let R={id:null,type:"mcp_response",success:!1,error:"Invalid request: frame too large",code:-32600};this.callbacks.writeFrame(c,d,R,{onFlushed:()=>{if(!c.destroyed)c.destroy()}})}hasLiveSocketRequest(d){return this.state.pendingSocketRequests.hasLiveRequest(d,this.state.timer.now())}async processSocketRequestLine(d,c,R,D){let k=null,P,C,M,F=(W)=>{},q=!1,U=()=>q&&this.state.clientSockets.get(d)===c&&!c.destroyed,K=(W)=>{if(C?.terminal)return;if(C)this.callbacks.writeTerminalSocketResponse(C,W,P);else this.callbacks.writeFrame(c,d,W,{deviceId:P});q=!0};try{let W;try{W=JSON.parse(R)}catch(ie){throw M=-32700,u(ie,"Parse error in daemon socket request")}if(k=Bm(W),!af(W))throw M=-32600,new t("Invalid daemon socket request");let V=W,z=[ms,iR,ck].includes(V.method),J=En(V,d,D,this.state.requestTimeoutEnv),X={id:V.id,sessionId:d,socket:c,admitted:z,terminal:!1,idleDeadline:z?void 0:J.deadline};if(C=X,this.state.pendingSocketRequests.add(X),this.announceResolvedBudget(c,d,V,{resolvedMs:J.totalTimeoutMs,controlFrame:z}),P=this.state.onFrameTrace?this.callbacks.frameDeviceId(V):void 0,this.state.onFrameTrace)this.callbacks.traceFrame("frame_parsed",V.id,{deviceId:P});(()=>{try{if(V.method==="tools/call"&&this.state.daemonState.isInitialized())F=this.state.daemonState.getDevicePool().beginMcpToolCall?.(d)??F}catch(ie){e.warn(`Could not begin MCP tool-call ownership claim: ${r(ie)}`,ie)}})();let re=await this.callbacks.handleRequest(d,c,V,{receivedAtMs:D,handling:{onAdmitted:(ie)=>{X.admitted=!0,X.idleDeadline=z?void 0:ie},context:J}});if(re)K(re);else this.state.pendingSocketRequests.delete(X),this.state.controlConnections.get(c)?.responseFlushed()}catch(W){if(Km(W,c.destroyed))e.debug(`Client cancelled request ${k} from ${d}`);else e.error(`Error processing request ${k} from ${d}:`,W);let V={id:k,type:"mcp_response",success:!1,error:r(W),...M===void 0?{}:{code:M},...gi(W,void 0)};K(V)}finally{F(U())}}writeTerminalSocketResponse(d,c,R){if(d.terminal)return;d.terminal=!0,this.callbacks.writeFrame(d.socket,d.sessionId,c,{onFlushed:()=>{this.state.pendingSocketRequests.delete(d),this.state.controlConnections.get(d.socket)?.responseFlushed()},deviceId:R})}withCanonicalToolCallDeviceIds(d){let c=d.params?.arguments;if(d.method!=="tools/call"||!TH(c)||!this.state.daemonState.isInitialized?.())return d;let R=$6(this.state.daemonState.getDevicePool?.(),c);return R===c?d:{...d,params:{...d.params,arguments:R}}}frameDeviceId(d){let c=d.params?.arguments?.deviceId;return typeof c==="string"?c:void 0}traceFrame(d,c,{deviceId:R,error:D,details:k}={}){if(this.state.onFrameTrace)this.state.onFrameTrace({event:d,atMs:this.state.timer.now(),wallMs:performance.now(),requestId:c,deviceId:R,error:D,...k})}releaseSocketSession(d,c){if(this.state.clientSockets.get(d)!==c)return;this.callbacks.abortMcpRequests(d),this.callbacks.forgetSocketDiscovery(d),this.callbacks.trackRequestHandler(G.cancelSessionExecutions(d,"socket_disconnect").then(()=>{return}).catch((R)=>{e.warn(`Cancelling executions of socket ${d} failed: ${r(R)}`)})),this.state.restartAdmission.releaseAcceptanceRestartAdmissionForOwner(d),this.state.sessions.delete(d),this.state.clientSockets.delete(d),this.state.notificationSubscribers.delete(d),this.state.resourceSubscriptions.delete(d),this.callbacks.clearBoundMcpClientKey(d),this.callbacks.releaseDevicePoolMcpSessionBindings(d),this.callbacks.clearConnectionDevicePin(d),this.state.daemonState.getBrokerConnectionScopes?.().unbind(d),this.state.releaseToolCallRecording(d),this.state.forgetSessionToolBindings(d),this.callbacks.forgetLateSessionToolBindings(d),this.callbacks.trackRequestHandler(this.state.ownedGestures.cancelAllFor(d))}forgetLateSessionToolBindings(d){if(!G.hasActiveSessionExecutions(d))return;G.waitForSessionExecutionsToEnd(d,ya).then((c)=>{if(this.state.forgetSessionToolBindings(d),!c)e.warn(`Socket ${d} still had executions ${ya}ms after it closed; forgot its bindings anyway`)})}trackRequestHandler(d){this.state.activeRequestHandlers.add(d),d.then(()=>this.state.activeRequestHandlers.delete(d),()=>this.state.activeRequestHandlers.delete(d))}abortMcpRequests(d){this.callbacks.abortRequestControllers(d,this.state.mcpRequestAbortControllers,"Daemon MCP client disconnected")}abortRequestControllers(d,c,R){let D=c.get(d);if(!D)return;c.delete(d);for(let k of D)k.abort(Error(R))}mcpRequestSignal(d,c=this.state.clientSockets.get(d),R){let D=new AbortController,k=()=>D.abort(R?.reason);if(R?.aborted)k();else R?.addEventListener("abort",k,{once:!0});let P=this.state.mcpRequestAbortControllers.get(d)??new Set;P.add(D),this.state.mcpRequestAbortControllers.set(d,P);let C=this.state.clientSockets.get(d);if(!c||C!==c||c.destroyed)D.abort(Error("Daemon MCP client disconnected"));return{signal:D.signal,dispose:()=>{if(R?.removeEventListener("abort",k),P.delete(D),P.size===0&&this.state.mcpRequestAbortControllers.get(d)===P)this.state.mcpRequestAbortControllers.delete(d)}}}isMcpRequestOwnerCurrent(d,c){let R=this.state.clientSockets.get(d);return!c.aborted&&R!==void 0&&!R.destroyed}get notificationTransport(){return{hasSocket:(d)=>this.state.clientSockets.has(d),write:(d,c,R)=>{let D=this.state.clientSockets.get(d);if(D)this.callbacks.writeFrame(D,d,c,{onFlushed:R})}}}broadcastListChanged(d){zm(this.state.notificationSubscribers,this.notificationTransport,d)}broadcastResourceUpdated(d){Xm(this.state.resourceSubscriptions,this.notificationTransport,d)}handleResourceSubscription(d,c){return Qm(this.state.resourceSubscriptions,d,c)}broadcastSessionDeviceRebound(d){let c=Array.from(this.state.notificationSubscribers).filter((R)=>this.callbacks.holdsSession(R,d.sessionId));tf(c,this.notificationTransport,this.state.pendingSessionReleaseWrites,d)}broadcastSessionReleased(d,c,R,D){Zm(this.state.notificationSubscribers,this.notificationTransport,this.state.pendingSessionReleaseWrites,{releasedSessionId:d,reason:c,release:R,recordingIds:D})}pushProgressNotification(d,c){ef(this.notificationTransport,d,c)}announceResolvedBudget(d,c,R,{resolvedMs:D,controlFrame:k}){if(k||R.type!=="mcp_request"||R.acceptsRequestBudget!==!0||D===R.timeoutMs)return;this.callbacks.writeFrame(d,c,{type:"daemon_notification",method:nF,requestId:R.id,timeoutMs:D})}writeFrame(d,c,R,{onFlushed:D,deviceId:k}={}){if(this.state.onFrameTrace&&R.type==="mcp_response"){this.callbacks.traceFrame("response_write_started",R.id??"null",{deviceId:k}),this.callbacks.writeFrameData(d,c,R,{onFlushed:(P)=>{this.callbacks.traceFrame("response_write_callback",R.id??"null",{deviceId:k,error:P?.message,details:{writableLengthInCallback:d.writableLength}}),D?.()},onWritten:(P,C)=>{this.callbacks.traceFrame("response_write_returned",R.id??"null",{deviceId:k,details:{byteLength:C,writableLengthAfterWrite:P}})}});return}this.callbacks.writeFrameData(d,c,R,{onFlushed:D})}writeFrameData(d,c,R,{onFlushed:D,onWritten:k}){if(d.destroyed){D?.(Error("socket destroyed"));return}try{let P=jm(R),C=Buffer.byteLength(P),M=this.callbacks.connectionFor(d,c).outboundWriteGuard(),F=M.admit(C);if(F!==void 0){let U=new On(F,Ca);e.warn(`Daemon RPC socket ${c} write queue exceeded limit; queuedBytes=${F}, limitBytes=${Ca}; destroying`),D?.(U),d.destroy();return}let q=d.write(P,(U)=>{if(!U&&!d.destroyed&&d.writableLength===0)this.state.controlConnections.get(d)?.refreshIdle(),M.flushed();D?.(U)});if(M.written(),k)k(d.writableLength,C);if(!q)this.state.controlConnections.get(d)?.startBackpressureIdle(),e.debug(`Daemon RPC socket ${c} backpressured; awaiting drain`)}catch(P){if(D?.(P instanceof Error?P:Error(r(P))),e.warn(`Daemon RPC write failed for ${c}: ${P}`),!d.destroyed)d.destroy()}}}var ge=(d)=>ho((c)=>Boolean(c),{message:d});function Ft(d){return(c)=>{let R=c!==null&&typeof c==="object"&&!Array.isArray(c)?c:{},D=d.safeParse(R);if(!D.success)throw Error(D.error.issues[0].message);return D.data}}var uf=Ft(g({key:ge("setFeatureFlag requires 'key' (string) and 'enabled' (boolean) params"),enabled:ho((d)=>typeof d==="boolean",{message:"setFeatureFlag requires 'key' (string) and 'enabled' (boolean) params"}),config:ho(()=>!0)})),Ba="setSessionToolEnabled requires sessionUuid, a user-configurable toolName, and enabled boolean params",ff=Ft(g({sessionUuid:ge(Ba),toolName:ho((d)=>Boolean(d)&&ch().isUserConfigurableTool(d),{message:Ba}),enabled:ho((d)=>typeof d==="boolean",{message:Ba})})),lf="updateService requires 'deviceId' (string) and 'platform' (string) params",hf=Ft(g({deviceId:ge(lf),platform:ge(lf).refine((d)=>d==="android"||d==="ios",(d)=>({message:`Invalid platform: ${d}. Must be 'android' or 'ios'.`})),force:yr()}).transform(({deviceId:d,platform:c,force:R})=>({deviceId:d,platform:c,force:R===!0}))),vi="setKeyValue requires deviceId, appId, fileName, key, and type params",gf=Ft(g({platform:ho(()=>!0),deviceId:ge(vi),appId:ge(vi),fileName:ge(vi),key:ge(vi),type:ge(vi),value:ho(()=>!0)})),Nn="removeKeyValue requires deviceId, appId, fileName, and key params",vf=Ft(g({platform:ho(()=>!0),deviceId:ge(Nn),appId:ge(Nn),fileName:ge(Nn),key:ge(Nn)})),Oa="clearKeyValueFile requires deviceId, appId, and fileName params",yf=Ft(g({platform:ho(()=>!0),deviceId:ge(Oa),appId:ge(Oa),fileName:ge(Oa)}));var XD={"ide/status":"startupProbe","ide/ping":"startupProbe","ide/updateService":"deviceMutation","ide/setKeyValue":"deviceMutation","ide/removeKeyValue":"deviceMutation","ide/clearKeyValueFile":"deviceMutation"};function Sf(d){return new Set(Object.entries(XD).filter(([,c])=>c===d).map(([c])=>c))}var wf=Sf("startupProbe"),_a=Sf("deviceMutation"),tt={"ide/setFeatureFlag":uf,"ide/setSessionToolEnabled":ff,"ide/updateService":hf,"ide/setKeyValue":gf,"ide/removeKeyValue":vf,"ide/clearKeyValueFile":yf};var Re=(d,c)=>ho(d,{message:c}),pt=(d,c)=>ho((R)=>R===void 0||d(R),{message:c}),Fa=(d)=>typeof d==="string",Na=(d)=>typeof d==="string"&&d.length>0,rt=(d)=>typeof d==="number"&&Number.isFinite(d),Df=(d)=>typeof d==="number"&&Number.isInteger(d),Af=(d)=>typeof d==="boolean",yi=(d)=>Re((c)=>c==="android"||c==="ios",`${d} requires platform 'android' or 'ios'`),Nt=(d)=>pt(Fa,`${d} deviceId must be a string when provided`),wi=(d)=>pt(Na,`${d} frameContext must be a non-empty string when provided`),Rf=["home","back","menu","power","volume_up","volume_down","recent","app_switch"],QD=g({platform:yi("input/tap"),x:Re(rt,"input/tap requires numeric x and y params"),y:Re(rt,"input/tap requires numeric x and y params"),duration:pt(Df,"input/tap duration must be an integer number of milliseconds when provided"),deviceId:Nt("input/tap"),frameContext:wi("input/tap")}).transform(({platform:d,deviceId:c,x:R,y:D,duration:k,frameContext:P})=>({platform:d,deviceId:c,x:R,y:D,duration:k,frameContext:P})),Hn="input/swipe requires numeric startX, startY, endX, and endY params",ZD=g({platform:yi("input/swipe"),startX:Re(rt,Hn),startY:Re(rt,Hn),endX:Re(rt,Hn),endY:Re(rt,Hn),durationMs:pt((d)=>Df(d)&&d>=1&&d<=60000,"input/swipe durationMs must be integer milliseconds between 1 and 60000"),deviceId:Nt("input/swipe"),frameContext:wi("input/swipe")}).transform(({platform:d,deviceId:c,startX:R,startY:D,endX:k,endY:P,durationMs:C,frameContext:M})=>({platform:d,deviceId:c,startX:R,startY:D,endX:k,endY:P,durationMs:C??300,frameContext:M})),ek=["platform","deviceId","text","submit","mode","frameContext","sessionUuid"],tk=g({platform:yi("input/typeText"),text:Re(Na,"input/typeText requires non-empty string text param"),submit:pt(Af,"input/typeText submit must be a boolean when provided"),deviceId:Nt("input/typeText"),frameContext:wi("input/typeText"),mode:pt((d)=>d==="append",'input/typeText mode must be "append" when provided')}).transform(({platform:d,deviceId:c,text:R,submit:D,mode:k,frameContext:P})=>({platform:d,deviceId:c,text:R,submit:D??!1,append:k==="append",frameContext:P})),ik=g({platform:yi("input/pressButton"),button:ho(Fa,{message:"input/pressButton requires button"}).refine((d)=>Rf.includes(d),{message:`input/pressButton button must be one of: ${Rf.join(", ")}`}),deviceId:Nt("input/pressButton"),frameContext:wi("input/pressButton")}).transform(({platform:d,deviceId:c,button:R,frameContext:D})=>({platform:d,deviceId:c,button:R==="app_switch"?"recent":R,responseButton:R,frameContext:D})),nk=["platform","deviceId","key","frameContext","sessionUuid"],rk=g({platform:yi("input/key"),key:ho(Fa,{message:"input/key requires key"}).refine(hJ,{message:`input/key key must be one of: ${xM.join(", ")}`}),deviceId:Nt("input/key"),frameContext:wi("input/key")}).transform(({platform:d,deviceId:c,key:R,frameContext:D})=>({platform:d,deviceId:c,key:R,frameContext:D}));function Pf(d){let c=`${d} requires numeric x and y params`;return g({platform:Re((R)=>R==="android",`${d} is only supported on platform 'android'`),gestureId:Re(Na,`${d} requires a non-empty gestureId`),x:Re(rt,c),y:Re(rt,c),deviceId:Nt(d),cancel:pt(Af,`${d} cancel must be a boolean when provided`)}).transform(({platform:R,deviceId:D,gestureId:k,x:P,y:C,cancel:M})=>({platform:R,deviceId:D,gestureId:k,x:P,y:C,cancel:M===!0}))}function ft(d,c,R){return(D)=>{if(!D||typeof D!=="object"||Array.isArray(D))throw Error(`${d} requires params object`);if(R){let P=Object.keys(D).filter((C)=>!R.includes(C));if(P.length>0)throw Error(`${d} unsupported params: ${P.join(", ")}`)}let k=c.safeParse(D);if(!k.success)throw Error(k.error.issues[0].message);return k.data}}var qn=ft("input/tap",QD),Kn=ft("input/swipe",ZD),Gn=ft("input/typeText",tk,ek),Vn=ft("input/pressButton",ik),Jn=ft("input/key",rk,nk),ak=new Map(["input/gestureStart","input/gestureMove","input/gestureEnd"].map((d)=>[d,ft(d,Pf(d))]));function Lt(d,c){return(ak.get(c)??ft(c,Pf(c)))(d)}var If=[{method:"input/tap",handler:"tap",parse:qn,dispatchHeld:!0},{method:"input/swipe",handler:"swipe",parse:Kn,dispatchHeld:!0},{method:"input/typeText",handler:"typeText",parse:Gn,dispatchHeld:!0},{method:"input/pressButton",handler:"pressButton",parse:Vn,dispatchHeld:!0},{method:"input/key",handler:"key",parse:Jn,dispatchHeld:!0},{method:"input/gestureStart",handler:"gesture",gestureKind:"start",parse:(d)=>Lt(d,"input/gestureStart"),dispatchHeld:!1},{method:"input/gestureMove",handler:"gesture",gestureKind:"move",parse:(d)=>Lt(d,"input/gestureMove"),dispatchHeld:!1},{method:"input/gestureEnd",handler:"gesture",gestureKind:"end",parse:(d)=>Lt(d,"input/gestureEnd"),dispatchHeld:!1}],dk=new Map(If.map((d)=>[d.method,d]));function Cf(d){return dk.get(d)}var Ht=new Set(If.filter((d)=>d.dispatchHeld).map((d)=>d.method)),jn={start:"input/gestureStart",move:"input/gestureMove",end:"input/gestureEnd"};async function Tf(d,c,R,D){let k=K0(c.tasks)?.declared===!0,P=await d.callTool({name:c.params.name,arguments:R,...k&&{_meta:h5()}},D);return k?tee(P)??P:P}async function Ef(d,c,R){if(!pV(c.method))throw Error(`Unsupported daemon method: ${c.method}`);let D={...c.params};delete D._meta;let k=K0(c.tasks)?.declared===!0,P=await d.request({method:c.method,params:{...D,...k&&{_meta:h5()}}},QQ,R);return eee(P)}function Bf(d,c){let R=ree(d);if(!R)return;return e.debug(`[TASKS] ${c.method} answered ${R.code}: ${R.message}`),{id:c.id,type:"mcp_response",success:!1,error:r(d),code:R.code,jsonRpcError:R}}class ke extends Error{charsSent;constructor(d,c){super(d);this.charsSent=c;this.name="InputTypeTextAppendError"}}class qt extends Error{failure;constructor(d){super(rF(d));this.failure=d;this.name="ReleasedBoundSessionError"}}function lk(d,c,R,D){return d?.context??En(c,R,D)}class La{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async handleRequest(d,c,R,{receivedAtMs:D=this.state.timer.now(),handling:k}={}){let P=lk(k,R,d,D),C=this.state.sessions.get(d);if(!C)return{id:R.id,type:"mcp_response",success:!1,error:"Session not found",code:yc};if(!this.state.acceptingRequests)return this.callbacks.shuttingDownBeforeStartResponse(R);let M=this.callbacks.rejectOnHandshakeMismatch(R);if(M)return M;if(R=this.callbacks.withCanonicalToolCallDeviceIds(R),R.method===ck)return this.state.notificationSubscribers.add(d),{id:R.id,type:"mcp_response",success:!0,result:{subscribed:!0}};if([XA,iF].includes(R.method))return this.callbacks.handleResourceSubscription(d,R);if(R.method===ms){let X=await YN(R,this.state.daemonState);return{id:R.id,type:"mcp_response",...X}}let F=this.callbacks.unqueuedRequest(C,c,R,P);if(F)return F;let{totalTimeoutMs:q,deadline:U}=P,K=this.callbacks.registerRequestCancellation(C,P),W=this.callbacks.socketAdmissionCancellation(R,d,c,K.signal),V,z=()=>this.runAdmittedRequest({request:R,sessionId:d,ownerSocket:c,receivedAtMs:D,context:P,cancellation:K,onInputDispatch:()=>V?.()}),J=this.state.onFrameTrace?this.callbacks.frameDeviceId(R):void 0;if(this.state.onFrameTrace)this.callbacks.traceFrame("admission_requested",R.id,{deviceId:J});return C.requestQueue.run(Pa(R),()=>{if(!this.state.acceptingRequests)return Promise.resolve(this.callbacks.shuttingDownBeforeStartResponse(R));if(k?.onAdmitted?.(U),this.state.onFrameTrace)this.callbacks.traceFrame("admission_granted",R.id,{deviceId:J});return this.callbacks.isProvisionDeviceCall(R)?this.callbacks.runProvisionBarrier(z,K.signal,()=>this.callbacks.mcpForwardFailureResponse({error:K.signal.reason,request:R,sessionId:d,ownerSocket:c,signal:K.signal})):Ht.has(R.method)?this.callbacks.runCancellableInputHandler((X)=>(V=X,z()),W.signal):this.callbacks.runCancellableQueuedHandler(z,K.signal)},{timer:this.state.timer,deadlineMs:U.value,signal:W.signal,timeoutError:(X)=>new Mr({toolName:R.method==="tools/call"?R.params?.name??R.method:R.method,timeoutMs:q,origin:"UnixSocketServer.handleRequest",code:up,detail:X?`timed out in queue (waiting in queue for ${Pa(R)})`:"timed out in queue before admission"})}).then(async(X)=>X&&!X.success?await this.callbacks.provisionCancellationReply(R,X,K.signal.aborted?K.signal:P.owner.signal)??X:X).finally(()=>{W.dispose(),K.dispose()})}unqueuedRequest(d,c,R,D){if(R.method===iR)return this.callbacks.cancelSocketRequest(d,R);if(pV(R.method))return this.callbacks.relayTaskRequest(d,c,R,D);return}async relayTaskRequest(d,c,R,D){let k=d.sessionId,P=this.callbacks.registerRequestCancellation(d,D),C=this.callbacks.mcpRequestSignal(k,c,P.signal);try{await this.callbacks.waitForStartup(R,D.deadline,C.signal);let M=await this.callbacks.forwardMcpRequest({request:R,route:this.callbacks.sharedMcpForwardRoute(`method:${R.method}`),socketSessionId:k,signal:C.signal,totalTimeoutMs:D.totalTimeoutMs,deadline:D.deadline});return{id:R.id,type:"mcp_response",success:!0,result:M}}catch(M){return Bf(M,R)??this.callbacks.mcpForwardFailureResponse({error:M,request:R,sessionId:k,ownerSocket:c,signal:C.signal})}finally{C.dispose(),P.dispose()}}runProvisionBarrier(d,c,R){let D=d();return this.callbacks.trackRequestHandler(D.then(()=>{},()=>{})),new Promise((k,P)=>{let C=()=>k(R());if(c.aborted)C();else c.addEventListener("abort",C,{once:!0});D.then(k,P).finally(()=>c.removeEventListener("abort",C))})}shuttingDownBeforeStartResponse(d){return{id:d.id,type:"mcp_response",success:!1,error:kg,...z0(W0())}}isProvisionDeviceCall(d){return d.method==="tools/call"&&d.params?.name==="provisionDevice"}async provisionCancellationReply(d,c,R){let D=this.state.forwardedCallKeys.get(d);if(!c||!this.callbacks.isProvisionDeviceCall(d)||D===void 0||!(R?.reason instanceof ut))return;let k=await r1.await(D,QC+Mm,this.state.timer);return k===void 0?void 0:{id:d.id,type:"mcp_response",success:!0,result:k}}mcpForwardFailureResponse({error:d,request:c,sessionId:R,ownerSocket:D,signal:k}){let P=r(d),C=Dm(d,k);if(Om(k,C)){if(e.debug(`MCP forward abandoned for ${R}: ${C?.message}`),D.destroyed)return}else{let M=d instanceof Error?d.stack:"no stack";e.error(`Error forwarding request to MCP server: ${P}`),xm(C),e.error(`Error stack: ${M}`),e.error(`Full error: ${JSON.stringify(d)}`)}return{id:c.id,type:"mcp_response",success:!1,error:P,...d instanceof qt?{boundSessionLoss:d.failure}:{},...gi(d,C),...(d instanceof ke||d instanceof lc)&&d.charsSent!==void 0?{charsSent:d.charsSent}:{}}}async waitForStartup(d,c,R){if(!this.state.startupCompletion||this.state.startupCompleted)return;let D=c.value-this.state.timer.now(),k=()=>new t(`Daemon still starting; retry ${d.method} after startup completes`);if(D<=0)throw k();let P=this.state.startupCompletion.then(void 0,(C)=>{throw new t(`Daemon startup failed: ${r(C)}`,{cause:C})});await l(P,{timer:this.state.timer,timeoutMs:D,signal:R,label:"Daemon startup",timeoutError:k})}registerRequestCancellation(d,{id:c,cancellation:R}){return d.requestCancellations.set(c,R),{signal:R.signal,dispose:()=>{if(d.requestCancellations.get(c)===R)d.requestCancellations.delete(c)}}}cancelSocketRequest(d,c){let R=c.params?.requestId;if(typeof R!=="string"||R.length===0)return{id:c.id,type:"mcp_response",success:!1,error:`${iR} requires a non-empty string params.requestId`};let D=d.requestCancellations.get(R);if(!D)return e.debug(`[SocketCancel] socketSession=${d.sessionId} cancel for request ${R} found no in-flight request (already answered or never seen)`),{id:c.id,type:"mcp_response",success:!0,result:{cancelled:!1}};d.requestCancellations.delete(R);let k=new ut(`Request ${R} was cancelled by its client (client-side timeout or abort); the daemon abandoned it so the next request on this connection can run.`);return e.warn(`[SocketCancel] socketSession=${d.sessionId} ${k.message}`),D.abort(k),{id:c.id,type:"mcp_response",success:!0,result:{cancelled:!0}}}requireRemainingMcpForwardBudget(d,c,R,D){let k=this.callbacks.remainingMcpForwardBudget({deadline:R}),P=Math.max(0,c-k);if(k>0&&(P===0||k>pa))return k;let C=d.method==="tools/call"?d.params?.name??d.method:d.method;if(k<=0)throw new Mr({toolName:C,timeoutMs:c,origin:"UnixSocketServer.handleRequest",detail:`spent ${c-k}ms ${D}`,...D==="waiting in queue"?{code:up}:{}});if(P>0){let M={code:"daemon_overloaded",retryable:!0,retryAfterMs:Em,reason:"insufficient_forward_budget",queueWaitMs:P,remainingTimeoutMs:Math.max(0,k)};throw new ia(`Daemon overloaded while handling ${C}: spent ${P}ms ${D}, leaving ${M.remainingTimeoutMs}ms of the ${c}ms deadline. Retry after ${M.retryAfterMs}ms.`,M)}throw new Mr({toolName:C,timeoutMs:c,origin:"UnixSocketServer.handleRequest",detail:`spent ${c-k}ms ${D}`})}socketAdmissionCancellation(d,c,R,D){if(!Ht.has(d.method))return{signal:D,dispose:()=>{}};return this.callbacks.mcpRequestSignal(c,R,D)}async runCancellableInputHandler(d,c){let R=new AbortController,D=!1,k=()=>{if(!D)R.abort(c?.reason)};if(c?.addEventListener("abort",k,{once:!0}),c?.aborted)k();try{return await this.callbacks.runCancellableQueuedHandler(()=>d(()=>{R.signal.throwIfAborted(),D=!0,c?.removeEventListener("abort",k)}),R.signal)}finally{c?.removeEventListener("abort",k)}}async runCancellableQueuedHandler(d,c){if(!c)return await d();c.throwIfAborted();let R=d();return this.callbacks.trackRequestHandler(R.then(()=>{},()=>{})),await l(R,{timer:this.state.timer,signal:c,label:"Cancelled socket request"})}async runAdmittedRequest(d){let{request:c,sessionId:R,ownerSocket:D,receivedAtMs:k,context:P,cancellation:C}=d,{deadline:M,owner:F}=P;try{if(c.method.startsWith("daemon/")){let U=await YN(c,this.state.daemonState,{signal:C.signal,context:{socketSessionId:R}});return{id:c.id,type:"mcp_response",...U}}if(!wf.has(c.method))F.adopt(C.signal),await this.callbacks.waitForStartup(c,M,C.signal);let q=await this.callbacks.runLocalSocketRequest(c,R,D,{cancelSignal:C.signal,receivedAtMs:k,onOwnerSignal:(U)=>F.adopt(U),onInputDispatch:d.onInputDispatch});if(q!==void 0)return{id:c.id,type:"mcp_response",success:!0,result:q};return await this.runAdmittedMcpForward(d)}catch(q){return this.callbacks.mcpForwardFailureResponse({error:q,request:c,sessionId:R,ownerSocket:D,signal:F.signal})}}async runAdmittedMcpForward(d){let{request:c,sessionId:R,ownerSocket:D,context:k,cancellation:P}=d,{totalTimeoutMs:C,deadline:M}=k,F,q=()=>{};try{if(c.method==="tools/call")await this.callbacks.restoreSelectorSessions(c.params?.arguments,R),F=this.callbacks.beginMcpSessionOwnerCall(c.params?.arguments,R,P.signal);let U=this.callbacks.getMcpForwardRoute(c,R),K=U instanceof Promise?await U:U,W=this.callbacks.mcpRequestSignal(R,D,P.signal);q=W.dispose,k.owner.adopt(W.signal);let V=await this.callbacks.runMcpForwardForCurrentRoute(K,c,R,{fn:async(z)=>{let J=this.callbacks.requireRemainingMcpForwardBudget(c,C,M,"waiting in queue"),X=Math.max(0,C-J),te=this.callbacks.describeMcpForwardRequest(c);e.debug(`[McpForward] start executionKey=${z.executionKey} clientKey=${z.clientKey} socketSession=${R} requestId=${c.id} ${te} queueWaitMs=${X} remainingTimeoutMs=${J}`);let re=this.state.timer.now();try{let ie=this.callbacks.wasRequestSessionActive(c),oe=await this.callbacks.forwardMcpRequest({request:c,route:z,socketSessionId:R,signal:W.signal,totalTimeoutMs:C,deadline:M});if(this.callbacks.isMcpRequestOwnerCurrent(R,W.signal))this.callbacks.recordBoundMcpClientKey(c,R,z,{sessionWasActiveBeforeForward:ie,response:oe});return oe}finally{e.debug(`[McpForward] end executionKey=${z.executionKey} clientKey=${z.clientKey} socketSession=${R} requestId=${c.id} ${te} forwardMs=${this.state.timer.now()-re}`)}},chainWait:{remainingMs:()=>this.callbacks.remainingMcpForwardBudget({deadline:M}),timeoutError:(z)=>new Mr({toolName:c.method==="tools/call"?c.params?.name??c.method:c.method,timeoutMs:C,origin:"UnixSocketServer.handleRequest",detail:`spent ${C-this.callbacks.remainingMcpForwardBudget({deadline:M})}ms waiting in queue for ${z}`,code:up})}});if(u5(V))return{id:c.id,type:"mcp_response",success:!1,error:kg,...z0(KQ(V))};return{id:c.id,type:"mcp_response",success:!0,result:V}}finally{F?.(),q()}}}class $a{timer;idGenerator;flights=new nt;joinable=new Map;constructor(d,c){this.timer=d;this.idGenerator=c}read(d,c,R=0){let{request:D,route:k}=d;if(D.method!=="tools/call"||D.tasks!==void 0||!et(D.params?.name,D.params?.arguments))return;let P={...D.params?.arguments};delete P[Tp],delete P[Ap];let C=Fr({name:D.params?.name,args:P,toolSelectionProfileUuid:k.toolSelectionProfileUuid??k.sessionUuid}),M=d.deadline.value-this.timer.now();if(M<=0)return Promise.reject(this.timeoutError(d));return l(()=>this.joinFlight(C,d,c,R),{timer:this.timer,signal:d.signal,timeoutMs:M,label:`Host inventory ${D.params?.name}`,timeoutError:()=>this.timeoutError(d)})}timeoutError(d){return new Mr({toolName:d.request.params?.name??"host inventory",timeoutMs:d.totalTimeoutMs,origin:"UnixSocketServer.handleRequest",detail:"waiting for shared host inventory"})}joinFlight(d,c,R,D){let k=this.selectFlight(d,c,D);return this.flights.run(k.startOrder,async()=>{try{return await R(this.sharedContext(c,k))}finally{if(this.joinable.get(d)===k)this.joinable.delete(d)}},c.signal)}selectFlight(d,c,R){let D=this.joinable.get(d);if(D&&D.startOrder>R&&D.deadlineMs>=c.deadline.value)return D;let k=this.timer.now(),P=Math.max(YA,c.totalTimeoutMs,c.deadline.value-k),C={startOrder:ka(),deadlineMs:k+P,timeoutMs:P};return this.joinable.set(d,C),C}sharedContext(d,c){let R={...d.request,timeoutMs:c.timeoutMs,progressToken:void 0};return{...d,request:R,socketSessionId:`host:inventory:${this.idGenerator.next()}`,signal:void 0,totalTimeoutMs:c.timeoutMs,deadline:new xh(c.deadlineMs-c.timeoutMs,c.timeoutMs)}}}import{AsyncLocalStorage as pk}from"async_hooks";var Ha=new pk;function Of(d,c,R){return Ha.run({sessionKey:d,...R!==void 0&&{taskOwnerKey:R}},c)}function xf(){return Ha.getStore()?.sessionKey}function _f(){return Ha.getStore()?.taskOwnerKey}var Ff=300000;function Lf(d,c,R,{idleCloseKey:D,chainWait:k}={}){if(D){let U=d.idleCloseKeys.get(c)??new Set;U.add(D),d.idleCloseKeys.set(c,U)}let P=d.tails.get(c),C=P??Promise.resolve(),F=(P&&k?mk(d.timer,c,P,k):C).then(()=>{if(D)d.onAcquired(D);return R()}),q=Promise.all([C,F.then(()=>{return},()=>{return})]).then(()=>{return});return d.tails.set(c,q),q.finally(()=>{if(d.tails.get(c)===q){d.tails.delete(c);let U=d.idleCloseKeys.get(c);d.idleCloseKeys.delete(c);for(let K of U??[])d.onDrained(K)}}),F}async function mk(d,c,R,D){try{await l(R,{timer:d,timeoutMs:Math.max(0,D.remainingMs()),label:`MCP forward wait for ${c}`})}catch(k){throw e.warn(`[McpForward] chain wait expired executionKey=${c}: ${r(k)}`),D.timeoutError(c)}}class qa{state;resolveCallbacks;discoveryCache;inventoryForward;constructor(d,c){this.state=d;this.resolveCallbacks=c;this.inventoryForward=new $a(d.timer,d.idGenerator),this.discoveryCache=new Mn(()=>this.state.mcpDispatcher.refreshResources?.()??Promise.resolve(),d.timer)}get callbacks(){return this.resolveCallbacks()}forgetSocketDiscovery(d){this.discoveryCache.forgetSocket(d)}rejectOnHandshakeMismatch(d){if(!this.state.handshakeEnforced)return null;let c=jQ(this.state.daemonIdentity,l5(d));if(c.ok)return null;return e.warn(`Rejecting daemon client on handshake ${c.reason} mismatch: ${c.message}`),{id:d.id,type:"mcp_response",success:!1,error:c.message,handshakeFailure:{code:"daemon_identity_mismatch",phase:"daemon-preflight",executionStarted:!1,reason:c.reason,daemon:this.state.daemonIdentity,client:l5(d)}}}runKeyedMcpForward(d,c,R,D){return Lf({tails:this.state.mcpForwardTails,idleCloseKeys:this.state.mcpForwardIdleCloseKeys,timer:this.state.timer,onAcquired:(k)=>this.callbacks.clearForwardKeyIdleTimer(k),onDrained:(k)=>this.callbacks.scheduleForwardKeyIdle(k)},d,c,{idleCloseKey:R,chainWait:D})}async runMcpForwardForCurrentRoute(d,c,R,{fn:D,chainWait:k}){if(c.method==="tools/call"&&et(c.params?.name,c.params?.arguments))return await D(d);let P=[d.executionKey],C=d;for(;;){let M=C,F=await this.callbacks.runKeyedMcpForward(M.executionKey,()=>this.callbacks.runMcpForwardAttempt(M,c,R,D),void 0,k);if(F.kind==="done")return F.value;if(C=F.route,P.push(C.executionKey),P.length>fa+1)throw new t(`MCP request ${c.id} was re-routed more than ${fa} times while waiting to run (execution keys: ${P.join(" -> ")}). The target device or session kept changing; retry once it is stable.`);e.debug(`[McpForward] rekey requestId=${c.id} initialExecutionKey=${M.executionKey} currentExecutionKey=${C.executionKey}`)}}async runMcpForwardAttempt(d,c,R,D){let k=this.callbacks.getMcpForwardRoute(c,R),P=k instanceof Promise?await k:k;if(P.executionKey!==d.executionKey)return{kind:"reroute",route:P};if(d.sessionUuid!==void 0&&P.clientKey!==d.clientKey&&!this.callbacks.hasActiveDaemonSession(d.sessionUuid))return e.debug(`[McpForward] released-session re-resolve requestId=${c.id} releasedSession=${d.sessionUuid} clientKey=${d.clientKey} -> ${P.clientKey}`),{kind:"done",value:await D(P)};return{kind:"done",value:await D(d)}}async forwardMcpRequest(d){d.signal?.throwIfAborted();let c=this.inventoryForward.read(d,(k)=>this.forwardUncachedMcpRequest(k),of());if(c)return await c;let R=d.request.method;if(R!=="tools/list"&&R!=="resources/list"||R==="resources/list"&&!this.state.mcpDispatcher.refreshResources)return await this.forwardUncachedMcpRequest(d);this.callbacks.requireRemainingMcpForwardBudget(d.request,d.totalTimeoutMs,d.deadline,"preparing discovery");let D=await this.callbacks.withAdmittedBoundSession(d.request.params,()=>this.discoveryCache.read(d,()=>this.forwardUncachedMcpRequest(d)));return d.signal?.throwIfAborted(),this.callbacks.requireRemainingMcpForwardBudget(d.request,d.totalTimeoutMs,d.deadline,"refreshing discovery"),D}async forwardUncachedMcpRequest(d){let c=await Of(d.socketSessionId,()=>this.state.mcpClientFactory(d.route.sessionUuid,d.route.toolSelectionProfileUuid,d.route.releasedSessionUuid),K0(d.request.tasks)?.ownerKey);try{d.signal?.throwIfAborted();let R=this.callbacks.requireRemainingMcpForwardBudget(d.request,d.totalTimeoutMs,d.deadline,"waiting in queues and preparing the MCP client");return await this.callbacks.handleIdeRequest(c,d.request,R,{socketSessionId:d.socketSessionId,deadline:d.deadline,originalTimeoutMs:d.totalTimeoutMs,signal:d.signal})}finally{await Promise.resolve().then(()=>c.close()).catch((R)=>{e.warn(`Closing an MCP forward failed: ${r(R)}`,R)})}}remainingMcpForwardBudget(d){return d.deadline.value-this.state.timer.now()}wasRequestSessionActive(d){let c=d.method==="tools/call"?this.callbacks.getSessionUuid(d.params?.arguments):void 0;return c?this.callbacks.hasActiveDaemonSession(c):!1}describeMcpForwardRequest(d){if(d.method==="tools/call"){let c=d.params?.name;return`method=tools/call tool=${typeof c==="string"?c:"?"}`}if(d.method==="resources/read"){let c=d.params?.uri;return`method=resources/read uri=${typeof c==="string"?c:"?"}`}return`method=${d.method}`}daemonGenerationMatches(d){return G9(this.callbacks.currentGenerationIdentity(),d)}currentGenerationIdentity(){return{pid:process.pid,startedAt:this.state.identityStartedAt,...this.state.processGenerationToken===void 0?{}:{processGenerationToken:this.state.processGenerationToken},version:this.state.daemonIdentity.version,buildId:this.state.daemonIdentity.build.buildId,entryScript:this.state.daemonIdentity.build.entryScript}}async republishDaemonIdentity(d){if(!this.callbacks.daemonGenerationMatches(d)||Dr(d)!==this.state.processGenerationToken||d.processStartedAt!==this.state.identityProcessStartedAt)return{accepted:!1,reason:"generation_changed"};if(this.state.identityRepublishInFlight)return this.state.identityRepublishInFlight;this.state.identityRepublishInFlight=this.callbacks.publishIdentity();try{return await this.state.identityRepublishInFlight}finally{this.state.identityRepublishInFlight=void 0}}async publishIdentity(){if(!this.state.onRepublishIdentity)return{accepted:!1,reason:"republish_unavailable"};try{return await this.state.onRepublishIdentity()?{accepted:!0}:{accepted:!1,reason:"startup_pending"}}catch(d){return e.warn("Failed to republish daemon identity",d),{accepted:!1,reason:"republish_failed"}}}requireFeatureFlagService(){if(!this.state.featureFlagService)throw Error("Feature flag service not available");return this.state.featureFlagService}async handleIdeRequest(d,c,R,{socketSessionId:D,deadline:k,originalTimeoutMs:P,signal:C}){C?.throwIfAborted();let M=this.callbacks.mcpRequestOptions(R,C),F=Vm({mcpClient:d,request:c,timeoutMs:R,options:M,admitted:(q,U)=>this.callbacks.withAdmittedBoundSession(q,U),readAdmissionArgs:(q)=>this.callbacks.boundSessionAdmissionArgs(q)});if(F)return await F;switch(c.method){case"tools/call":{let q=c.progressToken,U=this.state.idGenerator.next();this.state.forwardedCallKeys.set(c,U),mJ(U,k);let K=()=>AG(U),W=M;if(q!==void 0){let V=new AbortController,z=(re)=>this.state.timer.setTimeout(()=>V.abort(`Request timed out after ${Math.max(re,0)}ms`),Math.max(re,0)),J=z(R),X=Math.max(k.ceiling-this.state.timer.now(),R),te=U;K=()=>{this.state.timer.clearTimeout(J),AG(te)},W={...M,signal:this.callbacks.combineMcpRequestSignals(C,V.signal),timeout:X,maxTotalTimeout:X,onprogress:(re)=>{this.state.timer.clearTimeout(J),k.extendOnProgress(this.state.timer.now(),P),J=z(k.value-this.state.timer.now()),this.callbacks.pushProgressNotification(D,{requestId:c.id,progressToken:q,progress:re.progress,total:re.total,message:re.message})}}}try{return await this.callbacks.withAdmittedBoundSession(c.params.arguments,()=>{let V=this.callbacks.withSocketSessionAutolockKey(c.params.arguments,D,R);return this.callbacks.traceCallTool(c,()=>Tf(d,c,this.callbacks.withLiveDeadlineKey(V,U),W))},D).catch(async(V)=>{let z=KE(U);if(!z?.hasPending())return this.callbacks.textForwardFailure(U,c.params.name,V);let J=z.timeoutError(V),X=k.value-this.state.timer.now();if(X>0)try{await l(z.settled(),{timeoutMs:X,timer:this.state.timer,label:"Dispatched text settlement"})}catch(te){e.debug("Dispatched text settlement wait ended",te)}return this.state.shapeToolCallError(J,{toolName:c.params.name,source:"MCP"})})}finally{K()}}default:return await Ef(d,c,M)}}textForwardFailure(d,c,R){let D=KE(d)?.timeoutError(R);if(D)return this.state.shapeToolCallError(D,{toolName:c,source:"MCP"});throw R}async traceCallTool(d,c){if(!this.state.onFrameTrace)return await c();let R=this.callbacks.frameDeviceId(d);this.callbacks.traceFrame("callTool_entered",d.id,{deviceId:R});try{return await c()}finally{this.callbacks.traceFrame("callTool_settled",d.id,{deviceId:R})}}withLiveDeadlineKey(d,c){if(c===void 0||!d||typeof d!=="object"||Array.isArray(d))return d;return{...d,[Yv]:c}}withSocketSessionAutolockKey(d,c,R){let D=this.state.timer.now()+R;if(d===null||d===void 0)return{__mcpSessionId:c,...this.callbacks.oneShotCliMarker(c),[Rp]:R,[Tg]:D};if(!d||typeof d!=="object"||Array.isArray(d))return d;let k={...d},P=this.callbacks.honoursBoundSessionMarker(k,c);if(delete k[Ap],delete k[rf],delete k[Tp],this.callbacks.recordOneShotCliConnection(c,k),delete k[sk],delete k[Ko],delete k[_u],P)delete k.sessionUuid;return{...k,__mcpSessionId:c,...this.callbacks.oneShotCliMarker(c),[Rp]:R,[Tg]:D}}recordOneShotCliConnection(d,c){let R=c[ok]===!0;delete c[ok];let D=this.state.sessions.get(d);if(R&&D)D.oneShotCli=!0}oneShotCliMarker(d){return this.state.sessions.get(d)?.oneShotCli?{[sk]:!0}:{}}async createMcpClient(d,c,R){return await this.state.mcpDispatcher.connect({boundSessionUuid:d,toolSelectionProfileUuid:c,releasedSessionUuid:R,sessionKey:xf(),taskOwnerKey:_f()})}scheduleForwardKeyIdle(d){this.callbacks.clearForwardKeyIdleTimer(d);let c=this.state.timer.setTimeout(()=>{this.callbacks.onForwardKeyIdle(d)},Ff);this.state.forwardKeyIdleTimers.set(d,c)}clearForwardKeyIdleTimer(d){let c=this.state.forwardKeyIdleTimers.get(d);if(!c)return;this.state.timer.clearTimeout(c),this.state.forwardKeyIdleTimers.delete(d)}onForwardKeyIdle(d){if(this.state.forwardKeyIdleTimers.delete(d),this.state.mcpForwardTails.has(d)||this.callbacks.isMcpClientKeyBound(d))return;let c="device:";if(d.startsWith(c))this.state.appendTextInputs.delete(d.slice(c.length))}}class Ua{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}getMcpForwardRoute(d,c){if(d.method==="tools/call"){let R=this.callbacks.getToolsCallForwardRoute(d.params?.arguments,c,d.params?.name),D=(k)=>et(d.params?.name,d.params?.arguments)?{...k,executionKey:"host:inventory"}:this.callbacks.withDeviceReadLane(k,d,c);return R instanceof Promise?R.then(D):D(R)}return this.callbacks.withAdmittedBoundSession(this.callbacks.boundSessionAdmissionArgs(d),(R)=>this.callbacks.getAdmittedMcpForwardRoute(d,c,R))}withDeviceReadLane(d,c,R){let D=c.params?.name,k=c.params?.arguments;if(!d.executionKey.startsWith(va)||typeof D!=="string"||!this.callbacks.isDeviceReadToolCall(D,k))return d;let P=d.executionKey.slice(va.length),C=this.callbacks.getDeviceHolderSession(P);if(!C)return d;let M=this.state.daemonState.getSessionManager(),F=(K)=>K?at(K,M):void 0,q=F(C);if([d.sessionUuid,this.callbacks.getSessionUuid(k),this.callbacks.getDeviceLabelSession(k),this.callbacks.resolveImplicitAutolockSession(R,k),this.state.daemonState.getDevicePool().resolveOwnedDeviceSessionForMcpSession?.(R,P)].some((K)=>F(K)===q))return d;return{...d,executionKey:`${d.executionKey}${Um}`}}getDeviceLabelSession(d){let c=this.callbacks.getSessionUuid(d),R=d;return c&&typeof R?.device==="string"&&R.device.length>0?this.callbacks.resolveDeviceLabelSession(c,R.device):void 0}isDeviceReadToolCall(d,c){try{return this.state.deviceReadToolCallClassifier(d,c)}catch(R){return e.debug(`[McpForward] read classification failed for ${d}: ${R}`),!1}}getDeviceHolderSession(d){if(!this.state.daemonState.isInitialized())return;try{return this.callbacks.getSessionForDevice(d)??this.state.daemonState.getDevicePool().getDevice?.(d)?.autolockSessionId??void 0}catch(c){e.debug(`[McpForward] holder lookup failed for ${d}: ${c}`);return}}getAdmittedMcpForwardRoute(d,c,R){let D=this.callbacks.getBoundMcpClientRoute(c,R);if(d.method==="tools/list"||d.method==="resources/list"||d.method==="resources/list-templates")return this.callbacks.getDiscoveryForwardRoute(d,c,D);if(d.method==="ide/getNavigationGraph")return this.callbacks.getNavigationGraphForwardRoute(d,c,D);if(d.method==="resources/read")return this.callbacks.getResourceReadForwardRoute(d,c);return this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getDiscoveryForwardRoute(d,c,R){if(d.method==="tools/list"){let P=this.callbacks.getSessionUuid(d.params),C=this.callbacks.getToolSelectionProfileUuid(d.params);if(P)return this.callbacks.sessionScopedForwardRoute(c,P,void 0,{toolSelectionProfileUuid:C});if(C)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,C,void 0);return R??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}let D=this.callbacks.getSessionUuid(d.params),k=this.callbacks.getToolSelectionProfileUuid(d.params);if(D)return this.callbacks.sessionScopedForwardRoute(c,D,void 0,{toolSelectionProfileUuid:k});if(k)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,k,void 0);return R??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getNavigationGraphForwardRoute(d,c,R){let D=this.callbacks.getSessionUuid(d.params),k=this.callbacks.getRequestArgumentScopeKey(d.params);if(D)return this.callbacks.sessionScopedForwardRoute(c,D,k);if(k)return R?{...R,executionKey:k}:this.callbacks.sharedMcpForwardRoute(k);return R??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getResourceReadForwardRoute(d,c){let R=this.callbacks.getSessionUuid(d.params);if(R){let k=d.params?.[_u]===R?R:void 0;return this.callbacks.sessionScopedForwardRoute(c,R,void 0,{releasedSessionUuid:k===R?k:void 0})}let D=d.params?.uri;return this.callbacks.sharedMcpForwardRoute(typeof D==="string"?`resource:${D}`:"resource:unknown")}beginMcpSessionOwnerCall(d,c,R){let D=this.callbacks.ownedSessionsOwnerToken(d);if(D===void 0||!this.callbacks.isMcpRequestOwnerCurrent(c,R))return;try{if(!this.state.daemonState.isInitialized())return;let k=this.state.daemonState.getDevicePool().beginMcpSessionOwnerCall?.(c,D);return()=>{try{k?.()}catch(P){e.warn(`Unable to end MCP session owner call: ${r(P)}`,P)}}}catch(k){e.warn(`Unable to begin MCP session owner call: ${r(k)}`,k);return}}getToolsCallForwardRoute(d,c,R){return this.callbacks.withAdmittedBoundSession(d,(D)=>this.callbacks.getAdmittedToolsCallForwardRoute(d,c,R,D),c)}getAdmittedToolsCallForwardRoute(d,c,R,D){let k=this.callbacks.getRequestArgumentScopeKey(d),P=this.callbacks.getBoundMcpClientRoute(c,D),C=this.callbacks.getSessionUuid(d),M=this.callbacks.getToolSelectionProfileUuid(d)??P?.toolSelectionProfileUuid;if(this.callbacks.isUnboundDeviceAcquisitionTool(R,C))return this.callbacks.acquisitionMcpForwardRoute(c,R,M);if(this.callbacks.hasImplicitDeviceSelector(d))return this.callbacks.selectorMcpForwardRoute(c,d,k,M);if(C)return this.callbacks.profileReaffirmForwardRoute({args:d,socketSessionId:c,toolName:R,sessionUuid:C,toolSelectionProfileUuid:M,scopedKey:k,boundRoute:P})??this.callbacks.sessionScopedForwardRoute(c,C,k,{toolSelectionProfileUuid:M});if(M)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,M,k);if(k){if(P)return{...P,executionKey:k};return this.callbacks.sharedMcpForwardRoute(k)}if(P)return this.callbacks.hostInventoryOrBoundRoute(P,R,d);let F=this.callbacks.getImplicitAutolockScopeKey(c,d);if(F)return this.callbacks.sharedMcpForwardRoute(F);return this.callbacks.sharedMcpForwardRoute(`socket:${c}`)}hostInventoryOrBoundRoute(d,c,R){return et(c,R)?{...d,executionKey:"host:inventory"}:d}isUnboundDeviceAcquisitionTool(d,c){return typeof d==="string"&&Nm.has(d)&&!c}profileReaffirmForwardRoute(d){let{args:c,socketSessionId:R,toolName:D,sessionUuid:k,toolSelectionProfileUuid:P,scopedKey:C,boundRoute:M}=d;if(D!==At||k!==P)return;let F=this.callbacks.getAcquiredDeviceSessionUuid(c,k)??M?.sessionUuid;if(!F||!this.callbacks.hasActiveDaemonSession(F))return;return this.callbacks.sessionScopedForwardRoute(R,F,C,{toolSelectionProfileUuid:P})}getAcquiredDeviceSessionUuid(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return;let R=d[Ko];return Ze(R)&&R!==c?R:void 0}selectorMcpForwardRoute(d,c,R,D){let k=R??this.callbacks.getImplicitAutolockScopeKey(d,c)??`socket:${d}`;return D?this.callbacks.toolSelectionProfileScopedForwardRoute(d,D,k):this.callbacks.sharedMcpForwardRoute(k)}hasImplicitDeviceSelector(d){if(!d||typeof d!=="object"||Array.isArray(d))return!1;let c=d;if(c.device)return!1;if(this.callbacks.getSessionUuid(d))return!1;return c.platform==="android"||c.platform==="ios"||typeof c.deviceId==="string"}sharedMcpForwardRoute(d){return{executionKey:d,clientKey:d}}acquisitionMcpForwardRoute(d,c,R){let D=`socket:${d}:acquisition:${c}`;return{executionKey:D,clientKey:R?`${D}:tool-selection:${R}`:D,toolSelectionProfileUuid:R}}sessionMcpClientKey(d,c,R,D){let k=R?`:tool-selection:${R}`:"";return`socket:${d}:session:${c}${k}${D?":released-resource":""}`}toolSelectionProfileMcpClientKey(d,c){return`socket:${d}:tool-selection:${c}`}sessionScopedForwardRoute(d,c,R,{toolSelectionProfileUuid:D,releasedSessionUuid:k}={}){return{executionKey:R??`session:${c}`,clientKey:this.callbacks.sessionMcpClientKey(d,c,D,k),sessionUuid:c,toolSelectionProfileUuid:D,releasedSessionUuid:k}}toolSelectionProfileScopedForwardRoute(d,c,R){return{executionKey:R??`tool-selection:${c}`,clientKey:this.callbacks.toolSelectionProfileMcpClientKey(d,c),toolSelectionProfileUuid:c}}}class Ka{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async restoreSelectorSessions(d,c){let R=this.callbacks.ownedSessionsOwnerToken(d);if(R!==void 0&&this.state.clientSockets.has(c))try{if(this.state.daemonState.isInitialized())this.state.daemonState.getDevicePool().declareMcpSessionLivenessOwnerToken?.(c,R)}catch(F){e.warn(`Unable to declare MCP session owner token: ${r(F)}`,F)}let D=this.callbacks.selectorSessionIds(d);if(!D)return;let k=this.state.daemonState.getDevicePool(),P=this.state.clientSockets.get(c),C=await k.restoreOwnedDeviceSessionsForMcpSession?.(D,c,R)??[];if(this.callbacks.releaseBindingsIfSocketDisconnected(c,P,k))return;let M=new Set(C.map((F)=>F.sessionId));await k.restoreAutolockSessionsForMcpSession?.(D.filter((F)=>!M.has(F)),c),this.callbacks.releaseBindingsIfSocketDisconnected(c,P,k),this.callbacks.failIfCallTargetsRefusedRestore(d,C)}failIfCallTargetsRefusedRestore(d,c){let R=d&&typeof d==="object"&&!Array.isArray(d)?d:{};for(let{sessionId:D,deviceId:k,reason:P}of c)if(e.warn(`[McpForward] skipped restoring owned session ${D} on ${k}: ${P}`),R.sessionUuid===D||R.deviceId===k)throw BD(k)}ownedSessionsOwnerToken(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[Tp];return typeof c==="string"&&c.trim()!==""?c:void 0}selectorSessionIds(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[rf];return Array.isArray(c)&&c.every(Ze)?[...new Set(c)]:void 0}releaseBindingsIfSocketDisconnected(d,c,R){if(!c||this.state.clientSockets.get(d)===c)return!1;return R.releaseMcpSessionBindings?.(d),!0}releaseDevicePoolMcpSessionBindings(d){if(this.state.daemonState.isInitialized())this.state.daemonState.getDevicePool().releaseMcpSessionBindings?.(d)}clearConnectionDevicePin(d){this.state.clearConnectionDevicePin?.(d)}recordBoundMcpClientKey(d,c,R,{sessionWasActiveBeforeForward:D,response:k}){if(d.method!=="tools/call")return;if(vo(d.params?.name))return;let P=this.callbacks.getSessionUuid(d.params?.arguments);if(!P){this.callbacks.recordGeneratedToolSelectionProfile(d,k,c,R);return}if(this.callbacks.isReleasedBoundSession(d.params?.arguments,c)&&this.callbacks.isRetryableSessionRecoveryResult(k,P))return;this.callbacks.recordSessionBoundMcpClientKey(c,R,R.sessionUuid??P,{sessionWasActiveBeforeForward:D,toolName:d.params?.name,args:d.params?.arguments})}holdsSession(d,c){let R=c.split(":",1)[0]??c,D=this.state.boundMcpClientKeysBySocketSession.get(d)?.sessionUuid;if(D!==void 0&&(D===c||D===R))return!0;if(!this.state.daemonState.isInitialized())return!1;let k=this.state.daemonState.getDevicePool();return k.isSessionOwnedByConnection?.(c,d)===!0||k.isSessionOwnedByConnection?.(R,d)===!0}isSessionOwnedByOtherConnection(d,c){return this.state.daemonState.isInitialized()&&this.state.daemonState.getDevicePool().isSessionOwnedByOtherConnection?.(d,c)===!0}honoursBoundSessionMarker(d,c){let R=this.callbacks.getSessionUuid(d);if(d[Ko]!==R)return!1;if(R===void 0||!c||!this.state.daemonState.isInitialized())return!0;let D=this.state.daemonState.getSessionManager(),k=D.ownershipSessionUuid?.(R)??R,P=D.peekSession?.(k)?.livenessOwnerToken;return!P||this.callbacks.ownedSessionsOwnerToken(d)===P||!this.callbacks.isSessionOwnedByOtherConnection(R,c)}isRetryableSessionRecoveryResult(d,c){if(!d||typeof d!=="object"||!("isError"in d)||d.isError!==!0)return!1;let R=xn(d)?.payload.error;return R?.code==="session_recovery_pending"&&R.retryable===!0&&R.sessionUuid===c}recordSessionBoundMcpClientKey(d,c,R,{sessionWasActiveBeforeForward:D,toolName:k,args:P}){if(this.callbacks.isReleasedBoundSession(P,d)){this.callbacks.clearBoundMcpClientKey(d);return}if(this.callbacks.isSessionOwnedByOtherConnection(R,d))return;if(this.callbacks.targetsOneCallOnly(P,R))return;let C=this.callbacks.hasActiveDaemonSession(R);if((D||k==="executePlan")&&!C){this.callbacks.clearBoundMcpClientKey(d);return}this.state.boundMcpClientKeysBySocketSession.set(d,{clientKey:c.clientKey,executionKey:c.executionKey,sessionUuid:R,toolSelectionProfileUuid:c.toolSelectionProfileUuid,requiresLiveDaemonSession:D||C})}targetsOneCallOnly(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return!1;let R=d[Ko];return Ze(R)&&R!==c}recordGeneratedToolSelectionProfile(d,c,R,D){let k=this.callbacks.getGeneratedToolSelectionProfileUuid(d,c);if(!k)return!1;return this.state.boundMcpClientKeysBySocketSession.set(R,{clientKey:D.clientKey,executionKey:D.executionKey,toolSelectionProfileUuid:k,requiresLiveDaemonSession:!1}),!0}getBoundMcpClientRoute(d,c){let R=this.state.boundMcpClientKeysBySocketSession.get(d);if(!R)return;if(!R.requiresLiveDaemonSession||!this.state.daemonState.isInitialized()||c!==void 0&&R.sessionUuid===c)return{clientKey:R.clientKey,executionKey:R.executionKey,sessionUuid:R.sessionUuid,toolSelectionProfileUuid:R.toolSelectionProfileUuid};if(R.sessionUuid&&this.callbacks.hasActiveDaemonSession(R.sessionUuid))return{clientKey:R.clientKey,executionKey:R.executionKey,sessionUuid:R.sessionUuid,toolSelectionProfileUuid:R.toolSelectionProfileUuid};this.callbacks.clearBoundMcpClientKey(d);return}getToolSelectionProfileUuid(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[Ap];return Ze(c)?c:void 0}getGeneratedToolSelectionProfileUuid(d,c){if(d.params?.name!==At)return;return bh(c)}clearBoundMcpClientKey(d){if(!this.state.boundMcpClientKeysBySocketSession.get(d))return;this.state.boundMcpClientKeysBySocketSession.delete(d)}clearBoundMcpClientsForReleasedSession(d){for(let[c,R]of this.state.boundMcpClientKeysBySocketSession)if(R.sessionUuid===d)this.callbacks.clearBoundMcpClientKey(c)}isMcpClientKeyBound(d){for(let c of this.state.boundMcpClientKeysBySocketSession.values())if(c.clientKey===d)return!0;return!1}getSessionForDevice(d){if(!this.state.daemonState.isInitialized())return;try{return this.state.daemonState.getSessionManager().getSessionForDevice?.(d)??void 0}catch(c){e.debug(`Unable to resolve session for device ${d}: ${c}`);return}}getSessionIncarnation(d){if(!d||!this.state.daemonState.isInitialized())return;try{return this.state.daemonState.getSessionManager().getSession(d)??void 0}catch(c){e.debug(`Unable to capture session ${d}: ${c}`);return}}hasActiveDaemonSession(d){if(!this.state.daemonState.isInitialized())return!1;try{return this.state.daemonState.getSessionManager().getSession(d)!==null}catch(c){throw e.warn(`Unable to resolve bound session ${d}: ${r(c)}`,c),new qt({code:tF,sessionUuid:d,reason:"session-not-found"})}}getSessionUuid(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d.sessionUuid;return Ze(c)?c:void 0}isReleasedBoundSession(d,c){if(!d||typeof d!=="object"||Array.isArray(d)||!this.state.daemonState.isInitialized())return!1;let R=d,D=this.callbacks.getSessionUuid(R);return D!==void 0&&this.callbacks.honoursBoundSessionMarker(R,c)&&!this.callbacks.hasActiveDaemonSession(D)}boundSessionAdmissionArgs(d){let c=this.callbacks.getSessionUuid(d.params);return d.method==="resources/read"&&c!==void 0&&d.params?.[_u]===c&&d.params?.uri===`automobile:device-session/${c}/screenshot`?void 0:d.params}withAdmittedBoundSession(d,c,R){if(!this.callbacks.isReleasedBoundSession(d,R))return c();let D=this.callbacks.getSessionUuid(d);return this.callbacks.admitReleasedBoundSession(D).then(()=>c(D))}async admitReleasedBoundSession(d){try{if(await this.state.daemonState.getSessionManager().isReleasedSessionInRestartRecoveryWindow?.(d))return}catch(R){e.warn(`Unable to read restart recovery window for bound session ${d}: ${r(R)}`,R)}let c=this.state.daemonState.getSessionManager().getTerminalReleaseSnapshot?.(d)??await this.callbacks.expiredBoundSessionRelease(d);throw new qt({code:tF,sessionUuid:d,reason:c?.releaseReason??"session-not-found",...bi(c?.releaseReason),...c?{release:c}:{}})}async expiredBoundSessionRelease(d){try{return await this.state.daemonState.getSessionManager().getExpiredReleaseSnapshot?.(d)}catch(c){e.warn(`Unable to read the expired release of bound session ${d}: ${r(c)}`,c);return}}getRequestArgumentScopeKey(d){if(!d||typeof d!=="object"||Array.isArray(d))return;return this.callbacks.getObjectRequestArgumentScopeKey(d,d)}getObjectRequestArgumentScopeKey(d,c){let R=Ze(d.sessionUuid),D=typeof d.device==="string"&&d.device.length>0;if(R&&D)return this.callbacks.sessionToScopeKey(this.callbacks.resolveDeviceLabelSession(d.sessionUuid,d.device));if(typeof d.deviceId==="string"&&d.deviceId.length>0)return`device:${d.deviceId}`;if(R)return this.callbacks.sessionToScopeKey(d.sessionUuid);if(typeof d.__mcpSessionId==="string"&&d.__mcpSessionId.length>0)return this.callbacks.getImplicitAutolockScopeKey(d.__mcpSessionId,c)??`mcp-session:${d.__mcpSessionId}`;return}sessionToScopeKey(d){let c=this.callbacks.getAssignedDeviceForSession(d);return c?`device:${c}`:`session:${d}`}getImplicitAutolockScopeKey(d,c){let R=this.callbacks.resolveImplicitAutolockSession(d,c);return R?this.callbacks.sessionToScopeKey(R):void 0}resolveImplicitAutolockSession(d,c){if(!this.state.daemonState.isInitialized())return;try{let R=this.callbacks.getRequestPlatform(c),D=this.state.daemonState.getDevicePool().resolveAutolockSessionForMcpSession?.(d,R);if(!D)return;return D}catch(R){e.debug(`Unable to resolve autolock session for MCP session ${d}: ${R}`);return}}getRequestPlatform(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d.platform;return c==="android"||c==="ios"?c:void 0}resolveDeviceLabelSession(d,c){if(typeof c!=="string"||c.length===0||!this.state.daemonState.isInitialized())return d;try{let R=this.state.daemonState.getSessionManager().getDeviceLabels(d);if(!R)return d;let D=R[c];return typeof D==="string"&&D.length>0?D:d}catch(R){return e.debug(`Unable to resolve device label ${c} for session ${d}: ${R}`),d}}getAssignedDeviceForSession(d){if(!this.state.daemonState.isInitialized())return;try{return this.state.daemonState.getSessionManager().getSession(d)?.assignedDevice}catch(c){e.debug(`Unable to resolve device for session ${d}: ${c}`);return}}}import{createHash as fk}from"crypto";class Ga{ports;constructor(d){this.ports=d}routes=new Map([["ide/status",(d,c,R)=>this.ideStatus(d,c,R)],["ide/updateService",(d,c,R)=>this.ideUpdateService(d,c,R)],["ide/setKeyValue",(d,c,R)=>this.ideSetKeyValue(d,c,R)],["ide/removeKeyValue",(d,c,R)=>this.ideRemoveKeyValue(d,c,R)],["ide/clearKeyValueFile",(d,c,R)=>this.ideClearKeyValueFile(d,c,R)]]);async ideStatus(d,c,R){let D=this.ports.acceptanceDiscoveryCapability();return{structuredSessionNotFound:!0,structuredToolErrorCodes:!0,version:this.ports.daemonIdentity().version,pid:process.pid,launchNonce:I(h.DAEMON_LAUNCH_NONCE),buildId:this.ports.daemonIdentity().build.buildId,entryScript:this.ports.daemonIdentity().build.entryScript,acceptanceCapabilityFingerprint:D?fk("sha256").update(D).digest("hex").slice(0,8):null,startedAt:this.ports.identityStartedAt(),processStartedAt:this.ports.identityProcessStartedAt(),dbPath:this.ports.identityDbPath(),reportedPidFilePath:this.ports.identityPidFilePath(),reportedSocketPath:this.ports.socketPath(),reportedSockets:jB(this.ports.identitySockets()??{}),unavailableSockets:xY(),effectiveDebug:Pu(),options:this.ports.startupOptions(),..._d(this.ports.processGenerationToken()),activeProvisioning:G.hasActiveToolExecution("provisionDevice",{scope:"global"}),releaseVersion:cn(De()),android:{ctrlProxy:{expectedSha256:pb(),url:pf()}},ios:{xcTestService:{expectedSha256:AR(),expectedAppHash:tj,url:PR()}}}}async ideUpdateService(d,c,R){let D=tt["ide/updateService"](d.params),{devices:k,deviceId:P}=await this.ports.resolveIdeActionDevices(D.platform,D.deviceId,R?.signal);await this.ports.reconcileDiscoveryObservation(k,"socket:ide/updateService"),this.ports.assertDeviceActionable(P,"to update the accessibility service");let C=k.find((M)=>M.deviceId===P);if(!C)throw Error(`Device not found: ${D.deviceId}`);if(await this.ports.daemonState().getDevicePool().isShutdownReserved?.(C.deviceId))throw Error(`Device '${C.deviceId}' is shutting down.`);if(await this.assertIdeMutationOwnership(d,C,"ide/updateService",{force:D.force,ideMutation:R}),D.platform==="android"){R?.signal.throwIfAborted(),R?.dispatching(),E.resumeAfterDeviceStart(C.deviceId);let F=await le.getInstance(C).ensureCompatibleVersion({allowDownloadWhenInstalled:!0,bypassVersionCheckCache:!0});return{success:new Set(["compatible","upgraded","installed","reinstalled"]).has(F.status),message:`Accessibility service ${F.status}${F.error?`: ${F.error}`:""}`,status:F}}else{let M=ve.getInstance(C);return R?.signal.throwIfAborted(),R?.dispatching(),x.resumeAfterDeviceStart(C.deviceId),await M.forceRestart(),{success:!0,message:"CtrlProxy iOS restarted"}}}async ideSetKeyValue(d,c,R){let D=tt["ide/setKeyValue"](d.params);await this.ports.assertSocketToolEnabled(D.deviceId,"setKeyValue");let{platform:k,client:P,device:C}=await this.resolveKeyValueMutationClient(D.platform,D.deviceId,d,{action:"ide/setKeyValue",ideMutation:R}),{appId:M,fileName:F,key:q}=D,U=!1,K;if(D.value===null||D.value===void 0)({usedDirectFileFallback:U,resolution:K}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:R,viaSdk:(J)=>P.removePreference(M,F,q,{onDispatch:J}),viaDirectFile:(J)=>nI(J,C.deviceId,{appId:M,fileName:F},q)}));else{let J={key:q,value:D.value,type:D.type};F1(k,J.type),{usedDirectFileFallback:U,resolution:K}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:R,viaSdk:(X)=>P.setPreference(M,F,J,{onDispatch:X}),viaDirectFile:(X)=>B1(X,C.deviceId,{appId:M,fileName:F},J)})}let W=K?.resolvedStore,V=K?.effectiveValueDiffers,z=L1(U?mS(M,F):void 0,V);return{success:!0,...W?{resolvedStore:W}:{},...V?{effectiveValueDiffers:V}:{},...z?{warning:z}:{}}}async ideRemoveKeyValue(d,c,R){let D=tt["ide/removeKeyValue"](d.params);await this.ports.assertSocketToolEnabled(D.deviceId,"removeKeyValue");let{platform:k,client:P,device:C}=await this.resolveKeyValueMutationClient(D.platform,D.deviceId,d,{action:"ide/removeKeyValue",ideMutation:R}),{appId:M,fileName:F,key:q}=D,{usedDirectFileFallback:U,resolution:K}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:R,viaSdk:(z)=>P.removePreference(M,F,q,{onDispatch:z}),viaDirectFile:(z)=>nI(z,C.deviceId,{appId:M,fileName:F},q)}),W=K?.resolvedStore,V=U?mS(M,F):void 0;return{success:!0,...W?{resolvedStore:W}:{},...V?{warning:V}:{}}}async ideClearKeyValueFile(d,c,R){let D=tt["ide/clearKeyValueFile"](d.params);await this.ports.assertSocketToolEnabled(D.deviceId,"clearKeyValueFile");let{platform:k,client:P,device:C}=await this.resolveKeyValueMutationClient(D.platform,D.deviceId,d,{action:"ide/clearKeyValueFile",ideMutation:R}),{appId:M,fileName:F}=D,{usedDirectFileFallback:q,resolution:U}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:R,viaSdk:(V)=>P.clearPreferenceStore(M,F,{onDispatch:V}),viaDirectFile:(V)=>$1(V,C.deviceId,M,{fileName:F})}),K=U?.resolvedStore,W=q?mS(M,F):void 0;return{success:!0,...K?{resolvedStore:K}:{},...W?{warning:W}:{}}}async assertIdeMutationOwnership(d,c,R,{force:D=!1,ideMutation:k}={}){let P=c.deviceId,C=oj(d.method,d.params);if(!this.ports.daemonState().isInitialized())return;await this.assertFrameTargetProven(c,R,()=>C),this.ports.assertBrokerConnectionControl(k?.socketSessionId,R,{deviceId:P,requesterSessionUuid:C});let M=this.ports.daemonState().getSessionManager();await gb({action:R,deviceId:P,platform:c.platform,requesterSessionUuid:C,sessionManager:M,gate:this.ports.daemonState().getDevicePool()}),await mf({deviceId:P,platform:c.platform,gate:this.ports.daemonState().getDevicePool()});let F=M.getSessionForDevice?.(P)??void 0;if(!D)Nu({action:R,deviceId:P,ownerSessionUuid:F,requesterSessionUuid:C,sessionManager:M,remedy:"pass the holding session's sessionUuid, or wait for the holder to release the device."});if(F)await this.admitIdeMutationOnHolderSession(G.startExecution(R,void 0,F),{deviceId:P,holderSessionUuid:F,force:D},k)}async admitIdeMutationOnHolderSession(d,c,R){R?.track(d,!c.force);try{if(G.bindDeviceExecution(d.id,c.deviceId),c.force)return;if(await this.ports.admitInputAsControlCall(d,c.deviceId,c.holderSessionUuid,R?.signal),R)R.admit(d);else G.markSessionAdmitted(d.id)}finally{if(!R)G.endExecution(d.id)}}async runTrackedIdeMutation(d,c,R){let D=new AbortController,k,P,C,M=R?AbortSignal.any([R,D.signal]):D.signal,F={socketSessionId:d,signal:M,admit:(q)=>{C=q},dispatching:()=>{if(C)G.markSessionAdmitted(C.id)},track:(q,U)=>{if(k=q,!U)return;P=q;let K=q.abortController.signal;if(K.aborted){D.abort(K.reason);return}K.addEventListener("abort",()=>D.abort(K.reason),{once:!0})}};try{return M.throwIfAborted(),await H(M,()=>c(F))}catch(q){throw bm(P?.cancelReason)??q}finally{if(k)G.endExecution(k.id)}}async listBootedDevicesForIdeAction(d,c,R){R?.throwIfAborted();let D=xt.getInstance(),k=uu(await D.getBootedDevicesDetailed(d),this.ports.daemonState()?.isInitialized()?this.ports.daemonState().getDevicePool().getAllDevices?.():void 0);if(!k.devices.map((P)=>P.deviceId).includes(c)&&x0(k,d,c)){let P=k.discoveryErrors?.[d];throw d==="android"?new Gr(P):new ze(d,P)}return R?.throwIfAborted(),k.devices}async resolveIdeActionDevices(d,c,R){let D=await this.canonicalFrameDiscovery(d,await this.ports.listBootedDevicesForIdeAction(d,c,R),c);return{devices:D.devices,deviceId:D.deviceId??c}}async canonicalFrameDiscovery(d,c,R){return await WN(this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool():void 0,d,c,R)}async assertFrameTargetProven(d,c,R){if(!this.ports.daemonState().isInitialized())return;let D=this.ports.daemonState().getSessionManager();await zN(this.ports.daemonState().getDevicePool(),d,c,{heldBySession:Boolean(D.getSessionForDevice?.(d.deviceId)),sessions:xA(D),requester:R,sessionManager:D})}canonicalFrameDeviceId(d){return hm(this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool():void 0,d)}async resolveKeyValueMutationClient(d,c,R,{action:D,ideMutation:k}){let P=d??"android";if(P!=="android"&&P!=="ios")throw Error(`Invalid platform: ${P}. Must be 'android' or 'ios'.`);let{devices:C,deviceId:M}=await this.ports.resolveIdeActionDevices(P,c,k?.signal);await this.ports.reconcileDiscoveryObservation(C,"socket:ide/keyValueMutation"),this.ports.assertDeviceActionable(M,"to mutate stored values");let F=C.find((U)=>U.deviceId===M);if(!F)throw Error(`Device not found: ${c}`);await this.assertIdeMutationOwnership(R,F,D,{ideMutation:k}),k?.signal.throwIfAborted();let q=P==="ios"?x.getInstance(F):E.getInstance(F,this.ports.adbClientFactory());return{platform:P,client:q,device:F}}async runIdeKeyValueMutation(d,c,R,D){let k=!1,{fileName:P}=D,C=()=>{if(k)return;k=!0,D.ideMutation?.dispatching()};if(d!=="android")return D.ideMutation?.signal.throwIfAborted(),{usedDirectFileFallback:!1,resolution:await D.viaSdk(C)||void 0};let M;return{...await U1(R,P,()=>this.ports.adbClientFactory().create(c),{viaSdk:async()=>{D.ideMutation?.signal.throwIfAborted(),M=await D.viaSdk(C)||void 0},viaDirectFile:(q)=>(D.ideMutation?.signal.throwIfAborted(),C(),D.viaDirectFile(q).catch(AN))}),resolution:M}}}function $f(d){return new Map([["ide/listFeatureFlags",async()=>({flags:await d.requireFeatureFlagService().listFlags()})],["ide/setFeatureFlag",async(c,R)=>{let D=d.requireFeatureFlagService(),k=tt["ide/setFeatureFlag"](c.params);return d.assertBrokerHostMutation(R,"ide/setFeatureFlag"),await D.setFlag(k.key,k.enabled,k.config)}],["ide/setSessionToolEnabled",async(c,R)=>{let D=tt["ide/setSessionToolEnabled"](c.params);return d.assertBrokerControl(R,"ide/setSessionToolEnabled",{requesterSessionUuid:D.sessionUuid}),await d.sessionToolSelection().setEnabled(D.sessionUuid,D.toolName,D.enabled),d.emitToolsListChanged(),{sessionUuid:D.sessionUuid,toolName:D.toolName,enabled:D.enabled}}],["ide/ping",async()=>({ok:!0,timestamp:d.now()})]])}function Hf(d){return new Map([[rq,async(c)=>await d.republishIdentity(c.params)],[nq,async(c)=>d.restart.prepareDaemonRestart(c.params)],[iq,async(c)=>d.restart.prepareDaemonMaintenance(c.params)],[oq,async(c)=>d.restart.completeDaemonMaintenance(c.params)],[sq,async(c)=>d.restart.restartAdmittedDaemon(c.params)],[aq,async(c,R)=>d.restart.restartAcceptanceSession(c.params,R)],[cq,async(c,R)=>d.restart.commitAcceptanceRestart(c.params,R)],[dq,async(c,R)=>d.restart.releaseAcceptanceRestart(c.params,R)]])}function qf(d,c){let R=d==="input/key"?"Key":d==="input/tap"?"Tap":d==="input/swipe"?"Swipe":"Button press";if(c instanceof Error&&(("requestDispatched"in c)&&c.requestDispatched===!0||c.message.startsWith(`${R} outcome is indeterminate:`)))return Object.assign(c,{requestDispatched:!0});let D=r(c),k=d==="input/key"?oc.indeterminateError(c):d==="input/tap"?Tn(D):new t(`${d==="input/swipe"?"Swipe":"Button press"} outcome is indeterminate: the request was dispatched but no result was confirmed (${D}). Do not retry automatically.`);return Object.assign(k,{requestDispatched:!0})}class Wa{ports;constructor(d){this.ports=d}requireCurrentFrameContext(d,c,R){if(c===void 0)return;if(It()?.getCurrentFrameContext(d)!==c)throw Error(`${R} frameContext is stale or unavailable; observe a fresh frame before retrying`)}inputRequester(d,c){let R=oj(d.method,d.params);return()=>{if(R||!c||!this.ports.daemonState().isInitialized())return R;let D=df(d.params);if(!D)return;return this.ports.daemonState().getDevicePool().resolveAutolockSessionForMcpSession?.(c,D)}}async resolveInputTargetDevice(d,c,R,{action:D,bypassAndroidDeviceListCache:k=!1,requester:P}){let C=await this.ports.selectInputTargetDevice(d,c,R,{action:D,bypassAndroidDeviceListCache:k});return await this.ports.assertFrameTargetProven(C,D,P),this.ports.assertBrokerConnectionInputTarget(R,D,C.deviceId),this.ports.captureInputTargetOwner(C),C}assertBrokerConnectionInputTarget(d,c,R){this.ports.assertBrokerConnectionControl(d,c,{deviceId:R})}assertBrokerConnectionControl(d,c,R){if(!this.ports.daemonState().isInitialized())return;let D=this.ports.daemonState().getSessionManager(),k=jv({binding:this.ports.daemonState().getBrokerConnectionScopes?.().get(d),action:c,deviceId:R.deviceId,requesterSessionUuid:R.requesterSessionUuid,grantedDeviceOf:(P)=>D.getSession(P)?.assignedDevice});if(k)throw k}assertBrokerConnectionHostMutation(d,c){if(!this.ports.daemonState().isInitialized())return;let R=Yw({binding:this.ports.daemonState().getBrokerConnectionScopes?.().get(d),action:c});if(R)throw R}captureInputTargetOwner(d){if(!this.ports.daemonState().isInitialized())return;let c=this.ports.daemonState().getSessionManager().getSessionForDevice?.(d.deviceId);if(c)this.ports.inputTargetOwners().set(d,c)}async selectInputTargetDevice(d,c,R,{action:D,bypassAndroidDeviceListCache:k=!1}){let{devices:P,deviceId:C}=await this.ports.discoverInputTargetDevices(d,D,k,c);if(C){let q=P.find((U)=>U.deviceId===C);if(!q)throw Error(`Device not found: ${c}`);return q}let M=this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool().resolveAutolockSessionForMcpSession?.(R,d):void 0,F=M?this.ports.daemonState().getSessionManager().getSession(M)?.assignedDevice:void 0;if(F){let q=P.find((U)=>U.deviceId===F);if(!q)throw Error(`Device not found: ${F}`);return q}if(P.length===1)return P[0];if(P.length===0)throw Error(`No booted ${d} devices found for ${D}`);throw Error(`${D} requires deviceId when multiple ${d} devices are booted`)}async runTrackedKeyedDeviceInput(d,c,R,D){let k=`device:${c.deviceId}`;return await this.ports.runTrackedDeviceInput(d,c,async(P,C)=>this.ports.runKeyedMcpForward(k,()=>(P?.throwIfAborted(),this.ports.runHeldInputOperation(d,P,R,()=>{D?.onDispatch?.(),C?.()})),k,D?.chainWait),{ownerSignal:D?.ownerSignal,requester:D?.requester})}inputDeviceGate(d,c,R,{budgetStartMs:D,input:k}){let P=()=>R-(this.ports.timer().now()-D);return{onDispatch:k?.onDispatch,ownerSignal:k?.signal,requester:k?.requester,chainWait:{remainingMs:P,timeoutError:(C)=>new Mr({toolName:d,timeoutMs:R,origin:c,detail:`spent ${R-P()}ms waiting in queue for ${C}`,code:up})}}}async runHeldInputOperation(d,c,R,D){if(!Ht.has(d)||d==="input/typeText")return R(c,D);let k=!1,P=()=>{if(!k)D(),k=!0};try{let C=await R(c,P);return c?.throwIfAborted(),C}catch(C){if(k&&c?.aborted)throw qf(d,C);if(c?.reason instanceof DOMException&&c.reason.name==="AbortError")o(c);throw c?.throwIfAborted(),C}}dispatchFencedInput(d,c,R,{send:D,onDispatch:k}){return this.ports.runHeldInputOperation(`input/${d.toLowerCase()}`,c,(P,C)=>this.ports.holdDispatchedInputRequest(c,R,D,{onDispatch:C,label:`${d} request`}),()=>k?.())}async reconcileDiscoveryObservation(d,c){if(!this.ports.daemonState().isInitialized())return;await this.ports.daemonState().getDevicePool().reconcileDiscoveryObservation?.(d,c)}assertDeviceActionable(d,c){if(!this.ports.daemonState().isInitialized())return;this.ports.daemonState().getDevicePool().assertDeviceActionable?.(d,c)}async assertInputBindingGate(d,c,R){if(!this.ports.daemonState().isInitialized())return;await gb({action:d,deviceId:c.deviceId,platform:c.platform,requesterSessionUuid:R?.(),sessionManager:this.ports.daemonState().getSessionManager(),gate:this.ports.daemonState().getDevicePool()}),await mf({deviceId:c.deviceId,platform:c.platform,gate:this.ports.daemonState().getDevicePool()})}async runTrackedDeviceInput(d,c,R,{ownerSignal:D,requester:k}){this.ports.assertDeviceActionable(c.deviceId,"to run");let P=this.ports.daemonState().isInitialized()?this.ports.daemonState().getSessionManager():void 0,C=P?.getSessionForDevice?.(c.deviceId)??void 0;if(await this.ports.assertInputBindingGate(d,c,k),Nu({action:d,deviceId:c.deviceId,ownerSessionUuid:C,requesterSessionUuid:C?k?.():void 0,sessionManager:P}),C)this.ports.daemonState().getDevicePool().assertSessionReadyForAutomation?.(C);let M=this.ports.inputTargetOwners().get(c);if(M!==void 0&&M!==C)throw new gd(M,c.deviceId,`Session ${M} no longer owns device '${c.deviceId}' (it was rebound or released after this input resolved its target); the input was not sent.`);let F=G.startExecution(d,void 0,C),q=F.abortController.signal;try{G.bindDeviceExecution(F.id,c.deviceId),q.throwIfAborted(),await this.ports.admitInputAsControlCall(F,c.deviceId,C,D);let U=()=>G.markSessionAdmitted(F.id);if(!C)G.markSessionlessDeviceUse(F.id,c.deviceId);let K=(W)=>Ht.has(d)?this.ports.runCancellableInputHandler((V)=>R(W,()=>{V(),U()}),W):R(W,U);return await this.ports.answeringSessionRelease(F,()=>ml({execution:{...pu(F),deviceBinding:{bindDeviceExecution:(W)=>G.bindDeviceExecution(F.id,W)}}},()=>this.ports.runFencedInputOperation(q,D,K)))}finally{G.endExecution(F.id)}}async admitInputAsControlCall(d,c,R,D){if(!R)return;let k=d.abortController.signal;await YB({deviceId:c,holderSessionUuid:R,sessionManager:this.ports.daemonState().getSessionManager(),execution:pu(d),signal:D?AbortSignal.any([k,D]):k}),await this.ports.answeringSessionRelease(d,async()=>d.abortController.signal.throwIfAborted())}async answeringSessionRelease(d,c){try{return await c()}catch(R){let D=bm(d.cancelReason);if(D&&R instanceof Error&&"requestDispatched"in R&&R.requestDispatched===!0){let k=new lc(D.sessionUuid,D.releaseReason,D.details.idleTimeoutMs),P=d.toolName==="input/typeText"||R instanceof ke?"the text request":"the request";if(k.message=`${D.message} Cancellation arrived after ${P} had been dispatched; its outcome is indeterminate.`,R instanceof ke)k.charsSent=R.charsSent;throw k}throw D??R}}runFencedInputOperation(d,c,R){let D=c?AbortSignal.any([d,c]):d;return D.throwIfAborted(),H(D,()=>R(D))}async discoverInputTargetDevices(d,c,R,D){let k=await xt.getInstance().getBootedDevicesDetailed(d,{bypassAndroidDeviceListCache:R}),P=await this.ports.canonicalFrameDiscovery(d,k.devices,D);if(await this.ports.reconcileDiscoveryObservation(P.devices,`socket:${c}`),!k.succeededPlatforms.has(d))throw Error(`Unable to discover booted ${d} devices for ${c}`);return P}}class Ja{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async runLocalSocketRequest(d,c,R,{cancelSignal:D,receivedAtMs:k,onOwnerSignal:P,onInputDispatch:C}){if(!Gm(d.method,_a))return await this.callbacks.handleLocalSocketRequest(d,{socketSessionId:c});let M=this.callbacks.mcpRequestSignal(c,R,D);P(M.signal);try{return await this.callbacks.handleLocalSocketRequest(d,{socketSessionId:c,signal:M.signal,receivedAtMs:k,onInputDispatch:C})}finally{M.dispose()}}async handleLocalSocketRequest(d,{socketSessionId:c,signal:R,receivedAtMs:D,onInputDispatch:k}={}){if(d.method.startsWith("input/"))R?.throwIfAborted();let P={onDispatch:k,signal:R,receivedAtMs:D,requester:d.method.startsWith("input/")?this.callbacks.inputRequester(d,c):void 0},C=Cf(d.method);if(C)return await this.callbacks.dispatchInputRoute(C,d,c,P);return await this.callbacks.dispatchIdeSocketRequest(d,c,R)}async dispatchInputRoute(d,c,R,D){return await Wm(this.inputRouteHandlers,d,c,{socketSessionId:R,input:D})}inputRouteHandlers={tap:(d,c,R)=>this.callbacks.handleInputTap(d,c,R),swipe:(d,c,R)=>this.callbacks.handleInputSwipe(d,c,R),typeText:(d,c,R)=>this.callbacks.handleInputTypeText(d,c,R),pressButton:(d,c,R)=>this.callbacks.handleInputPressButton(d,c,R),key:(d,c,R)=>this.callbacks.handleInputKey(d,c,R),gesture:(d,c,R,D)=>this.callbacks.handleInputGesture(d,c,R,D)};async dispatchIdeSocketRequest(d,c,R){if(!_a.has(d.method))return await this.callbacks.handleIdeSocketRequest(d,c);return R?.throwIfAborted(),await this.callbacks.runTrackedIdeMutation(c,(D)=>this.callbacks.handleIdeSocketRequest(d,c,D),R)}ideDeviceRoutes=new Ga({daemonIdentity:()=>this.state.daemonIdentity,identityStartedAt:()=>this.state.identityStartedAt,identityProcessStartedAt:()=>this.state.identityProcessStartedAt,identityDbPath:()=>this.state.identityDbPath,identityPidFilePath:()=>this.state.identityPidFilePath,socketPath:()=>this.state.socketPath,identitySockets:()=>this.state.identitySockets,startupOptions:()=>this.state.startupOptions,processGenerationToken:()=>this.state.processGenerationToken,acceptanceDiscoveryCapability:()=>this.state.acceptanceDiscoveryCapability,daemonState:()=>this.state.daemonState,adbClientFactory:()=>this.state.adbClientFactory,assertSocketToolEnabled:(d,c)=>this.callbacks.assertSocketToolEnabled(d,c),reconcileDiscoveryObservation:(d,c)=>this.callbacks.reconcileDiscoveryObservation(d,c),assertDeviceActionable:(d,c)=>this.callbacks.assertDeviceActionable(d,c),assertBrokerConnectionControl:(d,c,R)=>this.callbacks.assertBrokerConnectionControl(d,c,R),admitInputAsControlCall:(...d)=>this.callbacks.admitInputAsControlCall(...d),listBootedDevicesForIdeAction:(d,c,R)=>this.callbacks.listBootedDevicesForIdeAction(d,c,R),resolveIdeActionDevices:(d,c,R)=>this.callbacks.resolveIdeActionDevices(d,c,R),runIdeKeyValueMutation:(d,c,R,D)=>this.callbacks.runIdeKeyValueMutation(d,c,R,D)});ideRouteHandlers=new Map([...$f({requireFeatureFlagService:()=>this.callbacks.requireFeatureFlagService(),sessionToolSelection:()=>this.state.sessionToolSelectionService??hc(),assertBrokerHostMutation:(d,c)=>this.callbacks.assertBrokerConnectionHostMutation(d,c),assertBrokerControl:(d,c,R)=>this.callbacks.assertBrokerConnectionControl(d,c,R),emitToolsListChanged:()=>_r.emit("tools"),now:()=>this.state.timer.now()}),...Hf({republishIdentity:(d)=>this.callbacks.republishDaemonIdentity(d),restart:{prepareDaemonRestart:(d)=>this.state.restartAdmission.prepareDaemonRestart(d),prepareDaemonMaintenance:(d)=>this.state.restartAdmission.prepareDaemonMaintenance(d),completeDaemonMaintenance:(d)=>this.state.restartAdmission.completeDaemonMaintenance(d),restartAdmittedDaemon:(d)=>this.state.restartAdmission.restartAdmittedDaemon(d),restartAcceptanceSession:(d,c)=>this.state.restartAdmission.restartAcceptanceSession(d,c),commitAcceptanceRestart:(d,c)=>this.state.restartAdmission.commitAcceptanceRestart(d,c),releaseAcceptanceRestart:(d,c)=>this.state.restartAdmission.releaseAcceptanceRestart(d,c)}}),...this.ideDeviceRoutes.routes]);async handleIdeSocketRequest(d,c,R){let D=this.ideRouteHandlers.get(d.method);return D?await D(d,c,R):void 0}async runTrackedIdeMutation(d,c,R){return await this.ideDeviceRoutes.runTrackedIdeMutation(d,c,R)}async listBootedDevicesForIdeAction(d,c,R){return await this.ideDeviceRoutes.listBootedDevicesForIdeAction(d,c,R)}async resolveIdeActionDevices(d,c,R){return await this.ideDeviceRoutes.resolveIdeActionDevices(d,c,R)}async canonicalFrameDiscovery(d,c,R){return await this.ideDeviceRoutes.canonicalFrameDiscovery(d,c,R)}async assertFrameTargetProven(d,c,R){return await this.ideDeviceRoutes.assertFrameTargetProven(d,c,R)}canonicalFrameDeviceId(d){return this.ideDeviceRoutes.canonicalFrameDeviceId(d)}async runIdeKeyValueMutation(d,c,R,D){return await this.ideDeviceRoutes.runIdeKeyValueMutation(d,c,R,D)}async assertSocketToolEnabled(d,c){let D=ch().getRegisteredTool(c)?.defaultEnabled??!1;if(!this.state.daemonState.isInitialized()){await KG(c,D,[void 0],{sessionToolSelectionService:this.state.sessionToolSelectionService,remediationMethodName:K4});return}let k=this.state.daemonState.getSessionManager(),P=k.getSessionForDevice?.(this.callbacks.canonicalFrameDeviceId(d))??void 0,C=at(P,k);await KG(c,D,[C,P],{sessionToolSelectionService:this.state.sessionToolSelectionService,remediationMethodName:K4})}inputDeviceGatingInstance;get inputDeviceGating(){return this.inputDeviceGatingInstance??=new Wa({daemonState:()=>this.state.daemonState,selectInputTargetDevice:(...d)=>this.callbacks.selectInputTargetDevice(...d),assertFrameTargetProven:(...d)=>this.callbacks.assertFrameTargetProven(...d),assertBrokerConnectionInputTarget:(...d)=>this.callbacks.assertBrokerConnectionInputTarget(...d),captureInputTargetOwner:(...d)=>this.callbacks.captureInputTargetOwner(...d),assertBrokerConnectionControl:(...d)=>this.callbacks.assertBrokerConnectionControl(...d),inputTargetOwners:()=>this.state.inputTargetOwners,discoverInputTargetDevices:(...d)=>this.callbacks.discoverInputTargetDevices(...d),runTrackedDeviceInput:(...d)=>this.callbacks.runTrackedDeviceInput(...d),runKeyedMcpForward:(...d)=>this.callbacks.runKeyedMcpForward(...d),runHeldInputOperation:(...d)=>this.callbacks.runHeldInputOperation(...d),timer:()=>this.state.timer,holdDispatchedInputRequest:(...d)=>this.callbacks.holdDispatchedInputRequest(...d),assertDeviceActionable:(...d)=>this.callbacks.assertDeviceActionable(...d),assertInputBindingGate:(...d)=>this.callbacks.assertInputBindingGate(...d),admitInputAsControlCall:(...d)=>this.callbacks.admitInputAsControlCall(...d),runCancellableInputHandler:(...d)=>this.callbacks.runCancellableInputHandler(...d),answeringSessionRelease:(...d)=>this.callbacks.answeringSessionRelease(...d),runFencedInputOperation:(...d)=>this.callbacks.runFencedInputOperation(...d),canonicalFrameDiscovery:(...d)=>this.callbacks.canonicalFrameDiscovery(...d),reconcileDiscoveryObservation:(...d)=>this.callbacks.reconcileDiscoveryObservation(...d)})}requireCurrentFrameContext(d,c,R){return this.inputDeviceGating.requireCurrentFrameContext(d,c,R)}inputRequester(d,c){return this.inputDeviceGating.inputRequester(d,c)}async resolveInputTargetDevice(d,c,R,D){return await this.inputDeviceGating.resolveInputTargetDevice(d,c,R,D)}assertBrokerConnectionInputTarget(d,c,R){return this.inputDeviceGating.assertBrokerConnectionInputTarget(d,c,R)}assertBrokerConnectionControl(d,c,R){return this.inputDeviceGating.assertBrokerConnectionControl(d,c,R)}assertBrokerConnectionHostMutation(d,c){return this.inputDeviceGating.assertBrokerConnectionHostMutation(d,c)}captureInputTargetOwner(d){return this.inputDeviceGating.captureInputTargetOwner(d)}async selectInputTargetDevice(d,c,R,{action:D,bypassAndroidDeviceListCache:k=!1}){return await this.inputDeviceGating.selectInputTargetDevice(d,c,R,{action:D,bypassAndroidDeviceListCache:k})}async runTrackedKeyedDeviceInput(d,c,R,D){return await this.inputDeviceGating.runTrackedKeyedDeviceInput(d,c,R,D)}inputDeviceGate(d,c,R,{budgetStartMs:D,input:k}){return this.inputDeviceGating.inputDeviceGate(d,c,R,{budgetStartMs:D,input:k})}async runHeldInputOperation(d,c,R,D){return await this.inputDeviceGating.runHeldInputOperation(d,c,R,D)}dispatchFencedInput(d,c,R,{send:D,onDispatch:k}){return this.inputDeviceGating.dispatchFencedInput(d,c,R,{send:D,onDispatch:k})}async reconcileDiscoveryObservation(d,c){return await this.inputDeviceGating.reconcileDiscoveryObservation(d,c)}assertDeviceActionable(d,c){return this.inputDeviceGating.assertDeviceActionable(d,c)}async assertInputBindingGate(d,c,R){return await this.inputDeviceGating.assertInputBindingGate(d,c,R)}async runTrackedDeviceInput(d,c,R,D={}){return await this.inputDeviceGating.runTrackedDeviceInput(d,c,R,D)}async admitInputAsControlCall(d,c,R,D){return await this.inputDeviceGating.admitInputAsControlCall(d,c,R,D)}async answeringSessionRelease(d,c){return await this.inputDeviceGating.answeringSessionRelease(d,c)}runFencedInputOperation(d,c,R){return this.inputDeviceGating.runFencedInputOperation(d,c,R)}async discoverInputTargetDevices(d,c,R,D){return await this.inputDeviceGating.discoverInputTargetDevices(d,c,R,D)}mcpRequestOptions(d,c){return c?{timeout:d,signal:c}:{timeout:d}}combineMcpRequestSignals(d,c){return d?AbortSignal.any([d,c]):c}}function ja(d,c){if(c.signal?.aborted)return c.signal.reason;let{deviceId:R,holderSessionId:D}=c,k=(P)=>`${d} on device '${R}' was lifted: ${P} before the stroke's start was acknowledged.`;return D?new gd(D,R,k(`session ${D} no longer holds the device`)):new mt(d,R,void 0,{message:k("a session acquired the device")})}var Uf=5000;class Ya{ports;constructor(d){this.ports=d}async handleInputGesture(d,c,R,D){let k=jn[c],P=this.ports.parseInputGestureParams(d.params,k),C,{targetDevice:M,result:F}=await this.ports.runInputRoute(d,R,D,{action:k,origin:"UnixSocketServer.handleInputGesture",args:P,checksFrame:!1,around:(q,U)=>this.ports.liftingStrokeOnSessionRefusal(c,R,q,{gestureId:P.gestureId,run:U}),dispatch:async({targetDevice:q,signal:U,dispatching:K,remainingTimeoutMs:W})=>{K?.();let V=E.getInstance(q,v);if(c!=="start")return this.ports.forwardGestureFrame(V,c,P,W);return C=this.ports.captureStrokeAdmission(q.deviceId,U),this.ports.forwardGestureStart(V,P,W,C)}});if(!F.success)throw Error(F.error??`${k} failed on ${P.platform}`);if(R)await this.ports.trackAckedGestureFrame(c,R,M,{gestureId:P.gestureId,startAdmission:C});return{action:k,platform:P.platform,deviceId:M.deviceId,success:!0,gestureId:P.gestureId,point:{x:P.x,y:P.y},...c==="end"?{cancel:P.cancel}:{}}}async trackAckedGestureFrame(d,c,R,{gestureId:D,startAdmission:k}){if(d==="end"){this.ports.ownedGestures().onEndAcked(c,R.deviceId,D);return}if(d!=="start")return;let P=!k||this.ports.strokeAdmissionStillHolds(k);if(await this.ports.ownedGestures().onStartAcked(c,R,D,{holderSessionId:k?.holderSessionId,admissionStillHolds:P}),k&&!P)throw ja(jn.start,k)}async liftingStrokeOnSessionRefusal(d,c,R,{gestureId:D,run:k}){try{return await k()}catch(P){if(d!=="start"&&Pm(P)){try{await this.ports.cancelGestureOnDevice(R,D)}catch(C){e.warn(`Failed to lift gesture ${D} on ${R.deviceId} after its session refused a frame: ${r(C)}`)}if(c)this.ports.ownedGestures().onEndAcked(c,R.deviceId,D)}else if(d!=="start"&&c)await this.ports.ownedGestures().cancelIfDeviceChangedHands(c,R.deviceId,D,this.ports.getSessionForDevice(R.deviceId));throw P}}captureStrokeAdmission(d,c){let R=Fe()?.execution?.executionId,D=R?G.getAdmittedSessionUse(R):void 0;return{deviceId:d,...D!==void 0?{holderSessionId:D}:{},holderIncarnation:this.ports.getSessionIncarnation(D),...c?{signal:c}:{}}}strokeAdmissionStillHolds(d){if(d.signal?.aborted)return!1;if(this.ports.getSessionForDevice(d.deviceId)!==d.holderSessionId)return!1;return this.ports.getSessionIncarnation(d.holderSessionId)===d.holderIncarnation}async forwardGestureStart(d,c,R,D){let k=await this.ports.forwardGestureFrame(d,"start",c,R);if(!k.success||this.ports.strokeAdmissionStillHolds(D))return k;try{await d.requestGestureEnd(c.gestureId,0,0,{cancel:!0,timeoutMs:Uf})}catch(P){e.warn(`Failed to lift gesture ${c.gestureId} on ${D.deviceId} whose holder left before its start was acked: ${r(P)}`)}throw ja(jn.start,D)}liftSessionlessStrokesOn(d){this.ports.trackRequestHandler(this.ports.ownedGestures().cancelAllUnheldOn(d))}liftStrokesHeldByOn(d,c){if(this.ports.getSessionForDevice(c)===d)return;this.ports.trackRequestHandler(this.ports.ownedGestures().cancelAllHeldByOn(d,c))}liftStrokesHeldBy(d){return this.ports.ownedGestures().cancelAllHeldBy(d)}cancelGestureOnDevice(d,c){return this.ports.runKeyedMcpForward(`device:${d.deviceId}`,async()=>E.getInstance(d,v).requestGestureEnd(c,0,0,{cancel:!0,timeoutMs:Uf}),`device:${d.deviceId}`)}forwardGestureFrame(d,c,R,D){let{gestureId:k,x:P,y:C,cancel:M}=R;switch(c){case"start":return d.requestGestureStart({gestureId:k,x:P,y:C,timeoutMs:D});case"move":return d.requestGestureMove(k,P,C,{timeoutMs:D});case"end":return d.requestGestureEnd(k,P,C,{cancel:M,timeoutMs:D})}}}class Xa{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}remainingBudgetAfterProbe(d,c,R,D){let k=c-(this.state.timer.now()-d);if(k<=0)throw new Mr({toolName:R,timeoutMs:c,origin:`UnixSocketServer.${D}`,detail:"iOS screen-scale probe consumed the request budget"});return k}async toIosRunnerCoordinates(d,c,R,{probeTimeoutMs:D,validateCanonicalCoordinates:k}){let P=d.getScreenScaleMetadata();if(P)return this.state.confirmedLegacyScaleDevices.delete(c),k?.(P),R.map((F)=>OY(F,P.nativeScale));if(this.state.confirmedLegacyScaleDevices.has(c))return R;let C;try{C=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,D)}catch(F){throw u(F,`Could not determine iOS screen scale for ${c}; the input coordinate scale probe failed`)}if(!C)throw new t(`Could not determine iOS screen scale for ${c}: the hierarchy probe returned no data. Retry once the device has produced a hierarchy.`);let M=d.getScreenScaleMetadata();if(!M)return this.state.confirmedLegacyScaleDevices.add(c),R;return k?.(M),R.map((F)=>OY(F,M.nativeScale))}requireCoordinatesWithinKnownScreenGeometry(d,c){if(!c)return;let[R,D]=d;if(R<0||R>=c.pixelWidth||D<0||D>=c.pixelHeight)throw Error(`input/tap coordinates x=${R}, y=${D} are outside device canonical pixel bounds x: 0..${c.pixelWidth-1}, y: 0..${c.pixelHeight-1}`)}inputRouteClock(d,c){return{queueEnterMs:c?.receivedAtMs??this.state.timer.now(),totalTimeoutMs:Z0(d)}}remainingInputBudgetMs(d,c,R,D){let k=this.state.timer.now()-R,P=D-k;if(P<=0)throw new Mr({toolName:d,timeoutMs:D,origin:c,detail:`spent ${k}ms waiting in queue`});return P}async runInputRoute(d,c,R,D){let{queueEnterMs:k,totalTimeoutMs:P}=this.callbacks.inputRouteClock(d,R),{args:C}=D,M=await this.callbacks.resolveInputTargetDevice(C.platform,C.deviceId,c,{action:D.action,bypassAndroidDeviceListCache:D.bypassAndroidDeviceListCache??!1,requester:R?.requester}),F=()=>this.callbacks.runTrackedKeyedDeviceInput(d.method,M,async(U,K)=>{qe(U);let W=D.reresolve?await D.reresolve(M):M;if(D.checksFrame)this.callbacks.requireCurrentFrameContext(M.deviceId,C.frameContext,D.action);let V=this.callbacks.remainingInputBudgetMs(d.method,D.origin,k,P);return await D.dispatch({targetDevice:M,executionDevice:W,signal:U,dispatching:K,remainingTimeoutMs:V,queueEnterMs:k,totalTimeoutMs:P})},this.callbacks.inputDeviceGate(d.method,D.origin,P,{budgetStartMs:k,input:R})),q=await(D.around?D.around(M,F):F());return{targetDevice:M,result:q}}async handleInputTap(d,c,R){let D=this.callbacks.parseInputTapParams(d.params),{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,R,{action:"input/tap",origin:"UnixSocketServer.handleInputTap",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>{if(D.platform==="android"){let X=E.getInstance(C,v);return this.callbacks.requireCoordinatesWithinKnownScreenGeometry([D.x,D.y],X.getScreenScaleMetadata?.()??null),await this.callbacks.dispatchFencedInput("Tap",M,q,{send:(te,re)=>X.requestTapCoordinates({x:D.x,y:D.y,duration:D.duration,timeoutMs:q,frameContext:D.frameContext,onDispatch:re,signal:te}),onDispatch:F})}let W=x.getInstance(C),[V,z]=await this.callbacks.toIosRunnerCoordinates(W,C.deviceId,[D.x,D.y],{probeTimeoutMs:q,validateCanonicalCoordinates:(X)=>this.callbacks.requireCoordinatesWithinKnownScreenGeometry([D.x,D.y],X)}),J=this.callbacks.remainingBudgetAfterProbe(U,K,d.method,"handleInputTap");return qe(M),await this.callbacks.dispatchFencedInput("Tap",M,J,{send:(X,te)=>W.requestTapCoordinates({x:V,y:z,duration:D.duration,timeoutMs:J,frameContext:D.frameContext,signal:X,onDispatch:te}),onDispatch:F})}});if(!P.success)throw Error(P.error??`input/tap failed on ${D.platform}`);return{action:"input/tap",platform:D.platform,deviceId:k.deviceId,success:!0,coordinates:{x:D.x,y:D.y}}}async handleInputSwipe(d,c,R){let D=this.callbacks.parseInputSwipeParams(d.params),{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,R,{action:"input/swipe",origin:"UnixSocketServer.handleInputSwipe",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>{if(D.platform==="android"){let re=E.getInstance(C,v);return await this.callbacks.dispatchFencedInput("Swipe",M,q,{send:(ie,oe)=>re.requestSwipe({x1:D.startX,y1:D.startY,x2:D.endX,y2:D.endY,duration:D.durationMs,timeoutMs:q,contextOptions:D.frameContext,onDispatch:oe,signal:ie}),onDispatch:F})}let W=x.getInstance(C),[V,z,J,X]=await this.callbacks.toIosRunnerCoordinates(W,C.deviceId,[D.startX,D.startY,D.endX,D.endY],{probeTimeoutMs:q}),te=this.callbacks.remainingBudgetAfterProbe(U,K,d.method,"handleInputSwipe");return qe(M),await this.callbacks.dispatchFencedInput("Swipe",M,te,{send:(re,ie)=>W.requestDrag({x1:V,y1:z,x2:J,y2:X,pressDurationMs:0,dragDurationMs:D.durationMs,holdDurationMs:0,timeoutMs:te,frameContext:D.frameContext,signal:re,onDispatch:ie}),onDispatch:F})}});if(!P.success)throw Error(P.error??`input/swipe failed on ${D.platform}`);return{action:"input/swipe",platform:D.platform,deviceId:k.deviceId,success:!0,start:{x:D.startX,y:D.startY},end:{x:D.endX,y:D.endY},durationMs:D.durationMs}}async handleInputGesture(d,c,R,D){return await this.inputStrokes.handleInputGesture(d,c,R,D)}async trackAckedGestureFrame(d,c,R,{gestureId:D,startAdmission:k}){return await this.inputStrokes.trackAckedGestureFrame(d,c,R,{gestureId:D,startAdmission:k})}async liftingStrokeOnSessionRefusal(d,c,R,{gestureId:D,run:k}){return await this.inputStrokes.liftingStrokeOnSessionRefusal(d,c,R,{gestureId:D,run:k})}captureStrokeAdmission(d,c){return this.inputStrokes.captureStrokeAdmission(d,c)}strokeAdmissionStillHolds(d){return this.inputStrokes.strokeAdmissionStillHolds(d)}async forwardGestureStart(d,c,R,D){return await this.inputStrokes.forwardGestureStart(d,c,R,D)}liftSessionlessStrokesOn(d){return this.inputStrokes.liftSessionlessStrokesOn(d)}liftStrokesHeldByOn(d,c){return this.inputStrokes.liftStrokesHeldByOn(d,c)}liftStrokesHeldBy(d){return this.inputStrokes.liftStrokesHeldBy(d)}cancelGestureOnDevice(d,c){return this.inputStrokes.cancelGestureOnDevice(d,c)}forwardGestureFrame(d,c,R,D){return this.inputStrokes.forwardGestureFrame(d,c,R,D)}async handleInputPressButton(d,c,R){let D=this.callbacks.parseInputPressButtonParams(d.params),{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,R,{action:"input/pressButton",origin:"UnixSocketServer.handleInputPressButton",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>await new Fn(C,null,this.state.timer,{holdRequest:(V,z,J,X)=>this.callbacks.holdDispatchedInputRequest(V,U+K-this.state.timer.now(),J,{onDispatch:X,label:"Button press request"})}).press(D.button,{timeoutMs:q,frameContext:D.frameContext,signal:M,onDispatch:F})});if(!P.success)throw Error(P.error??`input/pressButton failed on ${D.platform}`);return{action:"input/pressButton",platform:D.platform,deviceId:k.deviceId,success:!0,button:D.responseButton}}async handleInputKey(d,c,R){let D=this.callbacks.parseInputKeyParams(d.params);if(D.platform==="ios")throw Error(fJ);let{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,R,{action:"input/key",origin:"UnixSocketServer.handleInputKey",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>await this.callbacks.executeSocketInputKey(new oc(C,{adbFactory:v,timer:this.state.timer}),{key:D.key,frameContext:D.frameContext,totalTimeoutMs:K,remainingTimeoutMs:q,signal:M,dispatching:F})});if(!P.success)throw Error(P.error??`input/key failed on ${D.platform}`);return{action:"input/key",platform:D.platform,deviceId:k.deviceId,success:!0,key:D.key}}executeSocketInputKey(d,c){let{key:R,frameContext:D,totalTimeoutMs:k,remainingTimeoutMs:P,signal:C,dispatching:M}=c,F=!1,q=(U,K)=>d.press(R,P,D,{modifiers:[],signal:U,onDispatch:K});return this.callbacks.runHeldInputOperation("input/key",C,(U,K)=>this.callbacks.runInputOperationWithTimeout({toolName:"input/key",origin:"UnixSocketServer.handleInputKey",totalTimeoutMs:k,remainingTimeoutMs:P},()=>this.callbacks.holdDispatchedInputRequest(C,P,q,{onDispatch:()=>{F=!0,K?.()},label:"Key request"}),(W)=>F?oc.indeterminateError(W):void 0),()=>M?.())}inputStrokesInstance;get inputStrokes(){return this.inputStrokesInstance??=new Ya({parseInputGestureParams:(...d)=>this.callbacks.parseInputGestureParams(...d),runInputRoute:(...d)=>this.callbacks.runInputRoute(...d),liftingStrokeOnSessionRefusal:(...d)=>this.callbacks.liftingStrokeOnSessionRefusal(...d),forwardGestureFrame:(...d)=>this.callbacks.forwardGestureFrame(...d),captureStrokeAdmission:(...d)=>this.callbacks.captureStrokeAdmission(...d),forwardGestureStart:(...d)=>this.callbacks.forwardGestureStart(...d),trackAckedGestureFrame:(...d)=>this.callbacks.trackAckedGestureFrame(...d),ownedGestures:()=>this.state.ownedGestures,strokeAdmissionStillHolds:(...d)=>this.callbacks.strokeAdmissionStillHolds(...d),cancelGestureOnDevice:(...d)=>this.callbacks.cancelGestureOnDevice(...d),getSessionForDevice:(...d)=>this.callbacks.getSessionForDevice(...d),getSessionIncarnation:(...d)=>this.callbacks.getSessionIncarnation(...d),trackRequestHandler:(...d)=>this.callbacks.trackRequestHandler(...d),runKeyedMcpForward:(...d)=>this.callbacks.runKeyedMcpForward(...d)})}}async function Gf({timer:d,signal:c,timeoutMs:R,label:D,send:k,onDispatch:P}){c?.throwIfAborted();let C=d.now()+R,M=new AbortController,F=!1,q,U=()=>{if(!F){M.abort(c?.reason);return}q=d.setTimeout(()=>{let W=new t(`${D} deadline expired after dispatch`);M.abort(W)},Math.max(0,C-d.now()))};c?.addEventListener("abort",U,{once:!0});let K=c?M.signal:void 0;try{let W=H(K,()=>k(K,()=>{K?.throwIfAborted(),F=!0,P?.()}));return await l(W,{timer:d,signal:K,label:D})}finally{if(q!==void 0)d.clearTimeout(q);c?.removeEventListener("abort",U)}}class Za{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async handleInputTypeText(d,c,R){let D=this.callbacks.parseInputTypeTextParams(d.params),k,P=(F)=>{k=F},{targetDevice:C,result:M}=await this.callbacks.runInputRoute(d,c,R,{action:"input/typeText",origin:"UnixSocketServer.handleInputTypeText",args:D,bypassAndroidDeviceListCache:D.append,reresolve:async(F)=>D.append&&D.platform==="android"?await this.callbacks.resolveInputTargetDevice(D.platform,F.deviceId,c,{action:"input/typeText",bypassAndroidDeviceListCache:!0,requester:R?.requester}):F,checksFrame:!0,dispatch:async({executionDevice:F,signal:q,dispatching:U,remainingTimeoutMs:K,totalTimeoutMs:W})=>{let V=D.submit?"done":void 0,z=!1,J=()=>{R?.onDispatch?.(),z=!0,U?.()};try{return await this.callbacks.runInputOperationWithTimeout({toolName:d.method,origin:"UnixSocketServer.handleInputTypeText",totalTimeoutMs:W,remainingTimeoutMs:K},()=>this.callbacks.executeInputTypeText(D.platform,F,D.text,{imeAction:V,timeoutMs:K,append:D.append,frameContext:D.frameContext,onConfirmedAppendCharsSent:P,signal:q,dispatching:J}),(X)=>D.append&&k!==void 0?new ke(X.message,k):void 0)}catch(X){if(z&&q?.aborted)throw this.callbacks.indeterminateTextError(X,q.reason,k);throw X}}});if(!M.success){if(D.append&&M.charsSent!==void 0)throw new ke(M.error??`input/typeText failed on ${D.platform}`,M.charsSent);throw Error(M.error??`input/typeText failed on ${D.platform}`)}return{action:"input/typeText",platform:D.platform,deviceId:C.deviceId,success:!0,textLength:D.text.length,submitted:D.submit}}indeterminateTextError(d,c,R){let D=`Text input outcome is indeterminate: the request was dispatched but no result was confirmed when cancellation arrived (${r(c)}). Do not retry automatically. Observe before retrying.`,k=R??(d instanceof ke?d.charsSent:void 0),P=k===void 0?new t(D,{cause:d}):new ke(D,k);return Object.assign(P,{requestDispatched:!0})}holdDispatchedInputRequest(d,c,R,{onDispatch:D,label:k="Text input request"}={}){return Gf({timer:this.state.timer,signal:d,timeoutMs:c,label:k,send:R,onDispatch:D})}createSocketInputAdbFactory(d){return{create:(c,R)=>{let D=v.create(c,R);return new Proxy(D,{get:(k,P,C)=>{if(P==="execute")return(F,q={})=>{if(F[0]!=="shell"||F[1]!=="input")return D.execute(F,q);return this.callbacks.holdDispatchedInputRequest(q.signal,Math.min(q.timeoutMs??1/0,d.deadline()-this.state.timer.now()),(U,K)=>D.execute(F,{...q,signal:U,beforeDispatch:async(W)=>{await q.beforeDispatch?.(W),U?.throwIfAborted(),K()}}),{onDispatch:d.onDispatch,label:d.label})};let M=Reflect.get(k,P,C);return typeof M==="function"?M.bind(k):M}})}}}createSocketAppendTextInput(d){let c=0,R,D=this.callbacks.createSocketInputAdbFactory({deadline:()=>c,onDispatch:()=>R?.(),label:"Text input request"}),k=new _V(d,D,{timer:this.state.timer});return{appendText:(P,C={})=>(c=this.state.timer.now()+(C.timeoutMs??0),R=C.onDispatch,k.appendText(P,{timeoutMs:C.timeoutMs,beforeKeyEvents:C.beforeKeyEvents,signal:C.signal}))}}async executeInputTypeText(d,c,R,D){let{imeAction:k,timeoutMs:P,append:C=!1,frameContext:M,onConfirmedAppendCharsSent:F,signal:q,dispatching:U}=D,K=!1,W=()=>{if(!K)K=!0,U?.()},V=this.state.timer.now()+P,z=d==="android"?{platform:d,client:E.getInstance(c,v)}:{platform:d,client:x.getInstance(c)},{client:J}=z,X;if(C&&z.platform==="android"){let te=await this.callbacks.executeAndroidAppendText({targetDevice:c,text:R,deadline:V,totalTimeoutMs:P,frameContext:M,client:z.client,signal:q,onDispatch:W});if(te.charsSent!==void 0)F?.(te.charsSent);if(qe(q),!te.success)return{success:!1,error:te.error,...te.charsSent!==void 0?{charsSent:te.charsSent}:{}};X=te.charsSent}else{let te=C&&z.platform==="ios"?z.client:null,re=await this.callbacks.holdDispatchedInputRequest(q,V-this.state.timer.now(),(ie,oe)=>te?te.requestAppendText(R,P,void 0,{frameContext:M,abortSignal:ie,onDispatch:oe}):J.requestSetText(R,{timeoutMs:P,frameContext:M,abortSignal:ie,onDispatch:oe}),{onDispatch:W});if(qe(q),!re.success)return{success:!1,error:re.error}}return await this.callbacks.runImeActionWithinBudget(J,k,V,{totalTimeoutMs:P,appendCharsSent:X,signal:q,onDispatch:W})}async executeAndroidAppendText(d){let{targetDevice:c,text:R,deadline:D,totalTimeoutMs:k,frameContext:P,client:C,signal:M,onDispatch:F}=d,q=D-this.state.timer.now();if(q<=0)return{success:!1,error:`input/typeText exceeded ${k}ms budget before append key events`};let U=P===void 0?void 0:()=>this.callbacks.validateAppendFrameContext(C,P,D,k),K=this.callbacks.getAppendTextInput(c),W=async(z,J,X,te)=>await z.appendText(J,{timeoutMs:X,beforeKeyEvents:te,signal:M,onDispatch:F}),V=await W(K.input,R,q,U);if(V.success||!K.fromCache||M?.aborted||V.failureSource==="runner")return V;return await this.callbacks.retryAppendTextWithRebuiltHelper(c,R,V,{deadline:D,beforeKeyEvent:U,run:W})}async retryAppendTextWithRebuiltHelper(d,c,R,D){let{deadline:k,beforeKeyEvent:P,run:C}=D,M=R.charsSent;if(M===void 0)return R;let F=c.slice(M);if(F.length===0)return R;this.callbacks.evictDeviceInputCache(d.deviceId);let q=k-this.state.timer.now();if(q<=0)return R;let U=await C(this.callbacks.getAppendTextInput(d).input,F,q,M===0?P:void 0);return U.charsSent===void 0?{success:U.success,...U.error!==void 0?{error:U.error}:{}}:{...U,charsSent:M+U.charsSent}}async validateAppendFrameContext(d,c,R,D){let k=R-this.state.timer.now();if(k<=0)return{success:!1,error:`input/typeText exceeded ${D}ms budget before append frame context validation`};let P=await d.validateFrameContext(c,k);return P.success?{success:!0}:{success:!1,error:P.error??"Frame context is stale or unavailable; observe a fresh frame before retrying",failureSource:"runner"}}async runImeActionWithinBudget(d,c,R,D){let{totalTimeoutMs:k,appendCharsSent:P,signal:C,onDispatch:M}=D,F=(U)=>P!==void 0?{...U,charsSent:P}:U;if(!c)return F({success:!0});qe(C);let q=R-this.state.timer.now();if(q<=0)return F({success:!1,error:`input/typeText exceeded ${k}ms budget before submit`});try{let U=await this.callbacks.holdDispatchedInputRequest(C,q,(K,W)=>d.requestImeAction(c,q,void 0,{abortSignal:K,onDispatch:W}),{onDispatch:M});if(qe(C),!U.success){let K=Vv(c,U.error||"unknown error");return e.warn(`[input/typeText] ${K}`),F({...U,error:K})}return F(U)}catch(U){let K=Vv(c,r(U)||"unknown error");if(e.warn(`[input/typeText] ${K}`,U),C?.aborted)throw U;if(P===void 0){if(U instanceof Error)throw U.message=K,U;throw new t(K,{cause:U})}return{success:!1,error:K,charsSent:P}}}async runInputOperationWithTimeout(d,c,R){let{toolName:D,origin:k,totalTimeoutMs:P,remainingTimeoutMs:C}=d,M=!1,F=c();try{return await l(F,{timer:this.state.timer,timeoutMs:C,label:"Input operation",timeoutError:()=>{M=!0;let q=new Mr({toolName:D,timeoutMs:P,origin:k,detail:`operation exceeded remaining budget ${C}ms`});return R?.(q)??q}})}finally{if(M)await F.catch(()=>{return})}}parseInputTapParams(d){return qn(d)}parseInputSwipeParams(d){return Kn(d)}parseInputTypeTextParams(d){return Gn(d)}parseInputPressButtonParams(d){return Vn(d)}parseInputKeyParams(d){return Jn(d)}parseInputGestureParams(d,c){return Lt(d,c)}evictDeviceInputCache(d){if(this.state.appendTextInputs.delete(d))e.debug(`[UnixSocketServer] Evicted cached append helper for device ${d}`)}getAppendTextInput(d){let c=Ni(d.deviceId),R=this.state.appendTextInputs.get(d.deviceId);if(R&&R.incarnationToken===c)return{input:R.input,fromCache:!0};if(R)e.debug(`[UnixSocketServer] Rebuilding cached append helper for ${d.deviceId}: pool incarnation changed from ${R.incarnationToken} to ${c}`);let D=this.state.appendTextFactory(d);return this.state.appendTextInputs.set(d.deviceId,{input:D,incarnationToken:c}),{input:D,fromCache:!1}}}function hk(d){return{start:d.start.bind(d),startDetached:d.startDetached.bind(d),stopAcceptingAndFanOut:d.stopAcceptingAndFanOut.bind(d),beginAccepting:d.beginAccepting.bind(d),connectionHandlerWithFanOut:d.connectionHandlerWithFanOut.bind(d),reclaimExistingSocketBeforeBind:d.reclaimExistingSocketBeforeBind.bind(d),isListening:d.isListening.bind(d),getClientConnectionCount:d.getClientConnectionCount.bind(d),getAcceptedClientConnectionCount:d.getAcceptedClientConnectionCount.bind(d),quiesce:d.quiesce.bind(d),drainSessionReleaseNotifications:d.drainSessionReleaseNotifications.bind(d),close:d.close.bind(d),writeShutdownSocketResponse:d.writeShutdownSocketResponse.bind(d),closeListeningServer:d.closeListeningServer.bind(d),destroyClientSockets:d.destroyClientSockets.bind(d),drainActiveRequestHandlers:d.drainActiveRequestHandlers.bind(d)}}function gk(d){return{handleConnection:d.handleConnection.bind(d),connectionFor:d.connectionFor.bind(d),rejectOversizedFrame:d.rejectOversizedFrame.bind(d),hasLiveSocketRequest:d.hasLiveSocketRequest.bind(d),processSocketRequestLine:d.processSocketRequestLine.bind(d),writeTerminalSocketResponse:d.writeTerminalSocketResponse.bind(d),withCanonicalToolCallDeviceIds:d.withCanonicalToolCallDeviceIds.bind(d),frameDeviceId:d.frameDeviceId.bind(d),traceFrame:d.traceFrame.bind(d),releaseSocketSession:d.releaseSocketSession.bind(d),forgetLateSessionToolBindings:d.forgetLateSessionToolBindings.bind(d),trackRequestHandler:d.trackRequestHandler.bind(d),abortMcpRequests:d.abortMcpRequests.bind(d),abortRequestControllers:d.abortRequestControllers.bind(d),mcpRequestSignal:d.mcpRequestSignal.bind(d),isMcpRequestOwnerCurrent:d.isMcpRequestOwnerCurrent.bind(d),broadcastListChanged:d.broadcastListChanged.bind(d),broadcastResourceUpdated:d.broadcastResourceUpdated.bind(d),handleResourceSubscription:d.handleResourceSubscription.bind(d),broadcastSessionDeviceRebound:d.broadcastSessionDeviceRebound.bind(d),broadcastSessionReleased:d.broadcastSessionReleased.bind(d),pushProgressNotification:d.pushProgressNotification.bind(d),writeFrame:d.writeFrame.bind(d),writeFrameData:d.writeFrameData.bind(d)}}function vk(d){return{handleRequest:d.handleRequest.bind(d),unqueuedRequest:d.unqueuedRequest.bind(d),relayTaskRequest:d.relayTaskRequest.bind(d),runProvisionBarrier:d.runProvisionBarrier.bind(d),shuttingDownBeforeStartResponse:d.shuttingDownBeforeStartResponse.bind(d),isProvisionDeviceCall:d.isProvisionDeviceCall.bind(d),provisionCancellationReply:d.provisionCancellationReply.bind(d),mcpForwardFailureResponse:d.mcpForwardFailureResponse.bind(d),waitForStartup:d.waitForStartup.bind(d),registerRequestCancellation:d.registerRequestCancellation.bind(d),cancelSocketRequest:d.cancelSocketRequest.bind(d),requireRemainingMcpForwardBudget:d.requireRemainingMcpForwardBudget.bind(d),socketAdmissionCancellation:d.socketAdmissionCancellation.bind(d),runCancellableInputHandler:d.runCancellableInputHandler.bind(d),runCancellableQueuedHandler:d.runCancellableQueuedHandler.bind(d)}}function yk(d){return{forgetSocketDiscovery:d.forgetSocketDiscovery.bind(d),rejectOnHandshakeMismatch:d.rejectOnHandshakeMismatch.bind(d),runKeyedMcpForward:d.runKeyedMcpForward.bind(d),runMcpForwardForCurrentRoute:d.runMcpForwardForCurrentRoute.bind(d),runMcpForwardAttempt:d.runMcpForwardAttempt.bind(d),forwardMcpRequest:d.forwardMcpRequest.bind(d),remainingMcpForwardBudget:d.remainingMcpForwardBudget.bind(d),wasRequestSessionActive:d.wasRequestSessionActive.bind(d),describeMcpForwardRequest:d.describeMcpForwardRequest.bind(d),daemonGenerationMatches:d.daemonGenerationMatches.bind(d),currentGenerationIdentity:d.currentGenerationIdentity.bind(d),republishDaemonIdentity:d.republishDaemonIdentity.bind(d),publishIdentity:d.publishIdentity.bind(d),requireFeatureFlagService:d.requireFeatureFlagService.bind(d),handleIdeRequest:d.handleIdeRequest.bind(d),textForwardFailure:d.textForwardFailure.bind(d),traceCallTool:d.traceCallTool.bind(d),withLiveDeadlineKey:d.withLiveDeadlineKey.bind(d),withSocketSessionAutolockKey:d.withSocketSessionAutolockKey.bind(d),recordOneShotCliConnection:d.recordOneShotCliConnection.bind(d),oneShotCliMarker:d.oneShotCliMarker.bind(d),createMcpClient:d.createMcpClient.bind(d),scheduleForwardKeyIdle:d.scheduleForwardKeyIdle.bind(d),clearForwardKeyIdleTimer:d.clearForwardKeyIdleTimer.bind(d),onForwardKeyIdle:d.onForwardKeyIdle.bind(d)}}function Sk(d){return{getMcpForwardRoute:d.getMcpForwardRoute.bind(d),withDeviceReadLane:d.withDeviceReadLane.bind(d),getDeviceLabelSession:d.getDeviceLabelSession.bind(d),isDeviceReadToolCall:d.isDeviceReadToolCall.bind(d),getDeviceHolderSession:d.getDeviceHolderSession.bind(d),getAdmittedMcpForwardRoute:d.getAdmittedMcpForwardRoute.bind(d),getDiscoveryForwardRoute:d.getDiscoveryForwardRoute.bind(d),getNavigationGraphForwardRoute:d.getNavigationGraphForwardRoute.bind(d),getResourceReadForwardRoute:d.getResourceReadForwardRoute.bind(d),beginMcpSessionOwnerCall:d.beginMcpSessionOwnerCall.bind(d),getToolsCallForwardRoute:d.getToolsCallForwardRoute.bind(d),getAdmittedToolsCallForwardRoute:d.getAdmittedToolsCallForwardRoute.bind(d),hostInventoryOrBoundRoute:d.hostInventoryOrBoundRoute.bind(d),isUnboundDeviceAcquisitionTool:d.isUnboundDeviceAcquisitionTool.bind(d),profileReaffirmForwardRoute:d.profileReaffirmForwardRoute.bind(d),getAcquiredDeviceSessionUuid:d.getAcquiredDeviceSessionUuid.bind(d),selectorMcpForwardRoute:d.selectorMcpForwardRoute.bind(d),hasImplicitDeviceSelector:d.hasImplicitDeviceSelector.bind(d),sharedMcpForwardRoute:d.sharedMcpForwardRoute.bind(d),acquisitionMcpForwardRoute:d.acquisitionMcpForwardRoute.bind(d),sessionMcpClientKey:d.sessionMcpClientKey.bind(d),toolSelectionProfileMcpClientKey:d.toolSelectionProfileMcpClientKey.bind(d),sessionScopedForwardRoute:d.sessionScopedForwardRoute.bind(d),toolSelectionProfileScopedForwardRoute:d.toolSelectionProfileScopedForwardRoute.bind(d)}}function bk(d){return{restoreSelectorSessions:d.restoreSelectorSessions.bind(d),holdsSession:d.holdsSession.bind(d),failIfCallTargetsRefusedRestore:d.failIfCallTargetsRefusedRestore.bind(d),ownedSessionsOwnerToken:d.ownedSessionsOwnerToken.bind(d),selectorSessionIds:d.selectorSessionIds.bind(d),releaseBindingsIfSocketDisconnected:d.releaseBindingsIfSocketDisconnected.bind(d),releaseDevicePoolMcpSessionBindings:d.releaseDevicePoolMcpSessionBindings.bind(d),clearConnectionDevicePin:d.clearConnectionDevicePin.bind(d),recordBoundMcpClientKey:d.recordBoundMcpClientKey.bind(d),isSessionOwnedByOtherConnection:d.isSessionOwnedByOtherConnection.bind(d),honoursBoundSessionMarker:d.honoursBoundSessionMarker.bind(d),isRetryableSessionRecoveryResult:d.isRetryableSessionRecoveryResult.bind(d),recordSessionBoundMcpClientKey:d.recordSessionBoundMcpClientKey.bind(d),targetsOneCallOnly:d.targetsOneCallOnly.bind(d),recordGeneratedToolSelectionProfile:d.recordGeneratedToolSelectionProfile.bind(d),getBoundMcpClientRoute:d.getBoundMcpClientRoute.bind(d),getToolSelectionProfileUuid:d.getToolSelectionProfileUuid.bind(d),getGeneratedToolSelectionProfileUuid:d.getGeneratedToolSelectionProfileUuid.bind(d),clearBoundMcpClientKey:d.clearBoundMcpClientKey.bind(d),clearBoundMcpClientsForReleasedSession:d.clearBoundMcpClientsForReleasedSession.bind(d),isMcpClientKeyBound:d.isMcpClientKeyBound.bind(d),getSessionForDevice:d.getSessionForDevice.bind(d),getSessionIncarnation:d.getSessionIncarnation.bind(d),hasActiveDaemonSession:d.hasActiveDaemonSession.bind(d),getSessionUuid:d.getSessionUuid.bind(d),isReleasedBoundSession:d.isReleasedBoundSession.bind(d),boundSessionAdmissionArgs:d.boundSessionAdmissionArgs.bind(d),withAdmittedBoundSession:d.withAdmittedBoundSession.bind(d),admitReleasedBoundSession:d.admitReleasedBoundSession.bind(d),expiredBoundSessionRelease:d.expiredBoundSessionRelease.bind(d),getRequestArgumentScopeKey:d.getRequestArgumentScopeKey.bind(d),getObjectRequestArgumentScopeKey:d.getObjectRequestArgumentScopeKey.bind(d),sessionToScopeKey:d.sessionToScopeKey.bind(d),getImplicitAutolockScopeKey:d.getImplicitAutolockScopeKey.bind(d),resolveImplicitAutolockSession:d.resolveImplicitAutolockSession.bind(d),getRequestPlatform:d.getRequestPlatform.bind(d),resolveDeviceLabelSession:d.resolveDeviceLabelSession.bind(d),getAssignedDeviceForSession:d.getAssignedDeviceForSession.bind(d)}}function wk(d){return{runLocalSocketRequest:d.runLocalSocketRequest.bind(d),handleLocalSocketRequest:d.handleLocalSocketRequest.bind(d),dispatchInputRoute:d.dispatchInputRoute.bind(d),dispatchIdeSocketRequest:d.dispatchIdeSocketRequest.bind(d),handleIdeSocketRequest:d.handleIdeSocketRequest.bind(d),runTrackedIdeMutation:d.runTrackedIdeMutation.bind(d),listBootedDevicesForIdeAction:d.listBootedDevicesForIdeAction.bind(d),resolveIdeActionDevices:d.resolveIdeActionDevices.bind(d),canonicalFrameDiscovery:d.canonicalFrameDiscovery.bind(d),assertFrameTargetProven:d.assertFrameTargetProven.bind(d),canonicalFrameDeviceId:d.canonicalFrameDeviceId.bind(d),runIdeKeyValueMutation:d.runIdeKeyValueMutation.bind(d),assertSocketToolEnabled:d.assertSocketToolEnabled.bind(d),requireCurrentFrameContext:d.requireCurrentFrameContext.bind(d),inputRequester:d.inputRequester.bind(d),resolveInputTargetDevice:d.resolveInputTargetDevice.bind(d),assertBrokerConnectionInputTarget:d.assertBrokerConnectionInputTarget.bind(d),assertBrokerConnectionControl:d.assertBrokerConnectionControl.bind(d),assertBrokerConnectionHostMutation:d.assertBrokerConnectionHostMutation.bind(d),captureInputTargetOwner:d.captureInputTargetOwner.bind(d),selectInputTargetDevice:d.selectInputTargetDevice.bind(d),runTrackedKeyedDeviceInput:d.runTrackedKeyedDeviceInput.bind(d),inputDeviceGate:d.inputDeviceGate.bind(d),runHeldInputOperation:d.runHeldInputOperation.bind(d),dispatchFencedInput:d.dispatchFencedInput.bind(d),reconcileDiscoveryObservation:d.reconcileDiscoveryObservation.bind(d),assertDeviceActionable:d.assertDeviceActionable.bind(d),assertInputBindingGate:d.assertInputBindingGate.bind(d),runTrackedDeviceInput:d.runTrackedDeviceInput.bind(d),admitInputAsControlCall:d.admitInputAsControlCall.bind(d),answeringSessionRelease:d.answeringSessionRelease.bind(d),runFencedInputOperation:d.runFencedInputOperation.bind(d),discoverInputTargetDevices:d.discoverInputTargetDevices.bind(d),mcpRequestOptions:d.mcpRequestOptions.bind(d),combineMcpRequestSignals:d.combineMcpRequestSignals.bind(d)}}function Rk(d){return{remainingBudgetAfterProbe:d.remainingBudgetAfterProbe.bind(d),toIosRunnerCoordinates:d.toIosRunnerCoordinates.bind(d),requireCoordinatesWithinKnownScreenGeometry:d.requireCoordinatesWithinKnownScreenGeometry.bind(d),inputRouteClock:d.inputRouteClock.bind(d),remainingInputBudgetMs:d.remainingInputBudgetMs.bind(d),runInputRoute:d.runInputRoute.bind(d),handleInputTap:d.handleInputTap.bind(d),handleInputSwipe:d.handleInputSwipe.bind(d),handleInputGesture:d.handleInputGesture.bind(d),trackAckedGestureFrame:d.trackAckedGestureFrame.bind(d),liftingStrokeOnSessionRefusal:d.liftingStrokeOnSessionRefusal.bind(d),captureStrokeAdmission:d.captureStrokeAdmission.bind(d),strokeAdmissionStillHolds:d.strokeAdmissionStillHolds.bind(d),forwardGestureStart:d.forwardGestureStart.bind(d),liftSessionlessStrokesOn:d.liftSessionlessStrokesOn.bind(d),liftStrokesHeldByOn:d.liftStrokesHeldByOn.bind(d),liftStrokesHeldBy:d.liftStrokesHeldBy.bind(d),cancelGestureOnDevice:d.cancelGestureOnDevice.bind(d),forwardGestureFrame:d.forwardGestureFrame.bind(d),handleInputPressButton:d.handleInputPressButton.bind(d),handleInputKey:d.handleInputKey.bind(d),executeSocketInputKey:d.executeSocketInputKey.bind(d)}}function Dk(d){return{handleInputTypeText:d.handleInputTypeText.bind(d),indeterminateTextError:d.indeterminateTextError.bind(d),holdDispatchedInputRequest:d.holdDispatchedInputRequest.bind(d),createSocketInputAdbFactory:d.createSocketInputAdbFactory.bind(d),createSocketAppendTextInput:d.createSocketAppendTextInput.bind(d),executeInputTypeText:d.executeInputTypeText.bind(d),executeAndroidAppendText:d.executeAndroidAppendText.bind(d),retryAppendTextWithRebuiltHelper:d.retryAppendTextWithRebuiltHelper.bind(d),validateAppendFrameContext:d.validateAppendFrameContext.bind(d),runImeActionWithinBudget:d.runImeActionWithinBudget.bind(d),runInputOperationWithTimeout:d.runInputOperationWithTimeout.bind(d),parseInputTapParams:d.parseInputTapParams.bind(d),parseInputSwipeParams:d.parseInputSwipeParams.bind(d),parseInputTypeTextParams:d.parseInputTypeTextParams.bind(d),parseInputPressButtonParams:d.parseInputPressButtonParams.bind(d),parseInputKeyParams:d.parseInputKeyParams.bind(d),parseInputGestureParams:d.parseInputGestureParams.bind(d),evictDeviceInputCache:d.evictDeviceInputCache.bind(d),getAppendTextInput:d.getAppendTextInput.bind(d)}}function Jf(d,c){let R=new Ra(d,()=>W),D=new Ea(d,()=>W),k=new La(d,()=>W),P=new qa(d,()=>W),C=new Ua(d,()=>W),M=new Ka(d,()=>W),F=new Ja(d,()=>W),q=new Xa(d,()=>W),U=new Za(d,()=>W),K={...hk(R),...gk(D),...vk(k),...yk(P),...Sk(C),...bk(M),...wk(F),...Rk(q),...Dk(U)},W={...K,...c};return{implementations:K,callbacks:W}}class Ri{runtime;operations;callbacks;constructor(...d){this.runtime=new ba(d,()=>this.operations,ea,()=>this.maxInboundFrameBytes);let c=Jf(this.runtime,{start:(...R)=>this.start(...R),startDetached:(...R)=>this.startDetached(...R),stopAcceptingAndFanOut:(...R)=>this.stopAcceptingAndFanOut(...R),handleConnection:(...R)=>this.handleConnection(...R),releaseSocketSession:(...R)=>this.releaseSocketSession(...R),abortMcpRequests:(...R)=>this.abortMcpRequests(...R),mcpRequestSignal:(...R)=>this.mcpRequestSignal(...R),broadcastResourceUpdated:(...R)=>this.broadcastResourceUpdated(...R),pushProgressNotification:(...R)=>this.pushProgressNotification(...R),writeFrameData:(...R)=>this.writeFrameData(...R),handleRequest:(...R)=>this.handleRequest(...R),mcpForwardFailureResponse:(...R)=>this.mcpForwardFailureResponse(...R),requireRemainingMcpForwardBudget:(...R)=>this.requireRemainingMcpForwardBudget(...R),runKeyedMcpForward:(...R)=>this.runKeyedMcpForward(...R),getMcpForwardRoute:(...R)=>this.getMcpForwardRoute(...R),restoreSelectorSessions:(...R)=>this.restoreSelectorSessions(...R),recordBoundMcpClientKey:(...R)=>this.recordBoundMcpClientKey(...R),clearBoundMcpClientKey:(...R)=>this.clearBoundMcpClientKey(...R),forwardMcpRequest:(...R)=>this.forwardMcpRequest(...R),remainingMcpForwardBudget:(...R)=>this.remainingMcpForwardBudget(...R),getRequestArgumentScopeKey:(...R)=>this.getRequestArgumentScopeKey(...R),handleLocalSocketRequest:(...R)=>this.handleLocalSocketRequest(...R),handleIdeSocketRequest:(...R)=>this.handleIdeSocketRequest(...R),listBootedDevicesForIdeAction:(...R)=>this.listBootedDevicesForIdeAction(...R),runIdeKeyValueMutation:(...R)=>this.runIdeKeyValueMutation(...R),toIosRunnerCoordinates:(...R)=>this.toIosRunnerCoordinates(...R),handleInputTap:(...R)=>this.handleInputTap(...R),handleInputSwipe:(...R)=>this.handleInputSwipe(...R),handleInputGesture:(...R)=>this.handleInputGesture(...R),captureStrokeAdmission:(...R)=>this.captureStrokeAdmission(...R),strokeAdmissionStillHolds:(...R)=>this.strokeAdmissionStillHolds(...R),liftSessionlessStrokesOn:(...R)=>this.liftSessionlessStrokesOn(...R),liftStrokesHeldByOn:(...R)=>this.liftStrokesHeldByOn(...R),liftStrokesHeldBy:(...R)=>this.liftStrokesHeldBy(...R),handleInputTypeText:(...R)=>this.handleInputTypeText(...R),handleInputPressButton:(...R)=>this.handleInputPressButton(...R),handleInputKey:(...R)=>this.handleInputKey(...R),requireCurrentFrameContext:(...R)=>this.requireCurrentFrameContext(...R),resolveInputTargetDevice:(...R)=>this.resolveInputTargetDevice(...R),captureInputTargetOwner:(...R)=>this.captureInputTargetOwner(...R),runTrackedKeyedDeviceInput:(...R)=>this.runTrackedKeyedDeviceInput(...R),dispatchFencedInput:(...R)=>this.dispatchFencedInput(...R),runTrackedDeviceInput:(...R)=>this.runTrackedDeviceInput(...R),answeringSessionRelease:(...R)=>this.answeringSessionRelease(...R),handleIdeRequest:(...R)=>this.handleIdeRequest(...R),withSocketSessionAutolockKey:(...R)=>this.withSocketSessionAutolockKey(...R),scheduleForwardKeyIdle:(...R)=>this.scheduleForwardKeyIdle(...R),clearForwardKeyIdleTimer:(...R)=>this.clearForwardKeyIdleTimer(...R),evictDeviceInputCache:(...R)=>this.evictDeviceInputCache(...R),isListening:(...R)=>this.isListening(...R),getClientConnectionCount:(...R)=>this.getClientConnectionCount(...R),getAcceptedClientConnectionCount:(...R)=>this.getAcceptedClientConnectionCount(...R),quiesce:(...R)=>this.quiesce(...R),drainSessionReleaseNotifications:(...R)=>this.drainSessionReleaseNotifications(...R),close:(...R)=>this.close(...R)});this.operations=c.implementations,this.callbacks=c.callbacks}get server(){return this.runtime.server}set server(d){this.runtime.server=d}get acceptingRequests(){return this.runtime.acceptingRequests}set acceptingRequests(d){this.runtime.acceptingRequests=d}maxInboundFrameBytes=Hre;get sessions(){return this.runtime.sessions}set sessions(d){this.runtime.sessions=d}get clientSockets(){return this.runtime.clientSockets}set clientSockets(d){this.runtime.clientSockets=d}get activeRequestHandlers(){return this.runtime.activeRequestHandlers}set activeRequestHandlers(d){this.runtime.activeRequestHandlers=d}get pendingSocketRequests(){return this.runtime.pendingSocketRequests}set pendingSocketRequests(d){this.runtime.pendingSocketRequests=d}get notificationSubscribers(){return this.runtime.notificationSubscribers}set notificationSubscribers(d){this.runtime.notificationSubscribers=d}get resourceSubscriptions(){return this.runtime.resourceSubscriptions}get listChangedUnsubscribe(){return this.runtime.listChangedUnsubscribe}set listChangedUnsubscribe(d){this.runtime.listChangedUnsubscribe=d}get sessionReleaseUnsubscribe(){return this.runtime.sessionReleaseUnsubscribe}set sessionReleaseUnsubscribe(d){this.runtime.sessionReleaseUnsubscribe=d}get boundMcpClientKeysBySocketSession(){return this.runtime.boundMcpClientKeysBySocketSession}set boundMcpClientKeysBySocketSession(d){this.runtime.boundMcpClientKeysBySocketSession=d}get mcpForwardTails(){return this.runtime.mcpForwardTails}set mcpForwardTails(d){this.runtime.mcpForwardTails=d}get deviceReadToolCallClassifier(){return this.runtime.deviceReadToolCallClassifier}set deviceReadToolCallClassifier(d){this.runtime.deviceReadToolCallClassifier=d}get mcpClientFactory(){return this.runtime.mcpClientFactory}set mcpClientFactory(d){this.runtime.mcpClientFactory=d}get releaseToolCallRecording(){return this.runtime.releaseToolCallRecording}set releaseToolCallRecording(d){this.runtime.releaseToolCallRecording=d}get forgetSessionToolBindings(){return this.runtime.forgetSessionToolBindings}set forgetSessionToolBindings(d){this.runtime.forgetSessionToolBindings=d}get appendTextFactory(){return this.runtime.appendTextFactory}set appendTextFactory(d){this.runtime.appendTextFactory=d}get ownedGestures(){return this.runtime.ownedGestures}start(...d){return this.operations.start(...d)}startDetached(...d){return this.operations.startDetached(...d)}stopAcceptingAndFanOut(...d){return this.operations.stopAcceptingAndFanOut(...d)}handleConnection(...d){return this.operations.handleConnection(...d)}releaseSocketSession(...d){return this.operations.releaseSocketSession(...d)}abortMcpRequests(...d){return this.operations.abortMcpRequests(...d)}mcpRequestSignal(...d){return this.operations.mcpRequestSignal(...d)}broadcastResourceUpdated(...d){return this.operations.broadcastResourceUpdated(...d)}pushProgressNotification(...d){return this.operations.pushProgressNotification(...d)}writeFrameData(...d){return this.operations.writeFrameData(...d)}handleRequest(...d){return this.operations.handleRequest(...d)}mcpForwardFailureResponse(...d){return this.operations.mcpForwardFailureResponse(...d)}requireRemainingMcpForwardBudget(...d){return this.operations.requireRemainingMcpForwardBudget(...d)}runKeyedMcpForward(d,c,R,D){return this.operations.runKeyedMcpForward(d,c,R,D)}getMcpForwardRoute(...d){return this.operations.getMcpForwardRoute(...d)}restoreSelectorSessions(...d){return this.operations.restoreSelectorSessions(...d)}recordBoundMcpClientKey(...d){return this.operations.recordBoundMcpClientKey(...d)}clearBoundMcpClientKey(...d){return this.operations.clearBoundMcpClientKey(...d)}forwardMcpRequest(...d){return this.operations.forwardMcpRequest(...d)}remainingMcpForwardBudget(...d){return this.operations.remainingMcpForwardBudget(...d)}getRequestArgumentScopeKey(...d){return this.operations.getRequestArgumentScopeKey(...d)}handleLocalSocketRequest(...d){return this.operations.handleLocalSocketRequest(...d)}handleIdeSocketRequest(...d){return this.operations.handleIdeSocketRequest(...d)}listBootedDevicesForIdeAction(...d){return this.operations.listBootedDevicesForIdeAction(...d)}runIdeKeyValueMutation(...d){return this.operations.runIdeKeyValueMutation(...d)}toIosRunnerCoordinates(...d){return this.operations.toIosRunnerCoordinates(...d)}handleInputTap(...d){return this.operations.handleInputTap(...d)}handleInputSwipe(...d){return this.operations.handleInputSwipe(...d)}handleInputGesture(...d){return this.operations.handleInputGesture(...d)}captureStrokeAdmission(...d){return this.operations.captureStrokeAdmission(...d)}strokeAdmissionStillHolds(...d){return this.operations.strokeAdmissionStillHolds(...d)}liftSessionlessStrokesOn(...d){return this.operations.liftSessionlessStrokesOn(...d)}liftStrokesHeldByOn(...d){return this.operations.liftStrokesHeldByOn(...d)}liftStrokesHeldBy(...d){return this.operations.liftStrokesHeldBy(...d)}handleInputTypeText(...d){return this.operations.handleInputTypeText(...d)}handleInputPressButton(...d){return this.operations.handleInputPressButton(...d)}handleInputKey(...d){return this.operations.handleInputKey(...d)}requireCurrentFrameContext(...d){return this.operations.requireCurrentFrameContext(...d)}resolveInputTargetDevice(...d){return this.operations.resolveInputTargetDevice(...d)}captureInputTargetOwner(...d){return this.operations.captureInputTargetOwner(...d)}runTrackedKeyedDeviceInput(d,c,R,D){return this.operations.runTrackedKeyedDeviceInput(d,c,R,D)}dispatchFencedInput(d,c,R,D){return this.operations.dispatchFencedInput(d,c,R,D)}runTrackedDeviceInput(d,c,R,D={}){return this.operations.runTrackedDeviceInput(d,c,R,D)}answeringSessionRelease(d,c){return this.operations.answeringSessionRelease(d,c)}handleIdeRequest(...d){return this.operations.handleIdeRequest(...d)}withSocketSessionAutolockKey(...d){return this.operations.withSocketSessionAutolockKey(...d)}scheduleForwardKeyIdle(...d){return this.operations.scheduleForwardKeyIdle(...d)}clearForwardKeyIdleTimer(...d){return this.operations.clearForwardKeyIdleTimer(...d)}evictDeviceInputCache(...d){return this.operations.evictDeviceInputCache(...d)}isListening(...d){return this.operations.isListening(...d)}getClientConnectionCount(...d){return this.operations.getClientConnectionCount(...d)}getAcceptedClientConnectionCount(...d){return this.operations.getAcceptedClientConnectionCount(...d)}quiesce(...d){return this.operations.quiesce(...d)}drainSessionReleaseNotifications(...d){return this.operations.drainSessionReleaseNotifications(...d)}close(...d){return this.operations.close(...d)}get testHooks(){let d=this;return{sessions:this.runtime.sessions,get acceptingRequests(){return d.runtime.acceptingRequests},set acceptingRequests(c){d.runtime.acceptingRequests=c},input:this.callbacks,ide:this.callbacks,transport:this.callbacks,routing:this.callbacks,release:this.callbacks,restoreSelectorSessions:(c,R)=>this.callbacks.restoreSelectorSessions(c,R),getMcpForwardRoute:(c,R)=>this.callbacks.getMcpForwardRoute(c,R),withSocketSessionAutolockKey:(...c)=>this.callbacks.withSocketSessionAutolockKey(...c),recordBoundMcpClientKey:(...c)=>this.callbacks.recordBoundMcpClientKey(...c),boundMcpClientFor:(c)=>this.runtime.boundMcpClientKeysBySocketSession.get(c),requireCurrentFrameContext:(...c)=>this.callbacks.requireCurrentFrameContext(...c),broadcastListChanged:Gd(()=>this.callbacks.broadcastListChanged.bind(this),(c)=>{this.callbacks.broadcastListChanged=c}),waitForStartup:Gd(()=>this.callbacks.waitForStartup.bind(this),(c)=>this.callbacks.waitForStartup=c)}}}async function jf(d){await d.writeEarlyOwnerRecord(),await d.initializeDatabase()}var kk=200;class zf extends za{authenticator;auditRepository;constructor(d=$t(Cz),c=i,R=new Ym,D={}){super(d,c,"PerformanceStream");this.auditRepository=R,this.authenticator=D.authenticator??_n("performanceStream",{allowObserverSessions:!0})}async handleRequest(d){if(this.authenticator.authorize({sessionUuid:typeof d.sessionUuid==="string"?d.sessionUuid:void 0,deviceId:d.deviceId?.trim()||void 0}),d.command!=="poll")throw Error(`Unsupported performance stream command: ${String(d.command)}`);let c=this.createPollQuery(d),{sinceTimestamp:R,sinceId:D}=c,k=await this.auditRepository.listResultsSince(c),P=k.length>0?k[k.length-1]:void 0;return{success:!0,results:k,lastTimestamp:P?.timestamp??R,lastId:P?.id??D}}createPollQuery(d){let c=HU(d.startTime,"startTime"),R=HU(d.endTime,"endTime"),D=HU(d.sinceTimestamp,"sinceTimestamp"),k=VU(d.sinceId),P=qU(d.limit,kk);return{startTime:c,endTime:R,limit:P,deviceId:d.deviceId?.trim()||void 0,sessionId:d.sessionId?.trim()||void 0,packageName:d.packageName?.trim()||void 0,sinceTimestamp:D,sinceId:k}}createErrorResponse(d,c){return{success:!1,error:c}}}var ed=new In;function Yf(){return ed.instance?.getSocketPath()??$t(Cz)}async function Xf(){await ed.start(()=>new zf)}async function Qf(){await ed.stop()}var Ak=100,Pk=new gP;function Ik(d){return typeof d==="object"&&d!==null&&"command"in d}class eh extends za{authenticator;maxFrameBytes=Vre;repository;constructor(d=$t(Dz),c=i,R=Pk,D={}){super(d,c,"FailuresStream");this.repository=R,this.authenticator=D.authenticator??_n("failuresStream",{allowObserverSessions:!0})}handleUntypedRequest(d){if(!Ik(d))return Promise.reject(Error("Invalid request: expected an object with a command"));return this.handleRequest(d)}async handleRequest(d){switch(this.authenticator.authorize({sessionUuid:typeof d.sessionUuid==="string"?d.sessionUuid:void 0}),d.command){case"poll_notifications":return await this.handlePollNotifications(d);case"poll_groups":return await this.handlePollGroups(d);case"poll_timeline":return await this.handlePollTimeline(d);case"acknowledge":return await this.handleAcknowledge(d);default:throw Error(`Unsupported command: ${String(d.command)}`)}}createErrorResponse(d,c){return{success:!1,error:c}}async handlePollNotifications(d){let c=Py(d.sinceTimestamp,"sinceTimestamp"),R=VU(d.sinceId),D=qU(d.limit,Ak),k=Py(d.startTime,"startTime"),P=Py(d.endTime,"endTime"),C=BE(d.dateRange);if(C&&!k){let F=this.timer.now();P=P??F,k=P-LE(C)}let M=await this.repository.getNotificationsSince({sinceTimestamp:c,sinceId:R,startTime:k,endTime:P,limit:D,type:d.type,acknowledged:d.acknowledged});return{success:!0,notifications:M.notifications,lastTimestamp:M.lastTimestamp,lastId:M.lastId}}async handlePollGroups(d){let c=Py(d.startTime,"startTime"),R=Py(d.endTime,"endTime"),D=BE(d.dateRange);if(D&&!c){let P=this.timer.now();R=R??P,c=R-LE(D)}let k=await this.repository.getAggregatedGroups({startTime:c,endTime:R,type:d.type,severity:d.severity});return{success:!0,groups:k.groups,totals:k.totals}}async handlePollTimeline(d){let c=WU(d.aggregation),R=Py(d.startTime,"startTime"),D=Py(d.endTime,"endTime"),k=BE(d.dateRange),P=this.timer.now();if(k)D=D??P,R=D-LE(k);else D=D??P,R=R??D-86400000;let C=await this.repository.getTimelineData({startTime:R,endTime:D,aggregation:c});return{success:!0,dataPoints:C.dataPoints,previousPeriodTotals:C.previousPeriodTotals}}async handleAcknowledge(d){let c=d.notificationIds;if(!c||!Array.isArray(c))throw Error("notificationIds is required for acknowledge command");for(let R of c)if(typeof R!=="number"||!Number.isInteger(R)||R<0)throw Error(`Invalid notification ID: ${String(R)}`);return await this.repository.acknowledgeNotifications(c),{success:!0,acknowledgedCount:c.length}}}var td=new In;function th(){return td.instance?.getSocketPath()??$t(Dz)}async function ih(){await td.start(()=>new eh)}async function rh(){await td.stop()}var Ck=1n<<63n,Tk=1n<<62n,Mk=1n<<61n,Ek=1n<<59n,Bk=1n<<60n,id=59n,g5=0b11n<<id,oh=(1n<<id)-1n;function sh(d=0,c=0){let R=Buffer.allocUnsafe(12);return R.writeInt32BE(1748121140,0),R.writeInt32BE(d,4),R.writeInt32BE(c,8),R}function Di(d,{isConfig:c=!1,isKeyFrame:R=!1,rotation:D=null}={}){let k=d&oh;if(c){if(k|=Ck,D!==null)k|=Mk,k|=(BigInt(D)&0b11n)<<id}if(R)k|=Tk;return k}function ah(d,c){let R=Buffer.allocUnsafe(12);return R.writeBigInt64BE(BigInt.asIntN(64,d),0),R.writeInt32BE(c,8),R}function gt(d,c){return Buffer.concat([ah(d,c.length),c])}function dh(d){return gt(Ek|BigInt(d)&oh,Buffer.alloc(0))}function lh(){return gt(Bk,Buffer.alloc(0))}var Ok=1n<<61n,xk={downgraded_to_viewer:1,device_removed:2,identity_quarantined:3,daemon_shutdown:4,session_ended:5,device_restored:6};function nd(d){return ah(Ok|BigInt(xk[d]),0)}var rd=Buffer.from([0,0,0,1]),od=30000,_k=500,Fk=8,sd=1000,uh=6000,Ut=9000;function Nk(d){return d.platform==="android"?e5:wQ}class cd{host;deps;captureRegistry;timer;outboundStalls;constructor(d,c,R,{timer:D,outboundStalls:k}){this.host=d;this.deps=c;this.captureRegistry=R;this.timer=D,this.outboundStalls=k}async createSource(d,c,R){let{device:D}=d,k=D.deviceId,P=()=>{if(this.host.getCapture(k)!==d||d.generation!==R)return;if(d.lastSourceDataMs=this.timer.now(),d.firstEvidenceMs??=d.lastSourceDataMs,d.sourceFrameSequence++,d.lastIdleMs=null,d.encodedSinceSourceFrame=!1,!d.heartbeatTimer)this.startHeartbeat(k,d)},C=(M,F)=>{let q=this.host.getCapture(k);if(q!==d||d.generation!==R||M.length===0)return;if(F){if(q.lastEncodedDataMs=this.timer.now(),q.firstEvidenceMs??=q.lastEncodedDataMs,q.encodedSinceSourceFrame=!0,!q.heartbeatTimer)this.startHeartbeat(k,q)}this.broadcast(k,M)};return this.captureRegistry.acquire({device:D,create:(M)=>this.deps.createCaptureSource({...M,onError:M.onError}),hasConsumers:d.pendingSubscribers.size>0||d.subscribers.size>0,flexibleHints:c.fps===void 0?["fps"]:[],options:{device:D,onData:(M)=>C(M,!0),onReplayData:(M)=>C(M,!1),onSourceFrame:P,onSourceIdle:()=>{if(this.host.getCapture(k)!==d||d.generation!==R||!d.encodedSinceSourceFrame)return;d.lastIdleMs=this.timer.now()},onEncodedAccessUnit:()=>{if(this.host.getCapture(k)!==d||d.generation!==R)return;for(let M of d.parser.flush())this.broadcastNal(k,d,M);this.cacheCompletedAccessUnits(d,d.keyFrameAssembler.flush()),d.keyFrameAuBytes=0,d.lastEncodedBoundarySequence=d.sourceFrameSequence},onIdleAttestationSupport:(M)=>{if(this.host.getCapture(k)===d&&d.generation===R&&D.platform==="ios")d.legacySimulatorHelper=!M},onRotation:(M)=>{let F=this.host.getCapture(k);if(F===d&&d.generation===R)F.rotation=M},onDroppedFrames:(M)=>{if(this.host.getCapture(k)!==d||d.generation!==R||!Number.isSafeInteger(M)||M<0||!this.sourceEvidenceIsRecent(d,this.timer.now()))return;let q=dh(M);for(let U of d.subscribers)this.writePacketToSubscriber(k,d,U,{packet:q,isConfig:!1,isKeyFrame:!1})},onError:(M)=>{if(this.host.getCapture(k)===d&&d.generation===R)e.warn(`[VideoStream] capture failed for ${k}: ${M}`),this.host.stopCapture(k)},bitrateBps:c.bitrateKbps?c.bitrateKbps*1000:void 0,size:c.size,quality:c.quality,fps:c.fps??Nk(D)}})}resetForNewEncoder(d){this.clearHeartbeatTimer(d),d.parser=new ic,d.keyFrameAssembler=new Wf,d.keyFrameAuBytes=0,d.sps=null,d.pps=null,d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0,d.rotation=null,d.firstEvidenceMs=null,d.lastSourceDataMs=null,d.lastEncodedDataMs=null,d.lastIdleMs=null,d.lastLivenessProbeMs=null,d.encodedSinceSourceFrame=!1,d.legacySimulatorHelper=!1,d.sourceFrameSequence=0,d.lastEncodedBoundarySequence=null;for(let c of d.subscribers)d.waitingForKeyFrame.add(c)}primeSubscriber(d,c){this.replayParameterSets(d,c),this.replayCurrentIosKeyFrame(d.device,d,c)}broadcast(d,c){let R=this.host.getCapture(d);if(!R||c.length===0)return;for(let D of R.parser.push(c))this.broadcastNal(d,R,D)}broadcastNal(d,c,R){let D=_s(R);this.cacheCompleteKeyFrame(c,R,D);let k=D===qd||D===Vd;if(D===qd)c.sps=Buffer.from(R);if(D===Vd)c.pps=Buffer.from(R);let P=D===Ry,C=k?c.rotation:null,M=gt(Di(this.deps.nowUs(),{isConfig:k,isKeyFrame:P,rotation:C}),Buffer.concat([rd,R]));for(let F of c.subscribers)this.writePacketToSubscriber(d,c,F,{packet:M,isConfig:k,isKeyFrame:P})}cacheCompleteKeyFrame(d,c,R){let D=d.keyFrameAssembler.push(c);if(d.keyFrameAuBytes+=c.length,this.cacheCompletedAccessUnits(d,D),R===qd||R===Vd)d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;if(d.keyFrameAuBytes>gM)d.keyFrameAssembler=new Wf,d.keyFrameAuBytes=0}cacheCompletedAccessUnits(d,c){for(let R of c){let D=R.reduce((P,C)=>P+C.length,0);if(d.keyFrameAuBytes-=D,D>gM){d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;continue}let k=Buffer.concat(R.filter((P)=>_s(P)!==qd&&_s(P)!==Vd).flatMap((P)=>[rd,P]));if(R.some((P)=>_s(P)===Ry))d.latestKeyFrameAu=k,d.latestInterFrameAus=[],d.cachedGopBytes=k.length;else if(d.latestKeyFrameAu)if(d.cachedGopBytes+k.length>gM)d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;else d.latestInterFrameAus.push(k),d.cachedGopBytes+=k.length}}replayKeyFrame(d,c,R){if(!d.sps||!d.pps||!d.latestKeyFrameAu)return;this.writePacketToSubscriber(R,d,c,{packet:gt(Di(this.deps.nowUs(),{isKeyFrame:!0}),d.latestKeyFrameAu),isConfig:!1,isKeyFrame:!0});for(let D of d.latestInterFrameAus)this.writePacketToSubscriber(R,d,c,{packet:gt(Di(this.deps.nowUs(),{}),D),isConfig:!1,isKeyFrame:!1})}replayCurrentIosKeyFrame(d,c,R){if(d.platform==="ios"&&c.lastIdleMs!==null&&c.encodedSinceSourceFrame&&c.lastEncodedBoundarySequence===c.sourceFrameSequence&&this.timer.now()-c.lastIdleMs<=Ut)this.replayKeyFrame(c,R,d.deviceId)}writePacketToSubscriber(d,c,R,{packet:D,isConfig:k,isKeyFrame:P}){if(R.destroyed){this.host.detach(R);return}if(this.shouldSkipPacket(c,R,k,P))return;if(!R.write(D)){e.debug(`[VideoStream] subscriber is behind on ${d}; dropping to next key frame`),c.backpressuredSubscribers.add(R),c.waitingForKeyFrame.add(R);let C=()=>{let F=this.outboundStalls.get(R);if(!F)return;this.timer.clearTimeout(F.timeout),this.outboundStalls.delete(R);let q=this.host.getCapture(d);if(q!==c||!q.subscribers.has(R))return;q.backpressuredSubscribers.delete(R),this.requestKeyFrameForWaitingSubscriber(d,R)},M=this.timer.setTimeout(()=>{if(!this.outboundStalls.has(R))return;e.warn(`[VideoStream] subscriber stalled on ${d}; detaching`),this.host.detach(R),R.destroy()},this.deps.outboundStallTimeoutMs??od);this.outboundStalls.set(R,{timeout:M,onDrain:C}),R.once("drain",C)}}shouldSkipPacket(d,c,R,D){if(d.waitingForReplacement.has(c)||d.backpressuredSubscribers.has(c))return!0;if(!d.waitingForKeyFrame.has(c))return!1;if(!D)return!R;if(d.generation>0&&(!d.sps||!d.pps))return!0;return d.waitingForKeyFrame.delete(c),!1}requestKeyFrameForWaitingSubscriber(d,c,R=Fk){let D=this.host.getCapture(d);if(!D)return;if(c.destroyed||!D.waitingForKeyFrame.has(c))return;if(D.waitingForReplacement.has(c))return;let k=D.source;if(!k?.requestKeyFrame)return;if(k.requestKeyFrame()||R<=0)return;this.timer.setTimeout(()=>this.requestKeyFrameForWaitingSubscriber(d,c,R-1),_k)}replayParameterSets(d,c){let R=[d.sps,d.pps].filter((k)=>k!==null);if(R.length===0)return;let D=Buffer.concat(R.flatMap((k)=>[rd,k]));c.write(gt(Di(this.deps.nowUs(),{isConfig:!0,rotation:d.rotation}),D))}clearSubscriberStall(d){let c=this.outboundStalls.get(d);if(c)this.timer.clearTimeout(c.timeout),d.off("drain",c.onDrain),this.outboundStalls.delete(d)}startHeartbeat(d,c){c.heartbeatTimer=this.timer.setInterval(()=>{if(this.host.getCapture(d)!==c||!c.source)return;if(!this.hasFreshSourceEvidence(d,c)){if(this.host.getCapture(d)===c)this.host.stopCapture(d,!0);return}if(c.lastEncodedDataMs===null||c.lastSourceDataMs===null&&!this.idleEvidenceIsRecent(c,this.timer.now()))return;let R=lh();for(let D of c.subscribers){if(D.destroyed||c.waitingForKeyFrame.has(D)||c.backpressuredSubscribers.has(D))continue;D.write(R)}},sd)}hasFreshSourceEvidence(d,c){if(c.lastSourceDataMs===null||c.lastEncodedDataMs===null)return this.incompleteEvidenceIsRecent(c);return this.hasFreshCompleteSourceEvidence(d,c)}incompleteEvidenceIsRecent(d){let c=this.timer.now();return d.source!==null&&d.firstEvidenceMs!==null&&(this.idleEvidenceIsRecent(d,c)||c-d.firstEvidenceMs<Ut)}hasFreshCompleteSourceEvidence(d,c){let{source:R,lastSourceDataMs:D,lastEncodedDataMs:k}=c;if(!R||D===null||k===null)return!1;let P=this.timer.now();if(this.sourceEvidenceIsRecent(c,P)&&c.lastIdleMs!==null)return!0;if(Math.max(P-D,P-k,0)>=uh&&(c.lastLivenessProbeMs===null||P-c.lastLivenessProbeMs>=uh))try{if(R.requestKeyFrame?.("probe"))c.lastLivenessProbeMs=P}catch(M){e.warn(`[VideoStream] liveness key-frame request failed for ${d}: ${M}`)}return this.sourceEvidenceIsRecent(c,P)}sourceEvidenceIsRecent(d,c){if(d.lastSourceDataMs===null||d.lastEncodedDataMs===null)return!1;if(d.legacySimulatorHelper)return!0;if(this.idleEvidenceIsRecent(d,c))return!0;return Math.max(c-d.lastSourceDataMs,c-d.lastEncodedDataMs,0)<=Ut}idleEvidenceIsRecent(d,c){return d.lastIdleMs!==null&&d.encodedSinceSourceFrame&&c-d.lastIdleMs<=Ut}producerEvidenceIsStale(d){let c=this.timer.now();return(d.lastSourceDataMs===null||c-d.lastSourceDataMs>Ut)&&(d.lastIdleMs===null||c-d.lastIdleMs>Ut)}clearHeartbeatTimer(d){if(d.heartbeatTimer)this.timer.clearInterval(d.heartbeatTimer),d.heartbeatTimer=null}}function ph(){return new In}function ki(d){return d!==null&&"setHasConsumers"in d&&typeof d.setHasConsumers==="function"}var Pi="to stream video",Lk=new Set(["low","medium","high"]),vh=5,yh=60,Sh=1e6,wh=3000,Rh=200,ud=5000;function pd(d,c){return d!=="viewer"||c?.hasDeviceOwner===!1}function Yn(d,c){return d.quality===c.quality&&d.fps===c.fps&&d.bitrateKbps===c.bitrateKbps&&d.size?.width===c.size?.width&&d.size?.height===c.size?.height}function zn(d,c,R){return Number.isInteger(d)&&d>=c&&d<=R}function $k(d){return d===void 0||Lk.has(d)?null:`Unsupported quality "${d}"; expected low, medium, or high.`}function Hk(d){return d===void 0||zn(d,vh,yh)?null:`Invalid fps ${d}; expected an integer between ${vh} and ${yh}.`}function Uk(d){return d===void 0||zn(d,1,Sh)?null:`Invalid bitrateKbps ${d}; expected an integer between 1 and ${Sh}.`}function Kk(d){if(d===void 0)return null;let{width:c,height:R}=d??{};return zn(c,2,Number.MAX_SAFE_INTEGER)&&zn(R,2,Number.MAX_SAFE_INTEGER)?null:`Invalid size ${JSON.stringify(d)}; expected integer width/height >= 2.`}function Qn(d){return Gk(d.platform)??$k(d.quality)??Hk(d.fps)??Uk(d.bitrateKbps)??Kk(d.size)}function Gk(d){return d===void 0||d==="android"||d==="ios"?null:`Invalid platform ${JSON.stringify(d)}; expected "android" or "ios".`}function Dh(d,c){if(c instanceof om)return{id:d,type:"video_stream_response",success:!1,permission:{kind:"screen_recording",status:"needs_approval",approvalTarget:c.approvalTarget},error:c.message};return{id:d,type:"video_stream_response",success:!1,error:r(c),...Mc(c)}}async function kh(d,c,R="either",{timer:D=i,signal:k}={}){return hM(d,c,R,{timer:D,signal:k,source:"video-stream-resolve"})}async function Wk(d,c,R){return kh(d,c,R)}function Ah(d=new Xn){return{captureRegistry:bM(),ownershipChanges:()=>w.sessionManager()??null,deviceLifecycle:ma,sessionReleases:Ai,observerReleases:bb,resolveDevice:(c,R)=>Wk(d,c,R),createCaptureSource:async(c)=>{let R=await V0();return vM({device:c.device,onData:c.onData,onSourceFrame:c.onSourceFrame,onSourceIdle:c.onSourceIdle,onEncodedAccessUnit:c.onEncodedAccessUnit,onIdleAttestationSupport:c.onIdleAttestationSupport,onError:c.onError,onRotation:c.onRotation,onDroppedFrames:c.onDroppedFrames,bitrateBps:c.bitrateBps,size:c.size,quality:c.quality,fps:c.fps},R)},nowUs:()=>BigInt(Math.round(performance.now()*1000))}}var Zn=ph();function fd(){return Zn.instance?.getSocketPath?.()??$t(CB)}class Ph extends IR{deps;connections=new Set;captures=new Map;pendingStops=new Map;socketDeviceIds=new Map;socketSessionUuids=new Map;socketSubscriptionKinds=new Map;acknowledgedSubscribers=new Set;removeDeviceRestoredListener=null;removeDeviceRemovedListener=null;removeIdentityChangedListener=null;removeSessionReleaseListener=null;removeObserverReleaseListener=null;removeOwnershipListener=null;outboundStalls=new Map;endingSockets=new Map;subscribing=new Set;closed=!1;authenticator;admissionGate;pipeline;constructor(d,c=$t(CB),R=i,{authenticator:D=_n("video-stream subscribe",{allowObserverSessions:!0}),admissionGate:k=$s}={}){super(c,R,"VideoStream",{idleTimeoutMs:0});this.deps=d;this.authenticator=D,this.admissionGate=k,this.pipeline=new cd({getCapture:(P)=>this.captures.get(P),detach:(P)=>this.detach(P),stopCapture:(P,C)=>this.stopCapture(P,C)},d,d.captureRegistry??uG(),{timer:R,outboundStalls:this.outboundStalls})}activeDeviceIds(){return[...this.captures.keys()]}subscriberCount(d){let c=this.captures.get(d);return c?c.pendingSubscribers.size+c.subscribers.size:0}async start(){await super.start(),this.removeOwnershipListener=this.deps.ownershipChanges?.()?.onDeviceOwnershipChange((c)=>{this.reauthorizeSubscribers(c)})??null;let d=()=>{for(let c of this.captures.keys())this.reauthorizeSubscribers(c)};this.removeSessionReleaseListener=this.deps.sessionReleases?.subscribe(d)??null,this.removeObserverReleaseListener=this.deps.observerReleases?.subscribe(d)??null,this.subscribeDeviceLifecycle()}subscribeDeviceLifecycle(){let d=this.deps.deviceLifecycle?.();this.removeDeviceRestoredListener=d?.onDeviceRestored((c)=>{this.endDeviceSubscribers(c,"device_restored")})??null,this.removeDeviceRemovedListener=d?.onDeviceRemoved((c)=>{this.endDeviceSubscribers(c,"device_removed")})??null,this.removeIdentityChangedListener=d?.onDeviceIdentityChanged((c)=>{if(!this.captures.has(c))return;try{this.admissionGate.assertDeviceActionable(c,Pi)}catch(R){e.warn(`[VideoStream] identity no longer actionable for ${c}: ${r(R)}`),this.endDeviceSubscribers(c,"identity_quarantined")}})??null}async close(){this.closed=!0,this.removeOwnershipListener?.(),this.removeOwnershipListener=null,this.removeSessionReleaseListener?.(),this.removeSessionReleaseListener=null,this.removeObserverReleaseListener?.(),this.removeObserverReleaseListener=null,this.removeDeviceRestoredListener?.(),this.removeDeviceRestoredListener=null,this.removeDeviceRemovedListener?.(),this.removeIdentityChangedListener?.(),this.removeDeviceRemovedListener=null,this.removeIdentityChangedListener=null;for(let d of this.captures.keys())this.endDeviceSubscribers(d,"daemon_shutdown");await this.stopCapturesForClose(),this.socketDeviceIds.clear(),this.socketSessionUuids.clear(),this.socketSubscriptionKinds.clear(),this.acknowledgedSubscribers.clear(),this.subscribing.clear();for(let d of this.connections)this.endSocketBounded(d);try{await super.close()}finally{for(let{onClose:d}of this.endingSockets.values())d()}}async stopCapturesForClose(){let d=Symbol("video stream capture stop timeout");try{await l(async()=>{await Promise.all([...this.captures.keys()].map((c)=>this.stopCapture(c))),await Promise.all(this.pendingStops.values())},{timer:this.timer,timeoutMs:ud,label:"Video stream socket server shutdown",timeoutError:()=>d})}catch(c){if(c!==d)throw c;e.warn(`[VideoStream] shutdown abandoned the capture stop for ${[...this.pendingStops.keys()].join(", ")||"no device"} after ${ud}ms; continuing socket teardown`)}}isStreamingOrSubscribing(d){return this.socketDeviceIds.has(d)||this.subscribing.has(d)}async processLine(d,c){if(d.destroyed)return;if(this.isStreamingOrSubscribing(d))return;let R=this.parseJson(c);if(!R){this.sendJson(d,{type:"video_stream_response",success:!1,error:"Invalid JSON"}),d.end();return}if(R.action!=="subscribe"){this.sendJson(d,{id:R.id,type:"video_stream_response",success:!1,error:`Unsupported video stream action: ${R.action}`}),d.end();return}let D=Qn(R);if(D){this.sendJson(d,{id:R.id,type:"video_stream_response",success:!1,error:D}),d.end();return}this.subscribing.add(d);try{if(this.authenticator.authorize({sessionUuid:R.sessionUuid,deviceId:R.deviceId,admitViewer:!0}),R.deviceId!==void 0)this.admissionGate.assertDeviceActionable(R.deviceId,Pi);let k=await this.deps.resolveDevice(R.deviceId,R.platform);this.admissionGate.assertDeviceActionable(k.deviceId,Pi),Lp(this.authenticator,{sessionUuid:R.sessionUuid,deviceId:k.deviceId,admitViewer:!0});let P=await this.attach(d,k,R);if(P)this.acknowledgeSubscriber(d,P,R)}catch(k){if(e.warn(`[VideoStream] subscribe failed: ${k}`),this.detach(d),!d.destroyed)this.sendJson(d,Dh(R.id,k)),this.endSocketBounded(d)}finally{this.subscribing.delete(d)}}acknowledgeSubscriber(d,c,R){if(!this.socketDeviceIds.has(d))return;if(!this.checkSubscriberActionable(d,c.device.deviceId))return;if(this.authenticator.resolveSubscriptionIdentity)this.reconcileSubscriber(d,c.device.deviceId);else Lp(this.authenticator,{sessionUuid:R.sessionUuid,deviceId:c.device.deviceId,admitViewer:!0});if(!this.socketDeviceIds.has(d)||d.destroyed)return;if(this.sendJson(d,{id:R.id,type:"video_stream_response",success:!0,action:"subscribe",deviceId:c.device.deviceId,framing:"h264",heartbeatMs:sd,subscriptionKind:this.socketSubscriptionKinds.get(d)}),d.destroyed){this.detach(d);return}d.write(sh(c.appliedHints.size?.width??0,c.appliedHints.size?.height??0)),this.acknowledgedSubscribers.add(d),this.primeAcknowledgedSubscriber(c,d)}onConnectionEstablished(d){if(this.closed){d.destroy();return}this.connections.add(d),d.once("end",()=>d.destroy())}onConnectionClose(d){this.connections.delete(d),this.subscribing.delete(d),this.detach(d)}onConnectionError(d,c){this.subscribing.delete(d),this.detach(d)}reauthorizeSubscribers(d){let c=this.captures.get(d);if(!c)return;for(let R of[...c.pendingSubscribers,...c.subscribers])this.reconcileSubscriber(R,d)}reconcileSubscriber(d,c){if(!this.socketDeviceIds.has(d))return;let R=this.socketSubscriptionKinds.get(d)??"owner",D={sessionUuid:this.socketSessionUuids.get(d),deviceId:c};try{let k=this.authenticator.resolveSubscriptionIdentity?.(D);if(!k){this.authenticator.authorize({...D,requireOwnership:!0});return}let P=pM({...k,kind:R});if(P.action==="end")this.endSubscriber(d,c,P.reason);else if(P.action==="downgrade"){if(this.socketSubscriptionKinds.set(d,"viewer"),e.info(`[VideoStream] downgraded subscriber: deviceId=${c} kind=viewer reason=downgrade`),this.acknowledgedSubscribers.has(d)&&!d.destroyed)d.write(nd("downgraded_to_viewer"))}}catch(k){this.endSubscriber(d,c,"session_ended",{authorizationError:k})}}endDeviceSubscribers(d,c){let R=this.captures.get(d);if(!R)return;for(let D of[...R.pendingSubscribers,...R.subscribers]){let k=this.socketSubscriptionKinds.get(D)??"owner";this.endSubscriber(D,d,mM({kind:k,event:c}).reason)}}endSubscriber(d,c,R,D={}){if(!this.socketDeviceIds.has(d)&&!this.subscribing.has(d))return;let k=this.socketSubscriptionKinds.get(d),P=`[VideoStream] ending subscriber: deviceId=${c} kind=${k} reason=${R}`;if("authorizationError"in D||R==="device_removed"||R==="identity_quarantined")e.warn(P);else e.info(P);try{if(!d.destroyed){if(this.acknowledgedSubscribers.has(d))d.write(nd(R));this.sendJson(d,{type:"video_stream_response",success:!1,action:"unsubscribe",deviceId:c,terminal:!0,reason:R,subscriptionKind:this.socketSubscriptionKinds.get(d),error:`Video stream ended: ${R} for ${c}`}),this.endSocketBounded(d)}}catch(C){if(e.warn(`[VideoStream] failed to end subscriber for ${c}: ${r(C)}`),!d.destroyed)d.destroy()}finally{this.subscribing.delete(d),this.detach(d)}}endSocketBounded(d){if(d.destroyed||this.endingSockets.has(d))return;let c=()=>{let D=this.endingSockets.get(d);if(D)this.timer.clearTimeout(D.timeout),this.endingSockets.delete(d);d.off("close",c)},R=this.timer.setTimeout(()=>{d.destroy()},this.deps.outboundStallTimeoutMs??od);this.endingSockets.set(d,{timeout:R,onClose:c}),d.once("close",c),d.end(),d.destroySoon()}checkSubscriberActionable(d,c){try{return this.admissionGate.assertDeviceActionable(c,Pi),!0}catch(R){return e.warn(`[VideoStream] identity no longer actionable for ${c}: ${r(R)}`),this.endSubscriber(d,c,"identity_quarantined"),!1}}async attach(d,c,R){if(this.closed)throw new t("Video stream server is closed");let D=c.deviceId,k=this.pendingStops.get(D);if(k){if(await k,this.closed)throw new t("Video stream server is closed");if(d.destroyed)throw new t(`Video stream subscriber disconnected while stopping ${D}`)}Lp(this.authenticator,{sessionUuid:R.sessionUuid,deviceId:D,admitViewer:!0});let P=this.authenticator.resolveSubscriptionIdentity?.({sessionUuid:R.sessionUuid,deviceId:D}),C=P?BU(P):"owner";if(this.socketSubscriptionKinds.set(d,C),!this.checkSubscriberActionable(d,D))return null;let M=this.captures.get(D);if(M){if(this.clearIdleTimer(M),this.updateDesiredHints({deviceId:D,capture:M,request:R,identity:P,subscriptionKind:C}),M.pendingSubscribers.add(d),ki(M.source))M.source.setHasConsumers(!0);return this.socketDeviceIds.set(d,D),this.socketSessionUuids.set(d,R.sessionUuid),this.socketSubscriptionKinds.set(d,C),await M.startup,this.promoteSubscriber(M,d,!0),this.scheduleReconfigure(D,M),M}let F=pd(C,P)?R:{},q={device:c,desiredHints:{quality:F.quality,fps:F.fps,bitrateKbps:F.bitrateKbps,size:F.size},appliedHints:{quality:F.quality,fps:F.fps,bitrateKbps:F.bitrateKbps,size:F.size},hintKind:C,generation:0,reconfigureTimer:null,reconfiguring:null,source:null,startup:Promise.resolve(),pendingSubscribers:new Set([d]),subscribers:new Set,backpressuredSubscribers:new Set,waitingForKeyFrame:new Set,waitingForReplacement:new Set,sps:null,pps:null,parser:new ic,keyFrameAssembler:new Wf,keyFrameAuBytes:0,latestKeyFrameAu:null,latestInterFrameAus:[],cachedGopBytes:0,sourceFrameSequence:0,lastEncodedBoundarySequence:null,rotation:null,idleTimer:null,heartbeatTimer:null,firstEvidenceMs:null,lastSourceDataMs:null,lastIdleMs:null,encodedSinceSourceFrame:!1,legacySimulatorHelper:!1,lastEncodedDataMs:null,lastLivenessProbeMs:null};return this.captures.set(D,q),this.socketDeviceIds.set(d,D),this.socketSessionUuids.set(d,R.sessionUuid),this.socketSubscriptionKinds.set(d,C),q.startup=(async()=>{try{let U=await this.pipeline.createSource(q,q.appliedHints,q.generation);if(this.captures.get(D)!==q||!this.hasSubscribers(q)&&!q.idleTimer)throw await U.stop().catch((K)=>{e.warn(`[VideoStream] failed to stop abandoned capture for ${D}: ${K}`)}),new t(`Video capture for ${D} was stopped during startup.`);if(q.source=U,ki(U))U.setHasConsumers(this.hasSubscribers(q));if(await U.start(),this.captures.get(D)!==q||!this.hasSubscribers(q)&&!q.idleTimer)throw q.source=null,await U.stop().catch((K)=>{e.warn(`[VideoStream] failed to stop abandoned capture for ${D}: ${K}`)}),new t(`Video capture for ${D} was stopped during startup.`)}catch(U){if(this.pipeline.clearHeartbeatTimer(q),this.captures.get(D)===q)this.captures.delete(D);throw u(U,`Failed to start video capture for ${D}`)}})(),await q.startup,this.promoteSubscriber(q,d,!0),q}updateDesiredHints({deviceId:d,capture:c,request:R,identity:D,subscriptionKind:k}){if(!pd(k,D))return;let P=k==="owner"&&c.hintKind==="viewer",C=P?{}:c.desiredHints;if(k==="owner")c.hintKind="owner";if(c.desiredHints={quality:R.quality??C.quality,fps:R.fps??C.fps,bitrateKbps:R.bitrateKbps??C.bitrateKbps,size:P?R.size:C.size},this.retainSharedHints(c,c.desiredHints),!Yn(c.desiredHints,c.appliedHints))e.info(`[VideoStream] ${d} scheduling shared capture quality change`);if(!this.reconfigurePending(c))this.releaseReplacementWaiters(c)}reconfigurePending(d){return d.reconfiguring!==null||!Yn(d.desiredHints,d.appliedHints)}primeAcknowledgedSubscriber(d,c){if(!this.reconfigurePending(d))d.waitingForReplacement.delete(c),this.pipeline.primeSubscriber(d,c);this.pipeline.requestKeyFrameForWaitingSubscriber(d.device.deviceId,c)}releaseReplacementWaiters(d){if(this.reconfigurePending(d))return;for(let c of d.waitingForReplacement){if(!d.subscribers.has(c))continue;d.waitingForReplacement.delete(c),this.pipeline.primeSubscriber(d,c),this.pipeline.requestKeyFrameForWaitingSubscriber(d.device.deviceId,c)}}scheduleReconfigure(d,c){if(c.reconfigureTimer)this.timer.clearTimeout(c.reconfigureTimer),c.reconfigureTimer=null;if(this.captures.get(d)!==c||c.reconfiguring||!this.hasSubscribers(c)||Yn(c.desiredHints,c.appliedHints)){this.releaseReplacementWaiters(c);return}c.reconfigureTimer=this.timer.setTimeout(()=>{c.reconfigureTimer=null;let R=this.reconfigureCapture(d,c,{...c.desiredHints});c.reconfiguring=R,R.finally(()=>{c.reconfiguring=null,this.releaseReplacementWaiters(c),this.scheduleReconfigure(d,c)})},Rh)}retainSharedHints(d,c){if(!d.source||!K8(d.source,{device:d.device,onData:()=>{},bitrateBps:c.bitrateKbps?c.bitrateKbps*1000:void 0,size:c.size,quality:c.quality,fps:c.fps}))return!1;return d.appliedHints=c,!0}async reconfigureCapture(d,c,R){let D=c.source;if(!D||this.captures.get(d)!==c)return;if(this.retainSharedHints(c,R))return;c.generation++,c.source=null,this.pipeline.resetForNewEncoder(c);try{if(await D.stop(),this.captures.get(d)!==c)return;let k=await this.pipeline.createSource(c,R,c.generation);if(this.captures.get(d)!==c){await k.stop();return}if(c.source=k,ki(k))k.setHasConsumers(this.hasSubscribers(c));if(await k.start(),this.captures.get(d)!==c){await k.stop();return}c.appliedHints=R,e.info(`[VideoStream] ${d} shared capture quality changed`);let P=c.waitingForKeyFrame.values().next().value;if(P)this.pipeline.requestKeyFrameForWaitingSubscriber(d,P)}catch(k){if(e.warn(`[VideoStream] failed to reconfigure capture for ${d}: ${k}`),this.captures.get(d)===c)c.source??=D,this.stopCapture(d)}}hasSubscribers(d){return d.pendingSubscribers.size>0||d.subscribers.size>0}promoteSubscriber(d,c,R){if(c.destroyed){d.pendingSubscribers.delete(c);return}if(!d.pendingSubscribers.delete(c))return;if(d.subscribers.add(c),R)d.waitingForKeyFrame.add(c);if(this.reconfigurePending(d))d.waitingForReplacement.add(c)}detach(d){this.pipeline.clearSubscriberStall(d);let c=this.socketDeviceIds.get(d);if(this.socketDeviceIds.delete(d),this.socketSessionUuids.delete(d),this.socketSubscriptionKinds.delete(d),this.acknowledgedSubscribers.delete(d),!c)return;let R=this.captures.get(c);if(!R)return;if(R.pendingSubscribers.delete(d),R.subscribers.delete(d),R.backpressuredSubscribers.delete(d),R.waitingForKeyFrame.delete(d),R.waitingForReplacement.delete(d),!this.hasSubscribers(R)){if(R.reconfigureTimer)this.timer.clearTimeout(R.reconfigureTimer),R.reconfigureTimer=null;if(ki(R.source))R.source.setHasConsumers(!1);this.clearIdleTimer(R),R.idleTimer=this.timer.setTimeout(()=>{if(R.idleTimer=null,this.captures.get(c)===R&&!this.hasSubscribers(R))this.stopCapture(c)},wh)}}clearIdleTimer(d){if(d.idleTimer)this.timer.clearTimeout(d.idleTimer),d.idleTimer=null}stopCapture(d,c=!1){let R=this.pendingStops.get(d);if(R)return R;let D=this.captures.get(d);if(!D)return Promise.resolve();if(this.captures.delete(d),this.clearIdleTimer(D),this.pipeline.clearHeartbeatTimer(D),D.reconfigureTimer)this.timer.clearTimeout(D.reconfigureTimer),D.reconfigureTimer=null;for(let P of[...D.pendingSubscribers,...D.subscribers])this.detach(P),this.endSocketBounded(P);D.pendingSubscribers.clear(),D.subscribers.clear(),D.backpressuredSubscribers.clear(),D.waitingForKeyFrame.clear(),D.waitingForReplacement.clear();let k=(async()=>{try{try{if(c&&D.source)await G8(D.source,this.pipeline.producerEvidenceIsStale(D));else await D.source?.stop()}catch(P){e.warn(`[VideoStream] failed to stop capture for ${d}: ${P}`)}try{await D.startup}catch(P){e.debug(`[VideoStream] startup settled during stop for ${d}: ${P}`)}await D.reconfiguring}finally{this.pendingStops.delete(d)}})();return this.pendingStops.set(d,k),k}}async function Ih(d){await Zn.start(()=>new Ph(Ah(d?.getPlatformDeviceManager())))}async function Ch(){await Zn.stop()}function ot(){return{control:Bt,appearance:eG(),"device-snapshot":XK(),"failures-push":hoe(),"failures-stream":th(),"observation-stream":die(),"performance-push":Pie(),"performance-stream":Yf(),"telemetry-push":iie(),"device-gesture-recording":GK(),"video-recording":zK(),"video-stream":fd(),"webrtc-stream":nG()}}import Vk from"fs";import be from"path";var jk="terminal-release-intents.jsonl",Mh="terminal-release-intents",hd=".jsonl";function Th(d,c){return be.join(d,Mh,`${encodeURIComponent(c)}${hd}`)}function Xk(d,c,R){let D;try{D=JSON.parse(d)}catch(k){e.warn(`[TerminalReleaseJournal] Discarded corrupt line ${c} of ${R}: ${r(k)}`,k);return}if(typeof D==="object"&&D!==null){let k=D,{sessionId:P,reason:C,at:M}=k;if(typeof P==="string"&&P.length>0){if(k.lifted===!0)return{kind:"lifted",sessionId:P};if(typeof C==="string"&&C.length>0&&Number.isFinite(M))return{kind:"intent",intent:{sessionId:P,reason:C,at:M}}}}e.warn(`[TerminalReleaseJournal] Discarded corrupt line ${c} of ${R}: invalid journal record`);return}function Eh(d,c,R){let D=!1;for(let[k,P]of d.entries()){let C=Xk(P,k+1,R);if(C?.kind==="intent")c.set(C.intent.sessionId,C.intent);else if(C?.kind==="lifted")c.delete(C.sessionId);else D=!0}return D}function Qk(d){return`${JSON.stringify({sessionId:d,lifted:!0})}
39
+ `}function vd(d){return`${JSON.stringify({sessionId:d.sessionId,reason:d.reason,at:d.at})}
40
+ `}class Bh{filePath;fileSystem;peerJournalPath;intents=new Map;loaded=!1;directorySynced=!1;constructor(d,c,R){this.filePath=d;this.fileSystem=c;this.peerJournalPath=R}loadUnconfirmed(){return this.ensureLoaded(),Array.from(this.intents.values())}readDeadDaemon(d){let c=this.peerPath(d);return c===void 0?[]:Fh(c,this.fileSystem)}discardDeadDaemon(d){let c=this.peerPath(d);if(c===void 0)return;try{this.fileSystem.remove(c)}catch(R){e.warn(`[TerminalReleaseJournal] Could not remove the settled journal ${c}: `+r(R),R)}}peerPath(d){let c=this.peerJournalPath?.(d);return c===this.filePath?void 0:c}record(d){this.ensureLoaded(),this.intents.set(d.sessionId,d);try{return this.appendDurable(vd(d)),"durable"}catch(c){return e.warn(`[TerminalReleaseJournal] Failed to record the terminal release intent of session ${d.sessionId}: ${r(c)}`,c),"volatile"}}resolve(d,c){let R=this.ensureLoaded(),D=this.intents.get(d);if(!D||c!==void 0&&D.reason!==c)return;if(this.intents.delete(d),R&&this.compact(this.intents))return;try{this.appendDurable(Qk(d))}catch(k){e.warn(`[TerminalReleaseJournal] Failed to record the lifted fence of session ${d}: `+r(k),k)}}appendDurable(d){this.fileSystem.appendDurable(this.filePath,d,!this.directorySynced),this.directorySynced=!0}ensureLoaded(){if(this.loaded)return!0;let d;try{d=this.fileSystem.readText(this.filePath)}catch(R){return e.warn(`[TerminalReleaseJournal] Failed to read ${this.filePath}; unconfirmed terminal releases from a previous daemon cannot be applied yet: ${r(R)}`,R),!1}this.loaded=!0;let c=new Map(this.intents);if(this.intents.clear(),d!==void 0)this.replay(d);for(let[R,D]of c)this.intents.set(R,D);return!0}replay(d){let c=d.split(`
41
+ `),R=c.pop()??"",D=Eh(c,this.intents,this.filePath)||R.length>0;if(R.length>0)e.warn(`[TerminalReleaseJournal] Discarded a torn tail of ${this.filePath}; ${this.intents.size} intent(s) kept`);if(D||c.length!==this.intents.size)this.compact(this.intents)}compact(d){try{if(d.size===0)this.fileSystem.remove(this.filePath),this.directorySynced=!1;else this.fileSystem.replaceDurable(this.filePath,Array.from(d.values(),vd).join(""));return!0}catch(c){return e.warn(`[TerminalReleaseJournal] Failed to compact ${this.filePath}: ${r(c)}`,c),!1}}}function Zk(d=Vk,c=process.platform){let R=(D,k)=>{let P=d.openSync(D,k);try{d.fsyncSync(P)}finally{d.closeSync(P)}};return{listNames(D){try{return d.readdirSync(D).sort(iM)}catch(k){if(k.code==="ENOENT")return[];throw k}},readText(D){try{return d.readFileSync(D,"utf-8")}catch(k){if(k.code==="ENOENT")return;throw k}},appendDurable(D,k,P=!0){let C=d.mkdirSync(be.dirname(D),{recursive:!0,mode:448}),M=d.openSync(D,"a",384);try{d.writeSync(M,k),d.fsyncSync(M)}finally{d.closeSync(M)}if(P&&c!=="win32"){if(R(be.dirname(D),"r"),C!==void 0){R(be.dirname(C),"r");let F=be.relative(C,be.dirname(D)),q=C;for(let U of F?F.split(be.sep):[])q=be.join(q,U),R(be.dirname(q),"r")}}},replaceDurable(D,k){let P=`${D}.${process.pid}.tmp`,C=d.openSync(P,"w",384);try{d.writeSync(C,k),d.fsyncSync(C)}finally{d.closeSync(C)}try{d.renameSync(P,D)}catch(M){throw d.rmSync(P,{force:!0}),M}if(c!=="win32")R(be.dirname(D),"r")},remove(D){d.rmSync(D,{force:!0})}}}var tA=Zk();function _h(d){let c=d.dataDir??tm(),R=d.fileSystem??tA,D=Th(c,d.daemonSessionId);return rA(D,iA(c,d,R),R),new Bh(D,R,(k)=>Th(c,k))}function iA(d,c,R){let D=new Set(c.liveDaemonSessionIds);D.delete(c.daemonSessionId);let k=D.size===0?[be.join(d,jk)]:[],P=be.join(d,Mh),C;try{C=R.listNames(P)}catch(M){return e.warn(`[TerminalReleaseJournal] Failed to list ${P}; terminal releases of earlier daemons are applied by a later startup: ${r(M)}`,M),k}for(let M of C){if(!M.endsWith(hd))continue;let F=nA(M.slice(0,-hd.length));if(F!==void 0&&F!==c.daemonSessionId&&!D.has(F))k.push(be.join(P,M))}return k}function nA(d){try{return decodeURIComponent(d)}catch(c){e.debug(`[TerminalReleaseJournal] Ignoring journal file ${d}: ${r(c)}`);return}}function Fh(d,c){let R;try{R=c.readText(d)}catch(k){e.warn(`[TerminalReleaseJournal] Failed to read ${d}; its terminal releases are applied by a later startup: ${r(k)}`,k);return}let D=new Map;if(R!==void 0){let k=R.split(`
42
+ `),P=k.pop()??"";if(Eh(k,D,d),P.length>0)e.warn(`[TerminalReleaseJournal] Discarded a torn tail of ${d}`)}return Array.from(D.values())}function rA(d,c,R){for(let D of c){let k=Fh(D,R);if(k===void 0)continue;if(k.length>0)try{R.appendDurable(d,k.map(vd).join(""))}catch(P){e.warn(`[TerminalReleaseJournal] Failed to adopt ${D}; its terminal releases are applied by a later startup: ${r(P)}`,P);continue}try{R.remove(D)}catch(P){e.warn(`[TerminalReleaseJournal] Adopted but could not remove ${D}: ${r(P)}`,P)}}}function er(d,c,R){if(!c.isIosPassiveWorkEnabled())return[];let D=d.filter((P)=>P.platform==="ios"&&c.allows("ios","startup-warmup",P.id)),k=D.filter((P)=>R?.(P.id));if(k.length>0)e.info(`[Daemon] Skipping gated CtrlProxy iOS warm-up devices: ${k.map((P)=>P.id).join(", ")}`);return D.filter((P)=>!k.includes(P))}async function Nh(d,c,R){let D=Symbol("iOS startup budget");try{return await l(d,{timer:c,timeoutMs:R,unref:!0,label:"iOS startup budget",timeoutError:()=>D}),!0}catch(k){if(k!==D)throw k;return!1}}async function tr(d,c){let R={ready:[],deferred:[]},D=c.pendingPrefetch();if(D!==null){if(e.info(`[Daemon] CtrlProxy iOS runner prefetch in flight; waiting up to ${c.perDeviceTimeoutMs}ms before verifying ${d.length} iOS device(s)`),!await Nh(D,c.timer,c.perDeviceTimeoutMs))return e.info(`[Daemon] CtrlProxy iOS runner prefetch still in flight after ${c.perDeviceTimeoutMs}ms; deferring CtrlProxy iOS setup for ${d.length} iOS device(s) to the first tool call`),R.deferred.push(...d),R}return await Promise.all(d.map(async(k)=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Skipping CtrlProxy iOS startup for ${k}: daemon shutdown is in progress`);return}e.info(`[Daemon] Setting up CtrlProxy iOS for iOS device ${k}`);try{let P=c.verifyIosDevice(k,{skipCtrlProxyDownload:!0});if(!await Nh(P,c.timer,c.perDeviceTimeoutMs)){e.warn(`[Daemon] CtrlProxy iOS warm-up timed out for ${k}: phase=runner-setup after ${c.perDeviceTimeoutMs}ms; deferring to the resident startup`),R.deferred.push(k),P.then(()=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Deferred CtrlProxy iOS startup for ${k} completed after daemon shutdown began; ignoring`);return}e.info(`[Daemon] Deferred CtrlProxy iOS startup completed for ${k} after warm-up timeout`)},(C)=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Deferred CtrlProxy iOS startup for ${k} failed after daemon shutdown began; ignoring: ${r(C)}`);return}e.warn(`[Daemon] Deferred CtrlProxy iOS startup failed for ${k}: ${r(C)}`,C)});return}await P,e.info(`[Daemon] CtrlProxy iOS ready for iOS device ${k}`),R.ready.push(k)}catch(P){if(P instanceof qk)e.info(`[Daemon] Deferring CtrlProxy iOS setup for ${k} to the first tool call: ${P.message}`),R.deferred.push(k);else e.warn(`[Daemon] Failed to initialize CtrlProxy iOS for ${k}: ${P}`)}})),R}async function yd(d,c){if(await c(d))return d;let R=d>=Zw&&d<=Jv,D=R?Array.from({length:Jv-d},(k,P)=>d+1+P):[];for(let k of D)if(await c(k))return k;if(!R)throw Error(`Port ${d} is not available (outside the fallback range ${Zw}-${Jv})`);throw Error(D.length===0?`Port ${d} is not available (no higher port in the fallback range ${Zw}-${Jv})`:`No available ports in range ${d}-${Jv}`)}var Lh={"enter process":"process entry","entered daemon process":"process entry","tool-call-end activity subscription":"process entry","forward lease owner":"process entry","database prologue":"incumbent window","terminal release journal":"incumbent window","binding registry":"incumbent window","daemon collaborators":"incumbent window","http token prepare":"incumbent window","http ingress":"incumbent window","device discovery":"incumbent window","session rehydration":"incumbent window","session broker":"incumbent window","iOS services":"incumbent window","recorder teardown redrive":"incumbent window","control socket bind":"incumbent window","socket bind commit":"incumbent window","http token publish":"incumbent window","background registry upgrade":"after bind","session broker recovery":"after bind","services after socket bind":"after bind","heartbeat monitor":"after bind","maintenance monitors":"after bind","startup report":"after bind","startup failure tracker reset":"after bind"};async function Sd(d,c=()=>{}){for(let R of d)try{let D=R.run();if(D instanceof Promise)await D}catch(D){throw c(R.name),D}}function ce(d,c){return{name:d,run:c}}class bd{host;sessionBrokerRecovery;androidAvdProvenanceWarmPromise;startupLiveDaemonSessionIds=new Set;constructor(d){this.host=d}applyRuntimeOptions(d){if(d.networkMockable)N.setNetworkMockableEnabled(!0);if(d.dismissKeyboardAfterInput)N.setDismissKeyboardAfterInputEnabled(!0);if(d.eventAllMarkers&&d.eventAllMarkers.length>0)N.setEventAllMarkers(d.eventAllMarkers);if(d.debugPerf)DB(!0);if(d.noUiPerfMode)N.setUiPerfMode(!1);if(d.noNavigationScreenshots)N.setNavigationScreenshotsEnabled(!1);if(d.noWaitForPollingOverhead)N.setWaitForPollingOverheadEnabled(!1);if(d.memPerfAudit)N.setMemPerfAuditMode(!0);if(d.predictiveUi)N.setPredictiveUiEnabled(!0)}applyAccessibilityOptions(d){if(d.rawElementSearch)N.setRawElementSearchEnabled(!0);if(d.skipCtrlProxyDownload)N.setSkipCtrlProxyDownload(!0);if(d.runnerReadinessTimeoutMs!==void 0)N.setRunnerReadinessTimeoutMs(d.runnerReadinessTimeoutMs);if(d.noA11yIncludeNotImportantViews)N.setA11yIncludeNotImportantViews(!1);if(d.noA11yReportViewIds)N.setA11yReportViewIds(!1);if(d.noA11yRetrieveInteractiveWindows)N.setA11yRetrieveInteractiveWindows(!1);if(d.noOcclusion)N.setOcclusionEnabled(!1)}async start(){await this.host.startOn(this.processStartHost())}async startOn(d){this.host.setStartHost(d),this.host.setEnteredDaemonProcess(!1);try{await this.startUntilReady(),this.host.resolveStartupCompletion()()}catch(c){throw this.host.lifecycle.selfExitRecorder().record("startup-failure"),this.host.rejectStartupCompletion()(c),c}}async startUntilReady(){await this.host.startThroughSocketBind();try{await this.host.startAfterSocketBind()}catch(d){throw e.error(`Daemon startup failed after the socket bind; stopping: ${r(d)}`),this.host.rejectStartupCompletion()(d),await this.host.stopAfterFailedStartup(),d}}async stopAfterFailedStartup(){if(this.host.lifecycle.shutdownInProgress())return;let d=Symbol("post-bind startup failure stop timeout");try{await l(()=>this.host.stop(),{timer:this.host.services.timer(),timeoutMs:P0,label:"Post-bind startup failure stop",timeoutError:()=>d})}catch(c){e.warn(c===d?`Stopping after a failed startup exceeded ${P0}ms`:`Stopping after a failed startup failed: ${r(c)}`,c)}}processStartHost(){return{writeExitRecord:(d)=>AZ(Bt,d,this.host.exitRecordFileSystem()),enterProcess:()=>this.host.enterDaemonProcess(),publishForwardLeaseOwner:()=>{ane(Bt)},writeEarlyOwnerRecord:()=>this.host.writeEarlyOwnerRecord(),openTerminalReleaseJournal:(d)=>_h(d),prepareHttpToken:()=>this.host.prepareHttpToken(),publishHttpToken:()=>this.host.publishHttpToken(),startHttpIngress:()=>this.host.startHttpIngress(),sweepStaleAppearanceConfigs:async(d)=>{await pm(d,this.host.services.sessionManager(),{liveDaemonSessionIds:this.startupLiveDaemonSessionIds,ownDaemonSessionId:this.host.identity.daemonSessionId(),getPersistedSession:(c)=>this.host.readPersistedSession(c)})},redriveRecorderTeardowns:async()=>{try{let d=await this.host.initializeRecordingTeardownRedriveState(),c=new XM;return await this.host.redriveUnconfirmedCaptureTeardowns(this.host.services.sessionManager(),{recordingRepository:d.recordingRepository,liveDaemonSessionIds:new Set([...d.liveDaemonSessionIds].filter((R)=>R!==this.host.identity.daemonSessionId())),ownedCaptureIds:()=>d.videoRecorderService.listActiveRecordingIds(),onStartupOrphans:this.host.setStartupOrphanCaptures,onDeviceProcessStarted:(R)=>this.host.services.devicePool().setDeviceProcessStartedListener(R),onDeviceIncarnationAssigned:(R)=>{this.host.lifecycle.setRecorderDeviceIncarnationListener(R)},getDeviceIncarnation:(R)=>this.host.services.devicePool().getDeviceIncarnation(R),getDevice:(R)=>{let D=this.host.services.devicePool().getDevice(R);return D?{deviceId:D.id,name:D.name,platform:D.platform}:void 0},forceStopOrphanedCapture:(R,D,k)=>k?c.forceStopOrphanedCapture(R,D,k):c.forceStopOrphanedCapture(R,D),now:()=>this.host.services.timer().now(),timer:this.host.services.timer()})}catch(d){return e.warn("[Daemon] Recorder teardown initialization failed; continuing startup",d),!1}},bindControlSocket:()=>this.host.bindControlSocket(),startServicesAfterSocketBind:()=>this.host.startServicesAfterSocketBind(),startMaintenanceMonitors:()=>this.host.startMaintenanceMonitors()}}enterDaemonProcess(){Kae(ym),e.enableStdoutLogging();let d=OU();process.env[tS]??=oM(d),Yae(),process.chdir(d),e.info("Starting AutoMobile daemon..."),this.host.setupShutdownHandlers()}async startThroughSocketBind(){await Sd(this.startThroughSocketBindStages(),(d)=>{if(Lh[d]==="incumbent window"&&!this.host.identity.socketBindCommitted())this.host.restoreIncumbentOwnerRecord()})}startThroughSocketBindStages(){let d=()=>this.host.startHost();return[ce("enter process",()=>{d().enterProcess()}),ce("entered daemon process",()=>{this.host.setEnteredDaemonProcess(!0)}),ce("tool-call-end activity subscription",()=>{this.host.subscribeToolCallEndActivity()}),ce("forward lease owner",()=>{d().publishForwardLeaseOwner()}),ce("database prologue",()=>Ot.runPhase("daemonDatabaseInitialization",()=>jf({writeEarlyOwnerRecord:()=>d().writeEarlyOwnerRecord(),initializeDatabase:()=>this.host.initializeDatabase()}))),ce("terminal release journal",()=>{this.host.services.sessionManager().attachTerminalReleaseJournal(d().openTerminalReleaseJournal({daemonSessionId:this.host.identity.daemonSessionId(),liveDaemonSessionIds:this.startupLiveDaemonSessionIds}))}),ce("binding registry",()=>this.prepareStartupBindingRegistry()),ce("daemon collaborators",()=>{this.host.services.sessionManager().assertDaemonCollaboratorsAttached()}),ce("http token prepare",()=>{d().prepareHttpToken()}),ce("http ingress",()=>d().startHttpIngress()),ce("device discovery",async()=>{e.info("Initializing device pool..."),Ot.startPhase("deviceDiscovery"),await this.host.initializeDevicePoolWithTimeout(5000),Ot.endPhase("deviceDiscovery")}),ce("session rehydration",()=>this.rehydrateStartupSessions()),ce("session broker",async()=>{this.sessionBrokerRecovery=await this.host.installSessionBroker()}),ce("iOS services",()=>Ot.runPhase("iosServices",()=>this.host.initializeIosServices())),ce("recorder teardown redrive",()=>d().redriveRecorderTeardowns()),ce("control socket bind",async()=>{this.host.lifecycle.setSocketServer(await d().bindControlSocket())}),ce("socket bind commit",()=>{this.host.identity.setSocketBindCommitted(!0)}),ce("http token publish",()=>{d().publishHttpToken(),Ot.endPhase("socketServerStart")}),ce("background registry upgrade",()=>{if(e.info("Unix socket server started"),!this.host.lifecycle.sessionBrokerConfigPath()&&hh())this.host.startBackgroundRegistryUpgrade()})]}prepareStartupBindingRegistry(){if(this.host.lifecycle.sessionBrokerConfigPath()!==void 0)return Cp({brokerConfigured:!0,registryExists:hh(),open:()=>this.host.openBindingRegistry()});if(hh())this.host.openBindingRegistry(void 0,{quiet:!0}).catch((d)=>{e.warn(`[Daemon] Recovery registry open deferred; will retry after socket bind: ${r(d)}`,d)});return}async rehydrateStartupSessions(){try{let d=await Ot.runPhase("sessionRehydration",()=>this.host.services.sessionManager().rehydratePersistedSessions(this.host.services.devicePool()));await this.host.reownRehydratedManagedExecutions(d.rehydrated),await this.host.startHost().sweepStaleAppearanceConfigs(d)}catch(d){e.warn(`[Daemon] Session rehydration failed; continuing startup: ${d}`)}}async startHttpIngress(){if(this.warmAndroidAvdProvenanceCache(),!this.host.strictPort())this.host.identity.setPort(await this.findAvailablePort(this.host.identity.port()));Ot.startPhase("httpServerStart"),await this.host.services.httpIngress().start(),Ot.endPhase("httpServerStart")}async bindControlSocket(){return e.info(`Daemon host: "${this.host.host()}", port: ${this.host.identity.port()}`),e.info(`MCP_STREAMABLE_PATH: "${Qw}"`),e.info(`Creating UnixSocketServer at "${Bt}"`),this.host.lifecycle.setSocketServer(new Ri(Bt,void 0,void 0,ar.getInstance(),{identityStartedAt:this.host.identity.generationStartedAt(),processGenerationToken:this.host.identity.processGenerationToken(),startupOptions:this.host.services.options(),onRepublishIdentity:()=>this.host.republishIdentity(),startupCompletion:this.host.lifecycle.startupCompletion(),pidFilePath:Sr,sockets:ot(),dbPath:Gp(),processStartedAt:this.host.identity.processStartedAt(),onRestartAccepted:()=>{setImmediate(()=>process.kill(process.pid,"SIGTERM"))},liveAcceptanceStartupSecret:this.host.identity.liveAcceptanceStartupSecret(),acceptanceDiscoveryCapability:this.host.identity.acceptanceDiscoveryCapability(),mcpDispatcher:this.host.services.mcpDispatcher(),clearConnectionDevicePin:(d)=>this.host.services.deviceReadiness().clearConnectionDevicePin(d)},this.host.services.idGenerator(),{ownerLiveness:this.host.identity.incumbentOwnerGuard().asSocketOwnerLiveness()})),e.info("Starting Unix socket server..."),Ot.startPhase("socketServerStart"),await this.host.lifecycle.socketServer().start(),this.host.recordControlSocketIdentity(),this.host.lifecycle.socketServer()}async startServicesAfterSocketBind(){Ot.startPhase("auxiliarySocketServerStart"),await this.host.startAuxiliarySocket("video-recording",jK),await this.host.startAuxiliarySocket("device-gesture-recording",()=>YK(this.host.services.deviceReadiness())),await this.host.startAuxiliarySocket("device-snapshot",ZK),await this.host.startAuxiliarySocket("appearance",tG),await this.host.startAuxiliarySocket("performance-stream",Xf),await this.host.startAuxiliarySocket("observation-stream",()=>lj(this.host.services.timer())),this.host.configureDeviceDataStreamServer(),await this.host.startAuxiliarySocket("performance-push",Aie),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("failures-stream",ih),await this.host.startAuxiliarySocket("failures-push",goe),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("telemetry-push",oie),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("webrtc-stream",iG),await this.host.startAuxiliarySocket("video-stream",()=>Ih(this.host.services.deviceReadiness())),Ot.endPhase("auxiliarySocketServerStart"),sG({getTargets:()=>this.host.getAppearanceSyncTargets(),isEnabled:()=>this.host.services.passiveWorkPolicy().isAppearanceSyncEnabled(),beforeApply:(d)=>Jd(d,["nightMode"])}),ZY(),this.host.startAdbMissingDeviceListener(),this.host.startDeviceDisconnectMonitor(),await this.host.writePidFile(),this.host.identity.setCompleteIdentityPublished(!0),e.info(`DaemonState initialized: ${this.host.services.daemonState().isInitialized()}, device count: ${this.host.services.devicePool().getTotalDeviceCount()}`),this.host.startHealthCheckTimer()}startMaintenanceMonitors(){this.host.startNavigationRetentionMonitor(),this.host.startForwardLeaseIdleReleaser(),this.host.startPrivateDaemonOrphanWatchdog()}async startAfterSocketBind(){await Sd(this.startAfterSocketBindStages())}startAfterSocketBindStages(){return[ce("session broker recovery",()=>{this.sessionBrokerRecovery?.start()}),ce("services after socket bind",()=>this.host.startHost().startServicesAfterSocketBind()),ce("heartbeat monitor",()=>{this.host.startHeartbeatMonitor()}),ce("maintenance monitors",()=>{this.host.startHost().startMaintenanceMonitors()}),ce("startup report",()=>{Ot.emit("daemon",{host:this.host.host(),port:this.host.identity.port(),socketPath:Bt,deviceCount:this.host.services.devicePool().getTotalDeviceCount(),mcpHttpListenerBound:this.host.services.httpIngress().server?.listening??!1,daemonSocketListenerBound:this.host.lifecycle.socketServer()?.isListening()??!1}),e.info(`Daemon started: PID ${process.pid}, socket ${Bt}, HTTP port ${this.host.identity.port()}`)}),ce("startup failure tracker reset",()=>{this.host.startupFailureTracker().reset()})]}warmAndroidAvdProvenanceCache(){this.androidAvdProvenanceWarmPromise=Promise.resolve().then(()=>Ps.getInstance().getByName(this.host.avdManagerFactory()(),this.host.services.timer())).catch((d)=>{e.debug(`Android AVD provenance startup warm failed: ${r(d)}`)})}async findAvailablePort(d){return yd(d,(c)=>this.isPortAvailable(c))}async isPortAvailable(d){return new Promise((c)=>{let R=oA(),D=!1,k=i.setTimeout(()=>{if(!D)D=!0,R.close(()=>{}),c(!1)},1000);R.once("error",()=>{if(!D)D=!0,clearTimeout(k),c(!1)}),R.listen(d,this.host.host(),()=>{if(!D)D=!0,clearTimeout(k),R.close(()=>{c(!0)})})})}async initializeDevicePoolWithTimeout(d){let c=Symbol("device pool initialization timeout");try{await l(()=>this.host.initializeDevicePool(),{timer:this.host.services.timer(),timeoutMs:d,unref:!0,label:"Device pool initialization",timeoutError:()=>c})}catch(D){if(D!==c)throw D;e.warn(`Device pool initialization timed out after ${d}ms`)}let R=this.host.services.devicePool().getTotalDeviceCount();if(R===0)e.warn("Device pool is empty after initialization."),e.warn("Tests will fail until devices are available."),e.warn("Start an emulator or connect a physical device, then restart the daemon.");else e.info(`Device pool ready with ${R} device(s)`)}async initializeDevicePool(){try{let d=await this.host.services.devicePool().refreshDevicesWithOutcome(),c=this.host.services.devicePool().getAllDevices();if(c.length>0){let R=this.host.services.devicePool().getAllDevices().filter((D)=>dr(D.platform));for(let D of R)this.host.services.deviceSessionRegistry().onDeviceConnected({deviceId:D.id,platform:D.platform,incarnation:D.incarnation});e.info(`Device pool initialized with ${c.length} devices: ${c.map((D)=>D.id).join(", ")}`)}else if(d.failure===void 0)e.warn("No devices detected during daemon startup. Device pool is empty."),e.warn("Start an emulator or connect a physical device before creating sessions.")}catch(d){e.error(`Failed to initialize device pool: ${d}`)}}async initializeIosServices(){if(!this.host.services.passiveWorkPolicy().isIosPassiveWorkEnabled()){e.info("[Daemon] Skipping iOS CtrlProxy warm-up for live acceptance");return}let d=er(this.host.services.devicePool().getAllDevices(),this.host.services.passiveWorkPolicy(),(R)=>{let D=this.host.services.sessionManager().getSessionForDevice(R);return D!==null&&this.host.lifecycle.managedExecutionReowner()?.ownershipState(D)!==void 0});if(d.length===0){e.debug("[Daemon] No iOS devices to initialize CtrlProxy iOS for");return}e.info(`[Daemon] Initializing CtrlProxy iOS for ${d.length} iOS device(s)...`);let c=this.host.services.iosDeviceVerifier()();await tr(d.map((R)=>R.id),{timer:this.host.services.timer(),perDeviceTimeoutMs:5000,pendingPrefetch:()=>it.pendingPrefetch(),isShuttingDown:()=>this.host.lifecycle.shutdownInProgress(),verifyIosDevice:(R,D)=>c.verifyIosDevice(R,D)})}async initializeDatabase(){try{await this.host.databaseInitializer().initialize(),await this.host.toolSelectionProfileProvenanceLoader().load();let d=new Set(this.host.identity.incumbentOwnerGuard().withLiveIncumbent(this.host.liveDaemonSessionIdProvider().collectLiveDaemonSessionIds()));this.startupLiveDaemonSessionIds=d,await this.host.services.installedAppsRepository().clearOldDaemonSessions(this.host.identity.daemonSessionId(),d),await this.host.services.deviceSessionRepository().markStaleActiveSessionsExpired(this.host.identity.daemonSessionId(),this.host.services.timer().now(),e_,d),await this.host.setVideoRecordingManagerDependencies({liveDaemonSessionIds:d,daemonSessionId:this.host.identity.daemonSessionId()}),e.info(`[Daemon] Cleared old daemon session caches, current session: ${this.host.identity.daemonSessionId()}`)}catch(d){await UU(d,this.host.startupFailureTracker(),this.host.services.timer())}}get testHooks(){return{resolveStartupCompletion:()=>this.host.resolveStartupCompletion()(),rejectStartupCompletion:(d)=>this.host.rejectStartupCompletion()(d),startUntilReady:()=>this.startUntilReady(),daemonSessionId:()=>this.host.identity.daemonSessionId(),options:()=>this.host.services.options(),port:()=>this.host.identity.port(),processStartHost:()=>this.processStartHost(),setStartHost:(d)=>{this.host.setStartHost(d)},warmAndroidAvdProvenanceCache:()=>this.warmAndroidAvdProvenanceCache(),androidAvdProvenanceWarmPromise:()=>this.androidAvdProvenanceWarmPromise,startThroughSocketBind:()=>this.host.startThroughSocketBind(),startupStageNames:()=>[...this.startThroughSocketBindStages(),...this.startAfterSocketBindStages()].map((d)=>d.name)}}}function $h(d,c){if(d.observeResultIncludeElements)N.setObserveResultIncludeElementsEnabled(!0);if(d.toolResultsNoStructuredContent)N.setToolResultsNoStructuredContentEnabled(!0);if(d.actionsDiffObserve)N.setActionsDiffObserveEnabled(!0);if(d.actionsCompactMetadata!==void 0)N.setActionsCompactMetadataEnabled(d.actionsCompactMetadata);if(c.actionsCompactMetadata=N.isActionsCompactMetadataEnabled(),d.actionsNoObserve)N.setActionsNoObserveEnabled(!0);if(d.toolOutputsDir)N.setToolOutputsDir(d.toolOutputsDir)}import{writeSync as sA}from"fs";import{mkdir as aA}from"fs/promises";import{dirname as dA,isAbsolute as cA}from"path";class wd{boundSocketIdentities=new Map;host;files;platform;databasePath;reportStartupFailure;constructor(d,c={stat:Ig},R=process.platform,{databasePath:D=Gp,reportStartupFailure:k=(P)=>{sA(2,`${P}
43
+ `)}}={}){this.host=d,this.files=c,this.platform=R,this.databasePath=D,this.reportStartupFailure=k}async persistPidFileData(d,c){await aA(dA(Sr),{recursive:!0}),c?.throwIfAborted(),await dne(Sr,d,c),this.host.setPidFileWritten(!0)}async writeEarlyOwnerRecord(){if(!Sl())await bl();this.host.identity.incumbentOwnerGuard().captureIncumbentBeforeOverwrite();let d=this.host.identity.incumbentOwnerGuard().supersededOwnerForEarlyRecord(),c={pid:process.pid,launchNonce:I(h.DAEMON_LAUNCH_NONCE),daemonSessionId:this.host.identity.daemonSessionId(),socketPath:Bt,port:this.host.identity.port(),dbPath:this.databasePath(),startedAt:this.host.identity.generationStartedAt(),processStartedAt:this.host.identity.processStartedAt(),..._d(this.host.identity.processGenerationToken()),version:di,launchLogPath:this.launchLogPath(),assetVersion:cn(De()),options:this.host.services.options(),...d===void 0?{}:{supersededOwner:d}};await this.host.persistPidFileData(c),this.host.identity.incumbentOwnerGuard().recordContenderEarlyOwner(c),e.info(`Early daemon owner record written to ${Sr} (dbPath ${c.dbPath})`)}async writePidFile(d){if(!Sl())await bl();d?.throwIfAborted();let c=Vo(),R={pid:process.pid,launchNonce:I(h.DAEMON_LAUNCH_NONCE),daemonSessionId:this.host.identity.daemonSessionId(),socketPath:Bt,sockets:jB(ot()),port:this.host.identity.port(),dbPath:this.databasePath(),startedAt:this.host.identity.generationStartedAt(),processStartedAt:this.host.identity.processStartedAt(),..._d(this.host.identity.processGenerationToken()),version:di,launchLogPath:this.launchLogPath(),assetVersion:cn(De()),entryScript:c.entryScript,buildId:c.buildId,options:this.host.services.options()};await this.host.persistPidFileData(R,d),d?.throwIfAborted(),e.info(`PID file written to ${Sr}`)}republishIdentity(){return kZ(this.host.identity.completeIdentityPublished(),{pid:process.pid,startedAt:this.host.identity.generationStartedAt(),processGenerationToken:this.host.identity.processGenerationToken()},{readRecord:()=>_o(),writeRecord:()=>this.writePidFile(),isProcessRunning:(d)=>st(d,{debugLog:e.debug})},jB(ot()))}launchLogPath(){let d=I(h.DAEMON_LAUNCH_LOG_PATH);return d&&cA(d)?d:null}async cleanupDaemonFilesForShutdown(){if(!this.host.identity.socketBindCommitted())this.restoreIncumbentOwnerRecord();await eb(this.getDaemonFileCleanupOptions())}restoreIncumbentOwnerRecord(){try{this.host.identity.incumbentOwnerGuard().restoreIncumbentAfterRefusal()}catch(d){e.warn(`Failed to restore the incumbent daemon owner record after a refused start: ${d}`)}}recordControlSocketIdentity(){this.recordSocketIdentity(Bt)}recordSocketIdentity(d){try{let{dev:c,ino:R}=this.files.stat(d);this.boundSocketIdentities.set(d,{dev:c,ino:R})}catch(c){(this.platform==="win32"?e.debug:e.warn)(`[Daemon] Cannot record ownership of socket ${d}: ${c}`)}}async startAuxiliarySocket(d,c){try{await c()}catch(R){let D=Xne(d,R);if(!D){if(R instanceof kl)this.reportHeldSocketFailure(R);throw R}e.warn(`[Daemon] ${D.code}: ${d} disabled at ${D.socketPath}`,R);return}Zne(d),this.recordSocketIdentity(ot()[d])}reportHeldSocketFailure(d){try{this.reportStartupFailure(d.message)}catch(c){e.debug(`Unable to report startup failure: ${r(c)}`,c)}}getDaemonFileCleanupOptions(){let d=this.host.identity.socketBindCommitted(),c=d?[...this.boundSocketIdentities.keys()]:[],R=this.boundSocketIdentities;if(this.host.pidFileWritten())return{expectedPid:process.pid,socketBindCommitted:d,socketPaths:c,socketFileIdentities:R};let D=_o();return D&&D.pid!==process.pid?{expectedPid:process.pid,socketBindCommitted:d,socketPaths:c,socketFileIdentities:R}:{socketBindCommitted:d,socketPaths:c,socketFileIdentities:R}}}var nr=3000,lA=3000,Dd=2,uA=1080,mA=2340,fA=1170,gA=2532;function qh(d,c,R){return d.filter((D)=>{if(c.allows(D.platform,"observation-stream",D.id))return!0;return R?.(D),!1})}async function Uh(d,c,R){let D=c.filter((M)=>d===null||M.id===d),k=R.maxConcurrency??Dd;if(!Number.isInteger(k)||k<1)throw RangeError("Initial observation frame concurrency must be a positive integer");if(R.coordinator){if(!R.subscriber)throw Error("Coalesced initial frames require a subscriber target");let{coordinator:M,subscriber:F}=R;await Promise.all(D.map(async(q)=>{try{let U=await M.request(q.id,()=>Kh(q,R),F.signal,R.maxConcurrency);if(U&&!F.signal.aborted&&(R.isDeviceAllowed?.(q.id)??!0))Wh(q.id,U.frame,R,{...F,replay:U.replay})}catch(U){e.warn(`[Daemon] Failed to push initial observation frame for ${q.id}: ${r(U)}`,U)}}));return}let P=0;async function C(){while(P<D.length){let M=D[P++];await vA(M,R)}}await Promise.all(Array.from({length:Math.min(k,D.length)},()=>C()))}async function vA(d,c){try{let R=await Kh(d,c);if(R)Wh(d.id,R,c)}catch(R){e.warn(`[Daemon] Failed to push initial observation frame for ${d.id}: ${r(R)}`,R)}}async function Kh(d,c){let R={deviceId:d.id,name:d.name,platform:d.platform};if(d.platform!=="android"&&d.platform!=="ios")return;let D=c.streamServer.getLiveFrameGeneration?.(d.id),k=c.streamServer.getDeviceSessionUuid?.(d.id),P=d.platform==="android"?yA(c.androidClientFactory(R)):SA(c.iosClientFactory(R));if(!await P.client.ensureConnected())throw Error(`Failed to connect CtrlProxy to ${d.id}`);e.info(`[Daemon] Capturing initial observation frame for ${d.id}`);let C=c.streamServer.getCurrentFrameContextGeneration?.(d.id),M=await P.hierarchy();if(!M)throw Error(`No hierarchy available for initial observation frame on ${d.id}`);let F=M.hierarchy,q={hierarchy:F,frameContext:M.frameContext??F.frameContext,frameContextGeneration:C,liveFrameGeneration:D,deviceSessionUuid:k,recordHierarchy:(K)=>P.client.recordInitialObservationStreamHierarchy(F,K)},U=await Promise.resolve().then(()=>P.screenshot()).then((K)=>K,(K)=>{q.screenshotFailure={error:K};return});if(U){let K=d.platform==="android"?PA(F):CA(F);q.screenshot={...U,...K}}return q}function yA(d){return{client:d,hierarchy:async()=>{let c=await DA(d);return c?{hierarchy:d.convertToViewHierarchyResult(c.hierarchy),frameContext:c.frameContext}:null},screenshot:async()=>{let c=await d.captureScreenshotForObservationStream();return c.success&&c.data?{data:c.data,metadata:Bie(c),frameContext:c.frameContext,rotation:c.rotation}:void 0}}}function SA(d){return{client:d,hierarchy:async()=>{let c=await AA(d);return c?{hierarchy:d.convertToViewHierarchyResult(c.hierarchy),frameContext:c.frameContext}:null},screenshot:async()=>{let c=await d.requestScreenshotWithoutObservationStreamPush(lA);return c.success&&c.data?{data:c.data,metadata:Rd(JR,c.format),frameContext:c.frameContext,rotation:c.rotation}:void 0}}}function Wh(d,c,R,D){if(!bA(d,c,R.streamServer))return;if(D&&!D.replay&&c.hierarchyDelivered){Hh(d,c,c.captureSequence??null,{streamServer:R.streamServer,subscriber:D});return}let k=R.streamServer.pushHierarchyUpdate(d,c.hierarchy,c.frameContext,D?{...D,liveFrameGeneration:c.liveFrameGeneration,deviceSessionUuid:c.deviceSessionUuid,captureSequence:c.captureSequence,frameContextGeneration:c.frameContextGeneration}:void 0);if(!D||c.captureSequence===void 0&&k!==null)c.recordHierarchy(k);if(k!==null)c.hierarchyDelivered=!0,c.captureSequence=k,c.frameContextGeneration=R.streamServer.getCurrentFrameContextGeneration?.(d);Hh(d,c,k,{streamServer:R.streamServer,subscriber:D})}function bA(d,c,R){if(c.liveFrameGeneration!==void 0&&R.getLiveFrameGeneration&&c.liveFrameGeneration!==R.getLiveFrameGeneration(d))return!1;if(c.deviceSessionUuid!==void 0&&R.getDeviceSessionUuid&&c.deviceSessionUuid!==R.getDeviceSessionUuid(d))return!1;return c.frameContextGeneration===void 0||c.frameContextGeneration===R.getCurrentFrameContextGeneration?.(d)}function Hh(d,c,R,{streamServer:D,subscriber:k}){let P=c.screenshot;if(P&&(!k||R!==null)&&(!k||k.replay||!c.screenshotDelivered)){if(D.pushScreenshotUpdate(d,P.data,{screenWidth:P.width,screenHeight:P.height,metadata:P.metadata,options:{...RA(R,c.frameContext,P.frameContext),...wA(c.hierarchy),initialFrameSubscriber:k?{...k,liveFrameGeneration:c.liveFrameGeneration,deviceSessionUuid:c.deviceSessionUuid}:void 0,rotation:P.rotation,...P.frameContext===void 0?{}:{frameContext:P.frameContext}}}))c.screenshotDelivered=!0}if(c.screenshotFailure)throw c.screenshotFailure.error}function wA(d){let c=Zu(d);return c?{coordinateSpace:DR,nativeScale:c.nativeScale}:{}}function RA(d,c,R){if(d===null||c!==void 0&&R!==void 0&&c!==R)return{};return{captureSequence:d}}async function DA(d){let c=await d.getLatestHierarchy(!1,nr,void 0,{skipWaitForFresh:!0});if(c.hierarchy&&c.fresh)return{hierarchy:c.hierarchy,frameContext:c.frameContext};let R=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,nr);return R?{hierarchy:R.hierarchy,frameContext:R.frameContext}:null}async function AA(d){let c=await d.getLatestHierarchy(!1,nr,void 0,{skipWaitForFresh:!0});if(c.hierarchy&&c.fresh)return{hierarchy:c.hierarchy,frameContext:c.frameContext};let R=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,nr);return R?{hierarchy:R.hierarchy,frameContext:R.frameContext}:null}function PA(d){return{width:d.screenWidth??uA,height:d.screenHeight??mA}}function CA(d){let c=Zu(d);if(c)return{width:c.pixelWidth,height:c.pixelHeight};let R=d.screenScale??1;return{width:d.screenWidth?Math.round(d.screenWidth*R):fA,height:d.screenHeight?Math.round(d.screenHeight*R):gA}}var TA=1000,EA=20000,NA=60000;class kd{timer;maxConcurrency;getLiveFrameGeneration;getDeviceSessionUuid;captures=new Map;queue=[];recent;active=0;constructor(d=i,c=Dd,R=()=>0,D){this.timer=d;this.maxConcurrency=c;this.getLiveFrameGeneration=R;this.getDeviceSessionUuid=D;if(!Number.isInteger(c)||c<1)throw RangeError("Initial observation frame concurrency must be a positive integer");this.recent=new an(d,{ttlMs:TA,maxEntries:32})}request(d,c,R,D){if(D!==void 0){if(!Number.isInteger(D)||D<1)throw RangeError("Initial observation frame concurrency must be a positive integer");this.maxConcurrency=D}if(R.aborted)return Promise.resolve(void 0);let k=this.recent.get(d);if(k&&this.isFrameCurrent(d,k))return Promise.resolve({frame:k,replay:!0});this.recent.delete(d);let P=this.captures.get(d);if(!P)P={deviceId:d,run:c,started:!1,waiters:new Set},this.captures.set(d,P),this.queue.push(P);let C=P,M=C.started&&!this.isCaptureCurrent(C),F=new Promise((U,K)=>{let W=()=>{R.removeEventListener("abort",z),C.waiters.delete(V)},V={complete:(J)=>{W(),U(J)},fail:(J)=>{W(),K(J)}},z=()=>{if(V.complete(),!C.started&&C.waiters.size===0)this.captures.delete(d),this.queue.splice(this.queue.indexOf(C),1)};C.waiters.add(V),R.addEventListener("abort",z,{once:!0})});this.drain();let q=()=>this.request(d,c,R,D);return M?F.then(q,(U)=>(e.warn(`[Daemon] Superseded initial observation capture failed for ${d}: ${r(U)}`,U),q())):F}isCaptureCurrent(d){return d.liveFrameGeneration===this.getLiveFrameGeneration(d.deviceId)&&(!this.getDeviceSessionUuid||d.deviceSessionUuid===this.getDeviceSessionUuid(d.deviceId))}isFrameCurrent(d,c){return c.liveFrameGeneration===this.getLiveFrameGeneration(d)&&(!this.getDeviceSessionUuid||c.deviceSessionUuid===this.getDeviceSessionUuid(d))}drain(){while(this.active<this.maxConcurrency&&this.queue.length>0){let d=this.queue.shift();d.started=!0,this.active++,this.capture(d)}}acceptCapturedFrame(d,c,R,D){if(!c)return;if(c.liveFrameGeneration=R,D!==void 0)c.deviceSessionUuid=D;return this.isFrameCurrent(d,c)?c:void 0}async capture(d){let c=this.timer.now(),R=!0,D=!1,k=!1,P=!1,C,M=()=>{if(P)return;if(P=!0,C!==void 0)this.timer.clearTimeout(C),C=void 0;this.active--,this.drain()},F=()=>{if(R=!0,D)M()};try{let q=this.getLiveFrameGeneration(d.deviceId),U=this.getDeviceSessionUuid?.(d.deviceId);d.liveFrameGeneration=q,d.deviceSessionUuid=U;let K=d.run();R=!1,K.then(F,(z)=>{if(k&&!P)e.warn(`[Daemon] Initial observation capture rejected after its deadline for ${d.deviceId}: ${r(z)}`,z);F()});let W=await l(K,{timer:this.timer,timeoutMs:EA,label:`Initial observation frame for ${d.deviceId}`,onTimeout:()=>{k=!0,C=this.timer.setTimeout(()=>{if(!R&&!P)e.warn(`[Daemon] Initial observation capture slot backstop for ${d.deviceId} after ${this.timer.now()-c}ms; releasing its slot`),M()},Math.max(0,NA-(this.timer.now()-c)))}}),V=this.acceptCapturedFrame(d.deviceId,W,q,U);if(V?.screenshot&&d.waiters.size>0)this.recent.set(d.deviceId,V);for(let z of[...d.waiters])z.complete(V?{frame:V,replay:!1}:void 0)}catch(q){if(d.waiters.size===0)e.warn(`[Daemon] Initial observation capture failed for ${d.deviceId}: ${r(q)}`,q);for(let U of[...d.waiters])U.fail(q)}finally{if(this.captures.delete(d.deviceId),D=!0,R)M()}}}function Ad(d){return{deviceId:d.id,name:d.name,platform:d.platform,iosVersion:d.iosVersion}}function LA(d,c){return $c({hostRequestStartMs:d,readAndroidDeviceClockMs:async(R,D)=>(await v.create(Ad(R)).getDeviceTimestampMsWithSource(void 0,D)).timestampMs,observe:(R,{minTimestamp:D,signal:k})=>new xe(Ad(R)).execute({skipWaitForFresh:!1,minTimestamp:D,signal:k}),viewerRead:{applies:c,observe:(R,D)=>new xe(Ad(R),void 0,{deviceReadOnly:!0}).executeDeviceRead(D,"none")}})}function Vh(d,c,R){d.setOnSubscriberConnected((D,k)=>{e.info(`[Daemon] IDE plugin subscribed to observation stream (device: ${D??"all"}), ensuring WebSocket connections...`);let P=R.devicePool().getAllDevices(),C=qh(P,R.passiveWorkPolicy(),(M)=>bt(M.platform,M.id,"connect"));if(Uh(D,C,{streamServer:d,coordinator:c,subscriber:k,isDeviceAllowed:(M)=>{let F=R.devicePool().getAllDevices().find((q)=>q.id===M);return!!F&&R.passiveWorkPolicy().allows(F.platform,"observation-stream",M)},androidClientFactory:(M)=>E.getInstance(M,v),iosClientFactory:(M)=>zc(M,It)}).catch((M)=>{e.warn(`[Daemon] Error pushing initial observation frame: ${M}`)}),P.length===0)e.info("[Daemon] No devices in pool to connect")}),d.setOnScreenshotCadenceChanged((D)=>{let k=R.devicePool().getAllDevices().filter((P)=>D===null||P.id===D);for(let P of k)if(P.platform==="android"){if(!R.passiveWorkPolicy().allows("android","observation-stream",P.id)){bt("android",P.id,"screenshot cadence");continue}E.getExistingInstance(P.id)?.refreshObservationStreamScreenshotCadence()}else if(P.platform==="ios"){if(!R.passiveWorkPolicy().allows("ios","observation-stream",P.id)){bt("ios",P.id,"screenshot cadence");continue}x.getExistingInstance(P.id)?.refreshObservationStreamScreenshotCadence()}}),d.setOnHierarchyCadenceChanged((D)=>{let k=R.devicePool().getAllDevices().filter((P)=>D===null||P.id===D);for(let P of k)if(P.platform==="android"){if(!R.passiveWorkPolicy().allows("android","observation-stream",P.id)){bt("android",P.id,"hierarchy cadence");continue}E.getExistingInstance(P.id)?.refreshObservationStreamHierarchyCadence()}else if(P.platform==="ios"){if(!R.passiveWorkPolicy().allows("ios","observation-stream",P.id)){bt("ios",P.id,"hierarchy cadence");continue}let C=x.getExistingInstance(P.id);if(!C)continue;let M=d.getHierarchyIntervalMsForDevice(P.id);C.ensureConnected().then((F)=>{if(F)C.refreshObservationStreamHierarchyCadence(M)}).catch((F)=>{e.warn(`[Daemon] Failed to refresh iOS hierarchy cadence for ${P.id}: ${F}`)})}}),d.setOnStorageSubscriptionRequested((D)=>R.applyStorageSubscriptionRequest(D)),d.setOnObservationRequested(async({deviceId:D,sessionUuid:k,signal:P})=>{let C=_n("observationStream",{allowObserverSessions:!0}),M=D?[R.devicePool().getDevice(D)].filter((q)=>q!==null):R.devicePool().getAllDevices().filter((q)=>dr(q.platform));if(M.length===0)throw Error(D?`Device ${D} is not available`:"No devices are available");if(P.aborted)throw Error("Observation request was aborted");let F=R.timer().now();return Hc(M,LA(F,(q)=>Vc({sessionManager:R.sessionManager(),devicePool:R.devicePool()},q,k)),{timer:R.timer(),signal:P,assertDeviceActionable:(q)=>{R.devicePool().assertDeviceActionable(q.id,"to observe"),C.authorize({sessionUuid:k,deviceId:q.id,admitViewer:!0})}})},gr+Lc)}class Pd{host;initialFrameCoordinators=new WeakMap;constructor(d){this.host=d}onDeviceReadyForSessionRegistry(d){this.host.lifecycle.socketServer()?.evictDeviceInputCache(d);let c=this.host.services.devicePool().getDevice(d);if(!c||!dr(c.platform))return;if(c.platform==="ios")ve.getExistingInstance(d)?.rearmAfterDeviceReappearance().catch((D)=>{e.warn(`[Daemon] Failed to rearm iOS CtrlProxy for ${d}: ${r(D)}`)});if(c.platform==="android")E.noteDeviceOnline(d);this.host.services.deviceSessionRegistry().onDeviceConnected({deviceId:c.id,platform:c.platform,incarnation:c.incarnation})}getDeviceSessionRoutingTargets(){return{deviceDataStream:It(),performancePush:GD(),failuresPush:a2(),telemetryPush:_R()}}configureDeviceDataStreamServer(){this.setupDeviceSessionRouting(),this.host.setupDeviceDataStreamCallback()}setupDeviceSessionRouting(){let d=nie(this.host.services.deviceSessionRegistry(),this.host.services.devicePool()),{deviceDataStream:c,performancePush:R,failuresPush:D,telemetryPush:k}=this.host.getDeviceSessionRoutingTargets();if(this.host.lifecycle.setDeviceDataStreamServer(c),c?.setDeviceSessionResolver(d),R?.setDeviceSessionResolver(d),D?.setDeviceSessionResolver(d),k?.setDeviceSessionResolver(d),c)this.host.services.deviceSessionRegistry().setLifecycleListener({onSessionStarted:(P)=>c.pushDeviceSessionStarted(P),onSessionEnded:(P,C)=>c.pushDeviceSessionEnded(P,C)})}getInitialFrameCoordinator(d){let c=this.initialFrameCoordinators.get(d);if(!c)c=new kd(this.host.services.timer(),void 0,(R)=>d.getLiveFrameGeneration(R),(R)=>d.getDeviceSessionUuid(R)),this.initialFrameCoordinators.set(d,c);return c}setupDeviceDataStreamCallback(){let d=this.host.lifecycle.deviceDataStreamServer()??It();if(!d){e.warn("[Daemon] Observation stream server not available for callback setup");return}Vh(d,this.getInitialFrameCoordinator(d),{devicePool:()=>this.host.services.devicePool(),passiveWorkPolicy:()=>this.host.services.passiveWorkPolicy(),timer:()=>this.host.services.timer(),sessionManager:()=>this.host.services.sessionManager(),applyStorageSubscriptionRequest:(c)=>this.applyStorageSubscriptionRequest(c)}),e.info("[Daemon] Observation stream callback configured"),this.host.setupNavigationGraphStreamListener(d)}applyStorageSubscriptionRequest(d){return Jc({devicePool:this.host.services.devicePool()},d)}setupNavigationGraphStreamListener(d){this.host.lifecycle.navigationGraphBridge().listen(d)}get testHooks(){return{deviceDataStreamServer:()=>this.host.lifecycle.deviceDataStreamServer(),setupDeviceSessionRouting:()=>this.setupDeviceSessionRouting(),setupDeviceDataStreamCallback:()=>this.host.setupDeviceDataStreamCallback(),setupNavigationGraphStreamListener:(d)=>this.host.setupNavigationGraphStreamListener(d),applyStorageSubscriptionRequest:(d)=>this.applyStorageSubscriptionRequest(d)}}}class Id{timer;intervalMs;previousTick;constructor(d,c){this.timer=d;this.intervalMs=c;this.previousTick=this.readClock()}tick(){let d=this.readClock(),c=this.gap(this.previousTick,d,this.intervalMs);return this.previousTick=d,c}beginProbe(d){let c=this.readClock();return(R,D)=>{if(!(R instanceof Pe))return!1;let k=this.gap(c,this.readClock(),R.timeoutMs,R.startupMs??0),P=[d.lateMs,d.sleptMs,k.lateMs,k.sleptMs].some((C)=>C>kq);if(P)e.warn(`Database health probe timeout inconclusive: tick lateness=${d.lateMs}ms, probe overrun=${k.lateMs}ms, tick host sleep=${d.sleptMs}ms, probe host sleep=${k.sleptMs}ms, timeout=${R.timeoutMs}ms; strike count stays at ${D}`);return P}}readClock(){return{wall:this.timer.now(),monotonic:this.timer.monotonicNow?.()??this.timer.now()}}gap(d,c,R,D=0){return Eq({wallElapsedMs:Math.max(0,c.wall-d.wall-D),monotonicElapsedMs:Math.max(0,c.monotonic-d.monotonic-D),scheduledMs:R,monotonicIncludesHostSleep:this.timer.monotonicIncludesHostSleep,maxCredibleStallMs:OA})}}var Td=30000,$A=3,Jh=2*Td,Cd=10;function jh(d){let c=new Id(d.timer,Td),R=0,D="unknown",k=0,P=(V)=>{if(D!==V)R=0;D=V,R++},C=()=>{R=0,D="unknown"},M=()=>{let V=d.httpServer();if(!V)return e.warn("Health check failed: HTTP server not initialized"),P("http"),!1;if(!V.listening)return e.warn("Health check failed: HTTP server not listening"),P("http"),!1;if(!d.socketServerListening())return e.warn("Health check failed: Socket server not listening"),P("socket"),!1;if(!d.observationStreamHealthy()&&!ij("observation-stream"))return e.warn("Health check failed: Observation stream socket unavailable"),P("socket"),!1;return!0},F=(V,z)=>{if(!(V instanceof Pe)||!(z||(d.hostIoStalled?.()??!1)))return!1;if(k>=Cd){if(k===Cd)k++,e.error(`Host I/O stall excused ${Cd} consecutive database probe timeouts; counting further timeouts toward recovery`);return!1}return k++,e.warn(`Database health probe timeout inconclusive: host I/O stalled, timeout=${V.timeoutMs}ms; strike count stays at ${R}`),!0},q=async(V)=>{let z=c.beginProbe(V),J=d.hostIoStalled?.()??!1;try{await d.databaseHealthProbe().check(),d.onDatabaseFailureChanged(void 0),C(),k=0,e.debug("Health check passed")}catch(X){if(z(X,R))return!1;if(F(X,J))return!1;d.onDatabaseFailureChanged(r(X)),e.warn(`Health check failed: Database probe failed: ${X}`),P("database")}return!0},U=async()=>{try{if(!await d.onObservationStreamRestored())e.warn("Observation stream restored but daemon identity republish was declined")}catch(V){e.warn("Observation stream restored but daemon identity republish failed",V)}},K=async()=>{if(!ij("observation-stream")||d.observationStreamHealthy())return;try{await d.retryDegradedObservationStream()}catch(V){e.warn(`Observation stream bind retry failed; keeping daemon serving: ${r(V)}`,V);return}if(!ij("observation-stream")&&d.observationStreamHealthy())await U()},W=async()=>{let V=c.tick();try{if(M()){let z=await q(V);if(await K(),!z)return}if(R>=$A)e.error(`Health check failed ${R} times, attempting recovery...`),await d.recover(D),C()}catch(z){e.warn(`Health check error: ${z}`),P("unknown")}};return new Tl(d.timer,Td,W)}var zh={"missing-first-heartbeat":"never received first heartbeat","heartbeat-timeout":"heartbeat timeout","cli-idle-timeout":"idle past the CLI idle timeout","rehydration-owner-timeout":"awaiting reconnect past rehydration grace"};var HA=5000,qA=t0,UA=20000;function Yh(d,c){return Nf(d,c)}class Md{sessions;reap;intervalHandle=null;checkIntervalMs;graceMs;preFirstHeartbeatGraceMs;defaultHeartbeatTimeoutMs;stallThresholdMs;maxCredibleStallMs;bunVersionOverride;forceStuckRelease;clockSemanticsDisagreementReported=!1;executionVeto;lastScanSettledAt;lastScanSettledMonotonic;lastRawWallLeadMs;scanInFlight=!1;reapsInFlight=new Map;reapStartedAt=new Map;heartbeatsRefusedSince=new Map;timer;constructor(d,c,R,{timer:D=i,...k}={}){this.sessions=d;this.reap=R;this.timer=D,this.checkIntervalMs=k.checkIntervalMs??yD(),this.graceMs=k.graceMs??Yh(h.SESSION_HEARTBEAT_INITIAL_GRACE_MS.name,h.SESSION_HEARTBEAT_INITIAL_GRACE_MS.legacyName)??UA,this.preFirstHeartbeatGraceMs=k.preFirstHeartbeatGraceMs??LS(),this.defaultHeartbeatTimeoutMs=k.heartbeatTimeoutMs??Yh(h.SESSION_HEARTBEAT_TIMEOUT_MS.name,h.SESSION_HEARTBEAT_TIMEOUT_MS.legacyName)??cc(),this.stallThresholdMs=k.stallThresholdMs??kq,this.forceStuckRelease=k.forceStuckRelease,this.maxCredibleStallMs=k.maxCredibleStallMs??OA,this.bunVersionOverride=k.bunVersion,this.executionVeto=new YI(c,D,rv,()=>this.now())}start(){if(this.lastScanSettledAt===void 0)this.lastScanSettledAt=this.now(),this.lastScanSettledMonotonic=this.monotonicNow(),this.checkClockSemantics();if(this.sessions.setStallProbe?.(()=>this.forgiveStallIfLate()),this.intervalHandle)return;this.intervalHandle=this.timer.setInterval(()=>{try{Promise.allSettled(this.scan())}catch(d){e.warn(`Session heartbeat scan failed: ${r(d)}`,d)}},this.checkIntervalMs),this.intervalHandle.unref?.()}async stop(){if(this.sessions.setStallProbe?.(void 0),this.intervalHandle)this.timer.clearInterval(this.intervalHandle),this.intervalHandle=null;let d=[...this.reapsInFlight.values()];if(!(d.length===0||await l(Promise.allSettled(d).then(()=>!0),{timer:this.timer,timeoutMs:HA,label:"Heartbeat monitor release drain"}).catch((R)=>(e.debug(`Heartbeat monitor release drain did not finish: ${R}`),!1))))e.warn("Session heartbeat monitor did not settle before shutdown timeout")}async tick(){let c=(await Promise.allSettled(this.scan())).find((R)=>R.status==="rejected");if(c)throw c.reason}now(){return this.sessions.sessionNow?.()??this.timer.now()}monotonicNow(){return this.timer.monotonicNow?.()??this.timer.now()}sinceLastScan(d,c){if(this.lastScanSettledAt===void 0||this.lastScanSettledMonotonic===void 0)return;let R=Eq({wallElapsedMs:d-this.lastScanSettledAt,monotonicElapsedMs:c-this.lastScanSettledMonotonic,scheduledMs:this.checkIntervalMs,monotonicIncludesHostSleep:this.timer.monotonicIncludesHostSleep,maxCredibleStallMs:this.maxCredibleStallMs});return this.checkRawWallLead(c),R}checkRawWallLead(d){let c=this.timer.now()-d,R=c-(this.lastRawWallLeadMs??c);if(this.lastRawWallLeadMs=c,this.timer.monotonicIncludesHostSleep===!0&&R>this.stallThresholdMs)this.reportClockSemanticsDisagreement(R)}bunVersion(){return this.bunVersionOverride??process.versions.bun}checkClockSemantics(){if(this.timer.monotonicIncludesHostSleep===void 0)return;let d=L8(this.bunVersion());if(d)e.warn(`[SessionHeartbeatMonitor] ${d}`)}reportClockSemanticsDisagreement(d){if(this.clockSemanticsDisagreementReported)return;this.clockSemanticsDisagreementReported=!0,e.warn(`[SessionHeartbeatMonitor] The wall clock ran ${d}ms ahead of the monotonic clock, which pauses during host sleep here, but this platform is configured as running through it (Bun ${this.bunVersion()??"unknown"}, ${process.platform}); host sleep may be misjudged as a daemon stall. Update monotonicClockIncludesHostSleep (#10962).`)}forgiveOwnStall(){this.forgiveStallIfLate()}forgiveStallIfLate(){if(this.scanInFlight)return;let d=this.now(),c=this.monotonicNow(),R=this.sinceLastScan(d,c);if(R===void 0)return;let D=R.lateMs>this.stallThresholdMs?R.lateMs:0,k=R.sleptMs>this.stallThresholdMs?R.sleptMs:0;if(D===0&&k===0)return;let P=this.lastScanSettledAt??d;this.lastScanSettledAt=d-this.checkIntervalMs,this.lastScanSettledMonotonic=c-this.checkIntervalMs;let C=this.sessions.forgiveDaemonStall?.(d,D,k,P)??0;e.warn(`Heartbeat monitor tick fired ${D}ms late after the host slept ${k}ms; ${C} session(s) considered for stall forgiveness (host sleep counts toward idle); lease and idle extension counts are logged by the session manager`)}scan(){this.forgiveOwnStall(),this.scanInFlight=!0;try{return this.sessions.cleanupExpiredSessions(),this.forceStuckReleases(),this.reapStaleSessions()}finally{if(this.scanInFlight=!1,this.lastScanSettledAt!==void 0&&this.lastScanSettledMonotonic!==void 0)this.lastScanSettledAt=Math.max(this.lastScanSettledAt,this.now()),this.lastScanSettledMonotonic=Math.max(this.lastScanSettledMonotonic,this.monotonicNow())}}reapStaleSessions(){let d=[];for(let c of this.sessions.getAllSessions()){if(this.reapsInFlight.has(c.sessionId))continue;let R=Math.min(this.now(),this.heartbeatsRefusedSince.get(c)??1/0),D=c.ownership==="awaiting-owner"?this.rehydrationOwnerStaleReason(c,R):this.staleReason(c,R);if(!D){this.executionVeto.forget(c);continue}if(this.isVetoedByActiveExecution(c,D))continue;e.warn(`Session ${c.sessionId} ${zh[D]}, cancelling (reason=${D})`+(D==="heartbeat-timeout"?`; last heartbeat age=${R-(this.sessions.judgedLeaseHeartbeat?.(c)??ev(c))}ms, heartbeat timeout=${c.heartbeatTimeoutMs??this.defaultHeartbeatTimeoutMs}ms`:""));try{d.push(this.trackReap(c.sessionId,this.reap(c.sessionId,D)))}catch(k){e.warn(`Failed to reap stale session ${c.sessionId}`,k),d.push(Promise.reject(k))}}return d}trackReap(d,c){let R=c.catch((C)=>{throw e.warn(`Failed to reap stale session ${d}`,C),C}),D=R.then(()=>{return},()=>{return});this.reapsInFlight.set(d,D);let k=this.reapStartedAt.get(d),P=k?.sourceRelease&&this.sessions.isReleaseInProgress?.(d,k.at)===!0?{...k}:{at:this.now(),reported:!1};return this.reapStartedAt.set(d,P),D.then(()=>{if(this.reapsInFlight.get(d)===D)this.reapsInFlight.delete(d);if(this.reapStartedAt.get(d)===P)this.reapStartedAt.delete(d)}),R}forceStuckReleases(){this.trackSourceReleases();for(let d of this.reapStartedAt.keys())this.reportIfStuck(d)}trackSourceReleases(){let d=this.sessions.getNonTerminalReleasesInProgress?.()??[];this.heartbeatsRefusedSince=new Map(d.map((D)=>[D.session,D.startedAtMs]));let c=[d,this.sessions.getIdleReleasesInProgress?.(),this.sessions.getTerminalReleasesInProgress?.()].flatMap((D)=>D??[]),R=new Map(c.map((D)=>[D.sessionId,D.startedAtMs]));for(let[D,k]of this.reapStartedAt)if(k.sourceRelease&&R.get(D)!==k.at&&this.sessions.isReleaseInProgress?.(D,k.at)!==!0)this.reapStartedAt.delete(D);for(let[D,k]of R)if(!this.reapStartedAt.has(D))this.reapStartedAt.set(D,{at:k,reported:!1,sourceRelease:!0})}reportIfStuck(d){let c=this.reapStartedAt.get(d);if(!c||c.reported)return;let R=this.now(),D=R-c.at;if(R<(this.sessions.getReleaseStuckAtMs?.(d)??c.at+qA))return;if(c.reported=!0,!this.forceStuckRelease){e.warn(`Session ${d} release has not settled after ${D}ms; its device stays held until the teardown finishes. Other sessions are still judged on schedule.`);return}e.warn(`Session ${d} release has not settled after ${D}ms; forcing its device back to the pool while the session stays fenced (#10963).`),this.forceStuckRelease(d).catch((k)=>{e.warn(`Forcing the stuck release of session ${d} failed: ${r(k)}`,k)})}isVetoedByActiveExecution(d,c){let R=this.executionVeto.judge(d);if(R.kind!=="expired")return R.kind==="kept";return e.warn(`Session ${d.sessionId} (${zh[c]}) was kept for ${R.vetoedMs}ms by executions that never settled; releasing it anyway past their ${R.bound} bound (reason=${c})`),!1}staleReason(d,c){if(d.livenessPolicy==="cli-idle")return c>mh(d)?"cli-idle-timeout":void 0;return this.heartbeatLeaseStaleReason(d,c)}heartbeatLeaseStaleReason(d,c){let R=d.heartbeatTimeoutMs??this.defaultHeartbeatTimeoutMs,D=ev(d),k=this.sessions.judgedLeaseHeartbeat?.(d)??D;if(!d.hasReceivedHeartbeat&&k===D){if(d.heartbeatTimeoutSource==="default")return c-k>this.preFirstHeartbeatGraceMs?"missing-first-heartbeat":void 0;if(c-d.createdAt<this.graceMs)return}return bq(c,k,R,tv(d))?"heartbeat-timeout":void 0}rehydrationOwnerStaleReason(d,c){if(d.ownership!=="awaiting-owner")return;let R=d.recoveredFromUncleanDaemonExit?Math.min(d.heartbeatTimeoutMs,this.defaultHeartbeatTimeoutMs):d.heartbeatTimeoutMs,D=d.awaitingOwnerSince??c;return c-D>R+ps?"rehydration-owner-timeout":void 0}}var KA=15000;class Ed{port;idleMs;timer;lastBusyAt=new Map;interval;constructor(d,c,R=i,D=Math.min(Math.max(1,Math.floor(c/4)),KA)){this.port=d;this.idleMs=c;this.timer=R;this.interval=new Tl(R,D,async()=>{await this.sweep()})}start(){this.interval.start()}async stop(){await this.interval.stop()}async sweep(){let d=this.timer.now(),c=new Set(this.port.heldDeviceIds());for(let k of[...this.lastBusyAt.keys()])if(!c.has(k))this.lastBusyAt.delete(k);let R=[...c].filter((k)=>this.isIdle(k,d)),D=[];for(let k of R){if(!this.isIdle(k,this.timer.now()))continue;try{e.info(`[CTRL_PROXY] Releasing idle CtrlProxy forwarding lease for ${k} (no session or tool activity for ${this.idleMs}ms)`),this.lastBusyAt.delete(k),await this.port.release(k),D.push(k)}catch(P){e.warn(`[CTRL_PROXY] Failed to release idle forwarding lease for ${k}: ${r(P)}`,P)}}return D}isIdle(d,c){let R=this.port.activity(d);if(CZ(R))return this.lastBusyAt.set(d,c),!1;let D=this.lastBusyAt.get(d);if(D===void 0)return this.lastBusyAt.set(d,c),!1;let k=R.idleForMs??Number.POSITIVE_INFINITY;return Math.min(c-D,k)>=this.idleMs}}var GA=900000,WA=30000,VA=1;function Qh(d=process.env){return ep(h.PRIVATE_DAEMON_ORPHAN_IDLE_MS,d)??GA}var JA=h.DAEMON_LAUNCHER_PID.name;function Zh(d,c=process.env){let R=c[JA]?.trim()??"",D=jb(R);return D!==void 0&&D>1?D:d}var jA=h.HARNESS_PRIVATE_DAEMON.name;function eg(d,c,R=process.env){let D=R[jA]?.trim();if(D==="1"||D==="0")return D==="1";return Xh(R,[h.DAEMON_SOCKET_PATH.name,h.DAEMON_SOCKET_PATH.legacyName])!==""&&d!==c&&Xh(R,[h.AUX_SOCKET_DIR.name])!==""}function Xh(d,c){return c.map((R)=>d[R]?.trim()??"").find((R)=>R!=="")??""}class Bd{orphanIdleSince=null;lastClientActivityCount=null;handle=null;shutdownRequested=!1;launcherToken;port;idleMs;timer;checkIntervalMs;launcherGeneration;constructor(d,c,R=i,{checkIntervalMs:D=Math.min(WA,c),launcherGeneration:k=kt}={}){this.port=d,this.idleMs=c,this.timer=R,this.checkIntervalMs=D,this.launcherGeneration=k}start(){if(this.handle||this.idleMs<=0)return;this.launcherToken=this.port.launcherIsExplicit()?this.launcherGeneration.current(this.port.launcherPid()):void 0,this.handle=this.timer.setInterval(()=>this.check(),this.checkIntervalMs);let d=this.handle;if(typeof d.unref==="function")d.unref()}stop(){if(this.handle)this.timer.clearInterval(this.handle),this.handle=null}isOrphaned(){let d=this.port.parentPid();if(d===VA)return!0;let c=this.port.launcherPid();return this.port.launcherIsExplicit()?!this.port.isProcessRunning(c)||this.launcherToken!==void 0&&this.launcherGeneration.compare(c,this.launcherToken)==="different":d!==c}check(){if(this.shutdownRequested)return!1;let d=this.port.clientActivityCount(),c=this.lastClientActivityCount!==null&&d!==this.lastClientActivityCount;this.lastClientActivityCount=d;let R=this.isOrphaned()&&!c&&this.port.clientCount()===0&&this.port.liveSessionCount()===0,D=this.timer.now();if(!R)return this.orphanIdleSince=null,!1;if(this.orphanIdleSince??=D,D-this.orphanIdleSince<this.idleMs)return!1;this.shutdownRequested=!0,this.stop();let k=`private daemon's parent exited and it has had no clients or sessions for ${Math.round((D-this.orphanIdleSince)/1000)}s`;return e.warn(`[Daemon] Shutting down orphaned private daemon: ${k}`),this.port.shutdown(k),!0}}var tg=86400000,ig=7*tg,ng=90*tg,rg=50000,og=500000,sg=5000,zA=20,ag=21600000,dg=1e4,Od=2147483647;function cg(d){return{screenshotsCleared:0,nodeObservationsDeleted:0,edgeObservationsDeleted:0,suggestionObservationsDeleted:0,buildKeysDeleted:0,edgeTraversalsDeleted:0,prunedAt:d}}function rr(d,c=Number.MAX_SAFE_INTEGER){if(d===void 0)return;return Number.isSafeInteger(d)&&d>0&&d<=c?d:void 0}function lg(d,c=Number.MAX_SAFE_INTEGER){return rr(Nf(d.name,d.legacyName),c)}function xd(d={}){let c=(R,D,k,P=Number.MAX_SAFE_INTEGER)=>rr(R,P)??lg(D,P)??k;return{screenshotTtlMs:c(d.screenshotTtlMs,h.NAV_RETENTION_SCREENSHOT_TTL_MS,ig),structureTtlMs:c(d.structureTtlMs,h.NAV_RETENTION_STRUCTURE_TTL_MS,ng),perAppMaxObservations:c(d.perAppMaxObservations,h.NAV_RETENTION_PER_APP_MAX_OBSERVATIONS,rg),globalMaxObservations:c(d.globalMaxObservations,h.NAV_RETENTION_GLOBAL_MAX_OBSERVATIONS,og),evictionChunkSize:Math.min(c(d.evictionChunkSize,h.NAV_RETENTION_EVICTION_CHUNK_SIZE,sg),dg),maxEdgeTraversalsPerTransition:rr(d.maxEdgeTraversalsPerTransition)??zA}}function Fd(d){return rr(d,Od)??lg(h.NAV_RETENTION_INTERVAL_MS,Od)??ag}async function or(d,c){let R=d.selectFrom("navigation_build_keys").select(["id","app_id"]);if(c&&c.length>0)R=R.where("app_id","in",c);return(await R.execute()).map((k)=>({id:k.id,appId:k.app_id}))}async function Nd(d,c,R){let D=c??await or(d,R);if(D.length===0)return[];let k=await ZA(d,R),P=new Map;for(let C of D){let M=k.get(C.id)??Number.NEGATIVE_INFINITY;if(QA(P.get(C.appId),C.id,M))P.set(C.appId,{id:C.id,seen:M})}return Array.from(P.values(),(C)=>C.id)}function QA(d,c,R){if(d===void 0)return!0;return R>d.seen||R===d.seen&&c>d.id}function Ii(d,c){if(d.length!==c.length)return!1;let R=new Set(c);return d.every((D)=>R.has(D))}async function ZA(d,c){let R=d.selectFrom("navigation_node_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((q)=>["observation.build_key_id",q.fn.max("observation.last_seen_at").as("max_seen")]),D=d.selectFrom("navigation_edge_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((q)=>["observation.build_key_id",q.fn.max("observation.last_seen_at").as("max_seen")]),k=d.selectFrom("navigation_suggestion_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((q)=>["observation.build_key_id",q.fn.max("observation.last_seen_at").as("max_seen")]);if(c&&c.length>0)R=R.where("buildKey.app_id","in",c),D=D.where("buildKey.app_id","in",c),k=k.where("buildKey.app_id","in",c);let P=await R.groupBy("observation.build_key_id").execute(),C=await D.groupBy("observation.build_key_id").execute(),M=await k.groupBy("observation.build_key_id").execute(),F=new Map;for(let q of[...P,...C,...M]){let U=Number(q.max_seen??0),K=F.get(q.build_key_id);if(K===void 0||U>K)F.set(q.build_key_id,U)}return F}async function Ld(d,c){if(c.length===0)return new Map;let R=Array.from(new Set(c));return iP(d,R)}async function iP(d,c){let R=await d.selectFrom("navigation_node_observations").select((C)=>["build_key_id",C.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),D=await d.selectFrom("navigation_edge_observations").select((C)=>["build_key_id",C.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),k=await d.selectFrom("navigation_suggestion_observations").select((C)=>["build_key_id",C.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),P=new Map;for(let C of[...R,...D,...k]){let M=Number(C.max_seen??0),F=P.get(C.build_key_id);if(F===void 0||M>F)P.set(C.build_key_id,M)}return P}async function ug(d,c,R){if(c.length===0||R.length===0)return[];return(await d.selectFrom("navigation_node_observations").select("node_id").where("node_id","in",c).where("build_key_id","in",R).execute()).map((k)=>k.node_id)}async function sr(d,c){return c===null?nP(d):rP(d,c)}async function nP(d){let c=await d.selectNoFrom(f`(SELECT COUNT(*) FROM navigation_node_observations)
44
+ + (SELECT COUNT(*) FROM navigation_edge_observations)
45
+ + (SELECT COUNT(*) FROM navigation_suggestion_observations)`.as("c")).executeTakeFirstOrThrow();return Number(c.c)}async function rP(d,c){let R=await d.selectNoFrom(f`(SELECT COUNT(*) FROM navigation_node_observations AS o
46
+ JOIN navigation_build_keys AS bk ON bk.id = o.build_key_id WHERE bk.app_id = ${c})
47
+ + (SELECT COUNT(*) FROM navigation_edge_observations AS o
48
+ JOIN navigation_build_keys AS bk ON bk.id = o.build_key_id WHERE bk.app_id = ${c})
49
+ + (SELECT COUNT(*) FROM navigation_suggestion_observations AS o
50
+ JOIN navigation_build_keys AS bk ON bk.id = o.build_key_id WHERE bk.app_id = ${c})`.as("c")).executeTakeFirstOrThrow();return Number(R.c)}async function pg(d,c,R,D){let k=await mg(d,c,R,D).execute(),P=await fg(d,c,R,D).execute(),C=await oP(d,c,R,D).execute(),M=[...k.map((q)=>({kind:"node",id:q.id,buildKeyId:q.build_key_id,lastSeenAt:q.last_seen_at})),...P.map((q)=>({kind:"edge",id:q.id,buildKeyId:q.build_key_id,lastSeenAt:q.last_seen_at})),...C.map((q)=>({kind:"suggestion",id:q.id,buildKeyId:q.build_key_id,lastSeenAt:q.last_seen_at}))],F={node:0,edge:1,suggestion:2};return M.sort((q,U)=>q.lastSeenAt-U.lastSeenAt||F[q.kind]-F[U.kind]||q.id-U.id),M.slice(0,D)}function mg(d,c,R,D){let k=d.selectFrom("navigation_node_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)k=k.where("build_key_id","in",(P)=>P.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(R.length>0)k=k.where((P)=>P.or([P("build_key_id","not in",R),P("last_seen_at","<>",P.selectFrom("navigation_node_observations as t").select((C)=>C.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_node_observations.build_key_id"))]));return k.orderBy("last_seen_at","asc").orderBy("id","asc").limit(D)}function fg(d,c,R,D){let k=d.selectFrom("navigation_edge_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)k=k.where("build_key_id","in",(P)=>P.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(R.length>0)k=k.where((P)=>P.or([P("build_key_id","not in",R),P("last_seen_at","<>",P.selectFrom("navigation_edge_observations as t").select((C)=>C.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_edge_observations.build_key_id"))]));return k.orderBy("last_seen_at","asc").orderBy("id","asc").limit(D)}function oP(d,c,R,D){let k=d.selectFrom("navigation_suggestion_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)k=k.where("build_key_id","in",(P)=>P.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(R.length>0)k=k.where((P)=>P.or([P("build_key_id","not in",R),P("last_seen_at","<>",P.selectFrom("navigation_suggestion_observations as t").select((C)=>C.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_suggestion_observations.build_key_id"))]));return k.orderBy("last_seen_at","asc").orderBy("id","asc").limit(D)}var sP=()=>new Promise((d)=>setImmediate(d)),aP=3;class $d{db;config;removeScreenshotFile;logger;yieldBetweenBatches;resolveProtectedBuildKeyIds;constructor(d,c={},R={}){this.db=d;this.config=xd(c),this.removeScreenshotFile=R.removeScreenshotFile,this.logger=R.logger??e,this.yieldBetweenBatches=R.yieldBetweenBatches??sP,this.resolveProtectedBuildKeyIds=R.resolveProtectedBuildKeyIds??Nd}async prune(d){let c=cg(d);return await this.pruneScreenshots(d,c),await this.pruneExcessEdgeTraversals(c),await this.pruneObservationsByTtl(d,c),await this.enforceCaps(c),await this.pruneOrphanBuildKeys(c),c}async removeFiles(d){if(!this.removeScreenshotFile)return;for(let c of d)try{await this.removeScreenshotFile(c)}catch(R){this.logger.debug(`nav retention: failed to unlink screenshot ${c}: ${R}`)}}async retryAfterProtectionChange(d,c){if(c>=aP)return this.logger.debug(`nav retention: ${d} protection kept changing; defer remaining rows`),!1;return await this.yieldBetweenBatches(),!0}async revalidateEmptyProtection(d,c,R){let D=await this.resolveProtectedBuildKeyIds(this.db),k=!Ii(D,d);return{ids:D,retry:k&&await this.retryAfterProtectionChange(c,R)}}async refreshChangedProtection(d,c){return c?this.resolveProtectedBuildKeyIds(this.db):d}async pruneScreenshots(d,c){let R=d-this.config.screenshotTtlMs,D=this.config.evictionChunkSize,k=await this.resolveProtectedBuildKeyIds(this.db),P=0;for(;;){let C=await this.db.transaction().execute(async(F)=>{let q=F.selectFrom("navigation_nodes").select(["id","app_id","screenshot_path"]).where("screenshot_path","is not",null).where("last_seen_at","<",R);if(k.length>0)q=q.where("id","not in",(ie)=>ie.selectFrom("navigation_node_observations").select("node_id").where("build_key_id","in",k));let U=await q.limit(D).execute();if(U.length===0)return null;let K=Array.from(new Set(U.map((ie)=>ie.app_id))),W=await this.resolveProtectedBuildKeyIds(F,void 0,K),V=await ug(F,U.map((ie)=>ie.id),W),z=new Set(V),J=U.filter((ie)=>!z.has(ie.id)),X=W.some((ie)=>!k.includes(ie));if(J.length===0)return{clearedCount:0,clearedPaths:[],isFullBatch:U.length===D,activeBuildChanged:X};let te=J.map((ie)=>ie.id);await F.updateTable("navigation_nodes").set({screenshot_path:null}).where("id","in",te).execute();let re=[];for(let ie of J)if(ie.screenshot_path!==null)re.push(ie.screenshot_path);return{clearedCount:te.length,clearedPaths:re,isFullBatch:U.length===D,activeBuildChanged:X}});if(C===null){let F=await this.revalidateEmptyProtection(k,"screenshots",++P);if(k=F.ids,F.retry)continue;break}if(c.screenshotsCleared+=C.clearedCount,C.clearedCount>0)P=0;if(await this.removeFiles(C.clearedPaths),C.activeBuildChanged)k=await this.resolveProtectedBuildKeyIds(this.db);let M=C.clearedCount===0&&C.activeBuildChanged;if(M&&await this.retryAfterProtectionChange("screenshots",++P))continue;if(M)break;if(!C.isFullBatch||C.clearedCount===0)break;await this.yieldBetweenBatches()}}async pruneExcessEdgeTraversals(d){let c=this.config.maxEdgeTraversalsPerTransition,R=this.config.evictionChunkSize,D=await this.db.selectFrom("navigation_edges").select(["app_id","from_screen","to_screen","tool_name","tool_args"]).groupBy(["app_id","from_screen","to_screen","tool_name","tool_args"]).having((k)=>k.fn.countAll(),">",c).execute();for(let k of D){for(;;){let P=await this.db.transaction().execute((M)=>M.deleteFrom("navigation_edges").where("id","in",(F)=>F.selectFrom("navigation_edges as e").select("e.id").where("e.app_id","=",k.app_id).where("e.from_screen","=",k.from_screen).where("e.to_screen","=",k.to_screen).where(f`e.tool_name is ${k.tool_name}`).where(f`e.tool_args is ${k.tool_args}`).where(f`not exists (select 1 from test_edge_coverage c where c.edge_id = e.id)`).orderBy("e.id","desc").limit(R).offset(c)).executeTakeFirst()),C=Number(P.numDeletedRows??0);if(d.edgeTraversalsDeleted+=C,C<R)break;await this.yieldBetweenBatches()}await this.yieldBetweenBatches()}}async pruneObservationsByTtl(d,c){let R=d-this.config.structureTtlMs;c.nodeObservationsDeleted+=await this.pruneNodeObservationsByTtl(R),c.edgeObservationsDeleted+=await this.pruneEdgeObservationsByTtl(R),c.suggestionObservationsDeleted+=await this.pruneSuggestionObservationsByTtl(R)}async pruneNodeObservationsByTtl(d){let c=0,R=0,D=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let k=await this.db.transaction().execute(async(C)=>{let M=C.selectFrom("navigation_node_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select(["observation.id","observation.build_key_id","buildKey.app_id"]).where("observation.last_seen_at","<",d);if(D.length>0)M=M.where("observation.build_key_id","not in",D);let F=await M.limit(this.config.evictionChunkSize).execute();if(F.length===0)return null;let q=Array.from(new Set(F.map((J)=>J.app_id))),U=await this.resolveProtectedBuildKeyIds(C,void 0,q),K=new Set(U),W=F.filter((J)=>!K.has(J.build_key_id)).map((J)=>J.id),V=U.some((J)=>!D.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V};let z=await C.deleteFrom("navigation_node_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(z.numDeletedRows??0),isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V}});if(k===null){let C=await this.revalidateEmptyProtection(D,"node TTL",++R);if(D=C.ids,C.retry)continue;return c}if(c+=k.deletedCount,k.deletedCount>0)R=0;D=await this.refreshChangedProtection(D,k.protectionChanged);let P=k.protectionChanged&&k.deletedCount===0;if(P&&await this.retryAfterProtectionChange("node TTL",++R))continue;if(P)return c;if(!k.isFullBatch&&!k.protectionChanged||k.deletedCount===0)return c;await this.yieldBetweenBatches()}}async pruneEdgeObservationsByTtl(d){let c=0,R=0,D=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let k=await this.db.transaction().execute(async(C)=>{let M=C.selectFrom("navigation_edge_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select(["observation.id","observation.build_key_id","buildKey.app_id"]).where("observation.last_seen_at","<",d);if(D.length>0)M=M.where("observation.build_key_id","not in",D);let F=await M.limit(this.config.evictionChunkSize).execute();if(F.length===0)return null;let q=Array.from(new Set(F.map((J)=>J.app_id))),U=await this.resolveProtectedBuildKeyIds(C,void 0,q),K=new Set(U),W=F.filter((J)=>!K.has(J.build_key_id)).map((J)=>J.id),V=U.some((J)=>!D.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V};let z=await C.deleteFrom("navigation_edge_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(z.numDeletedRows??0),isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V}});if(k===null){let C=await this.revalidateEmptyProtection(D,"edge TTL",++R);if(D=C.ids,C.retry)continue;return c}if(c+=k.deletedCount,k.deletedCount>0)R=0;D=await this.refreshChangedProtection(D,k.protectionChanged);let P=k.protectionChanged&&k.deletedCount===0;if(P&&await this.retryAfterProtectionChange("edge TTL",++R))continue;if(P)return c;if(!k.isFullBatch&&!k.protectionChanged||k.deletedCount===0)return c;await this.yieldBetweenBatches()}}async pruneSuggestionObservationsByTtl(d){let c=0,R=0,D=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let k=await this.db.transaction().execute(async(C)=>{let M=C.selectFrom("navigation_suggestion_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select(["observation.id","observation.build_key_id","buildKey.app_id"]).where("observation.last_seen_at","<",d);if(D.length>0)M=M.where("observation.build_key_id","not in",D);let F=await M.limit(this.config.evictionChunkSize).execute();if(F.length===0)return null;let q=Array.from(new Set(F.map((J)=>J.app_id))),U=await this.resolveProtectedBuildKeyIds(C,void 0,q),K=new Set(U),W=F.filter((J)=>!K.has(J.build_key_id)).map((J)=>J.id),V=U.some((J)=>!D.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V};let z=await C.deleteFrom("navigation_suggestion_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(z.numDeletedRows??0),isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V}});if(k===null){let C=await this.revalidateEmptyProtection(D,"suggestion TTL",++R);if(D=C.ids,C.retry)continue;return c}if(c+=k.deletedCount,k.deletedCount>0)R=0;D=await this.refreshChangedProtection(D,k.protectionChanged);let P=k.protectionChanged&&k.deletedCount===0;if(P&&await this.retryAfterProtectionChange("suggestion TTL",++R))continue;if(P)return c;if(!k.isFullBatch&&!k.protectionChanged||k.deletedCount===0)return c;await this.yieldBetweenBatches()}}async enforceCaps(d){let c=await or(this.db),R=Array.from(new Set(c.map((P)=>P.appId)));for(let P of R){let M=await sr(this.db,P)-this.config.perAppMaxObservations;if(M>0)await this.evictOldest(P,M,this.config.perAppMaxObservations,d);await this.yieldBetweenBatches()}let k=await sr(this.db,null)-this.config.globalMaxObservations;if(k>0)await this.evictOldest(null,k,this.config.globalMaxObservations,d)}async evictOldest(d,c,R,D){let k=c,P=0,C=!1,M=d===null?void 0:[d],F=await this.resolveProtectedBuildKeyIds(this.db,void 0,M);while(k>0){if(C){if(k=Math.max(0,await sr(this.db,d)-R),C=!1,k===0)return}let q=Math.min(k,this.config.evictionChunkSize),U=await this.db.transaction().execute(async(K)=>{let W=await pg(K,d,F,q);if(W.length===0){let oe=await this.resolveProtectedBuildKeyIds(K,void 0,M);return{evictedCount:0,protectionChanged:!Ii(oe,F)}}let V=await this.resolveProtectedBuildKeyIds(K,void 0,M);if(!Ii(V,F))return{evictedCount:0,protectionChanged:!0};let z=await Ld(K,W.map((oe)=>oe.buildKeyId)),J=new Set(V),X=W.filter((oe)=>!J.has(oe.buildKeyId)||oe.lastSeenAt<(z.get(oe.buildKeyId)??Number.NEGATIVE_INFINITY));if(X.length===0)return{evictedCount:0,protectionChanged:!1};let te=X.filter((oe)=>oe.kind==="node").map((oe)=>oe.id),re=X.filter((oe)=>oe.kind==="edge").map((oe)=>oe.id),ie=X.filter((oe)=>oe.kind==="suggestion").map((oe)=>oe.id);if(te.length>0){let oe=await K.deleteFrom("navigation_node_observations").where("id","in",te).executeTakeFirst();D.nodeObservationsDeleted+=Number(oe.numDeletedRows??0)}if(re.length>0){let oe=await K.deleteFrom("navigation_edge_observations").where("id","in",re).executeTakeFirst();D.edgeObservationsDeleted+=Number(oe.numDeletedRows??0)}if(ie.length>0){let oe=await K.deleteFrom("navigation_suggestion_observations").where("id","in",ie).executeTakeFirst();D.suggestionObservationsDeleted+=Number(oe.numDeletedRows??0)}return{evictedCount:X.length,protectionChanged:!1}});if(U.evictedCount===0){if(U.protectionChanged)F=await this.resolveProtectedBuildKeyIds(this.db,void 0,M);if(U.protectionChanged&&await this.retryAfterProtectionChange("cap eviction",++P)){C=!0;continue}return}if(P=0,k-=U.evictedCount,k>0)await this.yieldBetweenBatches(),C=!0}}async pruneOrphanBuildKeys(d){let c=this.config.evictionChunkSize,R=async(P)=>{let C=await or(P),M=await this.resolveProtectedBuildKeyIds(P,C),F=new Map(C.map((U)=>[U.id,U.appId])),q=new Map(M.map((U)=>[F.get(U),U]));return{ids:M,byApp:q}},D=await R(this.db),k=0;for(;;){let P=await this.db.transaction().execute(async(M)=>{let F=M.selectFrom("navigation_build_keys").select(["id","app_id"]).where("id","not in",(X)=>X.selectFrom("navigation_node_observations").select("build_key_id")).where("id","not in",(X)=>X.selectFrom("navigation_edge_observations").select("build_key_id")).where("id","not in",(X)=>X.selectFrom("navigation_suggestion_observations").select("build_key_id"));if(D.ids.length>0)F=F.where("id","not in",D.ids);let q=await F.limit(c).execute();if(q.length===0)return{deleted:0,protectionChanged:!1};if(q.some((X)=>!D.byApp.has(X.app_id)))return{deleted:0,protectionChanged:!0,currentProtection:await R(M)};let U=Array.from(new Set(q.map((X)=>D.byApp.get(X.app_id)).filter((X)=>X!==void 0))),K=await M.selectFrom("navigation_build_keys").select("id").where("id","in",U).execute(),W=new Set(K.map((X)=>X.id));if(U.some((X)=>!W.has(X)))return{deleted:0,protectionChanged:!0};let V=Array.from(new Set(q.filter((X)=>X.id>(D.byApp.get(X.app_id)??0)).map((X)=>D.byApp.get(X.app_id)).filter((X)=>X!==void 0))),z=await Ld(M,V);if(V.some((X)=>!z.has(X)))return{deleted:0,protectionChanged:!0};let J=await M.deleteFrom("navigation_build_keys").where("id","in",q.map((X)=>X.id)).executeTakeFirst();return{deleted:Number(J.numDeletedRows??0),protectionChanged:!1}});if(d.buildKeysDeleted+=P.deleted,P.deleted>0)k=0;let C=P.protectionChanged;if(C||P.deleted===0){let M=P.currentProtection??await R(this.db);C||=!Ii(M.ids,D.ids),D=M}if(C&&await this.retryAfterProtectionChange("orphan sweep",++k))continue;if(C)return;if(P.deleted<c)return;await this.yieldBetweenBatches()}}}class Hd{retention;timer;timerHandle=null;running=!1;intervalMs;lastSummary=null;constructor(d,c=i,R){this.retention=d;this.timer=c;this.intervalMs=Fd(R)}start(){if(this.timerHandle)return;this.timerHandle=this.timer.setInterval(()=>{this.tick()},this.intervalMs);let d=this.timerHandle;if(d&&typeof d.unref==="function")d.unref()}stop(){if(this.timerHandle)this.timer.clearInterval(this.timerHandle),this.timerHandle=null}getLastSummary(){return this.lastSummary}async tick(){if(this.running)return;this.running=!0;try{let d=await Jt().track(()=>this.retention.prune(this.timer.now()));if(d)this.lastSummary=d}catch(d){e.warn(`Navigation retention pass failed: ${d}`,d)}finally{this.running=!1}}}class Ud{host;constructor(d){this.host=d}startHealthCheckTimer(){this.host.setHealthCheck(jh({timer:this.host.services.timer(),httpServer:()=>this.host.services.httpIngress().server,socketServerListening:()=>this.host.lifecycle.socketServer()?.isListening()??!1,observationStreamHealthy:()=>this.host.observationStreamHealth().isHealthy(),retryDegradedObservationStream:()=>this.host.observationStreamHealth().recover(),onObservationStreamRestored:()=>this.host.republishIdentity(),databaseHealthProbe:()=>this.host.services.databaseHealthProbe(),onDatabaseFailureChanged:(d)=>{this.host.setLastDatabaseHealthFailure(d)},recover:(d)=>this.host.attemptRecovery(d),hostIoStalled:this.host.hostIoStalled?.()??(()=>V8(Jh))})),this.host.healthCheck().start()}async stopHealthCheckTimer(){let d=this.host.healthCheck();this.host.setHealthCheck(null),await d?.stop()}startHeartbeatMonitor(){this.host.services.sessionManager().startRehydratedOwnerWindows(),this.host.lifecycle.setHeartbeatMonitor(new Md(this.host.services.sessionManager(),this.host.sessionExecutionProbe({excludeReads:!0}),async(d,c)=>{await this.host.cancelAndReleaseSession(d,c,{cutCallsLearnRelease:!0})},{timer:this.host.services.timer(),forceStuckRelease:(d)=>uq(this.host.services.sessionManager(),this.host.services.devicePool(),d)})),this.host.lifecycle.heartbeatMonitor().start()}startNavigationRetentionMonitor(){let d=new Pr,c=new $d(_e(),{},{removeScreenshotFile:(R)=>d.unlink(R)});this.host.lifecycle.setNavigationRetentionMonitor(new Hd(c,this.host.services.timer())),this.host.lifecycle.navigationRetentionMonitor().start()}startForwardLeaseIdleReleaser(){let d=mq((c)=>this.host.services.sessionManager().getSessionForDevice(c));this.host.lifecycle.setForwardLeaseIdleReleaser(new Ed({heldDeviceIds:()=>E.getForwardLeaseHeldDeviceIds(),activity:(c)=>GN(d,c),release:(c)=>E.releaseIdleForwardLease(c)},IB(),this.host.services.timer())),this.host.lifecycle.forwardLeaseIdleReleaser().start()}startPrivateDaemonOrphanWatchdog(){if(process.platform==="win32"||!eg(Bt,RB))return;let d=Zh(cz);this.host.lifecycle.setOrphanWatchdog(new Bd({parentPid:()=>process.ppid,launcherPid:()=>d,launcherIsExplicit:()=>d!==cz,isProcessRunning:(c)=>st(c),clientCount:()=>(this.host.lifecycle.socketServer()?.getClientConnectionCount()??0)+tie()+this.host.services.httpIngress().openRequestCount,clientActivityCount:()=>(this.host.lifecycle.socketServer()?.getAcceptedClientConnectionCount()??0)+rie()+this.host.services.httpIngress().requestsSeenCount,liveSessionCount:()=>this.host.services.sessionManager().getAllSessions().length,shutdown:()=>{this.host.lifecycle.selfExitRecorder().record("orphan-watchdog"),setImmediate(()=>process.kill(process.pid,"SIGTERM"))}},Qh(),this.host.services.timer())),this.host.lifecycle.orphanWatchdog().start()}async attemptRecovery(d="unknown"){try{if(e.info("Attempting daemon recovery..."),d==="database"){e.error("Database health check failed repeatedly; exiting daemon for a clean restart."),await this.host.recoverFromDatabaseHealthFailure()(1,this.host.lastDatabaseHealthFailure());return}if(this.host.lifecycle.socketServer()&&!this.host.lifecycle.socketServer().isListening()){e.info("Restarting socket server...");try{await this.host.lifecycle.socketServer().close()}catch(c){e.warn(`Error closing socket server during recovery: ${c}`)}this.host.lifecycle.setSocketServer(new Ri(Bt,void 0,void 0,ar.getInstance(),{identityStartedAt:this.host.identityState.generationStartedAt(),processGenerationToken:this.host.identityState.processGenerationToken(),startupOptions:this.host.services.options(),onRepublishIdentity:()=>this.host.republishIdentity(),startupCompletion:this.host.lifecycle.startupCompletion(),pidFilePath:Sr,sockets:ot(),dbPath:Gp(),processStartedAt:this.host.identityState.processStartedAt(),onRestartAccepted:()=>{setImmediate(()=>process.kill(process.pid,"SIGTERM"))},liveAcceptanceStartupSecret:this.host.identityState.liveAcceptanceStartupSecret(),acceptanceDiscoveryCapability:this.host.identityState.acceptanceDiscoveryCapability(),mcpDispatcher:this.host.services.mcpDispatcher()},this.host.services.idGenerator(),{ownerLiveness:this.host.identityState.incumbentOwnerGuard().asSocketOwnerLiveness()}));try{await this.host.lifecycle.socketServer().start(),this.host.identity.recordControlSocketIdentity(),e.info("Socket server restarted successfully")}catch(c){e.error(`Failed to restart socket server: ${c}`)}}if(!this.host.observationStreamHealth().isHealthy()){e.info("Restarting observation stream socket server...");try{await this.host.observationStreamHealth().recover(),this.host.configureDeviceDataStreamServer();let c=this.host.observationStreamHealth().isHealthy();(c?e.info:e.warn)(c?"Observation stream socket server restarted successfully":"Observation stream socket server remains unavailable after recovery")}catch(c){e.error(`Failed to restart observation stream socket server: ${c}`)}}}catch(c){e.error(`Recovery attempt failed: ${c}`)}}get testHooks(){return{observationStreamHealth:()=>this.host.observationStreamHealth(),setObservationStreamHealth:(d)=>{this.host.setObservationStreamHealth(d)},healthCheck:()=>this.host.healthCheck(),lastDatabaseHealthFailure:()=>this.host.lastDatabaseHealthFailure(),startHealthCheckTimer:()=>this.startHealthCheckTimer(),stopHealthCheckTimer:()=>this.stopHealthCheckTimer()}}}class Ti{sessions;plans;executions;constructor(d,c=N,R=G){this.sessions=d;this.plans=c;this.executions=R}hasPlanExecution(d,c){if(this.executions.hasActiveDeviceExecutions(d,{onlyToolName:"executePlan",onlySessionUuid:c}))return!0;return this.leasesForDevice(d,c).length>0}getPlanExecutionIds(d,c){return this.leasesForDevice(d,c).flatMap((R)=>R.executionId?[R.executionId]:[])}bindPlanExecutions(d,c){for(let R of this.leasesForDevice(d,c))if(R.executionId)this.executions.bindDeviceExecution(R.executionId,d,{skipRevoked:!0})}cancelPlanExecutions(d,c,R){return this.bindPlanExecutions(d,c),this.executions.cancelDeviceExecutions(d,R,{onlySessionUuid:c,onlyToolName:"executePlan",includeExecutionIds:this.getPlanExecutionIds(d,c)})}leasesForDevice(d,c){let R=new Set(this.sessions.getAllSessions().filter((D)=>D.assignedDevice===d).map((D)=>D.sessionId));return this.plans.getActivePlanExecutions().filter((D)=>{if(!D.sessionUuid)return c===void 0&&D.deviceId===d;let k=[D.sessionUuid,...D.labelSessionUuids??[]];return(c===void 0||this.ownerSession(D.sessionUuid)===this.ownerSession(c))&&k.some((P)=>R.has(P))})}ownerSession(d){return KB(d,this.sessions)}}var gg=15000,vg=Oy,hg=vg-2,dP=60000;function cP(d,c){return c!==void 0&&(d.transitionalSimulators?.length??0)>0}function uP(d,c){if(d!=="either")return{};let R=I$(c.map((D)=>D.platform));return{includeWatchOs:!0,...R.length>0?{includeAppleSimulatorPlatforms:R}:{}}}async function yg(d,c,{isPlanDevice:R=()=>!1,platform:D="either",bypassAndroidDeviceListCache:k=!1,heldDevices:P=[],iosDeviceListMaxAgeMs:C}){let M=[...d.getAllDevices().map((J)=>({platform:J.platform,id:J.id})),...P.map((J)=>({platform:J.platform,id:J.assignedDevice}))],F={bypassAndroidDeviceListCache:k,skipAndroidProfileEnrichment:!0,...uP(D,M),skipPhysicalIosDiscovery:!M.some((J)=>So(J.platform,J.id)==="ios-physical")},q=async(J)=>{let X=await c.getBootedDevicesDetailed(D,J);return X.devices=await pP(d,X.devices),X},U=await q({...F,...C===void 0?{}:{iosDeviceListMaxAgeMs:C}}),K=cP(U,C),W=new Set(U.devices.map((J)=>J.deviceId)),V=M.filter((J)=>!R(J.id)&&!W.has(J.id));if(K||V.some((J)=>Si(U,J.platform,J.id)&&(J.platform==="ios"||!k)))U=await q({...F,bypassAndroidDeviceListCache:k||V.some((J)=>J.platform==="android"),bypassIosDeviceListCache:K||V.some((J)=>So(J.platform,J.id)==="ios-simulator"),bypassPhysicalIosDeviceListCache:V.some((J)=>So(J.platform,J.id)==="ios-physical")});let z=U.devices.filter((J)=>!R(J.deviceId));if(z.length>0||M.some((J)=>!R(J.id)))await d.reconcileDiscoveryObservation(z,"disconnect-monitor",{settleMembership:!0});return U}async function pP(d,c){let R=d.mapAndroidDiscovery(c),D=new Set(R.map((F)=>F.deviceId)),k=d.getAllDevices().filter((F)=>F.platform==="android"),P=new Set(k.map((F)=>F.id));if(!R.some((F)=>F.platform==="android"&&!P.has(F.deviceId)&&Yo(F.deviceId)))return R;if(!k.some((F)=>!D.has(F.id)&&[F.id,...d.getAndroidTransportAliases(F.id)].some(Yo)))return R;return await d.normalizeAndroidDiscovery(c,!1,()=>!0,!1)}function Sg(d,c){return new Map([...c].flatMap((R)=>d.getAndroidTransportAliases(R).map((D)=>[D,R])))}async function bg(d,c,R){let D=[...R],k=Sg(d,D),P=await c.getAndroidOfflineDeviceIds(new Set([...D,...k.keys()]));return new Set([...P].map((C)=>k.get(C)??C))}function mP(d,c,R){return new Set([...d].filter((D)=>!c.has(D)&&R.get(D)==="android"))}async function wg(d,c,R,{candidateDeviceIds:D,bootedDeviceIds:k,candidatePlatforms:P}){if(R)return{};let C=mP(D,k,P),M=Sg(d,C);try{let F=C.size>0?await c.getAndroidListedDeviceStates(new Set([...C,...M.keys()])):new Map,q=[...F].map(([K,W])=>[M.get(K)??K,W]),U=new Map;for(let[K,W]of F){let V=M.get(K)??K;if(W==="offline"&&C.has(V)){let z=U.get(V)??new Set;z.add(K),U.set(V,z)}}return{offlineTransportIds:U,listedNonDeviceIds:new Set(q.map(([K])=>K)),offlineDeviceIds:new Set(q.filter(([,K])=>K==="offline").map(([K])=>K)),transitionalAdbDeviceIds:new Set(q.filter(([,K])=>uH(K)).map(([K])=>K))}}catch(F){if(!(F instanceof Jk))throw F;return e.warn(`[DisconnectMonitor] Retaining offline recovery attempts: ${r(F)}`),{}}}function Rg(d,c,R){return YX(R.transitionalAdbDeviceIds,My({transitional:c.transitionalSimulators,discovered:c.devices,devicePool:d}).map(({device:D})=>D.deviceId))}function Dg(d,c,R){let D=new Set,k=new Map,P=GX(R);for(let C of R)D.add(C.deviceId),k.set(C.deviceId,C.platform);for(let C of d.getAllDevices())D.add(C.id),k.set(C.id,C.platform),P.set(C.id,C.incarnation);for(let C of c.getAllSessions())if(D.add(C.assignedDevice),!k.has(C.assignedDevice))k.set(C.assignedDevice,C.platform);return{candidateDeviceIds:D,candidatePlatforms:k,candidateIncarnations:P}}function Pg(d,c,R){let D=d.length>0,k=new Map(d.map((P)=>[P.id,P]));if(D){e.warn("[DisconnectMonitor] All AutoMobile-owned Android emulators disappeared together; treating this as an ADB server reset and recovering by AVD name");for(let P of d)c.set(P.id,[])}for(let P of R)if(c.has(P.deviceId))c.get(P.deviceId).push(P.recordingId);return k}function Cg(d,c,R,D){for(let{deviceId:k,misses:P,budgetExhausted:C}of c.missed){let M=R.has(k),F=M?Math.min(P,hg):P;if(M)d.set(k,F);let U=`[DisconnectMonitor] Device ${k} not in booted list (${C?"budget exhausted":"absent"}, miss ${F}/${vg}, booted=${D.size})`;if(M&&P>hg)e.debug(U);else e.info(U)}for(let{deviceId:k,transitionalForMs:P}of c.transitional)e.info(`[DisconnectMonitor] Device ${k} listed in a transitional state for ${Math.round(P/1000)}s (budget ${h6/1000}s); keeping session`)}async function Mg(d,c,R){let{timer:D,stoppingRecordings:k}=d;if(k.has(c))return!1;k.add(c);let P=fP(c,R).finally(()=>k.delete(c)),C=Error("recording stop still running");try{return await l(P,{timer:D,timeoutMs:dP,label:"Stop recording after device disconnect",timeoutError:()=>C})}catch(M){if(M!==C)throw M;return e.warn(`[Daemon] Recording ${c} is still finishing after device ${R} disconnected; releasing the device without waiting`),!0}}async function fP(d,c){try{return await G1(d),e.warn(`[Daemon] Stopped recording ${d} after device ${c} disconnected`),!0}catch(R){return e.warn(`[Daemon] Failed to stop recording ${d} after device ${c} disconnected: ${R}`),await hP(d,c)}}async function hP(d,c){try{return await Xl(d),e.warn(`[Daemon] Marked recording ${d} interrupted after device ${c} disconnected`),!0}catch(R){return e.warn(`[Daemon] Failed to mark recording ${d} interrupted after device ${c} disconnected: ${R}`),!1}}function Kd(d,c){return d!==null&&d!==void 0&&(!Ar(d)||!!O(d))||c}var vP=120000;function yP(d,c){if(c===void 0)return;return{signature:c,unchanged:d?.signature===c?d.unchanged+1:0}}function SP(d,c,R=vP){return Q({initialDelayMs:d,maxDelayMs:R}).delayForAttempt(c+1)}function bP(d,c,R){return JSON.stringify([[...d].sort(),[...c].sort(),[...R].sort()])}function wP(d,c,R,D){if(R===void 0||c-R>=D)return"either";let k=d.filter(dr),P=k[0];return P&&k.every((C)=>C===P)?P:"either"}class Wd{cadence;lastSweepAt;lastEitherSweepAt;idleState;watching=!1;constructor(d,c){this.cadence=d;this.lastSweepAt=c}shouldRun(d,c){let R=this.watching;if(this.watching=d,d){if(this.idleState=void 0,!R)this.lastEitherSweepAt=void 0}if(!d&&c-this.lastSweepAt<SP(this.cadence.idleIntervalMs,this.idleState?.unchanged??0,this.cadence.maxIdleIntervalMs))return!1;return this.lastSweepAt=c,!0}selectPlatform(d,c,R){let D=this.watching&&!R?wP(d,c,this.lastEitherSweepAt,this.cadence.idleIntervalMs):"either";if(D==="either")this.lastEitherSweepAt=c;return D}recordSuccess(d){if(!this.watching)this.idleState=yP(this.idleState,d)}recordFailure(){this.idleState=void 0,this.lastEitherSweepAt=void 0}}function Eg(d,c,R,{bootedDeviceIds:D,pooledDeviceIds:k}){if(d.size===0||c!==0||![...R].every((P)=>D.has(P)))return;return bP(D,k,d)}function cr(d,c,R,D){let k=D.filter((P)=>P.platform==="android"&&P.avdName!==void 0&&P.androidImage!==void 0&&P.id.startsWith("emulator-"));if(!c.has("android")||k.length<2||!k.every((P)=>!d.has(P.id))||!k.some((P)=>R.has(P.id)))return[];return k}function jd(d,c,R,D){return cr(d,c,R,D).length>0}function Bg(d,c,R){let D=d.services.devicePool().getDevice(c),k=D?.assignmentCount,P=O(D)??d.services.sessionManager().getSessionForDevice(c),C=P?d.services.sessionManager().getSession(P):null,M=d.forceDisconnectedDeviceGenerations().get(c),F=R.get(c);return{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k,sessionIdAtDisconnect:P,sessionAtDisconnect:C,forceGenerationAtDisconnect:M,adbServerResetTarget:F}}function xg(d,c,{pooledDeviceAtDisconnect:R,assignmentCountAtDisconnect:D,sessionIdAtDisconnect:k,sessionAtDisconnect:P}){if(R){if(d.services.devicePool().getDevice(c)!==R||R.assignmentCount!==D)return!1}else if(d.services.devicePool().getDevice(c))return!1;if(!k)return d.services.sessionManager().getSessionForDevice(c)===null;return d.services.sessionManager().getSessionForDevice(c)===k&&d.services.sessionManager().getSession(k)===P}var RP=5000,DP=30000;class zd{host;constructor(d){this.host=d}hasPlanExecution(d,c){return new Ti(this.host.services.sessionManager()).hasPlanExecution(d,c)}async tryRecoverCapturedDisconnectTarget(d){let{deviceId:c,incidentId:R,pooledDevice:D,sessionId:k,session:P,forceGeneration:C,preparation:M}=d;if(!M){if(k&&await this.host.services.devicePool().waitForSessionPreservingRecovery(k,R))return this.host.retireAdbServerResetDisconnectState(c,C),!0;if(k&&this.host.services.devicePool().isSessionRecoveryInFlight(k))return await this.host.services.devicePool().finishEmulatorLossIncident(R,"not-attempted"),this.host.retireAdbServerResetDisconnectState(c,C),!0}if(!D||!k||!P)return!1;if(this.host.services.devicePool().finishSessionPreservingRecoveryPreparation(M),await this.host.services.devicePool().recoverSessionBoundDeviceAfterLoss(c,R,D)==="not-attempted")return!1;return this.host.retireAdbServerResetDisconnectState(c,C),!0}async recordAndTryRecoverCapturedDisconnect(d,c){let{pooledDeviceAtDisconnect:R,assignmentCountAtDisconnect:D,sessionIdAtDisconnect:k,sessionAtDisconnect:P,forceGenerationAtDisconnect:C}=c;if(await this.host.services.devicePool().isShutdownReservationHeld(d))return await this.host.services.devicePool().removeDisconnectedDevice(d,!0,void 0,R??void 0),{incidentId:void 0,handled:!0};let M=this.host.services.devicePool().prepareSessionPreservingRecovery(d,R??void 0);try{let F=await this.host.services.devicePool().recordEmulatorLossIncident(d,this.host.forceDisconnectedDeviceIds().has(d)?"adb-transport-failure":"device-discovery-miss",void 0,"absent");if(await this.host.shouldSkipStaleDisconnectCleanup(R,d,C)||!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:R,assignmentCountAtDisconnect:D,sessionIdAtDisconnect:k,sessionAtDisconnect:P}))return await this.host.services.devicePool().finishEmulatorLossIncident(F,"not-attempted"),{incidentId:F,handled:!0};let U=await this.tryRecoverCapturedDisconnectTarget({deviceId:d,incidentId:F,pooledDevice:R,sessionId:k,session:P,forceGeneration:C,preparation:M});return{incidentId:F,handled:U}}finally{this.host.services.devicePool().finishSessionPreservingRecoveryPreparation(M)}}startDeviceDisconnectMonitor(d=new Xn,c=this.host.listActiveVideoRecordings,R=BB,D={activeIntervalMs:RP,idleIntervalMs:DP}){if(this.host.lifecycle.deviceDisconnectMonitor())return;let k=this.createPlanDeviceLossCheck(d,(C)=>this.discoverAndReconcile(d,{platform:C,bypassAndroidDeviceListCache:!0}),R),P=new Wd(D,this.host.services.timer().now());this.host.lifecycle.setDeviceDisconnectMonitor(new Tl(this.host.services.timer(),D.activeIntervalMs,async()=>{let C={adbServerResetCohort:[],selectPlatform:(M,F)=>P.selectPlatform(M,this.host.services.timer().now(),F)};try{await this.checkDisconnects(d,c,R,{checkPlanDeviceLoss:k,sweep:C}),P.recordSuccess(C.idleSignature)}catch(M){P.recordFailure(),e.warn(`[Daemon] Device disconnect monitor failed: ${M}`)}finally{if(C.adbServerResetCohort.length>0)await this.host.services.devicePool().releaseAdbServerResetCohortReservations(C.adbServerResetCohort)}},{shouldRun:async()=>{let C=this.host.services.devicePool(),M=this.host.services.sessionManager().getAllSessions().length>0||C.getAllDevices().some(({id:F})=>{let q=C.getDevice(F);return Kd(q,C.isDeviceLeasedForAndroidStartup(F))})||N.isPlanExecutionActive()||(await c()).length>0;return P.shouldRun(M,this.host.services.timer().now())}})),this.host.lifecycle.deviceDisconnectMonitor().start()}discoverAndReconcile(d,c){return yg(this.host.services.devicePool(),d,{...c,isPlanDevice:(R)=>this.hasPlanExecution(R),heldDevices:[...this.host.services.sessionManager().getAllSessions(),...c.heldDevices??[]]})}logDisconnectMisses(...d){Cg(this.host.lifecycle.deviceDisconnectMisses(),...d)}collectDisconnectCandidates(d){return Dg(this.host.services.devicePool(),this.host.services.sessionManager(),d)}createPlanDeviceLossCheck(d,c,R=BB){let D=new lH({timer:this.host.services.timer(),isTransportRestarting:(k)=>R.isRestarting(k),getDevice:(k)=>this.host.services.devicePool().getDevice(k),getPlanSessionUuid:(k)=>at(k,this.host.services.sessionManager())??k,hasPlanExecution:(k,P)=>this.hasPlanExecution(k,P),getPlanExecutionIds:(k,P)=>new Ti(this.host.services.sessionManager()).getPlanExecutionIds(k,P),isStartupLeased:(k)=>this.host.services.devicePool().isDeviceLeasedForAndroidStartup(k),isShutdownReserved:(k)=>this.host.services.devicePool().isShutdownReservationHeld(k),discover:c,getOfflineDeviceIds:(k)=>bg(this.host.services.devicePool(),d,k),isAdbReset:(k,P)=>jd(k,P.succeededPlatforms,new Set(this.host.services.devicePool().getAllDevices().filter((C)=>!k.has(C.id)).map((C)=>C.id)),this.host.services.devicePool().getAllDevices()),recordLoss:(k)=>this.host.services.devicePool().recordEmulatorLossIncident(k,this.host.forceDisconnectedDeviceIds().has(k)?"adb-transport-failure":"device-discovery-miss",void 0,"absent"),finishLoss:(k)=>this.host.services.devicePool().finishEmulatorLossIncident(k,"not-attempted"),cancelPlan:(k,P,C)=>new Ti(this.host.services.sessionManager()).cancelPlanExecutions(k,P,C)});return async(k,P)=>{await D.check(k.missed.map(({deviceId:C})=>C),P),e.debug("[DisconnectMonitor] Checked device-scoped plan loss evidence")}}startDeferredSessionRecoverySweep(){this.host.trackDeferredSessionRecoverySweep(this.host.services.devicePool().retryDueDeferredSessionRecoveries((d)=>!this.hasPlanExecution(d)).catch((d)=>{e.warn(`[DisconnectMonitor] Deferred session recovery sweep failed: ${d}`,d)}))}prepareOfflineRecovery(d,c,R){this.host.setOfflineRecoveryAttemptedDeviceIds(XX(this.host.offlineRecoveryAttemptedDeviceIds(),d,c,{attemptedIncarnations:this.host.offlineRecoveryAttemptedIncarnations(),candidateIncarnations:R}));let D=new Set([...c??[]].filter((C)=>!this.hasPlanExecution(C)&&this.host.services.devicePool().isDeviceLeasedForAndroidStartup(C))),k=ZX(c??new Set,d,this.host.offlineRecoveryAttemptedDeviceIds(),new Set([...D,...[...c??[]].filter((C)=>this.hasPlanExecution(C))])),P=D.size>0?[]:k;return this.host.setOfflineRecoveryAttemptedDeviceIds(new Set([...this.host.offlineRecoveryAttemptedDeviceIds(),...P])),this.host.setOfflineRecoveryAttemptedIncarnations(new Map([...R].filter(([C])=>this.host.offlineRecoveryAttemptedDeviceIds().has(C)))),{dispatchTargets:P,offlineRecoveryTargets:k}}async recoverOfflineCandidates(d,c,R,D){if([...R].every((M)=>this.hasPlanExecution(M)))return!1;let k=c.offlineDeviceIds&&new Set([...c.offlineDeviceIds,...[...this.host.offlineRecoveryAttemptedDeviceIds()].filter((M)=>this.hasPlanExecution(M))]),{dispatchTargets:P}=this.prepareOfflineRecovery(R,k,D);if(P.length===0)return!1;e.warn(`[DisconnectMonitor] In-session device(s) ADB-offline (${P.join(", ")}); attempting bounded 'adb -s <serial> reconnect' recovery before miss-counting`);let C=P.flatMap((M)=>{let F=c.offlineTransportIds?.get(M);return F?.size?[...F]:[M]});return await d.recoverAndroidOfflineDevices(C),P.filter((M)=>!C.includes(M)).forEach((M)=>pR(M,"adb_reconnect")),!0}captureDisconnectCleanup(d,c){return this.host.captureDisconnectCleanup(d,c)}confirmDisconnectedDeviceCleanup(d,c){if(this.host.confirmedDisconnectedDeviceIds().add(d),this.host.lifecycle.deviceDisconnectMisses().reset(d),this.host.deviceDisconnectMissIncarnations().delete(d),this.host.offlineRecoveryAttemptedDeviceIds().delete(d),this.host.offlineRecoveryAttemptedIncarnations().delete(d),this.host.offlineEpisodes().delete(d),this.host.forceDisconnectedDeviceGenerations().get(d)===c)this.host.forceDisconnectedDeviceIds().delete(d),this.host.forceDisconnectedDeviceGenerations().delete(d)}async cleanupDisconnectedDevice(d,c,R){let D=this.captureDisconnectCleanup(d,R),{pooledDeviceAtDisconnect:k,forceGenerationAtDisconnect:P,adbServerResetTarget:C}=D;if(!C&&await this.host.shouldSkipStaleDisconnectCleanup(k,d,P))return;let M=!0;Fc().stopMonitoring(d);for(let F of c)if(!await this.host.stopRecordingAfterDeviceDisconnect(F,d))M=!1;if(!C&&await this.host.shouldSkipStaleDisconnectCleanup(k,d,P))return;if(C){if(await this.tryRecoverProcessWideAdbServerResetDevice(d,C,P))return}return this.finishDisconnectedDeviceCleanup(d,D,M)}async finishDisconnectedDeviceCleanup(d,c,R){let{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k,sessionIdAtDisconnect:P,sessionAtDisconnect:C,forceGenerationAtDisconnect:M}=c,{incidentId:F,handled:q}=await this.host.recordAndTryRecoverCapturedDisconnect(d,{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k??0,sessionIdAtDisconnect:P,sessionAtDisconnect:C,forceGenerationAtDisconnect:M});if(q)return;if(!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k,sessionIdAtDisconnect:P,sessionAtDisconnect:C})){await this.host.services.devicePool().finishEmulatorLossIncident(F,"not-attempted");return}if(P&&C)e.warn(`[DisconnectMonitor] Device ${d} confirmed disconnected \u2014 cancelling session ${P}`),await this.host.cancelAndReleaseSession(P,Un(d,F),{expectedSession:C});if(!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k})){await this.host.services.devicePool().finishEmulatorLossIncident(F,"not-attempted");return}if(await this.host.services.devicePool().removeDisconnectedDevice(d,!0,F,D??void 0),this.host.services.devicePool().getDevice(d))R=!1;else this.host.lifecycle.socketServer()?.evictDeviceInputCache(d);if(R)this.confirmDisconnectedDeviceCleanup(d,M)}trackDeferredSessionRecoverySweep(d){this.host.lifecycle.deferredSessionRecoverySweeps().add(d),d.then(()=>this.host.lifecycle.deferredSessionRecoverySweeps().delete(d),()=>this.host.lifecycle.deferredSessionRecoverySweeps().delete(d))}async tryRecoverProcessWideAdbServerResetDevice(d,c,R){try{return await this.recoverProcessWideAdbServerResetDevice(d,c,R)}catch(D){return e.warn(`[DisconnectMonitor] ADB-reset recovery failed for ${d}; continuing cohort cleanup: ${D}`),!1}}async recoverProcessWideAdbServerResetDevice(d,c,R){if(!await this.host.services.devicePool().recoverSessionBoundAndroidDeviceAfterAdbServerReset(d,c))return this.host.retireAdbServerResetDisconnectState(d,R),!1;return this.host.retireAdbServerResetDisconnectState(d,R),!0}retireAdbServerResetDisconnectState(d,c){if(this.host.lifecycle.socketServer()?.evictDeviceInputCache(d),this.host.lifecycle.deviceDisconnectMisses().reset(d),this.host.deviceDisconnectMissIncarnations().delete(d),this.host.confirmedDisconnectedDeviceIds().delete(d),this.host.forceDisconnectedDeviceGenerations().get(d)===c)this.host.forceDisconnectedDeviceIds().delete(d),this.host.forceDisconnectedDeviceGenerations().delete(d)}stopRecordingAfterDeviceDisconnect(d,c){return Mg({timer:this.host.services.timer(),stoppingRecordings:this.host.stoppingRecordings()},d,c)}async shouldSkipStaleDisconnectCleanup(d,c,R=this.host.forceDisconnectedDeviceGenerations().get(c)){if(!d){if(!this.host.services.devicePool().getDevice(c))return!1;if(this.host.lifecycle.deviceDisconnectMisses().reset(c),this.host.deviceDisconnectMissIncarnations().delete(c),this.host.confirmedDisconnectedDeviceIds().delete(c),this.host.forceDisconnectedDeviceGenerations().get(c)===R)this.host.forceDisconnectedDeviceIds().delete(c),this.host.forceDisconnectedDeviceGenerations().delete(c);return e.info(`[DisconnectMonitor] Skipping stale disconnect cleanup for recovered device ${c}`),!0}let D=await this.host.services.devicePool().isCurrentDisconnectedDevice(d);if(D==="current")return!1;if(D==="unknown")return e.warn(`[DisconnectMonitor] Retaining disconnect state for ${c}: recovery verification was inconclusive`),!0;if(this.host.lifecycle.deviceDisconnectMisses().reset(c),this.host.deviceDisconnectMissIncarnations().delete(c),this.host.confirmedDisconnectedDeviceIds().delete(c),this.host.forceDisconnectedDeviceGenerations().get(c)===R)this.host.forceDisconnectedDeviceIds().delete(c),this.host.forceDisconnectedDeviceGenerations().delete(c);return e.info(`[DisconnectMonitor] Skipping stale disconnect cleanup for recovered device ${c}`),!0}isCapturedDisconnectTargetCurrent(d,c){return this.host.isCapturedDisconnectTargetCurrent(d,c)}startAdbMissingDeviceListener(){if(this.host.lifecycle.unsubscribeAdbMissingDevice())return;this.host.lifecycle.setUnsubscribeAdbMissingDevice(gne((d)=>{if(!this.host.services.devicePool().getDevice(d.deviceId)&&!this.host.services.sessionManager().getSessionForDevice(d.deviceId))return;e.warn(`[Daemon] ADB reported tracked device ${d.deviceId} missing: ${d.message}`),this.host.forceDisconnectedDeviceIds().add(d.deviceId),this.host.forceDisconnectedDeviceGenerations().set(d.deviceId,(this.host.forceDisconnectedDeviceGenerations().get(d.deviceId)??0)+1)}))}async checkDisconnects(d,c,R,{checkPlanDeviceLoss:D,sweep:k}){this.startDeferredSessionRecoverySweep();let P=await c(),C=P.map(({deviceId:de,platform:pr})=>({assignedDevice:de,platform:pr})),M=this.host.services.devicePool().getAllDevices(),F=this.host.services.sessionManager().getAllSessions(),q=[...M.map(({id:de})=>de),...F.flatMap(({assignedDevice:de})=>de===void 0?[]:[de]),...P.map(({deviceId:de})=>de)].some((de)=>this.hasPlanExecution(de)),U=k.selectPlatform([...M.filter((de)=>Kd(de,this.host.services.devicePool().isDeviceLeasedForAndroidStartup(de.id))).map((de)=>de.platform),...F.map((de)=>de.platform),...P.map((de)=>de.platform)],q),K=await this.discoverAndReconcile(d,{iosDeviceListMaxAgeMs:gg,platform:U,heldDevices:C}),W=K.succeededPlatforms,V=new Set(K.devices.map((de)=>de.deviceId)),z=new Map,{candidateDeviceIds:J,candidatePlatforms:X,candidateIncarnations:te}=this.collectDisconnectCandidates(P),re=new Set([...J].filter((de)=>this.hasPlanExecution(de))),ie=new Set([...J].filter((de)=>!re.has(de))),oe=U==="ios"?{}:await wg(this.host.services.devicePool(),d,!1,{candidateDeviceIds:ie,bootedDeviceIds:V,candidatePlatforms:X});if(await this.recoverOfflineCandidates(d,oe,J,te))K=await this.discoverAndReconcile(d,{heldDevices:C,platform:U,bypassAndroidDeviceListCache:!0}),W=K.succeededPlatforms,V=new Set(K.devices.map((de)=>de.deviceId));let pe=QX({deviceDisconnectMisses:this.host.lifecycle.deviceDisconnectMisses(),confirmedDisconnectedDeviceIds:this.host.confirmedDisconnectedDeviceIds(),bootedDeviceIds:V,candidateDeviceIds:J,succeededPlatforms:W,succeededSources:K.succeededSources,candidatePlatforms:X,candidateIncarnations:te,deviceDisconnectMissIncarnations:this.host.deviceDisconnectMissIncarnations(),forceDisconnectedDeviceIds:this.host.forceDisconnectedDeviceIds(),transitionalDeviceIds:Rg(this.host.services.devicePool(),K,oe),offlineEpisodes:this.host.offlineEpisodes(),nowMs:this.host.services.timer().monotonicNow?.()??this.host.services.timer().now(),immediateDisconnectDeviceIds:JX(J,X,V,{listedNonDeviceIds:oe.listedNonDeviceIds,transportRestarts:R})});if(pe.skippedAllDiscoveryFailed){e.warn(`[DisconnectMonitor] No platform discovery succeeded but ${J.size} tracked \u2014 skipping miss count`);return}re=new Set([...re,...[...J].filter((de)=>this.hasPlanExecution(de))]),this.logDisconnectMisses(pe,re,V),await D(pe,V);for(let de of pe.disconnected.filter((pr)=>!re.has(pr)))z.set(de,[]);k.idleSignature=Eg(K.succeededPlatforms,this.host.lifecycle.deviceDisconnectMisses().size,J,{bootedDeviceIds:V,pooledDeviceIds:this.host.services.devicePool().getAllDevices().map((de)=>de.id)}),await this.cleanupDisconnects(V,W,z,{activeRecordings:P,sweep:k})}async cleanupDisconnects(d,c,R,{activeRecordings:D,sweep:k}){let P=cr(d,c,this.host.forceDisconnectedDeviceIds(),this.host.services.devicePool().getAllDevices()),C=P.some((U)=>this.hasPlanExecution(U.id));if(C)for(let U of P)R.delete(U.id);let M=C?[]:P,F=M.length>0?await this.host.services.devicePool().detachAdbServerResetCohort(M):{devices:[],deferred:!1};if(F.deferred){e.info("[DisconnectMonitor] Deferring process-wide ADB reset recovery until matching Android startup completes");return}k.adbServerResetCohort=F.devices;let q=Pg(k.adbServerResetCohort,R,D);for(let[U,K]of R)if(!this.hasPlanExecution(U))await this.host.cleanupDisconnectedDevice(U,K,q)}}async function _g(d){let c=new Ia(aS),R=await G.cancelToolExecutions("provisionDevice",c);if(R===0)return;if(!await G.waitForToolExecutionsToEnd("provisionDevice",d))e.warn(`Timed out after ${d}ms persisting ${R} interrupted provisionDevice operation(s) before daemon shutdown`)}async function Yd(d){if(!await Jt().drain(d))e.warn(`Timed out after ${d}ms draining in-flight DB writes; closing database anyway`)}async function Fg(d){if(!await X9(d))e.warn(`Timed out after ${d}ms awaiting in-flight startup migration; closing database anyway`)}async function Ng(d,c,R=dc){let D=R.pendingDeviceIds();if(D.length===0)return;let k=new AbortController,P=d.setTimeout(()=>k.abort(Error(`IME restore exceeded its ${c}ms shutdown bound`)),c);try{let C=await Promise.allSettled(D.map((M)=>R.flush(M,{signal:k.signal})));for(let[M,F]of C.entries())if(F.status==="rejected")e.warn(`[SendKeys] Shutdown IME restoration failed on ${D[M]}`,F.reason)}finally{d.clearTimeout(P)}}function Lg(d){return(c)=>{if(c.type==="uncaughtException"){d.error(`[daemon] uncaughtException in background task; keeping daemon alive: ${im(c.error)}`,c.error);return}d.error(`[daemon] unhandledRejection in background task; keeping daemon alive: ${im(c.reason)}`,c.reason)}}function se(d,c,R){return r5(t5,d,c,R)}var kP=1000,AP=2000,$g=1000,PP=1000,IP=3000,CP=5000;class Xd{host;shutdownHandlersRegistered=!1;shutdownSessionReleasesDrained=!0;shutdownSessionIds=[];constructor(d){this.host=d}setupShutdownHandlers(){if(this.shutdownHandlersRegistered)return;this.shutdownHandlersRegistered=!0,A0(),cQ(),KS(async(c)=>{if(this.host.lifecycle.selfExitRecorder().markCleanStop(),this.host.lifecycle.shutdownInProgress())return;this.host.lifecycle.setShutdownInProgress(!0),e.info(`Received ${c}, shutting down daemon...`),await this.host.stop()}),process.once("exit",()=>{this.host.lifecycle.selfExitRecorder().record("unexpected-exit"),Mz(this.host.getDaemonFileCleanupOptions())}),T0(Lg(e))}async stop(){this.host.lifecycle.setShutdownInProgress(!0),e.info("Stopping daemon..."),await v_([...this.shutdownQuiesceStages(),...this.shutdownStreamAndTransportStages(),...this.shutdownSessionAndStateStages()],(d,c)=>e.warn(d,c),{timer:this.host.services.timer()})}shutdownQuiesceStages(){let d={heartbeatMonitor:null,navigationRetentionMonitor:null,deviceDisconnectMonitor:null,forwardLeaseIdleReleaser:null};return[se("provisioning ingress quiesce","in-flight control-socket request handlers",()=>this.quiesceProvisioningIngress()),se("provisioning interruption","interrupted provisionDevice calls persisting their handoff",(c)=>Promise.all([W4(),_g(ol(c,$g))]).then(()=>{return})),se("shutdown release snapshot","nothing (synchronous)",()=>{this.host.lifecycle.setShutdownReleaseNotifications(new Set),this.host.lifecycle.setShutdownFallbackReleaseNotifications(new Set),this.shutdownSessionIds=[],d.heartbeatMonitor=this.host.lifecycle.heartbeatMonitor(),this.host.lifecycle.setHeartbeatMonitor(null),d.navigationRetentionMonitor=this.host.lifecycle.navigationRetentionMonitor(),this.host.lifecycle.setNavigationRetentionMonitor(null),d.deviceDisconnectMonitor=this.host.lifecycle.deviceDisconnectMonitor(),this.host.lifecycle.setDeviceDisconnectMonitor(null),this.host.lifecycle.orphanWatchdog()?.stop(),this.host.lifecycle.setOrphanWatchdog(null),d.forwardLeaseIdleReleaser=this.host.lifecycle.forwardLeaseIdleReleaser(),this.host.lifecycle.setForwardLeaseIdleReleaser(null)}),se("forward lease idle releaser","an in-flight idle forward-lease sweep (adb forward removal)",async()=>{await d.forwardLeaseIdleReleaser?.stop()}),se("managed execution release","the journal redrive loop stop and the binding registry close",()=>this.host.closeManagedExecutionRelease()),se("active capture and iOS CtrlProxy children","recording stop/finalize and iOS CtrlProxy child exit",()=>VK()),se("health check timer","the database health probe",async()=>{await this.host.stopHealthCheckTimer(),await this.host.services.databaseHealthProbe().dispose?.()}),se("location routes","nothing (synchronous)",()=>pO.stopAll()),se("prototype preview server","open preview event streams and the preview port close",()=>sJ()),se("shutdown monitors","the heartbeat and disconnect monitors and deferred recovery sweeps",(c)=>this.drainShutdownMonitors(d.navigationRetentionMonitor,d.heartbeatMonitor,d.deviceDisconnectMonitor,ol(c,$g))),se("ADB missing-device subscription","nothing (synchronous)",()=>this.unsubscribeAdbMissing()),se("session cleanup timer","nothing (synchronous)",()=>this.host.stopSessionTimers())]}shutdownStreamAndTransportStages(){return[se("video recording socket server","its connections closing",()=>KK()),se("device gesture recording socket server","its connections closing",()=>JK()),se("device snapshot socket server","its connections closing",()=>QK()),se("appearance socket server","its connections closing",()=>rG()),se("performance stream socket server","its connections closing",()=>Qf()),se("performance push socket server","its connections closing",()=>Tie()),se("device data stream socket server","its connections closing",()=>uj()),se("failures stream socket server","its connections closing",()=>rh()),se("failures push socket server","its connections closing",()=>yoe()),se("telemetry push socket server","its connections closing",()=>sie()),se("WebRTC stream socket server","WebRTC stream teardown (encoder stop, adb forward removal)",()=>oG()),se("video stream socket server","capture source stop (encoder stop, adb forward removal)",()=>Ch()),se("iOS simulator capture helper pool","simulator capture helper processes exiting",()=>yM.shutdown()),se("native helper registry","tracked helper processes exiting",async(d)=>{await uk().shutdown({timer:this.host.services.timer(),graceMs:Math.min(500,Math.max(0,(d.remainingMs()-1)/2))})}),se("host adb children","host adb children exiting",async(d)=>{await uY({timer:this.host.services.timer(),graceMs:Math.min(500,Math.max(0,(d.remainingMs()-1)/2))})}),se("appearance sync scheduler","an in-flight appearance sync",()=>aG()),se("performance monitor","an in-flight performance sample",()=>QY()),se("active HTTP sessions","streamable HTTP transports closing",()=>v_([...this.host.services.httpIngress().inFlightRequests().map(({requestScopeId:d,close:c})=>({name:`Streamable HTTP request ${d}`,run:c})),...this.host.services.mcpDispatcher().inFlightForwards().map(({requestScopeId:d,close:c})=>({name:`In-process MCP forward ${d}`,run:c}))],(d,c)=>e.warn(d,c))),se("active HTTP session registry","nothing (synchronous)",()=>this.clearHttpSessionRegistry()),se("HTTP server","open HTTP connections closing",()=>this.host.services.httpIngress().closeListener())]}shutdownSessionAndStateStages(){let d=n5({closeDatabase:()=>Q9({forShutdown:!0}),refusedAccessCount:()=>Z9(),drainWrites:(c)=>Yd(c),keepOpenReason:()=>this.shutdownSessionReleasesDrained?void 0:"a session terminal write is still in flight",warn:(c)=>e.warn(c)});return[se("active device sessions","session release teardown and terminal-row persistence",async(c)=>{await this.releaseActiveSessionsForShutdown(ol(c,Qv)),await Ng(this.host.services.timer(),ol(c,PP),this.host.pendingImeRestores)}),se("Unix socket server","release notification writes and in-flight request handlers",async()=>{if(this.host.lifecycle.socketServer())this.publishMissingShutdownReleaseNotifications(),await this.host.lifecycle.socketServer().drainSessionReleaseNotifications(),await this.host.lifecycle.socketServer().close()}),se("pending device cleanups","per-device cleanup registered by released sessions",async(c)=>{await this.host.services.sessionManager().drainPendingDeviceCleanups(ol(c,AP))}),se("CtrlProxy forwarding leases","adb forward removal",(c)=>this.releaseForwardLeases(ol(c,IP))),se("device allocation claims","device claim release",()=>this.host.services.devicePool().releaseDeviceClaimsForShutdown()),se("managed ADB server","adb kill-server",()=>this.host.stopManagedAdbServer()()),se("abandoned stage settle","earlier stages that passed their deadline",(c)=>d.settle(c)),se("database write drain","in-flight best-effort database writes",(c)=>Yd(ol(c,kP))),se("in-flight migrations","a cold-start migration still running",(c)=>Fg(ol(c,CP))),se("database","the database connection closing",(c)=>d.close(c)),se("late abandoned stage settle","earlier stages that passed their deadline",(c)=>d.lateSettle(c)),se("logger","the log file flush",async()=>{e.info("Daemon stopped"),await e.closeAfterFlush()}),se("daemon files","pid, socket and token file removal",async()=>{this.host.removeHttpToken(),await this.host.cleanupDaemonFilesForShutdown()})]}unsubscribeAdbMissing(){this.host.lifecycle.unsubscribeAdbMissingDevice()?.(),this.host.lifecycle.setUnsubscribeAdbMissingDevice(null)}releaseForwardLeases(d){return E.releaseForwardLeasesForShutdown(this.host.services.timer(),d)}clearHttpSessionRegistry(){this.host.services.httpIngress().clearSessions()}async drainShutdownMonitors(d,c,R,D){d?.stop(),Q8();let[k,P]=await Promise.all([c?c.stop().then(()=>!0):!0,R?R.stop():!0]);if(!k)e.warn("Session heartbeat monitor did not settle before daemon shutdown");if(!P)e.warn("Device disconnect monitor did not settle before daemon shutdown");let C=Symbol("recovery sweep drain timeout"),M=!0;try{await l(Promise.allSettled(this.host.lifecycle.deferredSessionRecoverySweeps()),{timer:this.host.services.timer(),timeoutMs:D,label:"Recovery sweep drain",timeoutError:()=>C})}catch(F){if(F!==C)throw F;M=!1}if(!M)e.warn(`Timed out after ${D}ms draining deferred session recovery sweeps; continuing daemon shutdown`)}async quiesceProvisioningIngress(){this.host.services.httpIngress().stopAccepting(),this.host.services.mcpDispatcher().stopAccepting(),this.host.services.httpIngress().abortPendingAdmissions(),this.host.services.httpIngress().closeListener().catch((c)=>{e.warn(`Failed to begin HTTP listener shutdown: ${r(c)}`,c)});let d=this.host.lifecycle.socketServer()?.quiesce();this.host.services.sessionManager().stopAcceptingSessionCreations(),await d}async releaseActiveSessionsForShutdown(d){let c=this.host.services.sessionManager().getAllKnownSessionIds();this.shutdownSessionIds=c;let R=c.map(async(C)=>{await this.host.cancelAndReleaseSession(C,"daemon-shutdown",{allowExpired:!0})}),D=(C)=>{for(let[M,F]of C.entries())if(F.status==="rejected")e.warn(`[Daemon] Failed to release session ${c[M]??"unknown"} during shutdown: ${F.reason}`)},k=Promise.allSettled(R);if(await Promise.resolve(),!await this.host.services.sessionManager().drainReleasePromises(d,R)){this.shutdownSessionReleasesDrained=!1,e.warn(`Timed out after ${d}ms draining session releases; database will remain open`),k.then(D);return}D(await k)}publishMissingShutdownReleaseNotifications(){let d=this.host.lifecycle.shutdownReleaseNotifications(),c=this.host.lifecycle.shutdownFallbackReleaseNotifications();if(!(d&&c))return;for(let R of this.shutdownSessionIds){if(d.has(R)||c.has(R))continue;c.add(R),Ai.emit(R,"daemon-shutdown")}}get testHooks(){return{markShutdownInProgress:()=>{this.host.lifecycle.setShutdownInProgress(!0)},quiesceProvisioningIngress:()=>this.quiesceProvisioningIngress()}}}function MP(d,c,R){let D=`${new Date(R).toISOString()} [ERROR] [Daemon] exiting with code ${d}: database health check failed repeatedly`;return c===void 0?D:`${D}; last failure: ${c.replace(/[\r\n]/g," ")}`}async function Hg(d,c,R){try{R.writeEmergency(MP(d,c,R.now()))}catch(D){}try{R.writeExitRecord()}catch(D){e.warn(`Failed to record database-health exit: ${r(D)}`,D)}R.cleanupDaemonFiles();try{await R.closeLogger()}finally{R.exit(d)}}class Zd{dependencies;constructor(d){this.dependencies=d}isHealthy(){let d=this.dependencies.getServer();return d!==null&&d.isListening()&&d.hasActiveSocketPath()}async recover(){await this.dependencies.stopServer(),await this.dependencies.startServer(),this.dependencies.configureCallbacks()}}function qg(d){return(c,R)=>Hg(c,R,{now:()=>d.timer().now(),writeEmergency:(D)=>eo(D),writeExitRecord:()=>d.selfExitRecorder().record("database-health"),cleanupDaemonFiles:()=>{Mz(d.getDaemonFileCleanupOptions())},closeLogger:()=>e.closeAfterFlush(),exit:(D)=>process.exit(D)})}function Kg(d){return new Zd({getServer:It,stopServer:uj,startServer:async()=>{await d.startAuxiliarySocket("observation-stream",()=>lj(d.timer()))},configureCallbacks:()=>d.configureDeviceDataStreamServer()})}function Gg(d){return new b4(d,void 0,(c)=>{Kq(c).catch((R)=>{e.warn(`[Appearance] Failed to drop config of observer ${c}`,R)}),bb.emit(c)})}function Wg(d){let c=M5(d);for(let R of c.warnings)e.warn(`[Daemon] ${R}`);return e.info(`[Daemon] Device recovery policy: onLoss=${c.policy.onLoss}, maxAttempts=${c.policy.maxAttempts}`),c}import{Http2ServerRequest as jg,constants as EP}from"http2";import{Http2ServerRequest as ec}from"http2";import{Readable as Vg}from"stream";import UP from"crypto";var vt=class extends Error{constructor(d,c){super(d,c);this.name="RequestError"}},BP=(d)=>{if(d instanceof vt)return d;return new vt(d.message,{cause:d})},OP=global.Request,Mi=class extends OP{constructor(d,c){if(typeof d==="object"&&Wt in d)d=d[Wt]();if(typeof c?.body?.getReader<"u")c.duplex??="half";super(d,c)}},xP=(d)=>{let c=[],R=d.rawHeaders;for(let D=0;D<R.length;D+=2){let{[D]:k,[D+1]:P}=R;if(k.charCodeAt(0)!==58)c.push([k,P])}return new Headers(c)},zg=Symbol("wrapBodyStream"),_P=(d,c,R,D,k)=>{let P={method:d,headers:R,signal:k.signal};if(d==="TRACE"){P.method="GET";let C=new Mi(c,P);return Object.defineProperty(C,"method",{get(){return"TRACE"}}),C}if(!(d==="GET"||d==="HEAD"))if("rawBody"in D&&D.rawBody instanceof Buffer)P.body=new ReadableStream({start(C){C.enqueue(D.rawBody),C.close()}});else if(D[zg]){let C;P.body=new ReadableStream({async pull(M){try{C||=Vg.toWeb(D).getReader();let{done:F,value:q}=await C.read();if(F)M.close();else M.enqueue(q)}catch(F){M.error(F)}}})}else P.body=Vg.toWeb(D);return new Mi(c,P)},Wt=Symbol("getRequestCache"),Yg=Symbol("requestCache"),lr=Symbol("incomingKey"),ur=Symbol("urlKey"),FP=Symbol("headersKey"),Gt=Symbol("abortControllerKey"),NP=Symbol("getAbortController"),Ei={get method(){return this[lr].method||"GET"},get url(){return this[ur]},get headers(){return this[FP]||=xP(this[lr])},[NP](){return this[Wt](),this[Gt]},[Wt](){return this[Gt]||=new AbortController,this[Yg]||=_P(this.method,this[ur],this.headers,this[lr],this[Gt])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach((d)=>{Object.defineProperty(Ei,d,{get(){return this[Wt]()[d]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach((d)=>{Object.defineProperty(Ei,d,{value:function(){return this[Wt]()[d]()}})});Object.defineProperty(Ei,Symbol.for("nodejs.util.inspect.custom"),{value:function(d,c,R){let D={method:this.method,url:this.url,headers:this.headers,nativeRequest:this[Yg]};return`Request (lightweight) ${R(D,{...c,depth:d==null?null:d-1})}`}});Object.setPrototypeOf(Ei,Mi.prototype);var LP=(d,c)=>{let R=Object.create(Ei);R[lr]=d;let D=d.url||"";if(D[0]!=="/"&&(D.startsWith("http://")||D.startsWith("https://"))){if(d instanceof ec)throw new vt("Absolute URL for :path is not allowed in HTTP/2");try{let M=new URL(D);R[ur]=M.href}catch(M){throw new vt("Invalid absolute URL",{cause:M})}return R}let k=(d instanceof ec?d.authority:d.headers.host)||c;if(!k)throw new vt("Missing host header");let P;if(d instanceof ec){if(P=d.scheme,!(P==="http"||P==="https"))throw new vt("Unsupported scheme")}else P=d.socket&&d.socket.encrypted?"https":"http";let C=new URL(`${P}://${k}${D}`);if(C.hostname.length!==k.length&&C.hostname!==k.replace(/:\d+$/,""))throw new vt("Invalid host header");return R[ur]=C.href,R},nc=Symbol("responseCache"),Kt=Symbol("getResponseCache"),yt=Symbol("cache"),pc=global.Response,Vt=class d{#t;#e;[Kt](){return delete this[yt],this[nc]||=new pc(this.#t,this.#e)}constructor(c,R){let D;if(this.#t=c,R instanceof d){let k=R[nc];if(k){this.#e=k,this[Kt]();return}else this.#e=R.#e,D=new Headers(R.#e.headers)}else this.#e=R;if(typeof c==="string"||typeof c?.getReader<"u"||c instanceof Blob||c instanceof Uint8Array)this[yt]=[R?.status||200,c,D||R?.headers]}get headers(){let c=this[yt];if(c){if(!(c[2]instanceof Headers))c[2]=new Headers(c[2]||{"content-type":"text/plain; charset=UTF-8"});return c[2]}return this[Kt]().headers}get status(){return this[yt]?.[0]??this[Kt]().status}get ok(){let c=this.status;return c>=200&&c<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach((d)=>{Object.defineProperty(Vt.prototype,d,{get(){return this[Kt]()[d]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach((d)=>{Object.defineProperty(Vt.prototype,d,{value:function(){return this[Kt]()[d]()}})});Object.defineProperty(Vt.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(d,c,R){let D={status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[nc]};return`Response (lightweight) ${R(D,{...c,depth:d==null?null:d-1})}`}});Object.setPrototypeOf(Vt,pc);Object.setPrototypeOf(Vt.prototype,pc.prototype);async function $P(d){return Promise.race([d,Promise.resolve().then(()=>Promise.resolve(void 0))])}function Xg(d,c,R){let D=(M)=>{d.cancel(M).catch(()=>{})};return c.on("close",D),c.on("error",D),(R??d.read()).then(C,k),d.closed.finally(()=>{c.off("close",D),c.off("error",D)});function k(M){if(M)c.destroy(M)}function P(){d.read().then(C,k)}function C({done:M,value:F}){try{if(M)c.end();else if(!c.write(F))c.once("drain",P);else return d.read().then(C,k)}catch(q){k(q)}}}function HP(d,c){if(d.locked)throw TypeError("ReadableStream is locked.");else if(c.destroyed)return;return Xg(d.getReader(),c)}var rc=(d)=>{let c={};if(!(d instanceof Headers))d=new Headers(d??void 0);let R=[];for(let[D,k]of d)if(D==="set-cookie")R.push(k);else c[D]=k;if(R.length>0)c["set-cookie"]=R;return c["content-type"]??="text/plain; charset=UTF-8",c},qP="x-hono-already-sent";if(typeof global.crypto>"u")global.crypto=UP;var gc=Symbol("outgoingEnded"),Jg=Symbol("incomingDraining"),KP=500,WP=67108864,tc=(d)=>{let c=d;if(d.destroyed||c[Jg])return;if(c[Jg]=!0,d instanceof jg){try{d.stream?.close?.(EP.NGHTTP2_NO_ERROR)}catch{}return}let R=0,D=()=>{clearTimeout(P),d.off("data",C),d.off("end",D),d.off("error",D)},k=()=>{D();let M=d.socket;if(M&&!M.destroyed)M.destroySoon()},P=setTimeout(k,KP);P.unref?.();let C=(M)=>{if(R+=M.length,R>WP)k()};d.on("data",C),d.on("end",D),d.on("error",D),d.resume()},VP=()=>new Response(null,{status:400}),Qg=(d)=>new Response(null,{status:d instanceof Error&&(d.name==="TimeoutError"||d.constructor.name==="TimeoutError")?504:500}),ac=(d,c)=>{let R=d instanceof Error?d:Error("unknown error",{cause:d});if(R.code==="ERR_STREAM_PREMATURE_CLOSE")console.info("The user aborted a request.");else{if(console.error(d),!c.headersSent)c.writeHead(500,{"Content-Type":"text/plain"});c.end(`Error: ${R.message}`),c.destroy(R)}},Zg=(d)=>{if("flushHeaders"in d&&d.writable)d.flushHeaders()},iv=async(d,c)=>{let[R,D,k]=d[yt],P=!1;if(!k)k={"content-type":"text/plain; charset=UTF-8"};else if(k instanceof Headers)P=k.has("content-length"),k=rc(k);else if(Array.isArray(k)){let C=new Headers(k);P=C.has("content-length"),k=rc(C)}else for(let C in k)if(C.length===14&&C.toLowerCase()==="content-length"){P=!0;break}if(!P){if(typeof D==="string")k["Content-Length"]=Buffer.byteLength(D);else if(D instanceof Uint8Array)k["Content-Length"]=D.byteLength;else if(D instanceof Blob)k["Content-Length"]=D.size}if(c.writeHead(R,k),typeof D==="string"||D instanceof Uint8Array)c.end(D);else if(D instanceof Blob)c.end(new Uint8Array(await D.arrayBuffer()));else Zg(c),await HP(D,c)?.catch((C)=>ac(C,c));c[gc]?.()},JP=(d)=>typeof d.then==="function",jP=async(d,c,R={})=>{if(JP(d))if(R.errorHandler)try{d=await d}catch(k){let P=await R.errorHandler(k);if(!P)return;d=P}else d=await d.catch(Qg);if(yt in d)return iv(d,c);let D=rc(d.headers);if(d.body){let k=d.body.getReader(),P=[],C=!1,M=void 0;if(D["transfer-encoding"]!=="chunked"){let F=2;for(let q=0;q<F;q++){M||=k.read();let U=await $P(M).catch((K)=>{console.error(K),C=!0});if(!U){if(q===1){await new Promise((K)=>setTimeout(K)),F=3;continue}break}if(M=void 0,U.value)P.push(U.value);if(U.done){C=!0;break}}if(C&&!("content-length"in D))D["content-length"]=P.reduce((q,U)=>q+U.length,0)}if(c.writeHead(d.status,D),P.forEach((F)=>{c.write(F)}),C)c.end();else{if(P.length===0)Zg(c);await Xg(k,c,M)}}else if(D[qP]);else c.writeHead(d.status,D),c.end();c[gc]?.()},vc=(d,c={})=>{let R=c.autoCleanupIncoming??!0;if(c.overrideGlobalObjects!==!1&&global.Request!==Mi)Object.defineProperty(global,"Request",{value:Mi}),Object.defineProperty(global,"Response",{value:Vt});return async(D,k)=>{let P,C;try{C=LP(D,c.hostname);let M=!R||D.method==="GET"||D.method==="HEAD";if(!M){if(D[zg]=!0,D.on("end",()=>{M=!0}),D instanceof jg)k[gc]=()=>{if(!M)setTimeout(()=>{if(!M)setTimeout(()=>{tc(D)})})};k.on("finish",()=>{if(!M)tc(D)})}if(k.on("close",()=>{if(C[Gt]){if(D.errored)C[Gt].abort(D.errored.toString());else if(!k.writableFinished)C[Gt].abort("Client connection prematurely closed.")}if(!M)setTimeout(()=>{if(!M)setTimeout(()=>{tc(D)})})}),P=d(C,{incoming:D,outgoing:k}),yt in P)return iv(P,k)}catch(M){if(!P)if(c.errorHandler){if(P=await c.errorHandler(C?M:BP(M)),!P)return}else if(!C)P=VP();else P=Qg(M);else return ac(M,k)}try{return await jP(P,k,c)}catch(M){return ac(M,k)}}};var nv=class{_webStandardTransport;_requestListener;_requestContext=new WeakMap;constructor(d={}){this._webStandardTransport=new p5(d),this._requestListener=vc(async(c)=>{let R=this._requestContext.get(c);return this._webStandardTransport.handleRequest(c,{authInfo:R?.authInfo,parsedBody:R?.parsedBody})},{overrideGlobalObjects:!1})}get sessionId(){return this._webStandardTransport.sessionId}set onclose(d){this._webStandardTransport.onclose=d}get onclose(){return this._webStandardTransport.onclose}set onerror(d){this._webStandardTransport.onerror=d}get onerror(){return this._webStandardTransport.onerror}set onmessage(d){this._webStandardTransport.onmessage=d}get onmessage(){return this._webStandardTransport.onmessage}async start(){return this._webStandardTransport.start()}async close(){return this._webStandardTransport.close()}async send(d,c){return this._webStandardTransport.send(d,c)}setSupportedProtocolVersions(d){this._webStandardTransport.setSupportedProtocolVersions(d)}setScopeChallengeResolver(d){this._webStandardTransport.setScopeChallengeResolver(d)}async handleRequest(d,c,R){let D=d.auth;await vc(async(k)=>this._webStandardTransport.handleRequest(k,{authInfo:D,parsedBody:R}),{overrideGlobalObjects:!1})(d,c)}closeSSEStream(d){this._webStandardTransport.closeSSEStream(d)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}};var zP=g({sessionId:y().min(1),livenessOwnerToken:yr().optional()});function av(d){let c;try{c=JSON.parse(d)}catch(D){return e.debug(`Invalid heartbeat JSON: ${D}`),{ok:!1,response:{status:400,body:{error:"Invalid JSON"}}}}let R=zP.safeParse(c);if(!R.success)return{ok:!1,response:{status:400,body:{error:"Missing sessionId"}}};return{ok:!0,sessionId:R.data.sessionId,livenessOwnerToken:R.data.livenessOwnerToken}}var ov={status:200,body:{status:"ok"}};function XP(d){return typeof d==="string"&&d.trim()?d:void 0}async function dv(d,c,R,D){let k=XP(D),P=d.getSession(R)??d.getReleasingSession?.(R)??null;if(!P||Yi(d,R,P)){let M=await hq(d,c,R,k);if(M.kind==="observer")return ov;return{status:404,body:{error:`Session not found: ${R}`,...Oh(M.recorded.releaseReason,M.recorded.idleTimeoutMs)}}}if(k?d.hasLivenessOwnership(R,k)||d.claimUnownedLivenessOwnership(R,k):!fq(P))d.recordHeartbeat(R);return ov}import{AsyncLocalStorage as eI}from"async_hooks";var QP={updates:Uw,lists:_r,log:e,maxUrisPerStream:256,maxUriMemberships:4096},ZP=s({method:_("subscriptions/listen"),params:s({notifications:s({resourceSubscriptions:S(n()).optional()})})});class Sc{bus;uriReferences=new Map;memberships=0;warnedLimit=!1;unsubscribeUpdates;unsubscribeLists;deps;constructor(d,c={}){this.bus=d;this.deps={...QP,...c},this.unsubscribeUpdates=this.deps.updates.subscribe((R)=>this.publishUpdated(R)),this.unsubscribeLists=this.deps.lists.subscribe((R)=>{this.bus.publish({kind:R==="tools"?"tools_list_changed":"resources_list_changed"})})}track(d){let c=ZP.safeParse(d);if(!c.success)return()=>{};let R=new Set(c.data.params.notifications.resourceSubscriptions??[]);if(R.size>this.deps.maxUrisPerStream||this.memberships+R.size>this.deps.maxUriMemberships){if(!this.warnedLimit)this.warnedLimit=!0,this.deps.log.warn("Modern MCP resource subscription URI limit reached; refusing stream");return null}for(let k of R)this.uriReferences.set(k,(this.uriReferences.get(k)??0)+1);this.memberships+=R.size;let D=!1;return()=>{if(!D)D=!0,this.release(R)}}close(){this.unsubscribeUpdates(),this.unsubscribeLists(),this.uriReferences.clear(),this.memberships=0}release(d){for(let c of d){let R=this.uriReferences.get(c);if(R===void 0)continue;if(this.memberships--,R===1)this.uriReferences.delete(c);else this.uriReferences.set(c,R-1)}}publishUpdated(d){if(this.uriReferences.size===0)return;try{let c=new Set(d(new Set(this.uriReferences.keys())));for(let R of c)if(this.uriReferences.has(R))this.publishUri(R)}catch(c){this.deps.log.warn("Modern MCP resource update resolution failed",c)}}publishUri(d){try{this.bus.publish({kind:"resource_updated",uri:d})}catch(c){this.deps.log.warn("Modern MCP resource update publication failed",c)}}}var tI=JSON.stringify({jsonrpc:"2.0",error:{code:-32000,message:"Method not allowed."},id:null}),rI=JSON.stringify({error:"Daemon is shutting down"});function Bi(d){return(Array.isArray(d)?d:[d]).filter((R)=>!!R&&typeof R==="object"&&!Array.isArray(R))}function cv(d){return typeof d==="string"||typeof d==="number"}function xi(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return;return Object.entries(d).find(([R])=>R===c)?.[1]}function oI(d){for(let c of Bi(d)){let R=xi(xi(c.params,"arguments"),vD);if(typeof R==="string"&&R.length>0)return R}return}function uv(d){return`\x00${typeof d}:${String(d)}`}function lv(d,c){return`${d}${uv(c)}`}function sI(d,c){let R=new Headers;for(let[D,k]of Object.entries(d.headers)){let P=Array.isArray(k)?k:k===void 0?[]:[k];for(let C of P)R.append(D,C)}return new Request(new URL(Qw,"http://localhost"),{method:"POST",headers:R,signal:c})}async function aI(d,c){if(c.destroyed||c.writableEnded){await d.body?.cancel();return}c.writeHead(d.status,Object.fromEntries(d.headers));let R=new TextDecoder;if(d.body)for await(let D of d.body){if(c.destroyed||c.writableEnded)break;c.write(R.decode(D,{stream:!0}))}if(!c.destroyed&&!c.writableEnded)c.end(R.decode())}var dI="2026-07-28",cI=1024;function lI(d,c){let D=c?.params?._meta?.[cs];return[d,D].some((k)=>typeof k==="string"&&k>=dI)}class bc{deps;inFlight=new Map;byCancelKey=new Map;accepting=!0;modernBus;modernEvents;modernListenStreams=0;modernScope=new eI;root=la("auto-mobile-mcp-http-root");constructor(d){this.deps=d}get inFlightCount(){return this.inFlight.size}inFlightRequests(){return Array.from(this.inFlight.values(),(d)=>({requestScopeId:d.requestScopeId,close:()=>d.close()}))}trackForTesting(d,c){this.inFlight.set(d,{requestScopeId:d,keyless:!1,cancelKeys:[],close:async()=>{this.inFlight.delete(d),await c()}})}stopAccepting(){this.accepting=!1,this.releaseModernEventsIfIdle()}clear(){this.accepting=!1,this.inFlight.clear(),this.byCancelKey.clear(),this.releaseModernEventsIfIdle()}async handle(d,c,R,D){if(d.method!=="POST"){c.writeHead(405,{"Content-Type":"application/json",Allow:"POST"}),c.end(tI);return}let k=KU(d.headers);if(await this.cancelNotifiedRequests(k,R),!this.accepting){c.writeHead(503,{"Content-Type":"application/json"}),c.end(rI);return}let P={requestScopeId:this.deps.idGenerator.next(),requestMcpSessionId:k??oI(R)};if(this.isModernRequest(d,R)){await this.handleModern(d,c,R,{scope:P,headerSessionKey:k,sendJsonRpcError:D});return}let C;try{C=this.deps.createServer(d,P)}catch(K){e.error("Failed to create MCP server:",K),D("Server error",K);return}let M=this.deps.createTransport(),F=this.track(P,k,R,{server:C,transport:M}),q=d.socket??void 0,U=()=>{q?.off("close",U),F.close().catch((K)=>{e.warn(`Stateless MCP request close failed: ${r(K)}`,K)})};c.once("close",U),c.once("finish",U),q?.once("close",U);try{await C.connect(M)}catch(K){e.error("MCP server connect failed:",K),D("Server error",K),await F.close();return}await this.dispatch(d,c,M,{parsedBody:R,sendJsonRpcError:D})}isModernRequest(d,c){if(!(this.deps.modern?.enabled()??$e(h.MCP_MODERN_ERA)))return!1;let R=(P)=>{let C=d.headers[P];return typeof C==="string"?C:void 0},D=R("mcp-protocol-version"),k=(this.deps.modern?.classify??MF)({httpMethod:d.method??"POST",protocolVersionHeader:D,mcpMethodHeader:R("mcp-method"),mcpNameHeader:R("mcp-name"),body:c});return k.kind==="modern"||k.kind==="reject"&&lI(D,c)}createModernHandler(d){return(this.deps.modern?.createHandler??YQ)((c)=>{let R=this.modernScope.getStore(),{req:D,scope:k}=R??{};if(!R||!D||!k)throw new t("Modern MCP request scope is missing");R.req=void 0,R.scope=void 0;let P=this.deps.createServer(D,{...k,era:c.era});if(!(P instanceof Gh))throw new t("Modern MCP serving requires an SDK McpServer");return P},{legacy:"reject",responseMode:"sse",keepAliveMs:0,bus:d})}async handleModern(d,c,R,{scope:D,headerSessionKey:k,sendJsonRpcError:P}){let C=this.getModernBus(),M=this.openListenSlot(R,c);if(!M)return;let F=new AbortController,q;try{q=this.createModernHandler(C)}catch(J){throw M.release(),J}let U=this.track(D,k,R,{server:q,transport:{close:async()=>{F.abort(),M.release()}}}),K=d.socket??void 0,W=()=>{K?.off("close",W),U.close().catch((J)=>{e.warn(`Modern MCP request close failed: ${r(J)}`,J)})};c.once("close",W),c.once("finish",W),K?.once("close",W);let V=this.startKeepalive(c),z=Bi(R).map((J)=>xi(J.params,"_meta")).find((J)=>J!==void 0);try{let J=await this.root.run(()=>this.modernScope.run({req:d,scope:D},()=>vm(Sm(z),()=>q.fetch(sI(d,F.signal),{parsedBody:R}))));await aI(J,c)}catch(J){e.error("Modern MCP HTTP request handling failed:",J),P("Server error",J)}finally{V(),K?.off("close",W),await U.close()}}openListenSlot(d,c){if(!Bi(d).some((k)=>k.method==="subscriptions/listen"))return{release:()=>{}};let D=this.modernListenStreams<(this.deps.modern?.maxListenStreams??cI)?this.modernEvents?.track(d):void 0;if(!D)return c.writeHead(429,{"Content-Type":"application/json","Retry-After":"5"}),c.end(JSON.stringify({error:"Subscription stream or resource URI limit reached"})),null;return this.modernListenStreams++,{release:()=>{D(),this.modernListenStreams--}}}getModernBus(){if(!this.modernBus){let d=this.deps.modern?.createEventBus?.()??new FF((c)=>e.warn(`Modern MCP event listener failed: ${r(c)}`,c));this.modernBus=d,this.modernEvents=new Sc(d)}return this.modernBus}releaseModernEventsIfIdle(){if(!this.accepting&&this.inFlight.size===0)this.modernEvents?.close(),this.modernEvents=void 0,this.modernBus=void 0}track(d,c,R,{server:D,transport:k}){let{requestScopeId:P}=d,C=Bi(R).map((q)=>q.id).filter(cv).map((q)=>lv(c??"",q)),M,F={requestScopeId:P,keyless:d.requestMcpSessionId===void 0,cancelKeys:C,close:(q)=>(M??=this.closeRequest(F,D,k,q),M)};this.inFlight.set(P,F);for(let q of C)this.byCancelKey.set(q,[...this.byCancelKey.get(q)??[],P]);return F}async closeRequest(d,c,R,D){try{let k=await this.deps.cancelScopeExecutions(d.requestScopeId,D??this.deps.closeReason());if(k>0)e.info(`Stateless MCP request ${d.requestScopeId} closed (cancelled ${k} executions)`)}finally{this.untrack(d);let k=await Promise.allSettled([R.close(),c.close()]);for(let P of k)if(P.status==="rejected")e.warn(`Stateless MCP request ${d.requestScopeId} teardown failed: ${im(P.reason)}`);if(d.keyless)this.deps.forgetScopeBindings(d.requestScopeId)}}untrack(d){if(this.inFlight.get(d.requestScopeId)===d)this.inFlight.delete(d.requestScopeId);for(let c of d.cancelKeys){let R=(this.byCancelKey.get(c)??[]).filter((D)=>D!==d.requestScopeId);if(R.length===0)this.byCancelKey.delete(c);else this.byCancelKey.set(c,R)}this.releaseModernEventsIfIdle()}async cancelNotifiedRequests(d,c){let R=Bi(c).filter((D)=>D.method==="notifications/cancelled");await Promise.all(R.map(async(D)=>{let k=xi(D.params,"requestId");if(!cv(k))return;let P=this.cancelledScopeId(d,k),C=P===void 0?void 0:this.inFlight.get(P);if(!C){e.debug(`notifications/cancelled for unknown request ${String(k)}`);return}let M=xi(D.params,"reason");await C.close(typeof M==="string"?M:"notifications/cancelled")}))}cancelledScopeId(d,c){if(d!==void 0)return this.byCancelKey.get(lv(d,c))?.at(-1);let R=uv(c),D=Array.from(this.byCancelKey.entries()).filter(([k])=>k.endsWith(R)).flatMap(([,k])=>k);if(D.length>1)e.warn(`Ignoring header-less notifications/cancelled for ambiguous request id ${String(c)}: ${D.length} in-flight requests share it`);return D.length===1?D[0]:void 0}startKeepalive(d){let c=this.deps.timer.setInterval(()=>{if(d.headersSent&&!d.writableEnded&&!d.destroyed)d.write(`:keepalive
51
+
52
+ `)},this.deps.keepaliveIntervalMs),R=!1,D=()=>{if(!R)R=!0,this.deps.timer.clearInterval(c)};return d.once("close",D),d.once("finish",D),D}async dispatch(d,c,R,{parsedBody:D,sendJsonRpcError:k}){let P=this.startKeepalive(c);try{await R.handleRequest(d,c,D)}catch(C){e.error("Streamable HTTP request handling failed:",C),k("Server error",C)}finally{P()}}}var uI=60000,pI=268435456,pv=30000,mI=1,fI=30000;class wc{deps;httpServer=null;httpServerClosePromise=null;shutdownIngressAbort=new AbortController;httpAllowedHosts=[];mcpHttpTransportFactory=(d)=>new nv({enableDnsRebindingProtection:!0,allowedHosts:d});mcpRequestServerFactory=(d,c)=>this.deps.createRequestMcpServer(d,c);mcpHttpEndpoint=new bc({timer:{setInterval:(d,c)=>this.deps.timer().setInterval(d,c),clearInterval:(d)=>this.deps.timer().clearInterval(d)},idGenerator:{next:()=>this.deps.idGenerator().next()},keepaliveIntervalMs:fI,createTransport:()=>this.mcpHttpTransportFactory(this.httpAllowedHosts),createServer:(d,c)=>this.mcpRequestServerFactory(d,c),cancelScopeExecutions:(d,c)=>G.cancelSessionExecutions(d,c),forgetScopeBindings:(d)=>FE(d),closeReason:()=>this.deps.isShutdownInProgress()?new Ia(aS):"streamable_http_onclose"});openHttpRequests=0;httpRequestsSeen=0;acceptingHttpSessions=!1;startupCompleted=!1;constructor(d){this.deps=d}get server(){return this.httpServer}get openRequestCount(){return this.openHttpRequests}get requestsSeenCount(){return this.httpRequestsSeen}markStartupCompleted(){this.startupCompleted=!0}get testHooks(){return{openRequestCount:()=>this.openRequestCount,requestsSeenCount:()=>this.requestsSeenCount,setHttpServer:(d)=>{this.httpServer=d},start:()=>this.start(),closeListener:()=>this.closeListener(),markStartupCompleted:()=>this.markStartupCompleted(),isAcceptingHttpSessions:()=>this.acceptingHttpSessions,setAcceptingHttpSessions:(d)=>{this.acceptingHttpSessions=d},setMcpTransportFactory:(d)=>{this.mcpHttpTransportFactory=d},setMcpRequestServerFactory:(d)=>{this.mcpRequestServerFactory=d},mcpHttpEndpoint:this.mcpHttpEndpoint,handleMcpHttpRequest:(d,c)=>this.handleMcpHttpRequest(d,c),readHttpBody:(d)=>this.readHttpBody(d)}}trackTransportForTesting(d,c){this.mcpHttpEndpoint.trackForTesting(d,c)}inFlightRequests(){return this.mcpHttpEndpoint.inFlightRequests()}clearSessions(){this.mcpHttpEndpoint.clear()}stopAccepting(){this.acceptingHttpSessions=!1,this.mcpHttpEndpoint.stopAccepting()}abortPendingAdmissions(){this.shutdownIngressAbort.abort()}async start(){if(!this.deps.httpToken().value)throw new t("Daemon HTTP token is not configured");let{host:d,port:c}=this.deps.address(),R=this.deps.httpServerFactory();this.httpServer=R,this.httpServerClosePromise=null,this.acceptingHttpSessions=!0;let D=[`127.0.0.1:${c}`,`localhost:${c}`,`[::1]:${c}`];this.httpAllowedHosts=D,R.requestTimeout=0,R.headersTimeout=0,R.timeout=0;let k=(P,C)=>this.handleHttpRequest(P,C,D);return R.on("request",(P,C)=>{k(P,C).catch((M)=>{if(e.warn(`HTTP request callback failed: ${r(M)}`,M),!C.headersSent)C.writeHead(500,{"Content-Type":"application/json"});C.end()})}),new Promise((P,C)=>{R.listen(c,d,()=>{e.info(`automobile:${d}:${c}${Qw}`),P()}),R.on("error",(M)=>{if(this.deps.strictPort()&&M.code==="EADDRINUSE"){C(new t(`Port ${c} on ${d} is required for this daemon start but is already in use by another process. Refusing to fall back to a different port `+"and risk a split-brain daemon (issue #6260) \u2014 find and stop whatever holds "+`port ${c} and retry.`));return}e.error(`HTTP server error: ${M}`),C(M)})})}closeListener(){let d=this.httpServer;if(!d)return Promise.resolve();return this.httpServerClosePromise??=new Promise((c,R)=>{d.close((D)=>{if(D){R(D);return}e.info("HTTP server stopped"),c()})}),this.httpServerClosePromise}admitHttpRequest(d,c,R){if(!d.headers.host||!R.includes(d.headers.host)||d.headers.origin)return c.writeHead(403,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Forbidden"})),!1;return!0}async awaitHttpTokenPublication(d){if(this.deps.httpToken().isPublished)return!0;if(this.acceptingHttpSessions&&!this.startupCompleted){if(!await this.awaitStartupAdmission(d))return!1;if(this.deps.httpToken().isPublished)return!0}return d.writeHead(503,{"Content-Type":"application/json","Retry-After":"1"}),d.end(JSON.stringify({error:"Service unavailable"})),!1}authenticateHttpRequest(d,c){let R=d.headers.authorization;delete d.headers.authorization;for(let k=d.rawHeaders.length-2;k>=0;k-=2)if(d.rawHeaders[k]?.toLowerCase()==="authorization")d.rawHeaders.splice(k,2);let D=this.deps.httpToken().value;if(!D||!rl(R,D))return c.writeHead(401,{"Content-Type":"application/json","WWW-Authenticate":"Bearer"}),c.end(JSON.stringify({error:"Unauthorized"})),!1;return!0}async handleHttpRequest(d,c,R){if(!this.admitHttpRequest(d,c,R)||!(this.deps.httpToken().isPublished||await this.awaitHttpTokenPublication(c))||!this.authenticateHttpRequest(d,c))return;if(this.openHttpRequests++,this.httpRequestsSeen++,c.once("close",()=>{this.openHttpRequests--}),d.method==="OPTIONS"){c.writeHead(200),c.end();return}let D=new URL(d.url,`http://${d.headers.host}`);if(D.pathname===oY)return this.handleHeartbeatHttpRequest(d,c);if(D.pathname===Qw)return this.handleMcpHttpRequest(d,c);else c.writeHead(404,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Not found"}))}async handleHeartbeatHttpRequest(d,c){if(d.method!=="POST"){c.writeHead(405,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Method not allowed"}));return}let R=await this.readHttpBody(d);if(!R.ok){this.respondToBodyReadFailure(c,R);return}let D=av(R.body);if(!D.ok){c.writeHead(D.response.status,{"Content-Type":"application/json"}),c.end(JSON.stringify(D.response.body));return}let k=await dv(this.deps.sessionManager(),this.deps.observerSessionRegistry(),D.sessionId,D.livenessOwnerToken);c.writeHead(k.status,{"Content-Type":"application/json"}),c.end(JSON.stringify(k.body))}async admitHttpMcpRequest(d){if(!this.acceptingHttpSessions)return d.writeHead(503,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:"Daemon is shutting down"})),!1;return this.awaitStartupAdmission(d)}async awaitStartupAdmission(d){if(this.startupCompleted)return!0;let c=Symbol("HTTP startup admission timeout"),R=this.shutdownIngressAbort.signal;try{return await l(this.deps.startupCompletion(),{timer:this.deps.timer(),timeoutMs:pv,signal:R,label:"HTTP MCP startup admission",timeoutError:()=>c}),!0}catch(D){if(R.aborted)return e.info("HTTP MCP request refused: daemon shut down during startup admission"),d.writeHead(503,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:"Daemon is shutting down"})),!1;if(D===c)return e.warn(`HTTP MCP request refused: daemon still starting after ${pv}ms`),d.writeHead(503,{"Content-Type":"application/json","Retry-After":String(mI)}),d.end(JSON.stringify({error:"Daemon is still starting"})),!1;return e.warn(`HTTP MCP request refused: daemon startup failed: ${r(D)}`),d.writeHead(503,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:"Daemon startup failed"})),!1}}async handleMcpHttpRequest(d,c){if(!await this.admitHttpMcpRequest(c))return;let R;if(d.method==="POST"){let k=await this.readHttpBody(d);if(!k.ok){this.respondToBodyReadFailure(c,k);return}try{R=JSON.parse(k.body)}catch(P){e.debug(`Invalid MCP JSON: ${P}`),c.writeHead(400,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Invalid JSON"}));return}}let D=(k,P)=>this.sendHttpJsonRpcError(c,R,k,P);if(!this.acceptingHttpSessions){c.writeHead(503,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Daemon is shutting down"}));return}return this.mcpHttpEndpoint.handle(d,c,R,D)}sendHttpJsonRpcError(d,c,R,D){if(d.headersSent)return;let k=c&&typeof c==="object"&&"id"in c?c.id:null;d.writeHead(200,{"Content-Type":"application/json"}),d.end(JSON.stringify({jsonrpc:"2.0",id:k,error:{code:-32603,message:R,data:D instanceof Error?D.message:void 0}}))}readHttpBody(d){let c=this.deps.timer();return new Promise((R)=>{let D=[],k=0,P=!1,C=(V)=>{if(P)return;P=!0,c.clearTimeout(W),d.off("data",M),d.off("end",F),d.off("error",q),d.off("aborted",U),d.off("close",K),R(V)},M=(V)=>{let z=Buffer.isBuffer(V)?V:Buffer.from(V);if(k+=z.length,k>pI){C({ok:!1,status:413,error:"Request body too large"}),d.destroy();return}D.push(z)},F=()=>C({ok:!0,body:Buffer.concat(D).toString("utf8")}),q=(V)=>{e.warn("HTTP request body read failed",V),C({ok:!1,status:400,error:"Request body read failed"})},U=()=>C({ok:!1,status:400,error:"Request aborted"}),K=()=>C({ok:!1,status:400,error:"Request closed"}),W=c.setTimeout(()=>{C({ok:!1,status:408,error:"Request body timed out"}),d.destroy()},uI);d.on("data",M),d.on("end",F),d.on("error",q),d.on("aborted",U),d.on("close",K)})}respondToBodyReadFailure(d,c){if(!d.destroyed)d.writeHead(c.status,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:c.error}))}}class Dc{host;httpIngress;mcpDispatcher;constructor(d){this.host=d;this.httpIngress=new wc({...d,createRequestMcpServer:(c,R)=>An(this.statelessMcpServerBase(),Dn({headers:c.headers}),R)}),this.mcpDispatcher=Pn({base:()=>this.statelessMcpServerBase(),idGenerator:{next:()=>d.idGenerator().next()},closeReason:()=>d.isShutdownInProgress()?new Ia(aS):ua})}statelessMcpServerBase(){return{deviceReadiness:this.host.deviceReadiness(),iosDependencies:this.host.iosDoctorDependencies,debug:this.host.debug(),acceptanceDiscoveryCapability:this.host.acceptanceDiscoveryCapability()}}}async function fv(d,c){let R=new Map,D=new Map,k=new Map,P=!1,C=hI(R,c),M=(U,K)=>{let W=c.getDeviceIncarnation(U),V=new Set(c.ownedCaptureIds()),z=(R.get(U)??[]).filter((J)=>J.captureTeardown&&(!K||!V.has(J.recordingId))&&hv(J,W));if(z.length===0||W!==void 0&&k.get(U)===W)return;if(W===void 0&&z.some((J)=>J.captureTeardown?.kind!=="ios-host-recorder")){e.warn(`[RecordingTeardownRedrive] Device ${U} has no pool incarnation; retaining capture descriptors until the device is pooled`);return}for(let J of z)J.hookDriven||=K;if(k.set(U,W),d.getSessionForDevice(U)!==null){if(D.set(U,{records:z,hookDriven:K}),!P)gI(d,D,c),P=!0}else if(W===void 0)d.registerPendingDeviceCleanup(U,vv(d,U,z,{deps:c,hookDriven:K}),Yl);else gv(d,U,z,{deps:c,hookDriven:K})};c.onDeviceIncarnationAssigned?.((U)=>M(U,!0)),c.onDeviceProcessStarted?.(async(U)=>{if(C.list(U).length===0)return;try{await l(()=>C.stop(U,void 0,{mode:"background"}),{timer:c.timer,timeoutMs:Yl,label:`Process-start orphan recorder teardown on ${U}`})}catch(K){e.warn(`[RecordingTeardownRedrive] Process-start teardown unconfirmed on ${U}`,K)}});let F;try{F=await c.recordingRepository.listRecordings({hasCaptureTeardown:!0,excludeLiveDaemonSessionIds:c.liveDaemonSessionIds})}catch(U){return e.warn("[RecordingTeardownRedrive] Could not read unconfirmed capture teardowns; continuing startup",U),!1}let q=new Set(c.ownedCaptureIds());for(let U of F){if(!U.captureTeardown||q.has(U.recordingId))continue;let K=R.get(U.deviceId)??[];K.push({...U}),R.set(U.deviceId,K)}for(let U of R.keys())M(U,!1);return c.onStartupOrphans?.(C),!0}function hI(d,c){let R=(k)=>(d.get(k)??[]).filter((P)=>P.captureTeardown&&!c.ownedCaptureIds().includes(P.recordingId)&&hv(P,c.getDeviceIncarnation(k))),D=(k)=>({recordingId:k.recordingId,deviceId:k.deviceId,ownerSessionUuid:k.ownerSessionUuid});return{list:(k)=>R(k).map(D),find:(k)=>{for(let P of d.keys()){let C=R(P).find((M)=>M.recordingId===k);if(C)return D(C)}return},stop:async(k,P,C)=>{let M=R(k).filter((F)=>!P||F.recordingId===P);try{await kc(k,M,c,{waitForExpiry:!1,mode:C?.mode??"user"})}finally{let F=new Set(M.map((q)=>q.withdrawRetry));for(let q of F)if(q&&!(d.get(k)??[]).some((U)=>U.withdrawRetry===q&&U.captureTeardown))q()}}}}function hv(d,c){if(c===void 0||d.firstMarkedIncarnation===void 0||d.firstMarkedIncarnation===c||Ac(d.captureTeardown)||Number.isFinite(Pc(d)))return!0;if(!d.warnedUnconfirmableRedrive)e.warn(`[RecordingTeardownRedrive] Unconfirmable descriptor for ${d.recordingId} is retained; device ${d.deviceId} is no longer quarantined for it after its first marked incarnation`),d.warnedUnconfirmableRedrive=!0;return!1}function gv(d,c,R,{deps:D,hookDriven:k=!1}){if(R=R.filter((M)=>M.captureTeardown),R.length===0)return;let P=R.map((M)=>{let F=Pc(M);return Number.isFinite(F)?Math.max(0,F-D.now()):0}),C=d.markDeviceNeedsRecorderTeardown(c,()=>kc(c,R,D,{waitForExpiry:!0,hookDriven:k}),Math.max(Yl,...P.map((M)=>M+Yl)));for(let M of R)M.withdrawRetry=C,M.firstMarkedIncarnation??=D.getDeviceIncarnation(c)}function gI(d,c,R){let D=(k,P=!1)=>{let C=c.get(k);if(!C)return;let{hookDriven:M}=C,{records:F}=C;if(c.delete(k),P){if(vI(F.filter((q)=>q.captureTeardown?.kind!=="ios-host-recorder"),R),F=F.filter((q)=>q.captureTeardown?.kind==="ios-host-recorder"),F.length===0)return}d.registerPendingDeviceCleanup(k,vv(d,k,F,{deps:R,hookDriven:M}),Yl)};d.onSessionRelease((k,P,C,M)=>{if(!M?.upgradeOnly)D(P,M?.deviceIdentityReplaced)}),d.onSessionDeviceUnbound((k,P,C)=>D(P,C?.deviceIdentityReplaced))}async function vI(d,c){for(let R of d)try{await c.recordingRepository.updateRecording(R.recordingId,{captureTeardown:void 0}),R.captureTeardown=void 0}catch(D){e.warn(`[RecordingTeardownRedrive] Could not clear replaced-device descriptor for ${R.recordingId}`,D)}}async function vv(d,c,R,{deps:D,hookDriven:k}){try{await l(()=>kc(c,R,D,{waitForExpiry:!1,hookDriven:k}),{timer:D.timer,timeoutMs:Yl,label:`Released orphan recorder teardown on ${c}`})}catch(P){e.warn(`[RecordingTeardownRedrive] Release-time teardown unconfirmed on ${c}`,P),gv(d,c,R,{deps:D,hookDriven:k})}}async function kc(d,c,R,{waitForExpiry:D,hookDriven:k=!1,mode:P="background"}){let C=[],M=[];for(let F of c){if(!F.captureTeardown||R.ownedCaptureIds().includes(F.recordingId))continue;try{await yI(F,R,D,{hookDriven:k,mode:P})}catch(q){e.warn(`[RecordingTeardownRedrive] Teardown unconfirmed for ${F.recordingId} on ${d}`,q),C.push(F.recordingId),M.push(q)}}if(C.length>0)throw new((M.every((q)=>q instanceof Zc))?Zc:t)(`Orphan recorder teardown on ${d} is unconfirmed for ${C.join(", ")}. Recover the device if retries fail.`,{cause:M[0]})}async function yI(d,c,R,{hookDriven:D,mode:k}){if(!R&&!Ac(d.captureTeardown)&&d.captureTeardown)await mv(d,c,!1,k);if(d.confirmation)return d.confirmation;let P=(async()=>{if((D||d.hookDriven)&&!await SI(d,c))return;let C=d.captureTeardown;if(!C||c.ownedCaptureIds().includes(d.recordingId))return;if(await mv(d,c,R,k),d.captureTeardown!==C)return;await c.recordingRepository.updateRecording(d.recordingId,{captureTeardown:void 0}),d.captureTeardown=void 0})();d.confirmation=P;try{await P}finally{if(d.confirmation===P)d.confirmation=void 0}}async function SI(d,c){if(c.ownedCaptureIds().includes(d.recordingId))return!1;if((await c.recordingRepository.listRecordings({hasCaptureTeardown:!0,excludeLiveDaemonSessionIds:c.liveDaemonSessionIds,deviceId:d.deviceId})).some((D)=>D.recordingId===d.recordingId))return!c.ownedCaptureIds().includes(d.recordingId);return d.captureTeardown=void 0,!1}function Ac(d){return d?.kind==="ios-host-recorder"?d.hostPid!==void 0:d?.devicePid!==void 0}function Pc(d){if(Ac(d.captureTeardown)||!d.captureTeardown)return NaN;return Date.parse(d.startedAt)+Oi*1000+Aq}async function mv(d,c,R,D){let k=d.captureTeardown;if(k.kind==="ios-host-recorder"){await c.forceStopOrphanedCapture(void 0,k,{mode:D});return}if(k.devicePid===void 0){let C=Pc(d);if(!Number.isFinite(C)||!R&&c.now()<C)throw new t(`Orphan recorder ${d.recordingId} on ${d.deviceId} has no pid and its screenrecord hard limit has not elapsed.`);if(c.now()<C)await c.timer.sleep(C-c.now());return}let P=c.getDevice(d.deviceId);if(!P)throw new Zc(`Cannot find device ${d.deviceId} to confirm orphan recorder teardown.`);await c.forceStopOrphanedCapture(P,k)}var jt={initializeRecordingTeardownRedriveState:(...d)=>eN(...d),listActiveVideoRecordings:(...d)=>sc(...d),redriveUnconfirmedCaptureTeardowns:(...d)=>fv(...d),setStartupOrphanCaptures:(...d)=>wX(...d),setVideoRecordingManagerDependencies:(...d)=>RX(...d)};async function yv(d,c){let R=d.services.sessionManager().getSession(c);if(d.lifecycle.shutdownInProgress()||!R||!d.services.sessionManager().isLiveManagedExecutionSession(c))return;let D=R.assignedDevice;if(er([{id:D,platform:R.platform}],d.services.passiveWorkPolicy()).length===0||d.services.sessionManager().getSessionForDevice(D)!==c)return;await tr([D],{timer:d.services.timer(),perDeviceTimeoutMs:5000,pendingPrefetch:()=>it.pendingPrefetch(),isShuttingDown:()=>d.lifecycle.shutdownInProgress(),verifyIosDevice:async(P,C)=>{if(!d.lifecycle.shutdownInProgress()&&d.services.sessionManager().isLiveManagedExecutionSession(c)&&d.services.sessionManager().getSession(c)?.assignedDevice===P&&d.services.sessionManager().getSessionForDevice(P)===c&&d.lifecycle.managedExecutionReowner()?.ownershipState(c)===void 0)await d.services.iosDeviceVerifier()().verifyIosDevice(P,C)}})}function Ic(d){return{getSession:(c)=>d().getSession(c),getPersistedSession:(c)=>d().getSession(c)}}class Sv{httpToken;stoppingRecordings=new Set;broker;sessionsCore;get sessions(){return this.sessionsCore??=this.createDaemonSessions(this.createDaemonCoreServices(),this.createDaemonIdentityState(),this.createDaemonLifecycleState())}startup;identity;streams;maintenance;disconnectCore;get disconnect(){return this.disconnectCore??=this.createDaemonDisconnect(this.createDaemonCoreServices(),this.createDaemonLifecycleState())}shutdown;injected;deviceReadiness;iosDoctorDependencies=bn({coreDeviceProbe:Ob()});exitRecordFileSystem=IA;startHost;selfExitRecorder=new l4({write:(d)=>this.startHost.writeExitRecord(d),now:()=>this.timer.now(),buildId:()=>Vo().buildId,options:()=>({...os(this.options),port:this.listen.port}),canRecord:()=>this.runtime.enteredDaemonProcess&&(this.runtime.socketBindCommitted||!this.incumbentOwnerGuard.hasLiveForeignOwner())});startupCompletion=dl();mcpServices=new Dc({deviceReadiness:()=>this.deviceReadiness,httpToken:()=>this.httpToken,iosDoctorDependencies:this.iosDoctorDependencies,debug:()=>this.listen.debug,acceptanceDiscoveryCapability:()=>this.acceptanceDiscoveryCapability,httpServerFactory:()=>this.injected.httpServerFactory(),timer:()=>this.timer,idGenerator:()=>this.idGenerator,address:()=>({host:this.listen.host,port:this.listen.port}),strictPort:()=>this.listen.strictPort,startupCompletion:()=>this.startupCompletion.promise,sessionManager:()=>this.sessionManager,observerSessionRegistry:()=>this.observerSessionRegistry,isShutdownInProgress:()=>this.shutdownState.inProgress});httpIngress=this.mcpServices.httpIngress;mcpDispatcher=this.mcpServices.mcpDispatcher;listen;incumbentOwnerGuard;deviceLoss=new Ir;observerSessionRegistry;sessionManager;devicePool;deviceSessionRegistry;daemonSessionId;installedAppsRepository;deviceSessionRepository;timer;sessionBrokerConfigPath=I(h.SESSION_BROKER_CONFIG)?bI(I(h.SESSION_BROKER_CONFIG)):void 0;processIdentity;passiveWorkPolicy;idGenerator;database;observationStreamHealth;navigationGraphBridge=new kr({server:()=>this.runtime.deviceDataStreamServer,sessionIds:()=>this.sessionManager.getAllSessions().map((d)=>d.sessionId),defaultManager:()=>he.getInstance(),managerForSession:(d)=>he.getInstanceForSession(d)});deviceStateChangeNotifier;options;acceptanceDiscoveryCapability=I(h.ACCEPTANCE_DISCOVERY_CAPABILITY);shutdownState=new Cr;runtime=new Er;daemonState;constructor(d={},c={}){let R=this.createDaemonCoreServices(),D=this.createDaemonIdentityState(),k=this.createDaemonLifecycleState();this.broker=this.createDaemonBroker(R,D,k),this.startup=this.createDaemonStartup(R,D,k),this.identity=this.createDaemonIdentity(R,D),this.streams=this.createDaemonStreams(R,k),this.maintenance=this.createDaemonMaintenance(R,D,k),this.shutdown=this.createDaemonShutdown(R,k);let{timer:P,deviceSessionRepository:C,idGenerator:M,databaseInitializer:F,startupFailureTracker:q,databaseHealthProbe:U,recoveryPolicyEnvironment:K,managedAdbServerShutdown:W,toolSelectionProfileProvenanceLoader:V,processBirthTime:z,processGenerationToken:J,incumbentOwnerGuard:X,installedAppsRepository:te,recoverFromDatabaseHealthFailure:re,...ie}=al(c);this.deviceReadiness=ie.deviceReadiness,this.daemonState=ie.daemonState,this.httpToken=new Lr(ie.httpTokenStore,c.idGenerator,ie.httpToken),this.injected={httpServerFactory:ie.httpServerFactory,liveDaemonSessionIdProvider:ie.liveDaemonSessionIdProvider,avdManagerFactory:ie.avdManagerFactory,iosDeviceVerifier:ie.iosDeviceVerifier,bindingExclusionFactory:ie.bindingExclusionFactory,foreignCtrlProxyForwardEvidence:ie.foreignCtrlProxyForwardEvidence,stopManagedAdbServer:W,hostIoStalled:ie.hostIoStalled},sS(),this.startupCompletion.promise.then(()=>{this.httpIngress.markStartupCompleted()},(pe)=>{e.debug(`Daemon startup completion rejected: ${r(pe)}`)}),this.options={...d},this.listen={port:d.port||ld,host:d.host||"127.0.0.1",strictPort:d.strictPort??!1,debug:d.debug||!1},iJ(this.listen.port),this.idGenerator=M,this.daemonSessionId=this.idGenerator.next(),this.timer=P,this.deviceStateChangeNotifier=Gc({timer:P,invalidate:wI,notify:KX}),this.processIdentity={generationStartedAt:this.timer.now(),processStartedAt:z(),processGenerationToken:J(),liveAcceptanceStartupSecret:lq()},this.incumbentOwnerGuard=X,this.passiveWorkPolicy=new br(Uc(process.env,p4),(pe)=>this.sessionManager.getAllSessions().some((de)=>de.assignedDevice===pe)),this.database={databaseInitializer:F,toolSelectionProfileProvenanceLoader:V,databaseHealthProbe:U,startupFailureTracker:q,recoverFromDatabaseHealthFailure:re??qg({timer:()=>this.timer,selfExitRecorder:()=>this.selfExitRecorder,getDaemonFileCleanupOptions:()=>this.identity.getDaemonFileCleanupOptions()})},this.observationStreamHealth=Kg({timer:()=>this.timer,startAuxiliarySocket:(...pe)=>this.identity.startAuxiliarySocket(...pe),configureDeviceDataStreamServer:()=>this.streams.configureDeviceDataStreamServer()}),this.deviceSessionRepository=C,this.sessionManager=new QI(this.timer,this.deviceSessionRepository,{sessionDeviceReboundEmitter:Iq}),this.sessionManager.attachDaemonSessionId(this.daemonSessionId),this.sessionManager.attachLiveDaemonSessionIds(()=>this.incumbentOwnerGuard.withLiveIncumbent(this.injected.liveDaemonSessionIdProvider.collectLiveDaemonSessionIds())),this.observerSessionRegistry=Gg(this.timer),this.sessions.configureSessionLifecycleCallbacks(),this.installedAppsRepository=te??new Ss;let oe=Wg(K);this.deviceSessionRegistry=new fB(this.timer,this.idGenerator),this.devicePool=this.sessions.createDevicePool(oe.policy,K),G.setAutolockSessionResolver({autolockSessionForMcpSession:(pe)=>this.devicePool.captureAutolockSessionForMcpSession(pe)}),this.daemonState.initialize(this.sessionManager,this.devicePool,this.deviceSessionRegistry,this.observerSessionRegistry),this.daemonState.setSessionBrokerMode(this.sessionBrokerConfigPath!==void 0),this.broker.installManagedExecutionRelease(),this.broker.installBrokerDeviceAcquisition(),this.startup.applyRuntimeOptions(d),this.startup.applyAccessibilityOptions(d),this.applyToolOutputOptions(d)}openBindingRegistry(...d){return this.broker.openBindingRegistry(...d)}stopSessionTimers(...d){return this.sessions.stopSessionTimers(...d)}subscribeToolCallEndActivity(...d){return this.sessions.subscribeToolCallEndActivity(...d)}start(...d){return this.startup.start(...d)}startOn(...d){return this.startup.startOn(...d)}stopAfterFailedStartup(...d){return this.startup.stopAfterFailedStartup(...d)}startThroughSocketBind(...d){return this.startup.startThroughSocketBind(...d)}startAfterSocketBind(...d){return this.startup.startAfterSocketBind(...d)}getDeviceSessionRoutingTargets(...d){return this.streams.getDeviceSessionRoutingTargets(...d)}setupDeviceDataStreamCallback(...d){return this.streams.setupDeviceDataStreamCallback(...d)}setupNavigationGraphStreamListener(...d){return this.streams.setupNavigationGraphStreamListener(...d)}startHeartbeatMonitor(...d){return this.maintenance.startHeartbeatMonitor(...d)}recordAndTryRecoverCapturedDisconnect(...d){return this.disconnect.recordAndTryRecoverCapturedDisconnect(...d)}startDeviceDisconnectMonitor(...d){return this.disconnect.startDeviceDisconnectMonitor(...d)}trackDeferredSessionRecoverySweep(...d){return this.disconnect.trackDeferredSessionRecoverySweep(...d)}stopRecordingAfterDeviceDisconnect(...d){return this.disconnect.stopRecordingAfterDeviceDisconnect(...d)}shouldSkipStaleDisconnectCleanup(...d){return this.disconnect.shouldSkipStaleDisconnectCleanup(...d)}isCapturedDisconnectTargetCurrent(...d){return xg({services:this.createDaemonCoreServices()},...d)}startAdbMissingDeviceListener(...d){return this.disconnect.startAdbMissingDeviceListener(...d)}cancelAndReleaseSession(...d){return this.sessions.cancelAndReleaseSession(...d)}attemptRecovery(...d){return this.maintenance.attemptRecovery(...d)}initializeDevicePoolWithTimeout(...d){return this.startup.initializeDevicePoolWithTimeout(...d)}initializeDevicePool(...d){return this.startup.initializeDevicePool(...d)}initializeIosServices(...d){return this.startup.initializeIosServices(...d)}initializeDatabase(...d){return this.startup.initializeDatabase(...d)}setupShutdownHandlers(...d){return this.shutdown.setupShutdownHandlers(...d)}get testHooks(){return{...this.startup.testHooks,...this.broker.testHooks,...this.streams.testHooks,...this.maintenance.testHooks,...this.shutdown.testHooks,sessionManager:this.sessionManager,devicePool:this.devicePool,deviceSessionRegistry:this.deviceSessionRegistry,navigationGraphBridge:this.navigationGraphBridge,httpIngress:this.httpIngress.testHooks,prepareHttpToken:()=>this.httpToken.prepare(),publishHttpToken:()=>this.httpToken.publish(),setSocketServer:(d)=>{this.runtime.socketServer=d&&qc(d)},registerTransport:(d,c)=>this.httpIngress.trackTransportForTesting(d,()=>c.close()),overrideRoutingTargets:(d)=>{this.getDeviceSessionRoutingTargets=d},overrideNavigationGraphListener:(d)=>{this.setupNavigationGraphStreamListener=d},attemptRecovery:(d)=>this.attemptRecovery(d),overrideAttemptRecovery:(d)=>{this.attemptRecovery=d},replaceSessionManager:(d)=>{this.sessionManager=d},replaceDevicePool:(d)=>{this.devicePool=d},recordAndTryRecoverCapturedDisconnect:this.recordAndTryRecoverCapturedDisconnect.bind(this),deviceLoss:this.deviceLoss,stoppingRecordings:this.stoppingRecordings,stopRecordingAfterDeviceDisconnect:this.stopRecordingAfterDeviceDisconnect.bind(this),runtime:this.runtime,startDeviceDisconnectMonitor:this.startDeviceDisconnectMonitor.bind(this),createPlanDeviceLossCheck:this.createPlanDeviceLossCheck.bind(this),overrideCapturedDisconnectChecks:(d)=>{Object.assign(this,d)},overrideCleanupDisconnectedDevice:(d)=>{this.cleanupDisconnectedDevice=d},deferredSessionRecoverySweeps:this.runtime.deferredSessionRecoverySweeps,replaceObserverSessionRegistry:(d)=>{this.observerSessionRegistry=d},overrideStartupStages:(d)=>{this.startThroughSocketBind=d.startThroughSocketBind??this.startThroughSocketBind,this.startAfterSocketBind=d.startAfterSocketBind??this.startAfterSocketBind,this.stopAfterFailedStartup=d.stopAfterFailedStartup??this.stopAfterFailedStartup},setSessionBrokerConfigPath:(d)=>{this.sessionBrokerConfigPath=d},setExitRecordFileSystem:(d)=>{this.exitRecordFileSystem=d},setupShutdownHandlers:()=>this.setupShutdownHandlers(),setSocketBindCommitted:(d)=>{this.runtime.socketBindCommitted=d},stopSessionTimers:()=>this.stopSessionTimers(),getAppearanceSyncTargets:()=>this.sessions.getAppearanceSyncTargets(),overrideStartSteps:(d)=>{this.startThroughSocketBind=d.startThroughSocketBind??this.startThroughSocketBind,this.openBindingRegistry=d.openBindingRegistry??this.openBindingRegistry,this.setupShutdownHandlers=d.setupShutdownHandlers??this.setupShutdownHandlers}}}async stop(...d){try{return await this.shutdown.stop(...d)}finally{this.daemonState.retireForeignAndroidSerialSource(this.devicePool)}}getSessionManager(){return this.sessionManager}getDeviceReadiness(){return this.deviceReadiness}getDevicePool(){return this.devicePool}createDaemonBroker(d,c,R){let D=this;return new Ys({readPersistedSession:Ic(()=>this.deviceSessionRepository).getSession,warmConfirmedManagedExecution:(k)=>yv({services:d,lifecycle:R},k),services:d,identity:c,lifecycle:R,bindingRegistry:()=>D.runtime.bindingRegistry,deviceClaimMirrors:()=>D.runtime.deviceClaimMirrors,setBindingRegistry:(k)=>{D.runtime.bindingRegistry=k},brokerDeviceAcquisition:()=>D.runtime.brokerDeviceAcquisition,setBrokerDeviceAcquisition:(k)=>D.runtime.brokerDeviceAcquisition=k,openBindingRegistry:(...k)=>this.openBindingRegistry(...k),cancelAndReleaseSession:(...k)=>this.cancelAndReleaseSession(...k)})}createDaemonSessions(d,c,R){let D=this;return new oa({services:d,identity:c,lifecycle:R,bindingExclusionFactory:()=>D.injected.bindingExclusionFactory,startBackgroundRegistryUpgrade:()=>this.broker.startBackgroundRegistryUpgrade(),bindingRegistry:()=>D.runtime.bindingRegistry,deviceClaimMirrors:()=>D.runtime.deviceClaimMirrors,foreignCtrlProxyForwardEvidence:()=>D.injected.foreignCtrlProxyForwardEvidence,deviceStateChangeNotifier:()=>D.deviceStateChangeNotifier,observerSessionRegistry:()=>D.observerSessionRegistry,cancelAndReleaseSession:(...k)=>this.cancelAndReleaseSession(...k),onDeviceReadyForSessionRegistry:(...k)=>this.streams.onDeviceReadyForSessionRegistry(...k),reownRehydratedManagedExecutions:(...k)=>this.broker.reownRehydratedManagedExecutions(...k)})}createDaemonStartup(d,c,R){let D=this,k=new bd({initializeRecordingTeardownRedriveState:()=>jt.initializeRecordingTeardownRedriveState(),redriveUnconfirmedCaptureTeardowns:(...P)=>jt.redriveUnconfirmedCaptureTeardowns(...P),setStartupOrphanCaptures:(...P)=>jt.setStartupOrphanCaptures(...P),setVideoRecordingManagerDependencies:(...P)=>jt.setVideoRecordingManagerDependencies(...P),enterDaemonProcess:(...P)=>this.enterDaemonProcess(...P),prepareHttpToken:()=>this.httpToken.prepare(),publishHttpToken:()=>this.httpToken.publish(),startHttpIngress:()=>this.startup.startHttpIngress(),bindControlSocket:(...P)=>this.bindControlSocket(...P),startServicesAfterSocketBind:(...P)=>this.startServicesAfterSocketBind(...P),startMaintenanceMonitors:(...P)=>this.startMaintenanceMonitors(...P),readPersistedSession:Ic(()=>this.deviceSessionRepository).getPersistedSession,start:(...P)=>this.start(...P),services:d,identity:c,lifecycle:R,startHost:()=>D.startHost,setStartHost:(P)=>D.startHost=P,enteredDaemonProcess:()=>D.runtime.enteredDaemonProcess,setEnteredDaemonProcess:(P)=>D.runtime.enteredDaemonProcess=P,resolveStartupCompletion:()=>D.startupCompletion.resolve,rejectStartupCompletion:()=>D.startupCompletion.reject,exitRecordFileSystem:()=>D.exitRecordFileSystem,strictPort:()=>D.listen.strictPort,host:()=>D.listen.host,startupFailureTracker:()=>D.database.startupFailureTracker,avdManagerFactory:()=>D.injected.avdManagerFactory,databaseInitializer:()=>D.database.databaseInitializer,toolSelectionProfileProvenanceLoader:()=>D.database.toolSelectionProfileProvenanceLoader,liveDaemonSessionIdProvider:()=>D.injected.liveDaemonSessionIdProvider,startOn:(...P)=>this.startOn(...P),startThroughSocketBind:(...P)=>this.startThroughSocketBind(...P),startAfterSocketBind:(...P)=>this.startAfterSocketBind(...P),stopAfterFailedStartup:(...P)=>this.stopAfterFailedStartup(...P),stop:(...P)=>this.stop(...P),writeEarlyOwnerRecord:(...P)=>this.writeEarlyOwnerRecord(...P),setupShutdownHandlers:(...P)=>this.setupShutdownHandlers(...P),subscribeToolCallEndActivity:(...P)=>this.subscribeToolCallEndActivity(...P),initializeDatabase:(...P)=>this.initializeDatabase(...P),openBindingRegistry:(...P)=>this.openBindingRegistry(...P),initializeDevicePoolWithTimeout:(...P)=>this.initializeDevicePoolWithTimeout(...P),reownRehydratedManagedExecutions:(...P)=>this.broker.reownRehydratedManagedExecutions(...P),installSessionBroker:(...P)=>this.broker.installSessionBroker(...P),startBackgroundRegistryUpgrade:()=>this.broker.startBackgroundRegistryUpgrade(),initializeIosServices:(...P)=>this.initializeIosServices(...P),restoreIncumbentOwnerRecord:(...P)=>this.identity.restoreIncumbentOwnerRecord(...P),republishIdentity:(...P)=>this.identity.republishIdentity(...P),recordControlSocketIdentity:()=>this.identity.recordControlSocketIdentity(),startAuxiliarySocket:(...P)=>this.startAuxiliarySocket(...P),configureDeviceDataStreamServer:(...P)=>this.streams.configureDeviceDataStreamServer(...P),setupDeviceSessionRouting:(...P)=>this.streams.setupDeviceSessionRouting(...P),getAppearanceSyncTargets:(...P)=>this.sessions.getAppearanceSyncTargets(...P),startAdbMissingDeviceListener:(...P)=>this.startAdbMissingDeviceListener(...P),startDeviceDisconnectMonitor:(...P)=>this.startDeviceDisconnectMonitor(...P),writePidFile:(...P)=>this.writePidFile(...P),startHealthCheckTimer:(...P)=>this.maintenance.startHealthCheckTimer(...P),startNavigationRetentionMonitor:(...P)=>this.maintenance.startNavigationRetentionMonitor(...P),startForwardLeaseIdleReleaser:(...P)=>this.maintenance.startForwardLeaseIdleReleaser(...P),startPrivateDaemonOrphanWatchdog:(...P)=>this.maintenance.startPrivateDaemonOrphanWatchdog(...P),startHeartbeatMonitor:(...P)=>this.startHeartbeatMonitor(...P),initializeDevicePool:(...P)=>this.initializeDevicePool(...P)});return this.startHost=k.processStartHost(),k}createDaemonIdentity(d,c){return new wd({pidFileWritten:()=>this.runtime.pidFileWritten,setPidFileWritten:(R)=>this.runtime.pidFileWritten=R,persistPidFileData:(...R)=>this.persistPidFileData(...R),writeEarlyOwnerRecord:(...R)=>this.writeEarlyOwnerRecord(...R),cleanupDaemonFilesForShutdown:(...R)=>this.cleanupDaemonFilesForShutdown(...R),services:d,identity:c})}createDaemonStreams(d,c){return new Pd({services:d,lifecycle:c,setupDeviceDataStreamCallback:(...R)=>this.setupDeviceDataStreamCallback(...R),getDeviceSessionRoutingTargets:(...R)=>this.getDeviceSessionRoutingTargets(...R),setupNavigationGraphStreamListener:(...R)=>this.setupNavigationGraphStreamListener(...R)})}createDaemonMaintenance(d,c,R){return new Ud({services:d,identityState:c,identity:this.identity,lifecycle:R,healthCheck:()=>this.runtime.healthCheck,setHealthCheck:(D)=>this.runtime.healthCheck=D,observationStreamHealth:()=>this.observationStreamHealth,setObservationStreamHealth:(D)=>this.observationStreamHealth=D,lastDatabaseHealthFailure:()=>this.runtime.lastDatabaseHealthFailure,setLastDatabaseHealthFailure:(D)=>this.runtime.lastDatabaseHealthFailure=D,recoverFromDatabaseHealthFailure:()=>this.database.recoverFromDatabaseHealthFailure,hostIoStalled:()=>this.injected.hostIoStalled,attemptRecovery:(...D)=>this.attemptRecovery(...D),sessionExecutionProbe:(...D)=>this.sessions.sessionExecutionProbe(...D),cancelAndReleaseSession:(...D)=>this.cancelAndReleaseSession(...D),republishIdentity:(...D)=>this.identity.republishIdentity(...D),configureDeviceDataStreamServer:(...D)=>this.streams.configureDeviceDataStreamServer(...D)})}createDaemonDisconnect(d,c){let R=this;return new zd({listActiveVideoRecordings:(...D)=>jt.listActiveVideoRecordings(...D),captureDisconnectCleanup:(D,k)=>Bg({services:d,forceDisconnectedDeviceGenerations:()=>R.deviceLoss.forceDisconnectedGenerations},D,k),stoppingRecordings:()=>this.stoppingRecordings,retireAdbServerResetDisconnectState:(...D)=>this.retireAdbServerResetDisconnectState(...D),cleanupDisconnectedDevice:(...D)=>this.cleanupDisconnectedDevice(...D),services:d,lifecycle:c,forceDisconnectedDeviceIds:()=>R.deviceLoss.forceDisconnectedIds,confirmedDisconnectedDeviceIds:()=>R.deviceLoss.confirmedDisconnectedIds,deviceDisconnectMissIncarnations:()=>R.deviceLoss.missIncarnations,offlineEpisodes:()=>R.deviceLoss.offlineEpisodes,offlineRecoveryAttemptedDeviceIds:()=>R.deviceLoss.offlineRecoveryAttemptedIds,setOfflineRecoveryAttemptedDeviceIds:(D)=>R.deviceLoss.offlineRecoveryAttemptedIds=D,offlineRecoveryAttemptedIncarnations:()=>R.deviceLoss.offlineRecoveryAttemptedIncarnations,setOfflineRecoveryAttemptedIncarnations:(D)=>R.deviceLoss.offlineRecoveryAttemptedIncarnations=D,forceDisconnectedDeviceGenerations:()=>R.deviceLoss.forceDisconnectedGenerations,shouldSkipStaleDisconnectCleanup:(...D)=>this.shouldSkipStaleDisconnectCleanup(...D),isCapturedDisconnectTargetCurrent:(...D)=>this.isCapturedDisconnectTargetCurrent(...D),trackDeferredSessionRecoverySweep:(...D)=>this.trackDeferredSessionRecoverySweep(...D),stopRecordingAfterDeviceDisconnect:(...D)=>this.stopRecordingAfterDeviceDisconnect(...D),recordAndTryRecoverCapturedDisconnect:(...D)=>this.recordAndTryRecoverCapturedDisconnect(...D),cancelAndReleaseSession:(...D)=>this.cancelAndReleaseSession(...D)})}createDaemonShutdown(d,c){let R=this;return new Xd({services:d,lifecycle:c,stopManagedAdbServer:()=>R.injected.stopManagedAdbServer,removeHttpToken:()=>this.httpToken.remove(),stop:(...D)=>this.stop(...D),getDaemonFileCleanupOptions:(...D)=>this.identity.getDaemonFileCleanupOptions(...D),closeManagedExecutionRelease:(...D)=>this.broker.closeManagedExecutionRelease(...D),stopHealthCheckTimer:(...D)=>this.maintenance.stopHealthCheckTimer(...D),stopSessionTimers:(...D)=>this.stopSessionTimers(...D),cleanupDaemonFilesForShutdown:(...D)=>this.cleanupDaemonFilesForShutdown(...D),cancelAndReleaseSession:(...D)=>this.cancelAndReleaseSession(...D)})}createDaemonCoreServices(){let d=this;return{deviceReadiness:()=>d.deviceReadiness,iosDeviceVerifier:()=>d.injected.iosDeviceVerifier,httpIngress:()=>d.httpIngress,mcpDispatcher:()=>d.mcpDispatcher,sessionManager:()=>d.sessionManager,devicePool:()=>d.devicePool,deviceSessionRegistry:()=>d.deviceSessionRegistry,installedAppsRepository:()=>d.installedAppsRepository,deviceSessionRepository:()=>d.deviceSessionRepository,timer:()=>d.timer,passiveWorkPolicy:()=>d.passiveWorkPolicy,idGenerator:()=>d.idGenerator,databaseHealthProbe:()=>d.database.databaseHealthProbe,options:()=>d.options,daemonState:()=>d.daemonState}}createDaemonIdentityState(){let d=this;return{port:()=>d.listen.port,setPort:(c)=>d.listen.port=c,completeIdentityPublished:()=>d.runtime.completeIdentityPublished,setCompleteIdentityPublished:(c)=>d.runtime.completeIdentityPublished=c,socketBindCommitted:()=>d.runtime.socketBindCommitted,setSocketBindCommitted:(c)=>d.runtime.socketBindCommitted=c,incumbentOwnerGuard:()=>d.incumbentOwnerGuard,daemonSessionId:()=>d.daemonSessionId,generationStartedAt:()=>d.processIdentity.generationStartedAt,processStartedAt:()=>d.processIdentity.processStartedAt,processGenerationToken:()=>d.processIdentity.processGenerationToken,liveAcceptanceStartupSecret:()=>d.processIdentity.liveAcceptanceStartupSecret,acceptanceDiscoveryCapability:()=>d.acceptanceDiscoveryCapability}}createDaemonLifecycleState(){let d=this;return{socketServer:()=>d.runtime.socketServer,setSocketServer:(c)=>d.runtime.socketServer=c,selfExitRecorder:()=>d.selfExitRecorder,startupCompletion:()=>d.startupCompletion.promise,heartbeatMonitor:()=>d.runtime.heartbeatMonitor,setHeartbeatMonitor:(c)=>d.runtime.heartbeatMonitor=c,navigationRetentionMonitor:()=>d.runtime.navigationRetentionMonitor,setNavigationRetentionMonitor:(c)=>d.runtime.navigationRetentionMonitor=c,forwardLeaseIdleReleaser:()=>d.runtime.forwardLeaseIdleReleaser,setForwardLeaseIdleReleaser:(c)=>d.runtime.forwardLeaseIdleReleaser=c,orphanWatchdog:()=>d.runtime.orphanWatchdog,setOrphanWatchdog:(c)=>d.runtime.orphanWatchdog=c,deviceDisconnectMonitor:()=>d.runtime.deviceDisconnectMonitor,setDeviceDisconnectMonitor:(c)=>d.runtime.deviceDisconnectMonitor=c,deferredSessionRecoverySweeps:()=>d.runtime.deferredSessionRecoverySweeps,deviceDisconnectMisses:()=>d.deviceLoss.misses,sessionBrokerConfigPath:()=>d.sessionBrokerConfigPath,managedExecutionReowner:()=>d.runtime.managedExecutionReowner,setManagedExecutionReowner:(c)=>d.runtime.managedExecutionReowner=c,deviceDataStreamServer:()=>d.runtime.deviceDataStreamServer,setDeviceDataStreamServer:(c)=>d.runtime.deviceDataStreamServer=c,navigationGraphBridge:()=>d.navigationGraphBridge,unsubscribeAdbMissingDevice:()=>d.runtime.unsubscribeAdbMissingDevice,setUnsubscribeAdbMissingDevice:(c)=>d.runtime.unsubscribeAdbMissingDevice=c,shutdownInProgress:()=>d.shutdownState.inProgress,setShutdownInProgress:(c)=>d.shutdownState.inProgress=c,recorderDeviceIncarnationListener:()=>d.runtime.recorderDeviceIncarnationListener,setRecorderDeviceIncarnationListener:(c)=>d.runtime.recorderDeviceIncarnationListener=c,shutdownReleaseNotifications:()=>d.shutdownState.releaseNotifications,setShutdownReleaseNotifications:(c)=>d.shutdownState.releaseNotifications=c,shutdownFallbackReleaseNotifications:()=>d.shutdownState.fallbackReleaseNotifications,setShutdownFallbackReleaseNotifications:(c)=>d.shutdownState.fallbackReleaseNotifications=c,backgroundRegistryUpgrade:()=>d.runtime.backgroundRegistryUpgrade,setBackgroundRegistryUpgrade:(c)=>d.runtime.backgroundRegistryUpgrade=c}}enterDaemonProcess(...d){return this.startup.enterDaemonProcess(...d)}writeEarlyOwnerRecord(...d){return this.identity.writeEarlyOwnerRecord(...d)}writePidFile(...d){return this.identity.writePidFile(...d)}persistPidFileData(...d){return this.identity.persistPidFileData(...d)}bindControlSocket(...d){return this.startup.bindControlSocket(...d)}startServicesAfterSocketBind(...d){return this.startup.startServicesAfterSocketBind(...d)}startAuxiliarySocket(...d){return this.identity.startAuxiliarySocket(...d)}startMaintenanceMonitors(...d){return this.startup.startMaintenanceMonitors(...d)}cleanupDaemonFilesForShutdown(...d){return this.identity.cleanupDaemonFilesForShutdown(...d)}bindingJournalOwner(...d){return this.broker.bindingJournalOwner(...d)}cleanupDisconnectedDevice(...d){return this.disconnect.cleanupDisconnectedDevice(...d)}createPlanDeviceLossCheck(...d){return this.disconnect.createPlanDeviceLossCheck(...d)}getDaemonFileCleanupOptions(...d){return this.identity.getDaemonFileCleanupOptions(...d)}retireAdbServerResetDisconnectState(...d){return this.disconnect.retireAdbServerResetDisconnectState(...d)}applyToolOutputOptions(d){$h(d,this.options)}}async function bre(d={}){let c=new Sv(d,{foreignCtrlProxyForwardEvidence:qB()});ch().setDeviceReadiness(c.getDeviceReadiness()),await c.start()}export{bre as startDaemon};
53
+
54
+ //# debugId=B8366AE485B29F8E64756E2164756E21