@kaeawc/auto-mobile 0.0.90 → 0.0.92

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 (280) hide show
  1. package/README.md +7 -0
  2. package/README.md.backup +7 -0
  3. package/dist/build-info.json +12 -11
  4. package/dist/schemas/README.md +16 -0
  5. package/dist/schemas/prototype-icon-names.json +302 -0
  6. package/dist/schemas/prototype-platform-permissions.json +75 -0
  7. package/dist/schemas/test-plan.schema.json +2 -2
  8. package/dist/src/chunk-09442h7v.js +4 -0
  9. package/dist/src/chunk-0dfnyfkh.js +5 -0
  10. package/dist/src/chunk-0e4gm1kj.js +5 -0
  11. package/dist/src/chunk-0eb8576f.js +4 -0
  12. package/dist/src/chunk-0rjm4nx7.js +5 -0
  13. package/dist/src/chunk-0w1spptt.js +6 -0
  14. package/dist/src/chunk-1zmh2eak.js +4 -0
  15. package/dist/src/chunk-28k63ha3.js +5 -0
  16. package/dist/src/chunk-2d4wmp8b.js +4 -0
  17. package/dist/src/chunk-2e6s75qv.js +78 -0
  18. package/dist/src/chunk-2v7tw1nj.js +5 -0
  19. package/dist/src/chunk-32jpxz2y.js +323 -0
  20. package/dist/src/chunk-34zxqcmq.js +5 -0
  21. package/dist/src/chunk-3jmvqygr.js +238 -0
  22. package/dist/src/chunk-3swvfhqt.js +5 -0
  23. package/dist/src/chunk-44bt78m9.js +5 -0
  24. package/dist/src/chunk-488vt2bp.js +4 -0
  25. package/dist/src/chunk-4fgdhcwx.js +5 -0
  26. package/dist/src/chunk-4jp2se4w.js +4 -0
  27. package/dist/src/chunk-4pfftt07.js +5 -0
  28. package/dist/src/chunk-4vhr9e4t.js +4 -0
  29. package/dist/src/chunk-4xd6zs3y.js +15 -0
  30. package/dist/src/chunk-51567pg8.js +4 -0
  31. package/dist/src/chunk-5agqsfev.js +4 -0
  32. package/dist/src/chunk-5d706gmr.js +4 -0
  33. package/dist/src/chunk-5kd4rqk7.js +5 -0
  34. package/dist/src/chunk-5s645vr4.js +4 -0
  35. package/dist/src/chunk-61t538bm.js +4 -0
  36. package/dist/src/chunk-6d3mmqxt.js +54 -0
  37. package/dist/src/chunk-6hyt398x.js +5 -0
  38. package/dist/src/chunk-6mnr8kpm.js +4 -0
  39. package/dist/src/chunk-6pg7bqck.js +4 -0
  40. package/dist/src/chunk-79q5xsdc.js +42 -0
  41. package/dist/src/chunk-7bdgand3.js +4 -0
  42. package/dist/src/chunk-84cp9dw5.js +4 -0
  43. package/dist/src/chunk-86f2h5ww.js +5 -0
  44. package/dist/src/chunk-8cghfzb2.js +19 -0
  45. package/dist/src/chunk-8en08r7q.js +5 -0
  46. package/dist/src/chunk-950qcq1e.js +10 -0
  47. package/dist/src/chunk-9rkfyt6q.js +5 -0
  48. package/dist/src/chunk-9tf2p9y9.js +5 -0
  49. package/dist/src/chunk-9y5bcy28.js +6 -0
  50. package/dist/src/chunk-a2sc4jm0.js +5 -0
  51. package/dist/src/chunk-a4k9rt7z.js +5 -0
  52. package/dist/src/chunk-aa5ng3d1.js +4 -0
  53. package/dist/src/chunk-ajsrz473.js +5 -0
  54. package/dist/src/chunk-b3h0a6ca.js +4 -0
  55. package/dist/src/chunk-b4cxdzwy.js +20 -0
  56. package/dist/src/chunk-b6a737qt.js +4 -0
  57. package/dist/src/chunk-bn64x5z5.js +5 -0
  58. package/dist/src/chunk-bvh649za.js +12 -0
  59. package/dist/src/chunk-c9nk1r78.js +5 -0
  60. package/dist/src/chunk-c9tyfg4j.js +26 -0
  61. package/dist/src/chunk-cfsdfqnm.js +4 -0
  62. package/dist/src/chunk-cxyf04jc.js +7 -0
  63. package/dist/src/chunk-d57432wq.js +4 -0
  64. package/dist/src/chunk-da08tx5v.js +4 -0
  65. package/dist/src/chunk-eka89q3k.js +4 -0
  66. package/dist/src/chunk-f2tc08m2.js +4 -0
  67. package/dist/src/chunk-f8tnk179.js +5 -0
  68. package/dist/src/chunk-f9s1kkhx.js +5 -0
  69. package/dist/src/chunk-fbp8a4rx.js +4 -0
  70. package/dist/src/chunk-fd2z0sze.js +4 -0
  71. package/dist/src/chunk-fk927f4q.js +54 -0
  72. package/dist/src/chunk-fxmr3a0f.js +4 -0
  73. package/dist/src/chunk-gaqwhd44.js +4 -0
  74. package/dist/src/chunk-ggtd5x5a.js +5 -0
  75. package/dist/src/chunk-gndcfrm7.js +4 -0
  76. package/dist/src/chunk-h3n4adc6.js +310 -0
  77. package/dist/src/chunk-h5pjbb83.js +4 -0
  78. package/dist/src/chunk-hgnnh302.js +4 -0
  79. package/dist/src/chunk-hmke8nhx.js +5 -0
  80. package/dist/src/chunk-j2bx12hn.js +4 -0
  81. package/dist/src/chunk-j70y1a2g.js +4 -0
  82. package/dist/src/chunk-jdqvcq0a.js +5 -0
  83. package/dist/src/chunk-jhnbfj19.js +55 -0
  84. package/dist/src/chunk-js1jpyxp.js +6 -0
  85. package/dist/src/chunk-kbjq0qvb.js +4 -0
  86. package/dist/src/chunk-kfwx57xd.js +4 -0
  87. package/dist/src/chunk-km0dy5vc.js +71 -0
  88. package/dist/src/chunk-kzwctna2.js +4 -0
  89. package/dist/src/chunk-m9ehyehy.js +4 -0
  90. package/dist/src/chunk-mct91p1f.js +4 -0
  91. package/dist/src/chunk-mf9spd4g.js +5 -0
  92. package/dist/src/chunk-mgrcansb.js +4 -0
  93. package/dist/src/chunk-mqc1d0eb.js +6 -0
  94. package/dist/src/chunk-n1zmpk0z.js +4 -0
  95. package/dist/src/chunk-ncyjf63g.js +4 -0
  96. package/dist/src/chunk-nr64d21q.js +973 -0
  97. package/dist/src/chunk-nwm2pq5v.js +168 -0
  98. package/dist/src/chunk-pm06b05d.js +9 -0
  99. package/dist/src/chunk-q50s00ry.js +4 -0
  100. package/dist/src/chunk-qv2918jt.js +4 -0
  101. package/dist/src/chunk-qwye1958.js +14 -0
  102. package/dist/src/chunk-r0f1q783.js +5 -0
  103. package/dist/src/chunk-r14wwk37.js +18 -0
  104. package/dist/src/chunk-r20pe1nv.js +5 -0
  105. package/dist/src/chunk-r8z9pfve.js +5 -0
  106. package/dist/src/chunk-rdpgkjf6.js +4 -0
  107. package/dist/src/chunk-rkr0dks9.js +5 -0
  108. package/dist/src/chunk-rn84t3sf.js +11 -0
  109. package/dist/src/chunk-s123kn7n.js +4 -0
  110. package/dist/src/chunk-s1zq65ny.js +4 -0
  111. package/dist/src/chunk-s73qn3fx.js +4 -0
  112. package/dist/src/chunk-sjn0nj4p.js +5 -0
  113. package/dist/src/chunk-sns0c35v.js +7 -0
  114. package/dist/src/chunk-stfzjr9y.js +8 -0
  115. package/dist/src/chunk-sz1a7p43.js +4 -0
  116. package/dist/src/chunk-t4dr5c8v.js +8 -0
  117. package/dist/src/chunk-tc8k9c1j.js +4 -0
  118. package/dist/src/chunk-teznhase.js +4 -0
  119. package/dist/src/chunk-ty9xgmz4.js +4 -0
  120. package/dist/src/chunk-tyazf3sk.js +145 -0
  121. package/dist/src/chunk-v6npjrjm.js +5 -0
  122. package/dist/src/chunk-v90es00d.js +4 -0
  123. package/dist/src/chunk-vbvtzkwz.js +5 -0
  124. package/dist/src/chunk-vefd8qee.js +8 -0
  125. package/dist/src/chunk-vs9r72ta.js +17 -0
  126. package/dist/src/chunk-w2mwa0jk.js +4 -0
  127. package/dist/src/chunk-w7zsh13a.js +9 -0
  128. package/dist/src/chunk-w88k0bgr.js +4 -0
  129. package/dist/src/chunk-wry6skrm.js +4 -0
  130. package/dist/src/chunk-wzdt0enk.js +4 -0
  131. package/dist/src/chunk-xhhv854c.js +4 -0
  132. package/dist/src/chunk-y58270hd.js +4 -0
  133. package/dist/src/chunk-yk0hmbex.js +4 -0
  134. package/dist/src/chunk-ympy4fdz.js +28 -0
  135. package/dist/src/chunk-yw436axy.js +4 -0
  136. package/dist/src/chunk-z04jrpjy.js +5 -0
  137. package/dist/src/chunk-z2xznczw.js +4 -0
  138. package/dist/src/chunk-z4xnrgps.js +4 -0
  139. package/dist/src/chunk-z7csyszv.js +4 -0
  140. package/dist/src/chunk-z8t0v07j.js +11 -0
  141. package/dist/src/chunk-z916af47.js +228 -0
  142. package/dist/src/chunk-zcr8he8q.js +5 -0
  143. package/dist/src/chunk-zd9vmkzn.js +9 -0
  144. package/dist/src/chunk-zg67wjkh.js +5 -0
  145. package/dist/src/chunk-zj939v0h.js +5 -0
  146. package/dist/src/chunk-zkdjwtc1.js +4 -0
  147. package/dist/src/chunk-zkv5kzt6.js +4 -0
  148. package/dist/src/daemon/processEntry.js +4 -0
  149. package/dist/src/index.js +4 -2797
  150. package/dist/src/runtime/bunRuntimeGuard.js +4 -0
  151. package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -3
  152. package/node_modules/strtok3/lib/BufferSizeError.js +1 -1
  153. package/node_modules/strtok3/lib/TokenWriter.js +151 -0
  154. package/node_modules/strtok3/lib/core.js +1 -0
  155. package/node_modules/strtok3/package.json +2 -2
  156. package/node_modules/token-types/LICENSE.txt +9 -9
  157. package/node_modules/token-types/{lib → dist/lib}/index.js +21 -3
  158. package/node_modules/token-types/package.json +81 -81
  159. package/package.json +10 -10
  160. package/schemas/README.md +16 -0
  161. package/schemas/prototype-icon-names.json +302 -0
  162. package/schemas/prototype-platform-permissions.json +75 -0
  163. package/schemas/test-plan.schema.json +2 -2
  164. package/node_modules/@borewit/text-codec/README.md +0 -87
  165. package/node_modules/@jimp/diff/node_modules/pixelmatch/README.md +0 -110
  166. package/node_modules/@jimp/diff/node_modules/pixelmatch/node_modules/pngjs/README.md +0 -433
  167. package/node_modules/@jimp/file-ops/dist/browser/index.js +0 -8
  168. package/node_modules/@jimp/js-png/README.md +0 -35
  169. package/node_modules/@jimp/js-png/src/__image_snapshots__/index-node-test-ts-png-should-use-png-options-1-snap.png +0 -0
  170. package/node_modules/@jimp/js-png/src/output.png +0 -0
  171. package/node_modules/@jimp/js-png/vitest.config.browser.mjs +0 -3
  172. package/node_modules/@jimp/plugin-resize/README.md +0 -12
  173. package/node_modules/@jimp/plugin-resize/vitest.config.browser.mjs +0 -3
  174. package/node_modules/@tokenizer/inflate/README.md +0 -114
  175. package/node_modules/@tokenizer/token/README.md +0 -19
  176. package/node_modules/await-to-js/README.md +0 -82
  177. package/node_modules/debug/README.md +0 -481
  178. package/node_modules/exif-parser/README.md +0 -83
  179. package/node_modules/file-type/readme.md +0 -667
  180. package/node_modules/ieee754/README.md +0 -51
  181. package/node_modules/mime/README.md +0 -178
  182. package/node_modules/ms/readme.md +0 -59
  183. package/node_modules/parse-bmfont-xml/README.md +0 -74
  184. package/node_modules/parse-bmfont-xml/lib/browser.js +0 -85
  185. package/node_modules/parse-bmfont-xml/node_modules/xml2js/README.md +0 -507
  186. package/node_modules/pngjs/README.md +0 -287
  187. package/node_modules/sax/README.md +0 -228
  188. package/node_modules/strtok3/README.md +0 -736
  189. package/node_modules/tinycolor2/README.md +0 -492
  190. package/node_modules/tinycolor2/cjs/test.js +0 -2191
  191. package/node_modules/tinycolor2/cjs/test_template.js +0 -26
  192. package/node_modules/tinycolor2/deno_asserts@0.168.0.mjs +0 -807
  193. package/node_modules/tinycolor2/esm/test.js +0 -2189
  194. package/node_modules/tinycolor2/esm/test_template.js +0 -24
  195. package/node_modules/tinycolor2/tinycolor.js +0 -1191
  196. package/node_modules/token-types/README.md +0 -120
  197. package/node_modules/uint8array-extras/readme.md +0 -318
  198. package/node_modules/xml-parse-from-string/README.md +0 -35
  199. package/node_modules/xmlbuilder/README.md +0 -86
  200. package/node_modules/zod/README.md +0 -208
  201. package/node_modules/zod/v4/locales/ar.d.cts +0 -4
  202. package/node_modules/zod/v4/locales/ar.d.ts +0 -4
  203. package/node_modules/zod/v4/locales/az.d.cts +0 -4
  204. package/node_modules/zod/v4/locales/az.d.ts +0 -4
  205. package/node_modules/zod/v4/locales/be.d.cts +0 -4
  206. package/node_modules/zod/v4/locales/be.d.ts +0 -4
  207. package/node_modules/zod/v4/locales/ca.d.cts +0 -4
  208. package/node_modules/zod/v4/locales/ca.d.ts +0 -4
  209. package/node_modules/zod/v4/locales/cs.d.cts +0 -4
  210. package/node_modules/zod/v4/locales/cs.d.ts +0 -4
  211. package/node_modules/zod/v4/locales/de.d.cts +0 -4
  212. package/node_modules/zod/v4/locales/de.d.ts +0 -4
  213. package/node_modules/zod/v4/locales/en.d.cts +0 -5
  214. package/node_modules/zod/v4/locales/en.d.ts +0 -5
  215. package/node_modules/zod/v4/locales/eo.d.cts +0 -5
  216. package/node_modules/zod/v4/locales/eo.d.ts +0 -5
  217. package/node_modules/zod/v4/locales/es.d.cts +0 -4
  218. package/node_modules/zod/v4/locales/es.d.ts +0 -4
  219. package/node_modules/zod/v4/locales/fa.d.cts +0 -4
  220. package/node_modules/zod/v4/locales/fa.d.ts +0 -4
  221. package/node_modules/zod/v4/locales/fi.d.cts +0 -4
  222. package/node_modules/zod/v4/locales/fi.d.ts +0 -4
  223. package/node_modules/zod/v4/locales/fr-CA.d.cts +0 -4
  224. package/node_modules/zod/v4/locales/fr-CA.d.ts +0 -4
  225. package/node_modules/zod/v4/locales/fr.d.cts +0 -4
  226. package/node_modules/zod/v4/locales/fr.d.ts +0 -4
  227. package/node_modules/zod/v4/locales/he.d.cts +0 -4
  228. package/node_modules/zod/v4/locales/he.d.ts +0 -4
  229. package/node_modules/zod/v4/locales/hu.d.cts +0 -4
  230. package/node_modules/zod/v4/locales/hu.d.ts +0 -4
  231. package/node_modules/zod/v4/locales/id.d.cts +0 -4
  232. package/node_modules/zod/v4/locales/id.d.ts +0 -4
  233. package/node_modules/zod/v4/locales/index.d.cts +0 -39
  234. package/node_modules/zod/v4/locales/index.d.ts +0 -39
  235. package/node_modules/zod/v4/locales/it.d.cts +0 -4
  236. package/node_modules/zod/v4/locales/it.d.ts +0 -4
  237. package/node_modules/zod/v4/locales/ja.d.cts +0 -4
  238. package/node_modules/zod/v4/locales/ja.d.ts +0 -4
  239. package/node_modules/zod/v4/locales/kh.d.cts +0 -4
  240. package/node_modules/zod/v4/locales/kh.d.ts +0 -4
  241. package/node_modules/zod/v4/locales/ko.d.cts +0 -4
  242. package/node_modules/zod/v4/locales/ko.d.ts +0 -4
  243. package/node_modules/zod/v4/locales/mk.d.cts +0 -4
  244. package/node_modules/zod/v4/locales/mk.d.ts +0 -4
  245. package/node_modules/zod/v4/locales/ms.d.cts +0 -4
  246. package/node_modules/zod/v4/locales/ms.d.ts +0 -4
  247. package/node_modules/zod/v4/locales/nl.d.cts +0 -4
  248. package/node_modules/zod/v4/locales/nl.d.ts +0 -4
  249. package/node_modules/zod/v4/locales/no.d.cts +0 -4
  250. package/node_modules/zod/v4/locales/no.d.ts +0 -4
  251. package/node_modules/zod/v4/locales/ota.d.cts +0 -4
  252. package/node_modules/zod/v4/locales/ota.d.ts +0 -4
  253. package/node_modules/zod/v4/locales/pl.d.cts +0 -4
  254. package/node_modules/zod/v4/locales/pl.d.ts +0 -4
  255. package/node_modules/zod/v4/locales/ps.d.cts +0 -4
  256. package/node_modules/zod/v4/locales/ps.d.ts +0 -4
  257. package/node_modules/zod/v4/locales/pt.d.cts +0 -4
  258. package/node_modules/zod/v4/locales/pt.d.ts +0 -4
  259. package/node_modules/zod/v4/locales/ru.d.cts +0 -4
  260. package/node_modules/zod/v4/locales/ru.d.ts +0 -4
  261. package/node_modules/zod/v4/locales/sl.d.cts +0 -4
  262. package/node_modules/zod/v4/locales/sl.d.ts +0 -4
  263. package/node_modules/zod/v4/locales/sv.d.cts +0 -4
  264. package/node_modules/zod/v4/locales/sv.d.ts +0 -4
  265. package/node_modules/zod/v4/locales/ta.d.cts +0 -4
  266. package/node_modules/zod/v4/locales/ta.d.ts +0 -4
  267. package/node_modules/zod/v4/locales/th.d.cts +0 -4
  268. package/node_modules/zod/v4/locales/th.d.ts +0 -4
  269. package/node_modules/zod/v4/locales/tr.d.cts +0 -5
  270. package/node_modules/zod/v4/locales/tr.d.ts +0 -5
  271. package/node_modules/zod/v4/locales/ua.d.cts +0 -4
  272. package/node_modules/zod/v4/locales/ua.d.ts +0 -4
  273. package/node_modules/zod/v4/locales/ur.d.cts +0 -4
  274. package/node_modules/zod/v4/locales/ur.d.ts +0 -4
  275. package/node_modules/zod/v4/locales/vi.d.cts +0 -4
  276. package/node_modules/zod/v4/locales/vi.d.ts +0 -4
  277. package/node_modules/zod/v4/locales/zh-CN.d.cts +0 -4
  278. package/node_modules/zod/v4/locales/zh-CN.d.ts +0 -4
  279. package/node_modules/zod/v4/locales/zh-TW.d.cts +0 -4
  280. package/node_modules/zod/v4/locales/zh-TW.d.ts +0 -4
@@ -0,0 +1,54 @@
1
+ // @bun
2
+ import{Jie,Nr,OY,i,KD,lb,GD,g$,Zie,yp,te,xo,Wi,roe,wl,rf,dr,Su,l,nt,BY,e}from"./chunk-z8t0v07j.js";import{g,K,E,$e,wu}from"./chunk-mf9spd4g.js";import{Yn,po,HM,uy,qb,tH,rH,py,my,fy,nI,br,jM,Ya,zb,aH,If,BP,dH,lH,eN,uH,aI}from"./chunk-mqc1d0eb.js";import"./chunk-ggtd5x5a.js";import{_s,GF,iv,ZS,XF,Ji,w,HQ,Qn,QS,DV,Kr,Ve,Gr,Yr,Cr,jQ,GQ,qc,is,mC,Mh,Vc,Uu,fC,Nh,av,tw,cv,iL,Ct,vr,Fh,iee,nw,o5,see,aee,Hu,$o,fm,uT,pT,qu,eu,cee,fT,uv,os,cw,uee,ei,Zd,Qd,pee,lL,Bh,uw,zV,Dt,mL,JV,XV,fee,pv,QV,So,c5,Ge,U,Je,pe,Zr,eW,ne,yT,fL,hn,u5,wee,dt,at,le,Ho,oW,rl,xn,yw,SL,xs,v,Ea,cs,bm,PC,Ia,qe,Po,TC,ww,cW,Yu,F,pW,mW,EC,fW,IC,Pm,Wh,qo,PL,S,Vo,ct,qt,Gc,en,Ce,Am,Ew,wv,Iw,SW,Ke,ko,ce,ps,il,rn,ol,ete,tte,PW,I5,EL,vn,rt,IL,NC,ou,xL,AW,Tv,km,$i,ep,gc,bn,Cw,rp,MT,Hn,su,DL,ite,ote,Dw,xa,ste,Ow,ate,cte,dte,Mw,me,$C,Iv,ML,hi,Fw,C5,Rt,pte,_W,xW,Sn,o,nn,gte,Lw,Bw,ip,O5,M5,DW,N5,M,zC,Ite,_te,xte,vc,Y5,J5,ms,Om,JT,et,QT,ge,eR,td,Hte,ni,ia,wn,nk,ik,ii,hs,uu,nR,oa,iR,lB,oi,Tt,Wv,cg,hB,dg,dk,oD,Jte,Xte,mR,vB,lp,ll,$m,cD,pk,dD,lD,fk,hk,IB,_B,fD,bR,Rz,vre,bre,Sre,D,Xv,Sr,_,Ls,k}from"./chunk-h3n4adc6.js";import{P7}from"./chunk-v6npjrjm.js";import{L,oo,m,ad,Ir,V3,Gm,Nt,Ym,rb,$s,_i,vi,$a,Wt,ke,z3,j3,K3,G3,up}from"./chunk-32jpxz2y.js";import{so,y,A,hr,z,f,Ne,kt,Wr,P,_k,n,a,h,ER,b,s,Ee,voe,p,I,pp}from"./chunk-79q5xsdc.js";import{Jl,eC,zS,L4,kr,sr,jd,Be,am,Ie,Bn,Ai,$c,Uc,Xs}from"./chunk-6d3mmqxt.js";import{zr,li,$P,cI,Jt,ui,Fl,Oo,Ja,Fp,hH,Jo,vy,iN,IX,_X,xX,CX,Xa,_f,HP,Cd,gH,Ec,Dd,uI,Ws,jG,In,DX,pI,OX,Kb,Nn,ha,Mo,Yb,FX,LX,vH,mI,XG,SH,wi,Ll,Jb,_n,Xb,Qa,dN,TH,kH,Zb,xf,t6,Qb,lN,VP,Cf,i6,ec,o6,wy,Df,hN,tS,xH,Et,gN,yN,QX,rS,vN,s6,Ue,SI,wI,tc,nS,CH,DH,OH,MH,AI,NH,dZ,FH,fo,pi,Bl,TN,Ic,bt,u6,Ff,fZ,Fd,v6,LN,b6,S6,$l,w6,CI}from"./chunk-nwm2pq5v.js";import{rc,Hl,Du,Vp,Wp,XN,Jf,ZN,hS,QN,cA,e0}from"./chunk-a2sc4jm0.js";import"./chunk-4fgdhcwx.js";import{zN,QZ,e7,sA,KN,Kf}from"./chunk-44bt78m9.js";import"./chunk-jhnbfj19.js";import"./chunk-0e4gm1kj.js";import"./chunk-pm06b05d.js";import{TJ,NU,jO,Vg}from"./chunk-t4dr5c8v.js";import"./chunk-r20pe1nv.js";import{pf,BO,Tl,uJ,HO,pJ,CU,El,gJ,yJ,Ka,iP,bJ,DU}from"./chunk-ympy4fdz.js";import"./chunk-f9s1kkhx.js";import"./chunk-9y5bcy28.js";import{hb,En,i9,B2,eE,bO,o9,s9,ja,a9,af,c9,SO,L$,B$,XR,PO,Ng,ZR,$$,gb,pa,f9,QR,nE,Al,h9,iE,U$,U2,H2,g9,H$,j$,AO,oE,P9,ln,hU,gU,vU,bU,SU,uE,wU,RU,Rb,pE,qg,AU,Pb,nJ,sK}from"./chunk-z916af47.js";import{No,JH,I6,MZ,BN,$N,_6,NZ,zs,Cu,xr,x6,LZ,QH,HN,O6,HZ,qZ,VZ,WZ,Ul,j}from"./chunk-8cghfzb2.js";import{Zo,vq,bq,Sq,he,I7,j0,L7,mh,G0}from"./chunk-tyazf3sk.js";import{$1,U1,H1,q1,V1,W1,z1,j1,DP,cX,AG,Yo,kG,dX,K1,EG,lX}from"./chunk-zd9vmkzn.js";import{S$}from"./chunk-r8z9pfve.js";import{o2}from"./chunk-8en08r7q.js";import{Wk,WY,zY,jY,KY,GY,Mg,A$,T$,k$,zk,E$,jk,lO,I$,E2,_$}from"./chunk-js1jpyxp.js";import{uX,JE,OP,DM,As,G1,Cp,OM,MP,MM,mX,LM,Y1,fX,BM,hX,DG,OG,$M,gX,J1,MG,X1,Z1,UM}from"./chunk-vs9r72ta.js";import"./chunk-z04jrpjy.js";import{VU,WU,kE,MJ,Wg,JO,KU,NJ,PK,GU,FJ,LJ,BJ,$J,UJ,yf,zg,Ad,YU,eM,QK,a1,Gg,NE,wf,g1,v8,b8,y1,S8,FE,lM,v1,Cb,w8,nG,R8,P8,A8,yP,SP,oG,w1,mM,_p,Hs,uo}from"./chunk-3jmvqygr.js";import"./chunk-6hyt398x.js";import{H6,r0}from"./chunk-hmke8nhx.js";import{xl,mG,Lb,xM,xP,Bb,$b,PG,iX,Ed,oX,sX}from"./chunk-rn84t3sf.js";import{w2,R2,A2}from"./chunk-4pfftt07.js";import{jE,lG}from"./chunk-qwye1958.js";import{x$}from"./chunk-zj939v0h.js";import"./chunk-vefd8qee.js";import"./chunk-4xd6zs3y.js";import"./chunk-0rjm4nx7.js";import"./chunk-kbjq0qvb.js";import{tv}from"./chunk-0w1spptt.js";import"./chunk-w7zsh13a.js";import{$U}from"./chunk-cxyf04jc.js";import"./chunk-jdqvcq0a.js";import"./chunk-c9nk1r78.js";import{cq}from"./chunk-34zxqcmq.js";import{dO,P$}from"./chunk-rkr0dks9.js";import{s2,a2,c2}from"./chunk-5kd4rqk7.js";import{d2,l2,u2}from"./chunk-ajsrz473.js";import{p2,m2,f2}from"./chunk-3swvfhqt.js";import{h2,g2,y2}from"./chunk-28k63ha3.js";import{w$,tO,rO,iO,v2,b2,S2}from"./chunk-r0f1q783.js";import{vd,bd,Rs,nf,Og,oO,za,Rp,sO,aO,qY,VY,k2,cO}from"./chunk-vbvtzkwz.js";import{EV}from"./chunk-f8tnk179.js";import{i2}from"./chunk-zcr8he8q.js";import{R6,GH,Hp}from"./chunk-a4k9rt7z.js";import"./chunk-sjn0nj4p.js";import"./chunk-bn64x5z5.js";import{fn}from"./chunk-sns0c35v.js";import"./chunk-zg67wjkh.js";import{wp,r,t,u}from"./chunk-9rkfyt6q.js";var Tc={async push(d,c){let R=_.getExistingInstance(d),C=Ea(d)?null:k.getExistingInstance(d);if(!C&&!R)throw new t(`No live CtrlProxy client to clear network state on ${d}`);if(C?.syncNetworkStateToDevice()===!1)throw new t(`Android network state was not delivered to ${d}`);await R?.syncNetworkStateFromHost(c)}};async function Mc(d,c,R,C){let T=new AbortController,B=R.now()+br,O=R.setTimeout(()=>T.abort(Error("Network cleanup deadline expired")),br);O.unref?.();try{await l(()=>Je(()=>d.push(c,{deadlineMs:B,abortSignal:T.signal})),{timer:R,signal:T.signal,label:"push cleared network state"})}catch(x){e.warn(`[networkState] Failed to push cleared network state to ${c}: ${r(x)}`,x);try{C?.(x)}catch(N){e.warn("[networkState] Failed to mark uncleared network state",N)}}finally{R.clearTimeout(O)}}function Bc(d,c={}){let R=c.pusher??Tc,C=(T,B,O)=>{if(!(c.state?.()??rn.getInstance()).clearDeviceOwnedBySession(B,T))return;if(O?.deviceIdentityReplaced){e.debug(`[networkState] Cleanup for session ${T} on replaced serial ${B}: skipped cleared-state device push`);return}let N=c.gapMarkerFor?.(T);d.registerPendingDeviceCleanup(B,Mc(R,B,c.timer??i,(H)=>{N?.(`network mock rules and simulation may remain on ${B}: ${r(H)}`)}),{name:"push cleared network state",leftover:"the released session's network mock rules and error simulation"})};d.onSessionRelease((T,B,O,x)=>{C(T,B,x)}),d.onSessionDeviceUnbound(C)}function Oc(d,c={}){let R=c.pusher??Tc;return(C)=>{if(!(c.state?.()??rn.getInstance()).clearSessionlessDeviceState(C))return;$b(d,C,Mc(R,C,c.timer??i),{timer:c.timer??i,capMs:br,label:"push cleared network state"})}}class Ni extends Error{}var kv=25000,lt=new Map;function Av(d,c=St){let R=(lt.get(d)??[]).filter((C)=>We(c,C.sessionId,d,C.recordingIds).length>0);if(R.length>0)lt.set(d,R);else lt.delete(d);return R}var Pv={android:120000,ios:120000},Cv=/^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$/i;function Mv(d){return Pv[Cv.test(d)?"ios":"android"]}var St={abandonRecordingsOnReplacedDevice:Bv,hasRecordingsToStop:(d,c)=>iP().length>0||ZR.hasSegmentedVideoRecordingsForOwner(d,c)||NU(d,c),stopSegmentedRecordings:ZR.stopSegmentedVideoRecordingsForOwner,captureSegmentedRecordingIdsForOwner:ZR.captureSegmentedRecordingIdsForOwner,listActiveVideoRecordings:(d)=>Ka({deviceId:d}),stopVideoRecording:async(d)=>{await CU(d)},isDeviceGestureRecordingOwnedBy:NU,ownedDeviceGestureRecordingId:jO,activeRecordingIdsForOwner:(d,c)=>{let R=jO(d,c);return[...DU(d,c),...ZR.segmentedVideoRecordingHandlesForOwner(d,c),...R===void 0?[]:[R]]},retainedCaptureIdsForOwner:(d,c)=>{let R=jO(d,c);return[...DU(d,c),...R===void 0?[]:[R]]},stopDeviceGestureRecording:async(d)=>{await Vg(d)},timer:i,finalizeCapMs:Mv,markVideoRecordingIncomplete:yJ,teardownRetryBackoff:te({initialDelayMs:1000,multiplier:2,maxDelayMs:8000}),teardownRetryBudgetMs:kv,markDeviceNeedsRecorderRecovery:(d)=>{let c=lt.get(d.deviceId)??[];c.push(d),lt.set(d.deviceId,c)}};function xc(d,c=St){return(R)=>{St.markDeviceNeedsRecorderRecovery(R),d.markDeviceNeedsRecorderTeardown(R.deviceId,()=>Ev(R.deviceId,c),Tl,"release-give-ups")}}async function Ev(d,c){let R=lt.get(d)??[];for(let T of R){let B=We(c,T.sessionId,d,T.recordingIds);await pr(c,B,c.ownedDeviceGestureRecordingId(T.sessionId,d))}let C=Av(d,c).flatMap((T)=>We(c,T.sessionId,d,T.recordingIds));if(C.length>0)throw new t(`Recorder teardown on device ${d} is still unconfirmed for ${C.join(", ")}. Recover the device if retries fail.`);lt.delete(d)}async function Bv(d,c){let R=DU(d,c),C=jO(d,c);await Promise.all([Li(()=>ZR.finalizeSegmentedVideoRecordingsForOwnerOnReplacedDevice(d,c)),...R.map((T)=>Li(()=>gJ(T))),...C===void 0?[]:[Li(()=>Vg(C,void 0,void 0,{hostOnly:!0}))]])}async function Li(d){try{await d()}catch(c){e.warn(`[RecordingSessionCleanup] Host-only recording cleanup failed: ${r(c)}`,c)}}var lr=new Map;function _c(d){let c=lr.get(d)??[];return lr.delete(d),c}class ur extends Error{}async function Xt(d,c){try{await c()}catch(R){e.warn(`[recording] Failed to ${d}: ${r(R)}`,R)}}async function Ov(d,c,R,{state:C,deviceGestureRecordingId:T}){let{stopping:B}=C,O=()=>{if(C.capExpired)return;let x=new Set(d.activeRecordingIdsForOwner(c,R));for(let N of B)if(!x.has(N))B.delete(N)};if(await Xt(`finalize segmented recordings of released session ${c??"(owner-less)"}`,()=>d.stopSegmentedRecordings(c,R)),O(),await Xt(`stop video recordings of released session ${c??"(owner-less)"} on ${R}`,async()=>{let x=await d.listActiveVideoRecordings(R);for(let{recordingId:N,ownerSessionUuid:H}of x){if(H!==c||C.capExpired&&!B.has(N))continue;if(!C.capExpired)B.add(N),C.owned.add(N);await Xt(`stop video recording ${N} of released session ${c??"(owner-less)"}`,async()=>{if(await d.stopVideoRecording(N),!C.capExpired)B.delete(N);e.info(`[recording] Stopped recording ${N} on ${R}: owning session ${c??"(owner-less)"} was released`)})}}),T!==void 0&&d.isDeviceGestureRecordingOwnedBy(c,R))await Xt(`stop device gesture recording of released session ${c??"(owner-less)"} on ${R}`,async()=>{await d.stopDeviceGestureRecording(T),O(),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 xv(d,c,R,C){let T=new Set(d.activeRecordingIdsForOwner(c,R)),B={stopping:new Set(T),owned:T,capExpired:!1},O=d.captureSegmentedRecordingIdsForOwner?.(c,R),x=[],N=d.ownedDeviceGestureRecordingId(c,R),H=d.finalizeCapMs(R),q=c??"(owner-less)";try{await l(Ov(d,c,R,{state:B,deviceGestureRecordingId:N}),{timer:d.timer,timeoutMs:H,label:`finalize recordings of released session ${q}`,timeoutError:()=>new ur,onTimeout:()=>{B.capExpired=!0;let W=O?.()??[];for(let Y of W)B.stopping.add(Y),T.add(Y);let V=new Set([...d.activeRecordingIdsForOwner(c,R),...W]);x=[...new Set([...[...B.stopping].filter((Y)=>V.has(Y)),...We(d,c,R,[...T])])]}})}catch(W){if(W instanceof ur)e.warn(`[recording] Finalizing recordings of released session ${q} on ${R} exceeded ${H}ms; force-stopping ${x.join(", ")||"none"} and marking incomplete`);else e.warn(`[recording] Finalizing recordings of released session ${q} on ${R} failed: ${r(W)}`,W)}if(!B.capExpired){let W=[...new Set([...T,...O?.()??[]])];if(x=We(d,c,R,W),x.length===0)return;e.warn(`[recording] Finalizing recordings of released session ${q} on ${R} left retained captures; force-stopping ${x.join(", ")} and marking incomplete`)}if(await pr(d,x,N),We(d,c,R,x).length===0)return;let G=Nv(d,{sessionId:c,deviceId:R,recordingIds:x,deviceGestureRecordingId:N,attempts:0});C(G,d.teardownRetryBudgetMs),await G}function We(d,c,R,C){let T=new Set(d.retainedCaptureIdsForOwner(c,R));return C.filter((B)=>T.has(B))}async function pr(d,c,R,C){await Promise.all(c.map((T)=>Xt(`force-stop recording ${T}`,()=>l(()=>T===R?d.stopDeviceGestureRecording(T):d.markVideoRecordingIncomplete(T),{timer:d.timer,timeoutMs:Tl,signal:C,label:`force-stop recording ${T}`}))))}async function _v(d,c,R){let C;try{await l(()=>new Promise((T)=>{C=d.timer.setTimeout(T,d.teardownRetryBackoff.delayForAttempt(c))}),{timer:d.timer,signal:R,label:"recording teardown retry backoff"})}finally{if(C!==void 0)d.timer.clearTimeout(C)}}async function Fv(d,c,R){let C=()=>We(d,c.sessionId,c.deviceId,c.recordingIds);while(!R.aborted&&C().length>0){if(await _v(d,c.attempts+1,R),R.aborted)return;let T=C();if(T.length===0)return;c.attempts+=1,await pr(d,T,c.deviceGestureRecordingId,R)}}async function Nv(d,c){let R=new AbortController;try{await l(()=>Fv(d,c,R.signal),{timer:d.timer,timeoutMs:d.teardownRetryBudgetMs,label:`retry recording teardown on ${c.deviceId}`,timeoutError:()=>new Ni,onTimeout:()=>R.abort()})}catch(C){if(!(C instanceof Ni))e.warn(`[recording] Teardown retry failed on ${c.deviceId}: ${r(C)}`,C);let T=We(d,c.sessionId,c.deviceId,c.recordingIds);if(T.length>0){let B={deviceId:c.deviceId,sessionId:c.sessionId,recordingIds:T,attempts:c.attempts,budgetMs:d.teardownRetryBudgetMs};e.warn(`[recording] Teardown gave up on device ${B.deviceId}, released session ${B.sessionId??"(owner-less)"}: recordings ${T.join(", ")}; ${B.attempts} attempts, ${B.budgetMs}ms budget; device needs recorder recovery`),d.markDeviceNeedsRecorderRecovery(B);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 Lv={timer:i,adoptVideoRecordings:bJ,adoptSegmentedRecordings:ZR.adoptOwnerlessSegmentedVideoRecordings,adoptDeviceGestureRecording:TJ};function $v(d,c){return d.finalizeCapMs(c)+Tl}function Fc(d,c=Lv){return(R,C)=>{if(d.getSessionForDevice(R)!==C)return;c.adoptSegmentedRecordings(R,C),c.adoptDeviceGestureRecording(R,C);let T=c.adoptVideoRecordings(R,C);if(!T)return;$b(d,R,T,{timer:c.timer,capMs:Tl,label:`persist adopted recording ownership for session ${C}`})}}function Nc(d,c=St){let R=(C,T,B)=>{if(B?.deviceIdentityReplaced){Li(()=>c.abandonRecordingsOnReplacedDevice(C,T));return}if(!c.hasRecordingsToStop(C,T))return;d.registerPendingDeviceCleanup(T,xv(c,C,T,(O,x)=>d.registerPendingDeviceCleanup(T,O,x)),$v(c,T))};d.onSessionRelease((C,T,B,O)=>{if(!O?.upgradeOnly){let x=[...new Set(c.activeRecordingIdsForOwner(C,T))];if(x.length>0)lr.set(C,x);R(C,T,O)}}),d.onSessionDeviceUnbound(R)}var mr=$C,Lc=3000;function Hc(d){return async(c,R)=>{if(d.viewerRead&&await d.viewerRead.applies(c))return d.viewerRead.observe(c,R);let C=c.platform==="android"?await d.readAndroidDeviceClockMs(c,R):d.hostRequestStartMs;return R.throwIfAborted(),d.observe(c,{minTimestamp:C,signal:R})}}function Hv(d,c,R){return{observationId:oo("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 Hi(d,c,R,C){return{deviceId:R,observation:Hv(d,c,C)}}async function Kc(d,c,R){let{timer:C,signal:T,assertDeviceActionable:B}=R,O=R.idGenerator??L,x=R.perDeviceTimeoutMs??mr;return(await Promise.allSettled(d.map(async(H)=>{if(T.aborted)return Hi(C,O,H.id,`Observation request was aborted for device ${H.id}`);try{B?.(H)}catch(V){let Y=r(V);return e.warn(`[Daemon] Skipped observation for ${H.id}: ${Y}`),Hi(C,O,H.id,Y)}let q=new AbortController,G=Error(`Observation request timed out after ${x}ms for device ${H.id}`),W=AbortSignal.any([T,q.signal]);try{let V=await l(c(H,W),{timer:C,timeoutMs:x,label:"Observation request",timeoutError:()=>G,onTimeout:()=>q.abort()});return{deviceId:H.id,observation:V}}catch(V){let Y=r(V);return e.warn(`[Daemon] Failed to observe ${H.id}: ${Y}`),Hi(C,O,H.id,Y)}}))).map((H,q)=>{if(H.status==="fulfilled")return H.value;let G=d[q],W=r(H.reason);return e.warn(`[Daemon] Observation task for ${G.id} rejected unexpectedly: ${W}`),Hi(C,O,G.id,W)})}function Ae(d){return()=>{throw Error(`DaemonSocketServer.${d} was called on a test double that did not define it`)}}function Wc(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 fr(d){return new Set((d??"").split(",").map((c)=>c.trim()).filter(Boolean))}function Jc(d,c){return{androidAppearanceSyncDevices:fr(E(g.ANDROID_APPEARANCE_SYNC_DEVICES,d)),androidObservationStreamDevices:fr(E(g.ANDROID_OBSERVATION_STREAM_DEVICES,d)),iosWarmupDevices:fr(E(g.IOS_WARMUP_DEVICES,d)),appearanceSyncEnabled:FH(E(g.APPEARANCE_SYNC,d)),iosPassiveWorkEnabled:d[c]===void 0}}class gr{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 C=c==="appearance-sync"?this.settings.androidAppearanceSyncDevices:this.settings.androidObservationStreamDevices;return this.isOwned(R)||C.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 dP}from"path";var qv=100;function jc(d){let{timer:c,invalidate:R,notify:C,debounceMs:T=qv}=d,B,O=!1;return Object.assign((N)=>{if(R(),B||O)return;B=c.setTimeout(()=>{B=void 0,C().catch((H)=>{e.warn(`[DeviceStateChangeNotifier] Resource notification failed: ${r(H)}`)})},T)},{dispose:()=>{if(O=!0,B)c.clearTimeout(B),B=void 0}})}function yr(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 zc(d){return async(c)=>{try{let R=c?await d.exportGraphSummaryForApp(c):await d.exportGraphSummary();return yr(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 Uv="to watch stored values";class wr{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(zc({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 C of d.getBuildContexts())if(C.deviceId!==Mw)c.pushBuildContextUpdate(C.deviceId,C.appId,{packageId:C.appId,versionCode:C.versionCode,...C.versionKey===void 0?{}:{versionKey:C.versionKey},contentHash:C.contentHash})}if(this.listenerManagers.has(d))return;this.listenerManagers.add(d),d.setBuildContextUpdateListener(({appId:R,deviceId:C,buildContext:T})=>{if(!this.listenerManagers.has(d)||C===Mw)return;this.deps.server()?.pushBuildContextUpdate(C,R,T===null?null:{packageId:R,versionCode:T.versionCode,...T.versionKey===void 0?{}:{versionKey:T.versionKey},contentHash:T.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 C=yr(R),T=d.getDeviceIdForApp(R.appId);this.deps.server()?.pushNavigationGraphUpdate(C,T),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 wt(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 C=d==="android"?g.ANDROID_OBSERVATION_STREAM_DEVICES.name:g.IOS_WARMUP_DEVICES.name;e.info(`[Daemon] Skipping observation-stream ${R} for ${d} device ${c}: passive-work policy filtered it; set ${C} to opt in`)}function Kv(d,c,R){let C=d.sessionManager.getSessionForDevice(c)??D(d.devicePool.getDevice(c));if(!C)return!1;let T=(B)=>rt(B,d.sessionManager);return T(C)!==T(R?.trim()||void 0)}async function Yc(d,c,R){let C=c.id;if(Kv(d,C,R))return!0;if(d.sessionManager.getSessionForDevice(C)??D(c))return!1;let T=c.platform,B=R?.trim()||void 0;try{return await Tv({action:"observe",deviceId:C,platform:T,requesterSessionUuid:B,sessionManager:d.sessionManager,gate:d.devicePool}),await km({deviceId:C,platform:T,gate:d.devicePool}),!1}catch(O){if(O instanceof li||O instanceof qt)e.debug(`[Daemon] observation of ${C} is read-only: ${r(O)}`);else e.warn(`[Daemon] ownership of ${C} unreadable; observation is read-only: ${r(O)}`,O);return!0}}async function Xc(d,{deviceId:c,sessionUuid:R,packageName:C,fileName:T,subscribe:B}){let O=d.devicePool.getAllDevices().filter((H)=>c===null||H.id===c),x=[],N=bn("observationStream",{allowObserverSessions:!0});for(let H of O){if(H.platform!=="android")continue;try{N.authorize({sessionUuid:R,deviceId:H.id,admitViewer:!0})}catch(G){x.push(r(G));continue}if(B)try{d.devicePool.assertDeviceActionable(H.id,Uv)}catch(G){x.push(r(G));continue}let q=k.getExistingInstance(H.id);if(!q)continue;if(B)await q.subscribeStorage(C,T);else await q.unsubscribeStorage(`${C}:${T}`)}if(x.length>0)throw new t(x.join("; "))}function Qc(d,c){let R=_.getInstance(d);return{ensureConnected:async()=>{let C=await R.ensureConnected(),T=c();if(C&&T)R.refreshObservationStreamHierarchyCadence(T.getHierarchyIntervalMsForDevice(d.deviceId));return C},getLatestHierarchy:(...C)=>R.getLatestHierarchy(...C),requestHierarchySyncWithoutObservationStreamPush:async(...C)=>{let T=await R.requestHierarchySyncWithoutObservationStreamPush(...C);return T?{hierarchy:T.hierarchy,...T.frameContext===void 0?{}:{frameContext:T.frameContext}}:null},convertToViewHierarchyResult:(C)=>R.convertToViewHierarchyResult(C),recordInitialObservationStreamHierarchy:(C,T)=>R.recordInitialObservationStreamHierarchy(C,T),requestScreenshotWithoutObservationStreamPush:(...C)=>R.requestScreenshotWithoutObservationStreamPush(...C)}}class Rr{misses;missIncarnations;confirmedDisconnectedIds;forceDisconnectedIds;forceDisconnectedGenerations;offlineRecoveryAttemptedIds;offlineRecoveryAttemptedIncarnations;offlineEpisodes;constructor(d={}){this.misses=d.misses??new JO,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 Dr{inProgress=!1;releaseNotifications=null;fallbackReleaseNotifications=null}class Ar{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 Pr{deviceClaimMirrors=new Ar;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 Gv,randomBytes as Vv,timingSafeEqual as Jv}from"crypto";import{closeSync as Zc,constants as el,fchmodSync as jv,fstatSync as zv,lstatSync as Tr,readdirSync as Yv,linkSync as Qv,mkdtempSync as Zv,rmdirSync as ey,mkdirSync as ty,openSync as tl,readFileSync as iy,renameSync as nl,rmSync as ny,unlinkSync as ry,writeFileSync as oy}from"fs";import{basename as sy,join as ay,dirname as sl}from"path";var dy=60000;function al(d){return d?d.next():Vv(32).toString("base64url")}class Mr{path;idGen;publishedToken;removalFiles;platform;renameFile;sleep;now;constructor(d=Mh("token"),c=L,R={}){this.path=d;this.idGen=c;this.removalFiles=R.removalFiles??{createDirectory:Zv,list:Yv,inspect:(C)=>Tr(C,{throwIfNoEntry:!1}),move:(C,T)=>{this.assertTarget(C),nl(C,T)},read:(C)=>this.readAt(C),restore:Qv,remove:ry,removeDirectory:ey},this.platform=R.platform??process.platform,this.now=R.now??Date.now,this.renameFile=R.renameFile??nl,this.sleep=R.sleep??((C)=>{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,C)})}assertTarget(d=this.path){let c=Tr(d,{throwIfNoEntry:!1});if(c&&(!c.isFile()||c.isSymbolicLink()))throw Error("Unsafe daemon HTTP token file")}observeDestination(){let d=Tr(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=te({initialDelayMs:10,maxDelayMs:100});for(let C=1;;C++){if(this.assertTarget(),C>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(T){let B=T instanceof Error&&"code"in T?T.code:void 0;if(this.platform!=="win32"||C>=5||B!=="EPERM"&&B!=="EBUSY"&&B!=="EACCES")throw u(T,"Unable to persist daemon HTTP token");e.debug("Retrying daemon HTTP token publication after a sharing violation"),this.sleep(R.delayForAttempt(C))}}}write(d){let c=`${this.path}.${this.idGen.next()}.tmp`,R=!1;try{ty(sl(this.path),{recursive:!0,mode:448}),this.assertTarget();let C=tl(c,"wx",384);R=!0;try{if(process.platform!=="win32")jv(C,384);oy(C,d,"utf8")}finally{Zc(C)}this.publish(c),R=!1,this.publishedToken=d.trim(),this.sweepRemovalDirectories()}catch(C){throw e.warn("Unable to persist daemon HTTP token"),u(C,"Unable to persist daemon HTTP token")}finally{if(R)try{ny(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=tl(d,el.O_RDONLY|(process.platform==="win32"?0:el.O_NOFOLLOW));let R=zv(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 iy(c,"utf8").trim()||void 0}catch{e.debug("Daemon HTTP token file unavailable");return}finally{if(c!==void 0)try{Zc(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()-dy&&(this.platform==="win32"||d.uid===process.getuid?.()&&(d.mode&4095)===448)}sweepRemovalDirectories(){let d=this.removalFiles;try{let c=sl(this.path),R=`${sy(this.path)}.remove-`;for(let C of d.list(c)){if(!C.startsWith(R)||!/^[A-Za-z0-9]{6}$/.test(C.slice(R.length)))continue;let T=ay(c,C),B=d.inspect(T);if(this.isStaleRemovalDirectory(B))this.cleanClaim(T)}}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 C=`${R}/token`;if(c.move(this.path,C),!cl(c.read(C)??"",d)){let T=c.inspect(C);if(T?.isFile()&&!T.isSymbolicLink())c.restore(C,this.path)}}catch{e.debug("Daemon HTTP token file removal unavailable")}finally{if(R)this.cleanClaim(R)}}}function dl(d,c){let R=d?.slice(0,7).toLowerCase()==="bearer "?d.slice(7):"";return cl(R,c)}function cl(d,c){let R=(T)=>Gv("sha256").update(T).digest();return Jv(R(d),R(c))&&d.length>0&&c.length>0}import{createServer as Sy}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 qi 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 cy}from"worker_threads";var ly=1000,hy=1e4,gy=50,yy=`
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 Er{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??z3,this.getDatabasePath=d.getDatabasePath??up,this.timeoutMs=d.timeoutMs??ly,this.initTimeoutMs=d.initTimeoutMs??hy,this.sqliteBusyTimeoutMs=d.sqliteBusyTimeoutMs??gy,this.workerFactory=d.workerFactory??((c,R)=>new cy(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(),C=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 qi(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 qi(this.initTimeoutMs))}}),C=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",C),onTimeout:()=>{if(R)this.abandonPendingWorkerRequest(R,new Pe(this.timeoutMs,"query",C))}})}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,C)=>{this.pendingRequest={resolve:R,reject:C},d.worker.postMessage({id:c})})}getWorker(){if(this.worker)return this.worker;let d=this.timer.now(),c=this.workerFactory(yy,{dbPath:this.getDatabasePath(),sqliteBusyTimeoutMs:this.sqliteBusyTimeoutMs}),R,C,T=new Promise((O,x)=>{R=O,C=x}),B={worker:c,readiness:T,ready:!1,startedAt:d,resolveReady:R,rejectReady:C};return this.worker=B,c.on("message",(O)=>{if(this.worker!==B)return;if("type"in O){if(!B.ready)B.ready=!0,B.resolveReady(),e.debug(`Database health probe worker ready after ${this.timer.now()-B.startedAt}ms`);return}if(!this.pendingRequest||O.id!==this.workerRequestId)return;let x=this.pendingRequest;if(this.pendingRequest=null,O.ok){x.resolve();return}let N=Error(O.message??"Database health probe failed");if(O.stack)N.stack=O.stack;x.reject(N)}),c.on("error",(O)=>{this.rejectWorker(B,O)}),c.on("exit",(O)=>{this.rejectWorker(B,Error(`Database health probe worker exited with code ${O}`))}),B}rejectWorker(d,c){if(this.worker!==d)return;this.worker=null,d.rejectReady(c),this.pendingRequest?.reject(c),this.pendingRequest=null}}function by(){return Date.now()-Math.max(0,process.uptime()*1000)}function Ry(d,c){return{deviceSessionRepository:d.deviceSessionRepository??new qb({timer:c}),idGenerator:d.idGenerator??L,databaseInitializer:d.databaseInitializer??new S$,startupFailureTracker:d.startupFailureTracker??new dO,databaseHealthProbe:d.databaseHealthProbe??new Er({timer:c})}}function Dy(d){return{recoveryPolicyEnvironment:d.recoveryPolicyEnvironment??process.env,processBirthTime:d.processBirthTime??by,processGenerationToken:d.processGenerationToken??Gm,liveDaemonSessionIdProvider:d.liveDaemonSessionIdProvider??new c5,incumbentOwnerGuard:d.incumbentOwnerGuard??new EG}}function ky(d){let c=d.deviceReadiness??Ic.createInstance();return{managedAdbServerShutdown:d.managedAdbServerShutdown??o2,toolSelectionProfileProvenanceLoader:d.toolSelectionProfileProvenanceLoader??I$,httpToken:d.httpToken??"",httpTokenStore:d.httpTokenStore??new Mr,httpServerFactory:d.httpServerFactory??(()=>Sy()),avdManagerFactory:d.avdManagerFactory??(()=>new Ng),deviceReadiness:c,iosDeviceVerifier:d.iosDeviceVerifier??(()=>c),bindingExclusionFactory:d.bindingExclusionFactory??VP,daemonState:d.daemonState??HQ}}function ul(d){let c=d.timer??i;return{...d,timer:c,...Ry(d,c),...Dy(d),...ky(d)}}class Br{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=al(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 pl(){let d,c;return{promise:new Promise((C,T)=>{d=C,c=T}),resolve:d,reject:c}}var At=25,It=1000,Pt=5000,fl=t6,ml=new WeakMap;class Oe{closing=new AbortController;backoff;shared;options;constructor(d){this.options={...d,initialDelayMs:d.initialDelayMs??At,maxDelayMs:d.maxDelayMs??It,maxBlockedWaitMs:d.maxBlockedWaitMs??Pt},this.backoff=d.backoff??te(this.options);let c=ml.get(d.timer);if(!c)c={quietUntilMs:0,queue:[]},ml.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 C,T,B=this.signal(c),O=()=>{if(C!==void 0)this.options.timer.clearTimeout(C)};B.addEventListener("abort",O,{once:!0});try{await l(()=>new Promise((x)=>{if(T=x,R?.addEventListener("abort",T,{once:!0}),R?.aborted)x();else C=this.options.timer.setTimeout(x,d)}),{timer:this.options.timer,signal:B,label:"Registry retry wait"})}finally{if(B.removeEventListener("abort",O),T)R?.removeEventListener("abort",T);if(C!==void 0)this.options.timer.clearTimeout(C)}}async run(d,c,R,C){let T=this.signal(R);T.throwIfAborted();let B=Promise.withResolvers(),O={resolve:B.resolve,reject:B.reject,expedited:C,started:!1},x=()=>this.schedule(),N=()=>{if(B.reject(T.reason),this.removeQueued(O),this.shared.active===O&&!O.started)this.shared.active=void 0;this.schedule()};T.addEventListener("abort",N,{once:!0}),C?.addEventListener("abort",x,{once:!0}),this.shared.queue.push(O);let H,q=!0;try{this.schedule(),await B.promise,T.throwIfAborted(),O.started=!0,H=this.options.timer.now();let G=await l(d,{timer:this.options.timer,signal:T,label:"Registry retry operation"});return q=!c(G),G}finally{if(T.removeEventListener("abort",N),C?.removeEventListener("abort",x),q&&H!==void 0)this.extendQuietPeriod(H);if(this.removeQueued(O),this.shared.active===O)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=(B)=>B.expedited?.aborted||c.now()>=d.quietUntilMs,C=d.active?void 0:d.queue.find(R),T=!d.active&&!C&&d.queue.length>0;try{this.updateQuietTimer(T)}catch(B){e.warn(`[Bindings] Registry retry quiet timer failed: ${r(B)}`,B);for(let O of[...d.queue])if(!R(O))this.removeQueued(O),O.reject(B)}if(C)this.removeQueued(C),d.active=C,C.resolve()}updateQuietTimer(d){let c=this.shared,R=this.options.timer;if(!d||c.wakeAtMs!==c.quietUntilMs){if(c.quietTimer!==void 0){let C=c.quietTimer;c.quietTimer=void 0,c.wakeAtMs=void 0,R.clearTimeout(C)}}if(d&&c.quietTimer===void 0){let C=R.setTimeout(()=>{if(c.quietTimer!==C)return;c.quietTimer=void 0,c.wakeAtMs=void 0,this.schedule()},c.quietUntilMs-R.now());c.quietTimer=C,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 hl=500,xe=700,gl=250,vl=300000,yl=30000,Or=te({initialDelayMs:250,maxDelayMs:5000}),Sl=256,bl="managed-execution-release",_r=At,Fr=It,Lr=Pt,Rl=5000;function $r(){return{marked:[],owed:[],stamped:new Set,stampWarned:!1}}function Se(d){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex}}function Ui(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 Ki(d,c){let R=(C)=>d.getSession(C)?.assignedDevice??d.getReleasingSession(C)?.assignedDevice??d.getTerminalReleaseSnapshot(C)?.deviceId??null;return{isSessionLive:(C)=>d.hasSession(C)||d.getReleasingSession(C)!==null,deviceOf:R,getKeepAwakeRestoreReport:(C)=>d.getKeepAwakeRestoreReport?.(C),releaseSession:async(C)=>{let T=R(C);return await As({manager:d,pool:c},T,C,{release:async()=>(T=await d.releaseSession(C),T)}),T},forceStuckRelease:async(C)=>{let T=!1;return await G1({forceStuckRelease:(B)=>{let O=d.forceStuckRelease(B);return T=O!==void 0,O}},c,C),T},hasDeviceCleanupInProgress:(C)=>d.hasDeviceCleanupInProgress(C)}}async function kl(d,c,R,C){let T;try{T=await Ay(d,c,R)}catch(O){let x=await Dl(d,c,R);if(x===null)throw O;let N=Se(R);return d.warn(`[BrokerExecutionRelease] Marking binding ${N.scopeKey}/${N.bindingIndex} settling failed after the mark was written; going on from the written mark: ${r(O)}`,O),x}if(!("refused"in T))return T;let B=await Dl(d,c,R);if(B===null)C.push({...Se(R),error:`could not mark settling: ${T.refused}`});return B}async function Ay(d,c,R){let C=await Iy(d,c,R);if(C!=="unjournaled")return C;let T=Se(R),B=await c.updateBindingState(T,{generation:R.generation,stableDeviceId:R.stableDeviceId},"settling",{settler:d.settlerIdentity()});if(B.kind!=="updated")return{refused:B.kind};return{key:T,execOwner:B.assignment.execOwner,generation:B.assignment.generation,stableDeviceId:B.assignment.stableDeviceId}}async function Dl(d,c,R){let C=Se(R),T=d.settlerIdentity(),B=await c.getAssignment(C);if(B===null||B.state!=="settling"||B.settler===null||!Ec(B.settler,T)||B.stableDeviceId!==R.stableDeviceId||B.generation!==R.generation+1)return null;let O={key:C,execOwner:B.execOwner,generation:B.generation,stableDeviceId:B.stableDeviceId},x=d.options.journal;if(!x)return O;let N=(await c.listOpenBindingJournal(C)).find((H)=>H.kind==="release"&&Ec(H.owner,T));if(!N)return O;return x.inFlight.add(N.id),{...O,journalEntryId:N.id}}async function Iy(d,c,R){let C=d.options.journal;if(!C)return"unjournaled";let T=Se(R),B=d.settlerIdentity(),O=await c.openBindingJournal(T,{kind:"release",phase:"intent",owner:B,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:B}}});if(O.kind==="opened")return C.inFlight.add(O.entry.id),{key:T,execOwner:O.assignment.execOwner,generation:O.assignment.generation,stableDeviceId:O.assignment.stableDeviceId,journalEntryId:O.entry.id};if(O.kind==="journal_open")return"unjournaled";return{refused:O.kind}}class Hr{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(C){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(C)}`,C),this.ctx.track(this.retry(d,c,R.sessionUuid))}return!0}async retry(d,c,R){let C=`${c.scopeKey}/${c.bindingIndex}/${R}`;if(this.ctx.isClosed()||this.inFlight.has(C))return;this.inFlight.add(C);let{timer:T}=this.ctx,B=T.now()+this.ctx.settlementCapMs;try{for(;;){if(await T.sleep(this.ctx.settlementPollMs),this.ctx.isClosed())return;let O=await this.ctx.retrier.run(`Clearing the owner of binding ${c.scopeKey}/${c.bindingIndex} for ended session ${R}`,B,()=>this.clearEndedOnce(d,c,R));if(!O.done||O.value==="done"||T.now()+this.ctx.settlementPollMs>B)return}}finally{this.inFlight.delete(C)}}async clearEndedOnce(d,c,R){let C=(await d.getAssignment(c))?.execOwner??null;if(C===null||C.sessionUuid!==R||this.ctx.isClosed())return"done";if(this.ctx.isSessionLive(R)||this.ctx.isExecOwnerLive(C))return"owner_live";return await d.releaseExecution(c,R),"done"}}class qr{ctx;constructor(d){this.ctx=d}async run(d,c,R,{stopWhen:C,schedule:T}={}){if(T?.fastRecovery)return this.runRecovery(d,R);let{timer:B}=this.ctx,O=!1,x=await this.ctx.registryRetry.execute(R,{maxAttempts:Number.MAX_SAFE_INTEGER,signal:this.ctx.closing,shouldRetry:()=>!(C?.()??!1),delays:(N)=>B.now()>=c?this.ctx.settlementSlowPollMs:this.ctx.backoff.delayForAttempt(N),onRetry:(N,H,q)=>{if(H===1)this.ctx.warn(`[BrokerExecutionRelease] ${d} failed; retrying in ${q}ms: ${N.message}`,N);if(B.now()>=c&&!O)O=!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: `+N.message,N)},expectedFailure:{reason:"the drain reports why it stopped retrying a registry step"}});if(x.success)return{done:!0,value:x.value};if(!this.ctx.isClosed())this.ctx.warn(`[BrokerExecutionRelease] ${d} failed and is no longer needed, so it is not retried: ${r(x.error)}`,x.error);return{done:!1}}async runRecovery(d,c){let R=this.ctx.timer.now(),C=0,T=!1,B;while(!this.ctx.isClosed()){C++;try{let O=await this.ctx.recoveryPacing.run(async()=>{let x=!1;try{return await l(()=>(B??=c(),B),{timer:this.ctx.timer,timeoutMs:this.ctx.recoveryTurnBudgetMs,signal:this.ctx.closing,label:d,onTimeout:()=>{x=!0}})}finally{if(!x)B=void 0}},()=>!0);if(this.ctx.isClosed())return{done:!1};if(C>1)e.info(`[BrokerExecutionRelease] ${d} resolved after ${this.ctx.timer.now()-R} ms (${C} attempts)`);return{done:!0,value:O}}catch(O){if(this.ctx.isClosed())return{done:!1};if(e.debug(`[BrokerExecutionRelease] ${d} failed: ${r(O)}`,O),!T&&this.ctx.timer.now()-R>this.ctx.recoveryWarnAfterMs)T=!0,this.ctx.warn(`[BrokerExecutionRelease] ${d} still failing after ${this.ctx.timer.now()-R} ms (${C} attempts): ${r(O)}`,O)}try{await this.ctx.recoveryPacing.wait(this.ctx.recoveryPacing.delay(C))}catch(O){if(!this.ctx.isClosed())e.debug(`[BrokerExecutionRelease] Recovery retry wait cancelled: ${r(O)}`,O);return{done:!1}}}return{done:!1}}}class Ur{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??Qa,this.drainBudgetMs=d.drainBudgetMs??hl,this.releaseBudgetMs=d.releaseBudgetMs??xe,this.settlementPollMs=d.settlementPollMs??gl,this.settlementCapMs=d.settlementCapMs??vl,this.settlementSlowPollMs=d.settlementSlowPollMs??yl,this.recoveryPacing=new Oe({timer:d.timer,initialDelayMs:_r,maxDelayMs:Fr,maxBlockedWaitMs:Lr}),this.ownerHolds=d.ownerHolds??dN,this.retrier=new qr({timer:d.timer,registryRetry:new hn(d.timer),recoveryPacing:this.recoveryPacing,backoff:d.registryRetryBackoff??Or,closing:this.closing.signal,isClosed:()=>this.closed,warn:(c,R)=>this.warn(c,R),settlementCapMs:this.settlementCapMs,settlementSlowPollMs:this.settlementSlowPollMs,recoveryTurnBudgetMs:xe,recoveryWarnAfterMs:Rl}),this.ownerClearer=new Hr({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!==Yn||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(),C=await R.findExecutionAssignments(d),T=c.isSessionLive(d);if(C.length===0&&!T)return this.reportReleased(R,d);this.rememberBindings(d,C);let B=c.deviceOf(d),O=this.holdOwner(d,B);try{return await this.drainHeldBindings(R,d,C,{live:T,device:B})}finally{O()}}async drainHeldBindings(d,c,R,{live:C,device:T}){let{cancellationRequested:B,drained:O}=await this.cancelAndDrain(c),x=[],N=$r();if(!O)await this.markSettling(d,c,R,{failures:x,marks:N});let H=C?await this.releaseSessionWithinBudget(c,T):{releasedDevice:T,releaseSettled:!0,releaseForced:!1},{releasedDevice:q,releaseForced:G}=H,W=O&&H.releaseSettled&&this.isSettled(c,q);if(!W&&O)await this.markSettling(d,c,R,{failures:x,marks:N});let V=await this.releaseOwnership(d,c,R,{failures:x,owed:N.owed});if(N.marked.length>0)this.track(this.settleLater(d,c,q,N.marked));if(N.owed.length>0){let Y=this.holdOwner(c,q);this.track(this.settleOwedMarks(d,c,q,{first:N,releaseHold:Y}))}return{...this.keepAwakeRestoreResult(c),...await LM(c),...await BM(c),sessionId:c,outcome:W?"reusable_for_this_binding":"cleanup_pending",settlement:W?"confirmed":"settling",alreadyReleased:!C,cancellationRequested:B,releaseForced:G,device:q,bindings:V,bindingFailures:x}}async cancelAndDrain(d){let{work:c}=this.options,R=await c.cancelDeviceSessionExecutions(d,bl);if(R===0&&!c.hasActiveDeviceSessionExecutions(d))return{cancellationRequested:R,drained:!0};let C=await c.waitForDeviceSessionExecutionsToEnd(d,this.drainBudgetMs);return{cancellationRequested:R,drained:C}}async reportReleased(d,c){let R=this.recentBindings.get(c)??[],C=(await Promise.all(R.map((B)=>d.getAssignment(B)))).filter((B)=>B!==null),T=this.options.work.hasActiveDeviceSessionExecutions(c)||C.some((B)=>B.state==="settling");return{...this.keepAwakeRestoreResult(c),...await LM(c),...await BM(c),sessionId:c,outcome:T?"cleanup_pending":"reusable_for_this_binding",settlement:T?"settling":"confirmed",alreadyReleased:!0,cancellationRequested:0,releaseForced:!1,device:null,bindings:C.map((B)=>Ui(B,!1)),bindingFailures:[]}}async releaseSessionWithinBudget(d,c){let{sessions:R,timer:C}=this.options,T=R.releaseSession(d);try{return{releasedDevice:await l(T,{timer:C,timeoutMs:this.releaseBudgetMs,unref:!0,label:`Managed execution release of session ${d}`})??c,releaseSettled:!0,releaseForced:!1}}catch(O){if(this.options.ownership?.isReleaseHeld(d))return e.debug(`[BrokerExecutionRelease] Session ${d} release awaits ownership; settlement continues within its hold cap`,O),{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(O),O)}let B=!1;try{B=await R.forceStuckRelease(d)}catch(O){this.warn(`[BrokerExecutionRelease] Forcing the stuck release of ${d} failed: `+r(O),O)}return{releasedDevice:c,releaseSettled:!1,releaseForced:B}}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 C=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 H=await this.options.registry();return{registry:H,held:await H.findExecutionAssignments(d)}});if(!C.done||C.value.held.length===0)return;let{registry:T,held:B}=C.value;this.rememberBindings(d,B);let O=[],x=$r();if(!this.isSettled(d,c))await this.markSettling(T,d,B,{failures:O,marks:x});await this.releaseOwnership(T,d,B,{failures:O,owed:x.owed});for(let H of O)this.warn(`[BrokerExecutionRelease] Binding ${H.scopeKey}/${H.bindingIndex} bookkeeping after the release of ${d} failed: ${H.error}`);let N=x.owed.length>0?this.holdOwner(d,c):void 0;R(),await Promise.all([x.marked.length>0?this.settleLater(T,d,c,x.marked):void 0,N?this.settleOwedMarks(T,d,c,{first:x,releaseHold:N}):void 0])}finally{R()}}async markSettling(d,c,R,{failures:C,marks:T}){await this.stampOwners(d,c,R,T),(await Promise.allSettled(R.map((O)=>this.markBinding(d,O,C)))).forEach((O,x)=>{if(O.status==="rejected")C.push({...Se(R[x]),error:`could not mark settling: ${r(O.reason)}; the binding keeps its owner record and the mark is retried`}),T.owed.push(R[x]);else if(O.value){if(T.marked.push(O.value),O.value.execOwner?.sessionUuid===c)this.options.ownership?.confirmOwnership(c)}})}async stampOwners(d,c,R,C){let T=this.settlerIdentity();(await Promise.allSettled(R.map(async(O)=>{let x=O.execOwner;if(C.stamped.has(O)||x===null||x.sessionUuid!==c||Ec(x,T))return x?.sessionUuid===c&&Ec(x,T);let N=await d.claimExecution(Se(O),{generation:O.generation,stableDeviceId:O.stableDeviceId},{...T,sessionUuid:c},{supersedesSessionUuid:c});if(N.kind==="binding_in_use")this.options.ownership?.loseOwnership?.(c);return N.kind==="claimed"}))).forEach((O,x)=>{if(O.status==="fulfilled"){if(C.stamped.add(R[x]),O.value)this.options.ownership?.confirmOwnership(c)}else if(!C.stampWarned){C.stampWarned=!0;let N=Se(R[x]);this.warn(`[BrokerExecutionRelease] Binding ${N.scopeKey}/${N.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(O.reason)}`,O.reason)}})}async markBinding(d,c,R){return kl({warn:this.warn.bind(this),settlerIdentity:this.settlerIdentity.bind(this),options:this.options},d,c,R)}async settleOwedMarks(d,c,R,{first:C,releaseHold:T}){let B=[...C.owed],O={...C,marked:[],owed:[...B]},x=()=>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(x())return;let H=[],q=O.owed;if(O.owed=[],await this.markSettling(d,c,q,{failures:H,marks:O}),O.owed.length>0)throw Error(H.map((G)=>G.error).join("; "));for(let G of H)this.warn(`[BrokerExecutionRelease] Binding ${G.scopeKey}/${G.bindingIndex} of released session ${c}: ${G.error}`)},{stopWhen:x}),this.closed)return;let N=[];await this.releaseOwnership(d,c,B,{failures:N,owed:[]});for(let H of N)this.warn(`[BrokerExecutionRelease] Clearing the owner of binding ${H.scopeKey}/${H.bindingIndex} for released session ${c} failed; the dead record pins nothing in this daemon (#11339) and the clear is retried: ${H.error}`)}finally{T()}if(O.marked.length>0)await this.settleLater(d,c,R,O.marked)}async releaseOwnership(d,c,R,{failures:C,owed:T}){return(await Promise.allSettled(R.map(async(O)=>T.includes(O)?{released:!1,assignment:O}:d.releaseExecution(Se(O),c)))).flatMap((O,x)=>{if(O.status==="rejected")return C.push({...Se(R[x]),error:r(O.reason)}),this.track(this.ownerClearer.retry(d,Se(R[x]),c)),[Ui(R[x],!1)];let N=O.value.assignment??R[x];return[Ui(N,O.value.released)]})}async settleLater(d,c,R,C){let{timer:T}=this.options,B=T.now()+this.settlementCapMs,O=!1;while(!this.isSettled(c,R)){if(this.closed)return;if(!O&&T.now()>=B)O=!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 T.sleep(O?this.settlementSlowPollMs:this.settlementPollMs)}await this.restoreOnceUnowned(d,C,B)}async restoreOnceUnowned(d,c,R){let C=(await Promise.all(c.map((B)=>this.restoreBindingOnceUnowned(d,B,R)))).filter((B)=>B!==null);if(C.length===0)return;let T=C.map((B)=>`${B.key.scopeKey}/${B.key.bindingIndex}`).join(", ");this.warn(`[BrokerExecutionRelease] A live execution still holds the owner record of settled binding(s) ${T} 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:C}=this.options;for(;;){if(await this.restoreReady(d,c,R)==="done"||this.closed)return null;if(C.now()>=R)return c;await C.sleep(this.settlementPollMs)}}async restoreReady(d,c,R){let C=await this.retrier.run(`Returning settled binding ${c.key.scopeKey}/${c.key.bindingIndex} to ready`,R,()=>this.restoreReadyOnce(d,c));return C.done?C.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 T=await this.restoreBindingState(d,c);if(T.kind!=="updated"&&T.kind!=="advanced")this.warn(`[BrokerExecutionRelease] Binding ${c.key.scopeKey}/${c.key.bindingIndex} settled but could not return to ready: ${T.kind}`);return"done"}async restoreBindingState(d,c){let R={generation:c.generation,stableDeviceId:c.stableDeviceId},C=this.options.journal;if(!C||c.journalEntryId===void 0)return d.updateBindingState(c.key,R,"ready");let T=await d.advanceBindingJournal(c.journalEntryId,{owner:this.settlerIdentity(),expectedPhase:"intent",phase:"committed",assignment:{kind:"state",expected:R,state:"ready"}});return C.inFlight.delete(c.journalEntryId),T}async closeSupersededEntry(d,c,R){let C=this.options.journal,T=R?.execOwner??null;if(!C||c.journalEntryId===void 0||T&&this.isExecOwnerLive(T))return;let B=!R||R.generation!==c.generation||R.stableDeviceId!==c.stableDeviceId;await d.advanceBindingJournal(c.journalEntryId,{owner:this.settlerIdentity(),expectedPhase:"intent",phase:B?"rolled_back":"committed"}),C.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 C=!1;return()=>{if(C||this.closed&&!this.isSettled(d,c))return;C=!0;let T=(this.ownerHoldCounts.get(d)??1)-1;if(T>0){this.ownerHoldCounts.set(d,T);return}this.ownerHoldCounts.delete(d),this.ownerHolds.delete(d)}}settlerIdentity(){return this.settler??=this.options.settler??{daemonId:`pid-${process.pid}`,...kH()},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>Sl){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 Il(d,c=`${Zb()}.session-broker.lock`){return{acquire:()=>{if(!_i(c,{pid:d.pid,ownerToken:d.daemonId,ownerGeneration:Nt}))throw new t("Another provider owns session-broker execution on this host; stop it before starting a replacement")},release:()=>vi(c,d.pid,d.daemonId)}}import{createHash as Py}from"crypto";function Mt(d,c){let R=Py("sha256").update(JSON.stringify(c)).digest("hex").slice(0,16);return`${d}:sha256:${R}`}var Vr="android-sdk-installed-catalog",Cy="android-native-catalog-v1";function Pl(d){let c=new Set,R=new Set;for(let C of d){if(c.has(C))R.add(C);c.add(C)}return R}function Ty(d,c,R,C){let T=c.profileArchetypes[d.id];return{profileId:d.id,...T===void 0?{}:{archetype:T},metadataState:R==="stale"||C||d.id.length===0?"stale":"current"}}function My(d){if(d<=1)return"major";return d===2?"minor":"patch"}function Ey(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 By(d,c,R){return d==="stale"||c||!R?"stale":"current"}function Oy(d){let c=DV(d);if(c===void 0)return{versionPrecision:"major"};let R=Mo(c);if(!R.ok)return{versionPrecision:"major"};return{osVersion:R.value.value,versionPrecision:My(R.value.precision)}}function xy(d,c,R){let C=Yr(d.packageName),T=By(c,R,Ey(d,C)),B=C?.apiLevel??d.apiLevel;return{systemImagePackage:d.packageName,...Oy(B),apiLevel:B,abi:C?.abi??d.abi,flavor:C?.tag??d.tag,installed:!0,metadataState:T}}function Cl(d,c,R,C={}){let T=C.metadataState??"current",B=Pl(d.map((q)=>q.id)),O=Pl(c.map((q)=>q.packageName)),x=d.map((q)=>Ty(q,R,T,B.has(q.id))).sort((q,G)=>q.profileId.localeCompare(G.profileId)),N=c.map((q)=>xy(q,T,O.has(q.packageName))).sort((q,G)=>q.systemImagePackage.localeCompare(G.systemImagePackage)),H=Mt(Vr,{adapterVersion:Cy,policy:Object.entries(R.profileArchetypes).sort(([q],[G])=>q.localeCompare(G)),profiles:x,releases:N});return{platform:"android",provenance:{source:Vr,revision:H,state:"ready"},profiles:x,releases:N,hostAbis:nS(C.hostArchitecture??process.arch)}}async function _y(d,c){let[R,C]=await Promise.allSettled([d.listDevices(c),d.listInstalledSystemImages(void 0,c)]);if(R.status==="rejected")throw R.reason;if(C.status==="rejected")throw C.reason;if(R.value.length===0)throw Error("Android emulator profile catalog returned no profiles.");return[R.value,C.value]}async function Jr(d,c,R={}){try{let[C,T]=await _y(d,R.signal);return Cl(C,T,c,R)}catch(C){if(R.signal?.aborted)throw C;let T=`Unable to read the installed Android emulator catalog: ${r(C)}`;return(R.logger??e).warn(T,C),{platform:"android",provenance:{source:Vr,revision:"unavailable",state:"unavailable",message:T},profiles:[],releases:[]}}}var jr="simctl-installed-catalog",Fy="simctl-fields-v1";function Ny(d){if(d.family==="duo")return"duo";return d.family==="ipad"?"tablet":"phone"}function Ml(d){if(d===void 0)return;let[c,R]=d.split("."),C=R?.replace(/0+$/,"");return C?`${Number(c)}.${C}`:String(Number(c))}function Ly(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=Ml(d.sizeInches),C=Ml(c.sizeInches);if(R!==void 0&&C!==void 0&&R!==C)return{modelType:d,conflict:!0};return{modelType:R===void 0?c:d,conflict:!1}}function $y(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 Hy(d){return/(?:^|[\s(])(\d+(?:\.\d+)?)-inch(?:[\s)]|$)/.exec(d)?.[1]}function qy(d){let c=Hy(d),R=(C)=>c===void 0?C:{...C,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 Uy(d){if(cs(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=$y(d.name);return{archetype:"phone",...c===void 0?{}:{modelType:c},conflict:!1}}if(d.productFamily==="iPad"){let c=qy(d.name);return{archetype:"tablet",...c===void 0?{}:{modelType:c},conflict:!1}}return{conflict:!1}}function Ky(d,c){let R=Uy(d),C=c.filter((x)=>x.simulatorDeviceTypeIdentifier===d.identifier);if(C.length>1)return{...R,conflict:!0};let T=C[0];if(!T)return R;let B=Ny(T.modelType);if(R.archetype!==void 0&&R.archetype!==B)return{...R,conflict:!0};let O=Ly(R.modelType,T.modelType);return{archetype:R.archetype??B,modelType:O.modelType,...O.conflict||T.aliases===void 0?{}:{aliases:T.aliases},conflict:O.conflict}}function Gy(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 Wy(d,c,R,{classificationConflict:C,malformedBounds:T}){let B=d.identifier.length>0&&d.name.length>0&&d.productFamily.length>0;return c==="stale"||R||C||T||!B?"stale":"current"}function Vy(d,c,R,C){let T=Ky(d,c),B=wI(d),O=SI(d)&&B===void 0,x=Wy(d,R,C,{classificationConflict:T.conflict,malformedBounds:O}),N=Gy(T.aliases);return{simulatorDeviceTypeIdentifier:d.identifier,...d.modelIdentifier?{modelIdentifier:d.modelIdentifier}:{},name:d.name,productFamily:d.productFamily,...N===void 0?{}:{aliases:N},...T.archetype===void 0?{}:{archetype:T.archetype},...T.modelType===void 0?{}:{modelType:T.modelType},metadataState:x,...B===void 0?{}:{minOsVersion:B.minVersion,maxOsVersion:B.maxVersion}}}function Jy(d){return d.platform==="iOS"||d.identifier.startsWith("com.apple.CoreSimulator.SimRuntime.iOS-")||d.name.startsWith("iOS ")}function jy(d,c,R){let C=Mo(d.version);return{runtimeId:d.identifier,...C.ok?{osVersion:C.value.value}:{},installed:d.isAvailable===!0,metadataState:c==="stale"||R||!d.identifier||!C.ok||d.isAvailable===void 0?"stale":"current"}}function Ol(d){let c=new Set,R=new Set;for(let C of d){if(c.has(C))R.add(C);c.add(C)}return R}function _l(d,c,R={}){let C=R.metadataState??"current",T=R.classifications??[],B=Ol(d.map((G)=>G.identifier)),O=c.filter(Jy),x=Ol(O.map((G)=>G.identifier)),N=d.map((G)=>Vy(G,T,C,B.has(G.identifier))).sort((G,W)=>G.simulatorDeviceTypeIdentifier.localeCompare(W.simulatorDeviceTypeIdentifier)),H=O.map((G)=>jy(G,C,x.has(G.identifier))).sort((G,W)=>G.runtimeId.localeCompare(W.runtimeId)),q=Mt(jr,{classificationVersion:Fy,classifications:[...T].sort((G,W)=>G.simulatorDeviceTypeIdentifier.localeCompare(W.simulatorDeviceTypeIdentifier)),models:N,releases:H});return{platform:"ios",provenance:{source:jr,revision:q,state:"ready"},models:N,releases:H}}async function zy(d,c){let R=(B)=>B.then((O)=>()=>O,(O)=>()=>{throw O}),[C,T]=await Promise.all([R(d.getDeviceTypesChecked(c)),R(d.getRuntimesChecked(void 0,c))]);return[C(),T()]}async function Xr(d,c={}){try{let[R,C]=await zy(d,c.signal);return _l(R,C,c)}catch(R){if(c.signal?.aborted)throw R;let C=`Unable to read the installed iOS simulator catalog: ${r(R)}`;return(c.logger??e).warn(C,R),{platform:"ios",provenance:{source:jr,revision:"unavailable",state:"unavailable",message:C},models:[],releases:[]}}}var Gi="simctl-watch-catalog";function Nl(d){let c=d.runtimes.map((C)=>{let T=C.version.trim()||cW(C.identifier);return{runtime:C.identifier,...T?{osVersion:T}:{},installed:C.isAvailable===!0}}).sort((C,T)=>C.runtime.localeCompare(T.runtime)),R=d.deviceTypes.map((C)=>({deviceType:C.identifier,name:C.name})).sort((C,T)=>C.deviceType.localeCompare(T.deviceType));return{platform:"watchos",provenance:{source:Gi,revision:Mt(Gi,{runtimes:c,deviceTypes:R}),state:"ready"},runtimes:c,deviceTypes:R}}async function Qr(d,c={}){if(!d)return{platform:"watchos",provenance:{source:Gi,revision:"not-installed",state:"not-installed",message:"Apple Watch simulators exist only on macOS hosts with Xcode's simctl."},runtimes:[],deviceTypes:[]};try{return Nl(await d.readCatalog(c.signal))}catch(R){if(c.signal?.aborted)throw R;let C=`Unable to read the Apple Watch simulator catalog: ${r(R)}`;return(c.logger??e).warn(C,R),{platform:"watchos",provenance:{source:Gi,revision:"unavailable",state:"unavailable",message:C},runtimes:[],deviceTypes:[]}}}function ql(d){let c=new F(null),R=process.platform==="darwin"?new oa(c):void 0;return(C,T)=>{if(C==="watchos")return Qr(R,{signal:T});if(C==="ios")return Xr(c,{signal:T,classifications:d.iosClassifications});return Jr({listDevices:(B)=>nR(void 0,B),listInstalledSystemImages:(B,O)=>uu(B,void 0,O)},{profileArchetypes:d.androidProfileArchetypes},{signal:T})}}class eo{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(Wh).map(({command:C})=>Pm(C).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((C)=>C?.toLowerCase()===d.toLowerCase())}findLiveEmulatorSerial(d){return GH(d,async()=>{let c=await this.listDevicesChecked();if(c.some((R)=>!R.name||ia(R.name,R.deviceId)))throw new t("Cannot identify a discovered emulator's AVD; retry cleanup after emulator discovery recovers");return c})}}function Yy(d,c){let R=new ii;return{registry:d,resolver:new Kr,filesystem:hX,liveness:new eo(new Df(new ne,{timer:c,procFs:wy}),()=>R.getBootedDevicesChecked(!0))}}function to(d,c,R){return d??Yy(c?.avdSnapshotCleanupRegistry(),R)}var Qt=180;class io{adb;hinge;timer;constructor(d,c=new SO,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),C={signal:c,assertCurrent:()=>c.throwIfAborted()};if(await IB(R,"opened",void 0,{supportsRearDisplay:!0,operation:C}))throw new t("Emulator refused unfolded posture; cannot prove opened baseline");let B=await this.hinge.setHingeAngle(R,Qt,{signal:c});if(!B.ok)throw new t(`Cannot restore hinge angle to ${Qt}: ${B.reason}`);let O=await this.hinge.getHingeAngle(R,{signal:c});if(!O.ok||O.degrees!==Qt)throw new t(`Hinge angle read-back did not confirm ${Qt} degrees`);let x=await fD(R,C);await _B(R,"opened",{states:x},{timer:this.timer,observe:()=>{throw new t("The device exposes no committed posture state to read back")},operation:C}),c.throwIfAborted()}catch(R){throw new t(`Cannot restore Android device '${d.deviceId}' to opened posture (${Qt} degrees): ${r(R)}`,{cause:R})}}}class no{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 Kl(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 C=d.getAllDevices().find((T)=>T.platform===c.platform&&(c.platform==="android"?(T.avdName??T.name)===c.name:T.id===c.deviceId));if(!C)return;if(!Sr(C))return`pooled runtime is ${Xv(C)}`;if(D(C)!==null)return"a session holds the runtime";if(d.isUnderShutdownReservation(C.id))return"shutdown reservation";return d.isDeviceLeasedForAndroidStartup(C.id)?"android startup lease":void 0}function ve(d){return d.platform==="android"?d.name:d.deviceId}var Xy=["android","ios","watchos"],Gl=["assigned_active","assigned_idle","deleting","preparing","orphaned"],ro=10,Qy={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 Zy(d){if(d.kind!=="orphaned")return Qy[d.kind];return d.orphanState==="transitioning"?"orphaned: booting or shutting down":"orphaned: running"}function eS(d){let{limit:c,usage:R,charged:C,chargedOmitted:T,retained:B,evictionFailures:O}=d;return{limit:c,usage:R,charged:C,...T?{chargedOmitted:T}:{},retained:B,evictionFailures:O}}function jl(d){let c=eS(d);return{message:iS(c),budget:c}}function iS(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((T)=>`${T.name??T.stableDeviceId} (${T.platform}, ${Zy(T)})`).join("; "),C=d.chargedOmitted??0;return`${c} Charged devices: ${R}${C>0?`; and ${C} 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,C)=>Gl.indexOf(R.kind)-Gl.indexOf(C.kind)||R.platform.localeCompare(C.platform)||R.stableDeviceId.localeCompare(C.stableDeviceId))}function _e(d,c){return JSON.stringify([d,c])}function sS(d,c){return c.find((R)=>Ws(R)===d.platform&&uI(R)===d.stableDeviceId)}function aS(d,c){if(d.scopeState===null)return"preparing";if(c.has(_e(d.platform,d.stableDeviceId)))return"deleting";return d.execSessionUuid!==null?"active":"assignedIdle"}function dS(d,c,R){return[{category:aS(d,c),platform:d.platform,stableDeviceId:d.stableDeviceId,journal:sS(d,R)}]}function Wl(d,c){let R=uI(c)??c.target.newName??c.target.oldStableId??c.target.oldName;if(!R)return;d.push({category:"preparing",platform:Ws(c),stableDeviceId:R,journal:c})}function cS(d){let{charges:c,seen:R}=zl(d);return pS(d,c,R),c}function zl(d){let c=d.openJournal.filter((O)=>HP(O.phase)),R=new Set(c.filter((O)=>O.kind==="replace"&&["intent","deleting"].includes(O.phase)&&O.target.oldStableId!==null).map((O)=>_e(O.platform,O.target.oldStableId))),C=new Map(d.managed.filter((O)=>!c.some((x)=>x.kind==="create"&&O.holder==="session_broker"&&O.scopeState!==null&&x.scopeKey===O.scopeKey&&x.bindingIndex===O.bindingIndex&&uI(x)!==O.stableDeviceId)).map((O)=>[_e(O.platform,O.stableDeviceId),O])),T=new Set(C.keys()),B=[...C.values()].flatMap((O)=>dS(O,R,c));for(let O of c){if(O.kind==="release")continue;let x=uI(O);if(x!==null){let N=_e(Ws(O),x);if(!T.has(N))Wl(B,O),T.add(N)}else if(!fS(O,C))Wl(B,O)}return{charges:B,seen:T}}function lS(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 uS(d){return jG(d.platform)}function Yl(d,c){let R=new Set(c),C=[];for(let T of d.inventory??[]){let B=ve(T);if(!uS(T)||!B||!Xa(T.name))continue;let O=_e(T.platform,B);if(!(d.managed.some((N)=>_e(N.platform,N.stableDeviceId)===O)||d.openJournal.some((N)=>N.platform===T.platform&&[N.target.oldStableId,N.target.oldName].some((H)=>H===B||H===T.name)||Ws(N)===T.platform&&[N.target.newStableId,N.target.newName].some((H)=>H===B||H===T.name)))&&!R.has(O)&&!T.name.startsWith(CX))C.push(T),R.add(O)}return C}function pS(d,c,R){for(let C of Yl(d,R)){let T=lS(C),B=ve(C);if(T===null||!B)continue;c.push({category:"orphaned",platform:C.platform,stableDeviceId:B,name:C.name,orphanState:T}),R.add(_e(C.platform,B))}}function mS(d){return Yl(d,zl(d).seen).filter((c)=>c.isRunning!==!0&&c.isRunningStateKnown===!1)}function fS(d,c){return d.target.oldStableId!==null&&c.has(_e(d.platform,d.target.oldStableId))}function gS(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 vS(d,c,R,C){let T=_e(c.platform,ve(c)??c.name),B=C.get(T);if(B)return B;let O=d.probeRunning?d.probeRunning(c,{signal:R}).catch((x)=>(R?.throwIfAborted(),e.debug(`[Bindings] running-state probe of ${c.name} failed: ${x}`),!1)):Promise.resolve(!1);return C.set(T,O),O}async function yS(d,c,R,C){let T=mS(c),B=new Set((await Promise.all(T.map(async(O)=>await vS(d,O,R,C)?O:null))).filter((O)=>O!==null));return(c.inventory??[]).map((O)=>B.has(O)?{...O,isRunning:!0,isRunningStateKnown:!0}:O)}async function SS(d,c,R,{timer:C,probes:T}){Vi(R,C);let B=await d.snapshotBindingResources(),O=[];for(let H of Xy){Vi(R,C);let q=await c.list(H,{signal:R.signal});if(!q.complete&&q.toolchain==="not_installed")continue;if(!q.complete)throw new t(`${H} inventory is incomplete; total-resource usage is unknown.`);O.push(...q.devices)}Vi(R,C);let x=await yS(c,{...B,inventory:O},R.signal,T),N=cS({...B,inventory:x});return{charges:N,charged:oS(N)}}function Vi(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 Vl(d,c){let R=d.filter((T)=>T.category!=="preparing"||T.journal?.kind!=="create"||T.journal.id<=c),C=R.some((T)=>T.category==="preparing"&&T.journal?.id===c);return R.length+(C?0:1)}class ao{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{Vi(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 C=new Map,T=()=>SS(d,this.deps.inventory,R,{timer:this.timer,probes:C}),B=await T();if(Vl(B.charges,R.journalEntryId)>c)B=await T();let O=gS(B.charges);return Vl(B.charges,R.journalEntryId)<=c?{kind:"admitted",enforced:!0,limit:c,usage:O,evicted:[]}:{kind:"exhausted",limit:c,usage:O,charged:B.charged.slice(0,ro),...B.charged.length>ro?{chargedOmitted:B.charged.length-ro}:{},retained:[],evictionFailures:[]}}}var bS=["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=g9){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(XR(R))return{kind:"failed",...wS(R),evidence:R};return{kind:"absent",evidence:R}}}function wS(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 C="error"in R&&typeof R.error==="string"?R.error:c,T="failure"in R?RS(R.failure):void 0;if(T)return{message:C,notAttempted:{reason:T}};if(DS("failure"in R?R.failure:void 0))return{message:C,escalationExhausted:!0};return{message:C}}}catch(R){e.debug(`[Bindings] Unparsed deleteDevice failure text: ${r(R)}`)}return{message:c}}function RS(d){if(!d||typeof d!=="object"||!("phase"in d)||d.phase!=="precondition"||!("code"in d))return;return bS.find((c)=>c===d.code)}function DS(d){return!!d&&typeof d==="object"&&"code"in d&&d.code===H2}class je extends Error{reason;constructor(d){super("Journal drive cancelled");this.reason=d}}function ue(d){if(d?.aborted)throw new je(d.reason)}function lo(d,c,R){return d.devices.find((C)=>C.platform===c&&ve(C)===R)}var mo=1000,ji=3,ho=6,zi=500;class go{registry;stages;constructor(d,c){this.registry=d;this.stages=c}async checkDeviceFree(d,c,R){let C=await this.stages.listInventory(d,d.platform,R);if(!C)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let T=lo(C,d.platform,c);if(!T)return C.complete?{kind:"free"}:{kind:"blocked",reason:"discovery_incomplete",message:`Device '${c}' was not listed and discovery was incomplete.`};let B=await this.stages.describeClaim(d,T,R);if(B.kind==="free")return{kind:"free"};return{kind:"blocked",reason:B.kind==="held"?"device_busy":"discovery_incomplete",message:`Device '${c}' is not free: ${B.reason}`}}async locateForDeletion(d,c,R,C){if(C)return{kind:"present",device:C};let T=await this.stages.listInventory(d,d.platform,R);if(!T)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let B=lo(T,d.platform,c);if(!B)return T.complete?{kind:"absent"}:{kind:"blocked",reason:"discovery_incomplete",message:`Device '${c}' was not listed and discovery was incomplete.`};let O=await this.stages.describeClaim(d,B,R);if(O.kind!=="free")return{kind:"blocked",reason:O.kind==="held"?"device_busy":"discovery_incomplete",message:`Device '${c}' cannot be deleted: ${O.reason}`};let x=await this.registry.findDeviceHolder(d.platform,c);if(ue(R),x?.kind!=="binding"||x.assignment.scopeKey!==d.scopeKey||x.assignment.bindingIndex!==d.bindingIndex||!Dd(x.assignment,d.binding))return{kind:"blocked",reason:"reconcile_in_progress",message:`Device '${c}' is no longer this binding's device.`};return{kind:"present",device:B}}async locateCreated(d,c){let{newStableId:R,newName:C}=d.target;if(!R&&!C)return{kind:"absent"};let T=Ws(d),B=await this.stages.listInventory(d,T,c);if(!B)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let O=B.devices.filter((N)=>N.platform===T&&(R?ve(N)===R:N.name===C));if(O.length===0)return B.complete?{kind:"absent"}:{kind:"blocked",reason:"discovery_incomplete",message:`Created device '${R??C}' was not listed and discovery was incomplete.`};let x=O.length===1?ve(O[0]):void 0;if(!x)return{kind:"blocked",reason:"discovery_incomplete",message:`Created device '${C}' is ambiguous (${O.length} listed).`};return{kind:"present",device:O[0],stableId:x}}}class Zt{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 C=this.removals.get(JSON.stringify([d,c]));for(let T of C??[])if(T.overdueAtMs!==void 0&&R-T.overdueAtMs>=mo)T.abandoned=!0;return this.removalBlocked(d,c)}removalBlocked(d,c){let R=JSON.stringify([d,c]),C=this.removals.get(R);if(!C)return!1;if([...C].filter((B)=>B.abandoned).length>=ji){if(!this.warned.has(R))this.warned.add(R),e.warn(`[BindingJournal] Removal of '${c}' reached the pending abandoned delete bound.`);return!0}return[...C].some((B)=>!B.abandoned)}markRemovalOverdue(d,c){let R=this.operations.get(d);if(R&&R.overdueAtMs===void 0)R.overdueAtMs=c}trackRemoval(d,c,R){let C=JSON.stringify([d,c]),T=this.removals.get(C)??new Set,B={abandoned:!1};T.add(B),this.removals.set(C,T);let O=Promise.resolve().then(R).finally(()=>{if(B.abandoned)e.debug(`[BindingJournal] Abandoned removal of '${c}' settled late.`);if(T.delete(B),this.operations.delete(O),T.size===0)this.removals.delete(C);if([...T].filter((x)=>x.abandoned).length<ji)this.warned.delete(C)});return this.operations.set(O,B),O}add(d){this.ids.add(d)}delete(d){this.ids.delete(d)}has(d){return this.ids.has(d)}}function Xl(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 Ql(d){return{stableDeviceId:null,deviceName:null,requestedSpec:d,resolvedSpec:null,specFingerprint:null,state:"provisioning"}}function vo(d){return{entryId:d.entry.id,kind:d.entry.kind,phase:d.entry.phase,outcome:d.kind,...d.kind==="blocked"?{reason:d.reason}:{}}}var kS={android:FX,ios:LX,watchos:vH};function Zl(d){let c=kS[Ws(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 C=new AbortController,T=c.signal?AbortSignal.any([c.signal,C.signal]):C.signal;try{return await l(()=>this.retryRemovalFlag(d,T),{timer:this.deps.timer,timeoutMs:c.deadlineMs===void 0?void 0:Math.max(0,c.deadlineMs-this.deps.timer.now()),signal:T,label:`removal flag for entry ${d.id}`,onTimeout:()=>C.abort()})}catch(B){if(!T.aborted)throw B;return e.warn(`[BindingJournal] Removal flag for entry ${d.id} interrupted: ${r(B)}`,B),d}}async retryRemovalFlag(d,c){for(let R=2;R<=ho;R++){c.throwIfAborted(),await this.deps.pacing.wait(this.deps.pacing.delay(R-1),c);let C=await this.tryRemovalFlag(d,c);if(C)return C.kind==="advanced"?C.entry:d}return e.warn(`[BindingJournal] Removal flag for entry ${d.id} exhausted registry retries.`),d}async tryRemovalFlag(d,c,R=!1){let C=this.deps.timer.now(),T=Error(`Removal flag for entry ${d.id} exceeded its write budget.`);try{let B=()=>this.deps.advance(d,{expectedPhase:d.phase,phase:d.phase,target:{removalRequested:!0,...d.target.newStableId?{newStableId:d.target.newStableId}:{}}},c),O=await(R?l(B,{timer:this.deps.timer,timeoutMs:zi,timeoutError:()=>T,label:`first removal flag write for entry ${d.id}`}):this.deps.pacing.run(B,(x)=>x.kind==="advanced",c));if(O.kind==="advanced"||O.kind==="journal_conflict")this.clear(d.id);return O}catch(B){if(B===T)return e.warn(`[BindingJournal] ${r(B)}`,B),{kind:"removal_flag_timed_out"};if($a(B)!=="retryable")throw e.warn(`[BindingJournal] Removal flag failed: ${r(B)}`,B),B;if(R)this.deps.pacing.noteBlocked(C);e.debug(`[BindingJournal] Removal flag deferred: ${r(B)}`,B);return}}}class ze extends Error{}class bo{deps;constructor(d){this.deps=d}async boundedStage(d,c,R){ue(c.cancel);let C=new AbortController,T=c.signal?AbortSignal.any([c.signal,C.signal]):C.signal,B=Error(`${c.label} timed out after ${c.timeoutMs}ms`);try{let O=await l(()=>d(T),{timer:this.deps.timer,timeoutMs:Math.max(0,c.timeoutMs),signal:c.signal,label:c.label,timeoutError:()=>B,onTimeout:()=>C.abort(B)});return ue(c.cancel),O}catch(O){if(c.cancel?.aborted)throw C.abort(c.cancel.reason),new je(c.cancel.reason);return e.warn(`[BindingJournal] ${c.label} failed: ${r(O)}`,O),R(c.signal?.aborted?Error(`${c.label} cancelled: ${r(O)}`):O)}}listInventory(d,c=d.platform,R){return this.boundedStage((C)=>this.deps.inventory.list(c,{signal:C}),{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},(C)=>({kind:"unknown",reason:r(C)}))}async deleteDevice(d,c,R){let{inFlight:C}=this.deps;if(C.removalBlocked(d.platform,d.stableId))return{kind:"failed",message:`Removal of device '${d.stableId}' is still in flight.`};let T;try{let B=await this.boundedStage((O)=>(T=C.trackRemoval(d.platform,d.stableId,()=>this.deps.deleter.deleteAndVerifyAbsence({...d,signal:O})),T),{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},(O)=>({kind:"failed",message:r(O)}));return{...B,nativeDeleteFailed:T!==void 0&&B.kind==="failed"&&!B.notAttempted}}finally{if(T)C.markRemovalOverdue(T,this.deps.timer.now())}}}function tu(d,c){return{target:{quarantinedAtMs:d},attempt:{error:c,nextAttemptAtMs:d+600000}}}function iu(d,c,R){let C=c.lastError??"its emulator would not stop";return{advance:{attempt:{error:C,nextAttemptAtMs:d+600000}},message:`Device '${R}' is quarantined: ${C}`}}var nu=120000,AS=30000,IS=1e4,PS=1e4,CS=5000,TS=25,MS=1000,ES=5000,BS=6,OS=te({initialDelayMs:1000,multiplier:2,maxDelayMs:60000});function Te(d,c,R){return{kind:"blocked",entry:d,reason:c,message:R}}function wo(d){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex}}class Ro{deps;inFlight;isOwnerLive;isExecOwnerLive;backoff;budgets;removalFlags;stages;locator;constructor(d){this.deps=d;this.inFlight=d.inFlight??new Zt,this.isOwnerLive=d.isOwnerLive??Qa,this.isExecOwnerLive=d.isExecOwnerLive??Qa,this.backoff=xo(d.backoff??OS),this.budgets={discoveryMs:AS,claimMs:IS,matchMs:PS,deleteGraceMs:CS,...d.stageBudgets},this.removalFlags=new yo({timer:d.timer,pacing:new Oe({timer:d.timer,initialDelayMs:TS,maxDelayMs:MS,maxBlockedWaitMs:ES}),advance:(c,R,C)=>this.advanceStep(c,R,C)}),this.stages=new bo({inventory:d.inventory,deleter:d.deleter,claims:d.claims,timer:d.timer,inFlight:this.inFlight,budgets:this.budgets}),this.locator=new go(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 je)throw e.debug("[BindingJournal] acquisition redrive cancelled"),R.reason;throw R}}async redriveBindingEntries(d,c){ue(c);let R=[],C=await this.deps.registry.listOpenBindingJournal(d);if(ue(c),C.length===0){let T=await this.adoptUnjournaledWork(d,c);C=T?[T]:[]}for(let T of C){let B=await this.driveEntry(T,c);if(B.kind==="skipped")return{kind:"blocked",reason:Xl(B.entry),message:`Binding ${d.bindingIndex} has unfinished ${B.entry.kind} work (${B.why}).`,entry:B.entry,redriven:R};if(R.push(vo(B)),B.kind==="blocked")return{kind:"blocked",reason:B.reason,message:B.message,entry:B.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 C=await this.deps.registry.listOpenBindingJournal();for(let T of C){if(c?.aborted)break;try{let B=await this.driveEntry(T,c,{fromPass:!0});if(B.kind==="skipped")R.skipped+=1;else(B.kind==="settled"?R.settled:R.blocked).push(vo(B))}catch(B){if(B instanceof je){e.debug("[BindingJournal] pass cancelled");break}e.warn(`[BindingJournal] redrive of entry ${T.id} failed: ${r(B)}`,B),R.blocked.push({entryId:T.id,kind:T.kind,phase:T.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 C=d.target.oldStableId,T=await this.deps.registry.getAssignment(wo(d));if(ue(R),!C||!T||!Dd(T,d.binding))return this.closeStep(d,"rolled_back",R);if(T.execOwner&&this.isExecOwnerLive(T.execOwner))return Te(d,"binding_in_use",`Binding is held by ${T.execOwner.sessionUuid}.`);let B=this.pendingRemoval(d,d.platform,C,"step");if(B)return B;let O=await this.locator.locateForDeletion(d,C,R,c.device);if(O.kind==="blocked")return this.recordBlocked(d,O.reason,O.message,{signal:R});if(O.kind==="present"&&d.target.quarantinedAtMs!==void 0)return this.probeQuarantine(d,C,R);let x=O.kind==="present"?await this.stages.deleteDevice({platform:d.platform,stableId:C,name:d.target.oldName,deadlineMs:c.deadlineMs??this.deps.timer.now()+nu,signal:c.signal},R):{kind:"absent",evidence:{listed:!1}};return ue(R),this.recordDeletion(d,C,x,R)}async probeQuarantine(d,c,R){let C=iu(this.deps.timer.now(),d,c),T=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleting",...C.advance},R);return{kind:"blocked",entry:T.kind==="advanced"?T.entry:d,reason:"cleanup_quarantined",message:C.message}}async recordDeletion(d,c,R,C){if(R.kind==="failed"){let B=R.escalationExhausted===!0,O=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleting",assignment:{kind:"state",expected:d.binding,state:"cleanup_pending"},...B?tu(this.deps.timer.now(),R.message):{attempt:this.attemptAfter(d,R.message,this.entryRemovalInFlight(d))}},C);return{kind:"blocked",entry:O.kind==="advanced"?O.entry:d,reason:B?"cleanup_quarantined":"cleanup_pending",message:`Deleting device '${c}' failed: ${R.message}`,evidence:R.evidence}}let T=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleted",assignment:{kind:"commit",expected:d.binding,next:{...Ql(d.target.requestedSpec),platform:Ws(d)}}},C);if(T.kind!=="advanced"||!T.assignment)return{kind:"blocked",entry:d,reason:"reconcile_in_progress",message:`Recording the deletion failed: ${T.kind}.`};return{kind:"deleted",entry:T.entry,assignment:T.assignment,evidence:R.evidence}}async settleCreation(d,c={adopt:!0}){return(d.target.newStableId?this.pendingRemoval(d,Ws(d),d.target.newStableId):void 0)??this.creationStep(d,c)}async removalRegistryStage(d,c){let R=Math.min(zi,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 ze("Removal deferred to journal redrive: registry stage timed out.")})}async creationStep(d,c,R){try{return await this.creationRegistryStep(d,c,R)}catch(C){if(!(C instanceof ze))throw C;let T=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] ${T}`,C),Te(d,"reconcile_in_progress",T)}}async creationRegistryStep(d,c,R){ue(R);let C=await this.locator.locateCreated(d,R);if(C.kind==="absent")return this.removalRegistryStage(()=>this.closeStep(d,"rolled_back",R),c.deadlineMs);if(C.kind==="blocked")return this.removalBlocked(d,C.reason,C.message,{signal:R,deadlineMs:c.deadlineMs});let{device:T,stableId:B}=C,O=this.pendingRemoval(d,Ws(d),B,"step");if(O)return O;let x=await this.removalRegistryStage(()=>this.deps.registry.findDeviceHolder(Ws(d),B),c.deadlineMs);if(ue(R),x)return this.removalRegistryStage(()=>this.closeStep(d,"rolled_back",R),c.deadlineMs);let N=await this.removalRegistryStage(()=>this.deps.registry.getAssignment(wo(d)),c.deadlineMs);ue(R);let H=N!==null&&Dd(N,d.binding),q=Zl(d);if(c.adopt&&!this.removalFlags.removalIntended(d)&&H&&q){let G=await this.stages.boundedStage(()=>this.deps.matcher.matches(T,q),{label:`configuration for entry ${d.id}`,timeoutMs:this.budgets.matchMs,signal:R,cancel:R},()=>"unknown");if(G==="unknown")return this.recordBlocked(d,"discovery_incomplete",`Configuration of '${B}' is unreadable.`,{signal:R});if(G==="match")return this.adoptCreated(d,T,B,R)}return this.removeCreated(d,T,B,{deadlineMs:c.deadlineMs,signal:R})}async close(d,c){return this.closeStep(d,c)}async closeStep(d,c,R){let C=await this.advanceStep(d,{expectedPhase:d.phase,phase:c},R);return this.removalFlags.clear(d.id),{kind:"settled",entry:C.kind==="advanced"?C.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 C=await this.deps.registry.advanceBindingJournal(d.id,{...c,owner:this.deps.owner});return ue(R),C}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 C=await this.takeOwnership(d,c);if(C.kind==="skipped")return C;let T=C.entry,B=this.pendingEntryRemoval(T,R.fromPass);if(B)return B;if(T.attempts>0&&T.nextAttemptAtMs>this.deps.timer.now())return{kind:"skipped",entry:T,why:`retry due in ${T.nextAttemptAtMs-this.deps.timer.now()}ms`};this.inFlight.add(T.id);try{for(let O=0;O<BS;O+=1){ue(c);let x=await this.step(T,c);if(x.kind!=="next")return x;T=x.entry}return Te(T,"reconcile_in_progress","Journal entry did not settle.")}finally{this.inFlight.delete(T.id)}}async takeOwnership(d,c){if(Ec(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(wo(d));if(ue(c),!R||!Dd(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 Te(d,"binding_settling","The binding's settler is still watching its work.");if(R.execOwner&&this.isExecOwnerLive(R.execOwner))return Te(d,"binding_in_use",`Binding is held by ${R.execOwner.sessionUuid}.`);let C=R.stableDeviceId;if(C){let B=await this.locator.checkDeviceFree(d,C,c);if(B.kind==="blocked")return this.recordBlocked(d,B.reason,B.message,{signal:c})}let T=await this.advanceStep(d,{expectedPhase:d.phase,phase:"committed",assignment:{kind:"state",expected:d.binding,state:"ready"}},c);if(T.kind!=="advanced")return Te(d,"reconcile_in_progress",`Restoring the binding failed: ${T.kind}.`);return{kind:"settled",entry:T.entry}}async adoptCreated(d,c,R,C){if(this.removalFlags.removalIntended(d))return this.removeCreated(d,c,R,{signal:C});let T=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"}}},C);if(T.kind==="advanced")return{kind:"settled",entry:T.entry};if(T.kind==="journal_conflict")return Te(d,"reconcile_in_progress","The journal entry changed during adoption.");return this.removeCreated(d,c,R,{signal:C})}async removeCreated(d,c,R,{deadlineMs:C,signal:T}={}){if(!d.target.removalRequested){this.markRemovalIntended(d);let N=await this.removalRegistryStage(()=>this.advanceStep(d,{expectedPhase:d.phase,phase:d.phase,target:{removalRequested:!0,newStableId:R}},T),C);if(N.kind==="advanced"||N.kind==="journal_conflict")this.removalFlags.clear(d.id);if(N.kind!=="advanced")return Te(d,"reconcile_in_progress",`Recording removal of '${R}' failed: ${N.kind}.`);d=N.entry}let B=await this.stages.describeClaim(d,c,T);if(B.kind!=="free")return this.removalBlocked(d,B.kind==="held"?"device_busy":"discovery_incomplete",`Uncommitted device '${R}' cannot be removed: ${B.reason}`,{target:{newStableId:R},signal:T,deadlineMs:C});let O=await this.stages.deleteDevice({platform:Ws(d),stableId:R,name:c.name,deadlineMs:C??this.deps.timer.now()+nu,signal:T},T);if(O.kind==="failed")return this.removalBlocked(d,"cleanup_pending",`Removing uncommitted device '${R}' failed: ${O.message}`,{target:{newStableId:R},signal:T,deadlineMs:C});let x=await this.removalRegistryStage(()=>this.advanceStep(d,{expectedPhase:d.phase,phase:"rolled_back",target:{newStableId:R}},T),C);return this.removalFlags.clear(d.id),{kind:"settled",entry:x.kind==="advanced"?x.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 C=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),C.kind==="opened")return e.warn(`[BindingJournal] binding ${d.bindingIndex} was left ${R.state} without a journal entry; redriving it as entry ${C.entry.id}`),C.entry;return C.kind==="journal_open"?C.entry:null}removalBlocked(d,c,R,{target:C,signal:T,deadlineMs:B}){return this.removalRegistryStage(()=>this.recordBlocked(d,c,R,{target:C,signal:T}),B)}async recordBlocked(d,c,R,{target:C,signal:T}={}){let B=C?.newStableId&&d.phase==="creating"?"created":d.phase,O=await this.advanceStep(d,{expectedPhase:d.phase,phase:B,...C?{target:C}:{},attempt:this.attemptAfter(d,R,this.entryRemovalInFlight(d))},T);return Te(O.kind==="advanced"?O.entry:d,c,R)}entryRemovalInFlight(d){return this.inFlight.hasRemoval(d.platform,d.target.oldStableId??"")||this.inFlight.hasRemoval(Ws(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",C=R?d.target.oldStableId:d.target.newStableId;return C?this.pendingRemoval(d,R?d.platform:Ws(d),C,c?"pass":"caller"):void 0}pendingRemoval(d,c,R,C="caller"){if(!(C==="pass"?this.inFlight.hasRemovalForPass(c,R,this.deps.timer.now()):C==="caller"?this.inFlight.hasRemoval(c,R):this.inFlight.removalBlocked(c,R)))return;return Te(d,"cleanup_pending",`Removal of device '${R}' is still in flight.`)}}import{createHash as xS}from"crypto";function ru(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 au(d,c,R){let C=vH.safeParse(c);if(!C.success)return{kind:"unsupported",code:"spec_unsupported",message:`A watchOS binding spec names exactly runtime and deviceType: ${_k(C.error)}`};if(!d)return{kind:"unsupported",code:"spec_unsupported",message:"Apple Watch simulators exist only on macOS hosts with Xcode's simctl."};let T;try{T=await d.readCatalog(R)}catch(O){return R?.throwIfAborted(),e.warn(`[Bindings] watch catalog unreadable: ${r(O)}`,O),{kind:"unresolved",message:`The Apple Watch simulator catalog could not be read: ${r(O)}`}}let B=C.data;try{U2(B,T)}catch(O){if(!(O instanceof t))throw O;let x=T.runtimes.find((H)=>H.identifier===B.runtime);return{kind:"unsupported",code:T.deviceTypes.some((H)=>H.identifier===B.deviceType)&&x&&!x.isAvailable?"runtime_incompatible":"spec_unsupported",message:O.message}}return{kind:"resolved",resolvedSpec:{runtime:B.runtime,deviceType:B.deviceType,displayCutout:"unknown"}}}var du=1,pu="pixel_8",_S={phone:pu,tablet:"pixel_tablet",foldable:"pixel_fold",tv:wl("tv"),watch:wl("watch"),automotive:wl("automotive"),"xr-headset":wl("xr-headset"),"xr-glasses":wl("xr-glasses")};function Ao(d,c){let R=xS("sha256").update(Cr({version:du,platform:d,resolvedSpec:c})).digest("hex");return{version:du,hash:R}}function ri(d){let c={...d};return delete c.deviceFamily,c}function FS(d,c){if(c.deviceFamily===void 0)return;if(c.deviceType===void 0)return d==="android"?NS(c):void 0;let R=d==="ios"?bm(c.deviceType):rf({profileId:c.deviceType,systemImageTag:Yr(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 NS(d){let c=rf({systemImageTag:Yr(d.runtime)?.tag});return roe(c)?c===d.deviceFamily?void 0:`runtime '${d.runtime}' is a ${c} image; it conflicts with deviceFamily '${d.deviceFamily}'.`:void 0}function LS(d,c){if(d!=="android"||c.deviceFamily===void 0||!("configuration"in c))return;return["screenWidth","screenHeight","screenDensity"].some((C)=>c.configuration?.[C]!==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 cu="com.apple.CoreSimulator.SimRuntime.";class Yi{iosRuntimeCatalog;androidDefaultDeviceType;androidDefaultDeviceTypesByFamily;androidImageCatalog;androidProfileCatalog;watchCatalog;constructor(d,c={}){this.iosRuntimeCatalog=d;this.androidDefaultDeviceType=c.androidDefaultDeviceType??pu,this.androidDefaultDeviceTypesByFamily={..._S,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 T=await this.resolve(d,{runtime:c.runtime,deviceType:c.deviceType},R);return T.kind==="resolved"?{kind:"creatable"}:T}if(!this.androidProfileCatalog)return{kind:"creatable"};let C;try{C=await this.androidProfileCatalog.listProfileIds(R.signal)}catch(T){return e.warn(`[Bindings] Android profile catalog unreadable: ${r(T)}`,T),{kind:"unresolved",message:`The Android hardware profile catalog could not be read: ${r(T)}`}}if(C.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 H=await au(this.watchCatalog,c,R.signal);return H.kind==="resolved"?{...H,fingerprint:Ao(d,H.resolvedSpec)}:H}let C=this.catalogRead(R.signal),T=await this.findUnsupportedSpec(d,c,R.signal,C);if(T)return{kind:"unsupported",code:"spec_unsupported",message:T};let B=await this.resolveDeviceType(d,c,C);if(B.kind!=="resolved")return B.resolution;let O={...ri(c),deviceType:B.deviceType},x=OH(d,O);if(x.kind!=="resolved")return{kind:"unsupported",code:"spec_unsupported",message:x.message};if(d==="ios"&&this.iosRuntimeCatalog&&c.deviceType!==void 0){let H=await this.findIosIncompatibility(O,C);if(H)return{kind:"unsupported",code:"runtime_incompatible",message:H}}let N={...O,displayCutout:x.displayCutout};return{kind:"resolved",resolvedSpec:N,fingerprint:Ao(d,N)}}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(([C,T])=>({runtimes:C,deviceTypes:T}))}return c}}async findUnsupportedSpec(d,c,R,C){let T=LS(d,c)??FS(d,c);if(T!==void 0)return T;if(d==="android")return Yr(c.runtime)?await this.findMissingAndroidImage(c.runtime,R):`Android runtime '${c.runtime}' is not a system-image identifier.`;return c.runtime.startsWith(cu)?await this.findMissingIosCatalogEntry(c,C):`iOS runtime '${c.runtime}' is not a CoreSimulator runtime identifier (${cu}...).`}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 Do("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 Do("spec_unsupported","An iOS spec without deviceType needs the simulator catalog to choose a model.");let C,T;try{({runtimes:C,deviceTypes:T}=await R())}catch(O){return e.warn(`[Bindings] iOS catalog unreadable; cannot choose a model: ${r(O)}`,O),{kind:"refused",resolution:{kind:"unresolved",message:`The simulator catalog could not be read to choose a model: ${r(O)}`}}}let B=mu(c.runtime,C,T,c.deviceFamily);return B?{kind:"resolved",deviceType:B}:Do("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(C){e.warn(`[Bindings] Android image check skipped: ${r(C)}`,C);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,C;try{({runtimes:R,deviceTypes:C}=await c())}catch(B){e.warn(`[Bindings] iOS catalog check skipped: ${r(B)}`,B);return}if(!R.some((B)=>B.identifier===d.runtime)){let B=R.map((O)=>O.identifier);return`iOS runtime '${d.runtime}' is not installed on this host. Install it with Xcode, or request an installed runtime (${B.join(", ")||"none installed"}).`}if(d.deviceType===void 0||C.some((B)=>B.identifier===d.deviceType))return;let T=C.filter((B)=>B.productFamily==="iPhone").map((B)=>B.identifier);return`iOS device type '${d.deviceType}' is not installed on this host. Request an installed device type (iPhone types: ${T.join(", ")||"none installed"}; all types: xcrun simctl list devicetypes).`}async findIosIncompatibility(d,c){let R,C;try{({runtimes:R,deviceTypes:C}=await c())}catch(O){e.warn(`[Bindings] iOS catalog check skipped: ${r(O)}`,O);return}let T=MH(d,R,C);if(!T)return;let B=T.compatibleRuntimes.map((O)=>O.id).join(", ")||"none installed";return T.unavailable?`Runtime '${d.runtime}' is not available. Compatible installed runtimes: ${B}.`:`Device type '${d.deviceType}' does not support runtime '${d.runtime}'. Compatible installed runtimes: ${B}.`}}function Do(d,c){return{kind:"refused",resolution:{kind:"unsupported",code:d,message:c}}}function mu(d,c,R,C){let T=c.find((H)=>H.identifier===d);if(!T?.isAvailable)return;let B=R.filter((H)=>C===void 0?H.productFamily==="iPhone"&&!H.modelIdentifier?.startsWith("iPod")&&!cs(H.identifier):bm(H.identifier)===C),O=(H)=>tc(H,T.version).status,x=B.filter((H)=>O(H)==="supported"),N=B.filter((H)=>O(H)==="unknown");return(x.toSorted(lu).at(-1)??N.toSorted(lu).at(-1))?.identifier}function lu(d,c){let R=/^(iPhone|iPad)(\d+),(\d+)$/.exec(d.modelIdentifier??""),C=/^(iPhone|iPad)(\d+),(\d+)$/.exec(c.modelIdentifier??"");if(!R||!C)return Number(Boolean(R))-Number(Boolean(C));return Number(R[2])-Number(C[2])||Number(C[3])-Number(R[3])||c.name.length-d.name.length||(d.identifier<c.identifier?1:d.identifier>c.identifier?-1:0)}class ie extends Error{failure;constructor(d){super(d.message);this.failure=d;this.name="ReconcileAbort"}}var $S={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},HS={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 Io(d,c,R){let C=R.toLowerCase().replace(/[^a-z0-9]/g,"").slice(0,8);if(C.length===0)throw Error(`Binding device name nonce '${R}' has no usable characters`);return`${xX}${Co(d)}${c}-${C}`}function Co(d){return`${d.scopeKey.slice(0,8)}-${d.bindingIndex}-g`}function ut(d){return`v${d.version}:${d.hash}`}function Q(d,c,R={}){return{code:d,retryable:R.retryable??$S[d],message:c,nextAction:HS[d],...R.provision?{provision:R.provision}:{},...R.capacity?{capacity:R.capacity}:{},...R.budget?{budget:R.budget}:{}}}function To(d,c){switch(d.kind){case"scope_not_valid":return Q("scope_not_valid",`Binding scope is no longer valid (${c}).`);case"binding_missing":return Q("concurrent_modification",`Binding disappeared during ${c}.`);case"stale_binding":return Q("concurrent_modification",`Binding binding changed during ${c} (now generation ${d.current.generation}).`);case"device_assigned_elsewhere":return Q("concurrent_modification",`Device is already assigned to binding ${d.holder.bindingIndex} of another scope (${c}).`)}}function Fe(d,c){switch(d.kind){case"binding_in_use":return Q("binding_in_use",`Binding is held by live session ${d.owner.sessionUuid} (${c}).`);case"binding_not_ready":return Q("concurrent_modification",`Binding stopped being ready during ${c}.`);default:return To(d,c)}}function Xi(d){return d&&d.length>0?{externalDevices:[...d]}:{}}function Bt(d){if(d instanceof Nn)return Q("capacity_exhausted",d.message,{capacity:{limit:d.limit,booted:d.booted,retryAfterMs:d.retryAfterMs,...Xi(d.details.externalDevices),...d.details.heldDevices?.length?{heldDevices:[...d.details.heldDevices]}:{}}});if(d instanceof Ue){if(d.code==="discovery_incomplete")return Q("discovery_incomplete",d.message);if(d.code==="runtime_incompatible")return Q("runtime_incompatible",d.message);let c=d.diagnostics.capacity;if(d.code==="capacity_exhausted"&&c)return Q("capacity_exhausted",d.message,{capacity:{limit:c.limit,booted:c.booted,retryAfterMs:d.diagnostics.retryAfterMs??0,...Xi(c.externalDevices),...c.heldDevices?.length?{heldDevices:[...c.heldDevices]}:{}}});return Q("provision_failed",d.message,{retryable:d.retryable,provision:{code:d.code,retryable:d.retryable}})}return Q("provision_failed",r(d),{retryable:!1})}function Me(d){return{generation:d.generation,stableDeviceId:d.stableDeviceId}}function fu(d){let{createDeadlineMs:c,deadlineMs:R}=d.request;if(c===void 0||c>=R)return d;return{...d,request:{...d.request,deadlineMs:c}}}function qS(d){return d.isRunning||d.platform!=="android"&&d.state!==void 0&&o6.has(d.state)}class Eo{deps;host;constructor(d,c){this.deps=d;this.host=c}async createAndCommit(d,c,R,{replacing:C,...T}={}){let{request:B}=d,O;if(C===void 0)try{if(this.host.checkBudget(B),await this.assertCreatable(d),!T.bootReservation)O=await this.assertBootCapacity(B)}catch(H){throw await this.removeNeverBoundBinding(d,c,"pre-provision refusal"),H}else if(this.host.checkBudget(B),!T.bootReservation)O=await this.assertBootCapacity(B);let x=Io(B.key,c.generation+1,this.deps.idGenerator.next());d.evidence.createdName=x;let N=C?await this.advanceToCreating(d,C,x):await this.openCreateEntry(d,c,x);this.deps.journal.inFlight.add(N.id);try{if(C===void 0&&this.deps.resourceBudget)await this.admitFreshCreation(d,c,N);let H;try{let G=()=>this.deps.provisioner.provision({platform:B.platform,name:x,spec:{...ri(B.requestedSpec),deviceType:d.resolvedSpec.deviceType},mode:"create",deadlineMs:B.deadlineMs,signal:B.signal}),W=B.platform,V=()=>W==="watchos"?G():f9({platform:W,name:x,spec:{runtime:B.requestedSpec.runtime,deviceType:d.resolvedSpec.deviceType}},O,this.deps.timer,G);H=T.bootReservation?await T.bootReservation.run(V):await V()}catch(G){return await this.failedCreate(d,c,N,{fresh:C===void 0,error:G})}let q=this.host.isBindingReady(B.platform,H);return await this.host.readyOrReleaseOnBusy(H,async(G)=>{if(H.created&&!q)this.deps.journal.markRemovalIntended(N);if(N=await this.recordCreated(d,N,H.device,{release:G,removalRequested:H.created&&!q}),!q)return await this.discardUncommitted(d,H,N,{release:G,reason:Q("readiness_incomplete",`Device '${x}' did not reach ${SH(B.platform)}.`)});let W=await this.deps.journal.advance(N,{expectedPhase:"created",phase:"committed",assignment:{kind:"commit",expected:N.binding,next:{stableDeviceId:H.device.stableId,deviceName:H.device.name,requestedSpec:B.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ut(d.fingerprint),state:"ready"}}});if(W.kind==="journal_conflict")throw await this.host.releaseSession(H.sessionUuid),new ie(Q("concurrent_modification","The binding's journal entry was taken over."));if(W.kind!=="advanced")return await this.discardUncommitted(d,H,N,{release:G,reason:Fe(W,"create commit")});return this.noteJournal(d,W.entry),await this.host.claimAndReady(d,R,W.assignment,{provisioned:H})})}finally{this.deps.journal.inFlight.delete(N.id)}}async openCreateEntry(d,c,R){let{request:C}=d,T=await this.deps.registry.openBindingJournal(C.key,{kind:"create",phase:"creating",owner:this.deps.journal.owner,target:this.journalTarget(d,c,R),assignment:{kind:"state",expected:Me(c),state:"provisioning"}});if(T.kind==="journal_open")throw new ie(Q("reconcile_in_progress",`Binding ${C.key.bindingIndex} has unfinished work.`));if(T.kind!=="opened")throw new ie(Fe(T,"create"));return this.noteJournal(d,T.entry),T.entry}async advanceToCreating(d,c,R){let C=await this.deps.journal.advance(c,{expectedPhase:"deleted",phase:"creating",target:{newName:R}});if(C.kind!=="advanced")throw new ie(Q("concurrent_modification",`Replacement journal changed: ${C.kind}.`));return this.noteJournal(d,C.entry),C.entry}async failedCreate(d,c,R,{fresh:C,error:T}){let{request:B}=d;if(T instanceof Ue&&T.retryable&&T.code==="timeout"&&T.diagnostics.retainedDevice&&T.diagnostics.retainedDevice.name===R.target.newName&&T.diagnostics.retainedDevice.platform==="ios"&&B.platform==="ios"&&!B.signal?.aborted){try{await this.recordCreated(d,R,T.diagnostics.retainedDevice)}catch(x){throw e.warn(`[Bindings] retaining created device failed: ${r(x)}`,x),new ie(Bt(T))}throw new ie({...Bt(T),retainedDevice:T.diagnostics.retainedDevice})}let O=await this.settleFailedCreate(d,R);if(C)await this.removeFailedUnboundBinding(d,c,O);throw new ie(Bt(T))}async recordCreated(d,c,R,{release:C,removalRequested:T=!1}={}){let B=await this.deps.journal.advance(c,{expectedPhase:"creating",phase:"created",target:{newStableId:R.stableId,newName:R.name,...T?{removalRequested:!0}:{}}}).catch(async(O)=>{throw e.warn(`[Bindings] recording created device failed: ${r(O)}`,O),await C?.(),O});if(B.kind!=="advanced")throw await C?.(),new ie(Q("concurrent_modification","The binding's journal entry was taken over."));return this.noteJournal(d,B.entry),B.entry}async admitFreshCreation(d,c,R){let C;try{C=await this.deps.resourceBudget.admitCreation({journalEntryId:R.id,deadlineMs:d.request.deadlineMs,signal:d.request.signal}),this.host.checkBudget(d.request)}catch(x){let N=await this.settleFailedCreate(d,R,!0);throw await this.removeFailedUnboundBinding(d,c,N),x}if(C.kind==="admitted")return;let T=await this.settleFailedCreate(d,R,!0);if(await this.removeFailedUnboundBinding(d,c,T),C.kind==="unknown")throw new ie(Q("discovery_incomplete",C.message));let{message:B,budget:O}=jl(C);throw new ie(Q("binding_budget_exhausted",B,{budget:O}))}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(C){throw await this.removeNeverBoundBinding(d,c,"empty-binding discovery refusal"),C}}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(C){e.warn(`[Bindings] removing never-bound binding after ${R} failed: ${r(C)}`,C)}}async settleFailedCreate(d,c,R=!1){try{if(R){let T=(await this.deps.journal.close(c,"rolled_back")).entry;return this.noteJournal(d,T),T}let C=await this.deps.journal.settleCreation(c,{adopt:!1,deadlineMs:d.request.deadlineMs});return this.noteJournal(d,C.entry),C.entry}catch(C){e.warn(`[Bindings] settling failed creation entry ${c.id} failed; redrive will retry: `+r(C),C)}}async discardUncommitted(d,c,R,{release:C,reason:T}){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 C()}try{await this.cleanupUncommitted(d,c,R)}catch(B){if(B instanceof ze)e.warn(`[Bindings] uncommitted cleanup deferred: ${r(B)}`,B),d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:B.message};else if($a(B)!=="retryable")throw e.warn(`[Bindings] uncommitted cleanup failed: ${r(B)}`,B),B;e.debug(`[Bindings] uncommitted cleanup deferred: ${r(B)}`)}throw new ie(T)}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 C=await this.deps.journal.removalRegistryStage(()=>this.deps.registry.findDeviceHolder(d.request.platform,c.device.stableId),d.request.deadlineMs);if(C){let O=C.kind==="binding"?`binding ${C.assignment.bindingIndex} of scope ${C.assignment.scopeKey}`:"the managed free pool";d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:`kept: held by ${O}`},e.warn(`[Bindings] not discarding '${c.device.stableId}': it is held by ${O}`),this.noteJournal(d,(await this.deps.journal.removalRegistryStage(()=>this.deps.journal.close(R,"rolled_back"),d.request.deadlineMs)).entry);return}let T=await this.deps.journal.settleCreation(R,{adopt:!1,deadlineMs:d.request.deadlineMs});this.noteJournal(d,T.entry);let B=T.kind==="settled";if(d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:B,...T.kind==="blocked"?{message:T.message}:{}},!B)e.warn(`[Bindings] uncommitted device '${c.device.stableId}' was not removed: `+(T.kind==="blocked"?T.message:"unknown"))}async replaceOrphan(d,c,R){let{request:C}=d;await this.assertCreatable(d),this.host.checkBudget(C);let T=await this.reserveReplacement(C,c,R);try{this.host.checkBudget(C);let B={stableDeviceId:ve(R),deviceName:R.name,requestedSpec:C.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ut(d.fingerprint),state:"replacing"},O=await this.deps.registry.openBindingJournal(C.key,{kind:"replace",phase:"deleting",owner:this.deps.journal.owner,target:{...this.journalTarget(d,c,null),oldStableId:B.stableDeviceId,oldName:R.name},assignment:{kind:"commit",expected:Me(c),next:B}});if(O.kind==="journal_open")throw new ie(Q("reconcile_in_progress",`Binding ${C.key.bindingIndex} has unfinished work.`));if(O.kind!=="opened")throw new ie(Fe(O,"reclaim"));return d.evidence.adoptedFrom="orphan",await this.finishReplacement(d,O.entry,R,T)}finally{T?.release()}}async replaceAssigned(d,c,R,C){let{request:T}=d;await this.assertCreatable(d),await this.assertReplaceable(T,c,R,C);let B=await this.reserveReplacement(T,c,R);try{return this.host.checkBudget(T),await this.replaceReserved(d,c,R,B)}finally{B?.release()}}async replaceReserved(d,c,R,C){let{request:T}=d,B=await this.deps.registry.openBindingJournal(T.key,{kind:"replace",phase:"deleting",owner:this.deps.journal.owner,target:this.journalTarget(d,c,null),assignment:{kind:"state",expected:Me(c),state:"replacing"}});if(B.kind==="journal_open")throw new ie(Q("reconcile_in_progress",`Binding ${T.key.bindingIndex} has unfinished work.`));if(B.kind!=="opened")throw new ie(Fe(B,"replace"));return await this.finishReplacement(d,B.entry,R,C)}async finishReplacement(d,c,R,C){let{request:T,evidence:B}=d,O=c.target.oldStableId;this.noteJournal(d,c),this.deps.journal.inFlight.add(c.id);let x,N;try{let H=await this.deps.journal.driveDeletion(c,{device:R,deadlineMs:T.deadlineMs,signal:T.signal});if(this.noteJournal(d,H.entry),H.kind!=="deleted"){if(H.kind==="blocked")throw B.deletion=H.evidence,new ie(Q(H.reason,H.message));throw new ie(Q("concurrent_modification",`Device '${O}' is no longer this binding's device.`))}B.deletion=H.evidence,B.deletedStableId=O,x=H.entry,N=H.assignment,C?.markReplacedDeviceGone()}finally{this.deps.journal.inFlight.delete(c.id)}return await this.createAndCommit(d,N,"replaced",{replacing:x,bootReservation:C})}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:ut(d.fingerprint)}}noteJournal(d,c){d.evidence.journal={entryId:c.id,kind:c.kind,phase:c.phase}}async assertReplaceable(d,c,R,C){let T=c.stableDeviceId;if(!C)throw new ie(Q("discovery_incomplete","Replacement requires complete device discovery."));let B=await this.deps.claims.describe(R);if(B.kind!=="free")throw new ie(Q(B.kind==="held"?"device_busy":"discovery_incomplete",`Device '${T}' cannot be replaced: ${B.reason}`));this.host.checkBudget(d);let O=await this.deps.registry.findDeviceHolder(c.platform,T);if(O?.kind!=="binding"||O.assignment.scopeKey!==d.key.scopeKey||O.assignment.bindingIndex!==d.key.bindingIndex||!gH(O.assignment,Me(c)))throw new ie(Q("concurrent_modification",`Device '${T}' is no longer this binding's device.`))}async reserveReplacement(d,c,R){if(!this.deps.capacity)return;let C=hN(c.platform)===hN(d.platform)&&qS(R);this.host.checkBudget(d);let T=await this.deps.capacity.reserve(d.platform,{replacingDeviceId:C?R.deviceId:void 0,resolveReplacingDeviceId:C&&!R.deviceId?(B)=>this.deps.inventory.runtimeDeviceId?.(R,B)??Promise.resolve(void 0):void 0,timeoutMs:Math.max(1,d.deadlineMs-this.deps.timer.now()),signal:d.signal});if(T.kind==="available")return T.reservation;throw this.assertCapacityCheck(d,T),new ie(Q("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 ie(Q(R.code,R.message));if(R?.kind==="unresolved")throw new ie(Q("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 ie(Q("discovery_incomplete",c.message));if(c.kind==="exhausted"&&c.booted>=c.limit)throw new ie(Q("capacity_exhausted",`${c.booted} ${d.platform} device(s) booted; limit is ${c.limit}.${i6(c)}`,{capacity:{limit:c.limit,booted:c.booted,retryAfterMs:c.retryAfterMs,...Xi(c.externalDevices),...c.heldDevices?.length?{heldDevices:[...c.heldDevices]}:{}}}))}}function Bo(){return{daemonId:`pid-${process.pid}`,pid:process.pid,processGenerationToken:Gm()??null}}function hu(d){return`${d.scopeKey}#${d.bindingIndex}`}class Qi{androidConfigReader;constructor(d){this.androidConfigReader=d}async matches(d,c){switch(d.platform){case"watchos":return ru(d,c);case"android":return await this.matchesAndroid(d,c);case"ios":return US(d,c);case"tvos":case"visionos":return"mismatch"}}async matchesAndroid(d,c){let R;try{R=await this.androidConfigReader.readConfig(d.name)}catch(T){return e.warn(`[Bindings] cannot read AVD config for '${d.name}': ${r(T)}`,T),"unknown"}if(!R)return"unknown";let C={...c,deviceType:c.deviceType??R.deviceName};if(!CH(C,R))return"mismatch";return gu(c.deviceFamily,()=>rf({systemImageTag:R.systemImagePackage?Yr(R.systemImagePackage)?.tag:void 0,profileId:R.deviceName,width:R.screenWidth,height:R.screenHeight,density:R.screenDensity}))}}function US(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 DH(R,d)===void 0?gu(c.deviceFamily,()=>bm(d.deviceType)):"mismatch"}function gu(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 _o{deps;inFlight=new Map;isExecOwnerLive;idGenerator;reservations;creation;journal;constructor(d){this.deps=d;this.isExecOwnerLive=d.isExecOwnerLive??Qa,this.idGenerator=d.idGenerator??L,this.reservations=d.reservations??dN,this.journal=new Ro({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??Bo(),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 Eo({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:XG,releaseSession:(c)=>this.releaseSession(c),readyOrReleaseOnBusy:(c,R)=>this.readyOrReleaseOnBusy(c,R),claimAndReady:(c,R,C,{provisioned:T,reservation:B})=>this.claimAndReady(c,R,C,{provisioned:T,reservation:B})})}async reconcile(d){let c=hu(d.key),R=this.inFlight.get(c),C=!1,T=(R??Promise.resolve()).then(()=>{return},()=>{return}).then(()=>C?void 0:this.reconcileSerialized(d));this.inFlight.set(c,T);try{if(R){let B=await this.waitForQueue(R,d);if(B)return C=!0,{outcome:"failed",failure:B,assignment:await this.failedResultAssignment(d,void 0),evidence:{initial:null,inventoryComplete:null}}}return await T}finally{let B=()=>{if(this.inFlight.get(c)===T)this.inFlight.delete(c)};if(C)T.then(B,B);else B()}}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?Q("cancelled","Binding preparation was cancelled."):Q("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 ze||$a(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 ie||$a(R)==="retryable")return{outcome:"failed",failure:R instanceof ie?R.failure:Q("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 C=await this.deps.resolver.resolve(d.platform,d.requestedSpec,{signal:d.signal});if(C.kind==="unsupported")throw new ie(Q(C.code,C.message));if(C.kind==="unresolved")throw new ie(Q("discovery_incomplete",C.message));let T={request:d,resolvedSpec:C.resolvedSpec,fingerprint:C.fingerprint,evidence:c},B=await R.initBinding(d.key,{role:d.role,platform:d.platform,requestedSpec:d.requestedSpec});if(B.kind==="scope_not_valid")throw new ie(Q("scope_not_valid","Binding scope is not valid."));let O=await this.redriveUnfinished(d,B.assignment,c),x=await this.recoverIfSettled(d,O);if(c.initial={generation:x.generation,stableDeviceId:x.stableDeviceId,state:x.state},this.assertBindingAcceptsWork(d,x),x.platform!==d.platform)return await this.changePlatform(T,x);let N=async()=>{let W=await this.deps.inventory.list(d.platform,{signal:d.signal});return c.inventoryComplete=W.complete,this.checkBudget(d),W},H=x.stableDeviceId===null?await this.withEmptyBindingCleanup(T,x,N):await N();if(x.stableDeviceId===null)return await this.fillEmptyBinding(T,x,H);let q=H.devices.find((W)=>W.platform===d.platform&&ve(W)===x.stableDeviceId);if(!q){if(!H.complete)throw new ie(Q("discovery_incomplete",`Assigned device '${x.stableDeviceId}' was not listed and discovery was incomplete.`));return c.assignedMissing=!0,await this.createAndCommit(T,x,"created")}let G=await this.deps.matcher.matches(q,d.requestedSpec);if(c.assignedMatch=G,G==="unknown")throw new ie(Q("discovery_incomplete",`Configuration of assigned device '${x.stableDeviceId}' could not be read.`));if(G==="match")return await this.reuseAssigned(T,x,q);return await this.replaceAssigned(T,x,q,H.complete)}async redriveUnfinished(d,c,R){let C=await this.journal.redriveBinding(d.key);if(C.redriven.length>0)R.redriven=C.redriven;if(C.kind==="blocked")throw new ie(Q(C.reason,C.message));if(C.redriven.length===0)return c;let T=await this.deps.registry.getAssignment(d.key);if(!T)throw new ie(Q("scope_not_valid","Binding disappeared during redrive."));return T}async recoverIfSettled(d,c){if(c.state!=="settling")return c;let R=(await this.deps.registry.recoverSettledBindings(d.key.scopeKey)).find((C)=>C.bindingIndex===d.key.bindingIndex);if(R)return R;throw new ie(Q("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 ie(Q("binding_in_use",`Binding ${d.key.bindingIndex} is held by live session ${c.execOwner.sessionUuid}.`));if(c.state==="cleanup_pending")throw new ie(Q("cleanup_pending",`Binding ${d.key.bindingIndex} still holds device '${c.stableDeviceId}' pending cleanup.`));if(c.state==="replacing")throw new ie(Q("reconcile_in_progress",`Binding ${d.key.bindingIndex} is mid-replacement of '${c.stableDeviceId}'.`))}async changePlatform(d,c){let{request:R,evidence:C}=d;if(c.stableDeviceId===null){let O=await this.withEmptyBindingCleanup(d,c,async()=>{let x=await this.deps.inventory.list(R.platform,{signal:R.signal});return C.inventoryComplete=x.complete,this.checkBudget(R),x});return await this.fillEmptyBinding(d,c,O)}let T=await this.deps.inventory.list(c.platform,{signal:R.signal});C.inventoryComplete=T.complete,this.checkBudget(R);let B=T.devices.find((O)=>O.platform===c.platform&&ve(O)===c.stableDeviceId);if(!B){if(!T.complete)throw new ie(Q("discovery_incomplete",`Assigned device '${c.stableDeviceId}' was not listed and discovery was incomplete.`));C.assignedMissing=!0,await this.assertCreatable(d);let O=await this.emptyOnRequestedPlatform(d,c);return await this.createAndCommit(d,O,"created")}return C.assignedMatch="mismatch",await this.replaceAssigned(d,c,B,T.complete)}async emptyOnRequestedPlatform(d,c){let{request:R}=d,C=await this.deps.registry.commitBinding(R.key,Me(c),{platform:R.platform,stableDeviceId:null,deviceName:null,requestedSpec:R.requestedSpec,resolvedSpec:null,specFingerprint:null,state:"provisioning"});if(C.kind!=="committed")throw new ie(To(C,"platform change"));return C.assignment}async reuseAssigned(d,c,R){this.assertNoLiveExecutionOn(d,R);let C=await this.reserveExecution(d,c);try{return await this.reuseReserved(d,c,R,C)}catch(T){if(C)await this.releaseReservation(d.request.key,C);throw T}finally{if(C)this.reservations.delete(C)}}async reuseReserved(d,c,R,C){d={...d,resolvedSpec:await this.existingSpec(R)};let T=await this.provisionExisting(d,R);return await this.readyOrReleaseOnBusy(T,async()=>{let B=Me(c),O=ut(d.fingerprint),N=c.state==="ready"&&c.specFingerprint===O&&Cr(c.requestedSpec)===Cr(d.request.requestedSpec)&&this.resolvedIdentityMatches(c.resolvedSpec,d.resolvedSpec)?await this.deps.registry.updateBindingState(d.request.key,B,"ready"):await this.deps.registry.commitBinding(d.request.key,B,{stableDeviceId:c.stableDeviceId,deviceName:T.device.name,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:O,state:"ready"});if(N.kind!=="updated"&&N.kind!=="committed")throw await this.releaseSession(T.sessionUuid),new ie(Fe(N,"reuse"));return await this.claimAndReady(d,"reused",N.assignment,{provisioned:T,reservation:C})})}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:C}=d.request;if(!R||c.state!=="ready")return;let T=`reserve-${this.idGenerator.next()}`;this.reservations.add(T);try{let B=await this.deps.registry.claimExecution(C,Me(c),{...R,sessionUuid:T});if(B.kind!=="claimed")throw new ie(Fe(B,"reservation"))}catch(B){throw this.reservations.delete(T),B}return T}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 C=await this.withEmptyBindingCleanup(d,c,async()=>{if(!R.complete)throw new ie(Q("discovery_incomplete","Device discovery was incomplete for an empty binding."));let B=await this.findAdoptionCandidate(d,R.devices);if(c.platform!==d.request.platform)await this.assertCreatable(d);return B});if(c.platform!==d.request.platform)c=await this.emptyOnRequestedPlatform(d,c);let T=fu(d);if(C)return await this.creation.replaceOrphan(T,c,C);return await this.createAndCommit(T,c,"created")}async findAdoptionCandidate(d,c){let{request:R}=d,C=Co(R.key),T=R.priorDeviceHint?.stableId,B=c.filter((O)=>O.platform===R.platform).map((O)=>({device:O,stableId:ve(O)})).filter((O)=>!!O.stableId).sort((O,x)=>Number(x.stableId===T)-Number(O.stableId===T)||O.stableId.localeCompare(x.stableId));for(let{device:O,stableId:x}of B){if(!Xa(O.name)||!O.name.slice(O.name.indexOf("-")+1).startsWith(C))continue;if(await this.deps.registry.findDeviceHolder(R.platform,x)||this.sessionsOn(O).length>0||(await this.deps.claims.describe(O)).kind!=="free")continue;if(await this.deps.matcher.matches(O,R.requestedSpec)==="match")return O}return}async existingSpec(d){let c=await this.deps.provisioner.readExistingSpec(d);if(!c)throw new ie(Q("discovery_incomplete",`The configuration of device '${d.name}' could not be read.`));return c}async createAndCommit(d,c,R,{replacing:C,...T}={}){return this.creation.createAndCommit(d,c,R,{replacing:C,...T})}async withEmptyBindingCleanup(d,c,R){return this.creation.withEmptyBindingCleanup(d,c,R)}async replaceAssigned(d,c,R,C){return this.creation.replaceAssigned(d,c,R,C)}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((C)=>this.deps.provisioner.releaseSession(C)))}catch(C){throw e.warn(`[Bindings] releasing stale session(s) on '${c.name}' failed: ${r(C)}`,C),new ie(Q("stale_session",`An earlier execution's session on '${c.name}' could not be released: ${r(C)}`))}return d.evidence.releasedStaleSessions=R,new Set(R)}assertNoLiveExecutionOn(d,c,R=this.sessionsOn(c)){let C=R.find((T)=>this.deps.claims.isLiveExecution?.(T));if(C!==void 0)throw new ie(Q("binding_in_use",`Binding ${d.request.key.bindingIndex} is held by live session ${C} on '${c.name}'.`))}async provisionExisting(d,c){let{request:R}=d,C=await this.releaseStaleSessions(d,c),T;try{T=await this.deps.provisioner.provision({platform:R.platform,name:c.name,...R.platform!=="android"&&c.deviceId?{deviceId:c.deviceId}:{},spec:ri(R.requestedSpec),mode:"adopt",deadlineMs:R.deadlineMs,signal:R.signal})}catch(B){throw new ie(Bt(B))}if(C.has(T.sessionUuid))throw await this.releaseSession(T.sessionUuid),new ie(Q("stale_session",`Provisioning '${c.name}' returned earlier session ${T.sessionUuid}.`));if(!XG(R.platform,T))throw await this.releaseSession(T.sessionUuid),new ie(Q("readiness_incomplete",`Device '${c.name}' did not reach ${SH(R.platform)}.`));return T}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 ie(Q("cancelled","Binding preparation was cancelled."));if(this.deps.timer.now()>=d.deadlineMs)throw new ie(Q("timeout","Binding preparation deadline passed."))}async claimAndReady(d,c,R,{provisioned:C,reservation:T}){let{owner:B,key:O}=d.request;if(!B)return this.ready(d,c,R,C);let x=await this.deps.registry.claimExecution(O,Me(R),{...B,sessionUuid:C.sessionUuid},T?{supersedesSessionUuid:T}:{});if(x.kind!=="claimed")throw await this.releaseSession(C.sessionUuid),new ie(Fe(x,"execution claim"));return this.ready(d,c,x.assignment,C)}async readyOrReleaseOnBusy(d,c){let R=!1,C=async()=>{if(!R)R=!0,await this.releaseSession(d.sessionUuid)};try{return await c(C)}catch(T){if($a(T)==="retryable"||T instanceof zr)await C();throw T}}ready(d,c,R,C){return{outcome:"ready",disposition:c,assignment:R,device:C.device,sessionUuid:C.sessionUuid,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:d.fingerprint,readiness:C.readiness,...C.lifecycle!==void 0?{lifecycle:C.lifecycle}:{},evidence:d.evidence}}}var KS={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 Ye(d,c,R){return{code:d,retryable:R,message:c,nextAction:KS[d]??"Retry."}}function GS(d,c){return c!==void 0&&c>0?{createDeadlineMs:d-c}:{}}var WS=5000;class Fo{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 Oe({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},C=(q,G)=>({contractVersion:1,scope:{...R,scopeKey:q,...G?{revived:G}:{}}}),T;try{T=tH(d.idleTimeoutMs)}catch(q){return{...C(null),outcome:"failed",bindings:[],failure:Ye("binding_config_invalid",r(q),!1)}}let B=this.deps.timer.now()+(d.preparationTimeoutMs??Po),O,x;try{O=await this.deps.registry(),x=await this.admitScope(O,R)}catch(q){if(q instanceof zr)return e.warn(`[Bindings] Registry schema unsupported: ${r(q)}`,q),{...C(null),outcome:"failed",bindings:[],failure:Ye(q.code,r(q),q.retryable)};if($a(q)!=="retryable"&&!(q instanceof Jo))throw q;return{...C(Cd(R)),outcome:"failed",bindings:[],failure:Q("discovery_incomplete",r(q))}}if(x.kind==="failed")return{...C(Cd(R)),outcome:"failed",bindings:[],failure:x.failure};let{bindings:N,failure:H}=await this.acquireBindings(O,x.scopeKey,d.requests,{deadlineMs:B,...GS(B,d.createRetryReserveMs),idleTimeoutMs:T,livenessOwnerToken:c.livenessOwnerToken,signal:c.signal});return{...C(x.scopeKey,x.revived),outcome:H?"failed":"ready",idleTimeoutMs:T,bindings:N,...H?{failure:H}:{}}}async acquireBindings(d,c,R,C){let T=[],B=[],O;for(let x of R){let N={scopeKey:c,bindingIndex:x.bindingIndex},H=await this.acquireBinding(d,N,x,C);if(T.push(H),H.failure){O=H.failure;break}B.push({key:N,sessionUuid:H.sessionUuid})}if(!O&&C.signal?.aborted)O=Ye("cancelled","The binding acquisition was cancelled.",!0);if(O){await Promise.all(B.map(({key:x,sessionUuid:N})=>this.backOut(d,x,N)));for(let x of T)if(!x.failure)x.sessionUuid=null}return{bindings:T,failure:O}}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:Ye("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:Ye("scope_transition_pending",`Runner incarnation '${R.current.runnerIncarnation}' is still being retired.`,!0)}}}async acquireBinding(d,c,R,C){let T;try{T=await this.deps.reconcile(d,{key:c,role:R.role,platform:R.platform,requestedSpec:R.requestedSpec,...R.priorDeviceHint?{priorDeviceHint:R.priorDeviceHint}:{},deadlineMs:C.deadlineMs,...C.createDeadlineMs===void 0?{}:{createDeadlineMs:C.createDeadlineMs},signal:C.signal,owner:this.deps.owner()})}catch(x){if(!(x instanceof zr))throw x;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:Ye(x.code,r(x),x.retryable)}}if(T.outcome==="failed")return{bindingIndex:R.bindingIndex,role:R.role,platform:R.platform,assignmentGeneration:T.assignment?.generation??null,device:null,sessionUuid:null,requestedSpec:R.requestedSpec,resolvedSpec:T.assignment?.resolvedSpec??null,specFingerprint:null,disposition:null,readiness:null,lifecycle:{evidence:T.evidence},failure:T.failure};let B={bindingIndex:R.bindingIndex,role:R.role,platform:R.platform,assignmentGeneration:T.assignment.generation,device:T.device,sessionUuid:T.sessionUuid,requestedSpec:T.requestedSpec,resolvedSpec:T.resolvedSpec,specFingerprint:T.specFingerprint,disposition:T.disposition,readiness:T.readiness,lifecycle:{...T.lifecycle!==void 0?{provision:T.lifecycle}:{},evidence:T.evidence}},O=await this.handOff(T.sessionUuid,C);if(O)return await this.backOut(d,c,T.sessionUuid),{...B,sessionUuid:null,failure:O};return B}async handOff(d,c){try{let R=await this.deps.sessions.claimLivenessOwnership(d,c.livenessOwnerToken);if(R!=="claimed")return Ye("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 ${Yn} policy failed: ${r(R)}`,R),Ye("execution_policy_failed",r(R),!0)}}async backOut(d,c,R){let C=this.deps.timer.now(),T={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(B){if(T.owedSinceMs=this.deps.timer.now(),T.ownerClearOwed=!0,T.lastError=r(B),!this.closed)e.info(`[Bindings] Clearing binding ${c.scopeKey}/${c.bindingIndex}'s owner ${R} failed: ${T.lastError}; cleanup continues in the background`,B)}try{await this.deps.sessions.releaseSession(R)}catch(B){if(!T.ownerClearOwed)T.owedSinceMs=this.deps.timer.now();if(T.sessionReleaseOwed=!0,T.lastError=r(B),!this.closed)e.info(`[Bindings] Releasing backed-out session ${R} for binding ${c.scopeKey}/${c.bindingIndex} failed: ${T.lastError}; cleanup continues in the background`,B)}if(T.ownerClearOwed||T.sessionReleaseOwed)this.retainBackOutCleanup(d,T),this.pacing.noteBlocked(C)}retainBackOutCleanup(d,c){let R=JSON.stringify([c.key.scopeKey,c.key.bindingIndex,c.sessionUuid]);if(this.closed)return;let C=this.backOutCleanups.get(R);if(C){C.cleanup.ownerClearOwed||=c.ownerClearOwed,C.cleanup.sessionReleaseOwed||=c.sessionReleaseOwed,C.cleanup.lastError=c.lastError;return}this.backOutCleanups.set(R,{registry:d,cleanup:c}),this.startBackOutRetry(R,d,c)}startBackOutRetry(d,c,R){let C=this.retryBackOutCleanup(d,c,R).catch((T)=>{if(!this.closed)R.lastError=r(T),e.warn(`${this.backOutCleanupLabel(R)} retry stopped; no task remains: ${R.lastError}`,T)}).finally(()=>this.background.delete(C));this.background.add(C)}async retryBackOutCleanup(d,c,R){for(let C=1;!this.closed;C++){if(await this.pacing.wait(this.pacing.delay(C)),this.closed)return;if(await this.pacing.run(()=>(R.attempts=C,this.retryBackOutOnce(c,R)),(B)=>B)){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()+xe;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(C){if(!this.closed)c.lastError=r(C),this.logBackOutRetryFailure(c,C);return!1}}async retryBackOutStep(d,c,R,{step:C,deadlineMs:T}){let B=T-this.deps.timer.now();if(B<=0)throw Error(`${this.backOutCleanupLabel(d)} ${C} attempt deadline reached`);let O=await l(()=>{let x=c.get(d);if(!x)x=R().then(void 0,(N)=>{throw c.delete(d),N}),c.set(d,x);return x},{timer:this.deps.timer,timeoutMs:B,signal:this.closeController.signal,label:`${this.backOutCleanupLabel(d)} ${C}`});return c.delete(d),O}async retryBackOutOwnerClear(d,c,R){let C=()=>this.retryBackOutStep(c,this.backOutOwnerClears,()=>d.releaseExecution(c.key,c.sessionUuid),{step:"owner clear",deadlineMs:R});if(this.backOutOwnerClears.has(c)){await C();return}let T=()=>this.retryBackOutStep(c,this.backOutOwnerReads,()=>d.getAssignment(c.key),{step:"ownership read",deadlineMs:R});if(this.backOutOwnerReads.has(c))await T();let B=(await T())?.execOwner;if(!this.closed&&B&&this.isBackedOutOwner(B,c.sessionUuid))await C()}logBackOutRetryFailure(d,c){let R=`${this.backOutCleanupLabel(d)} retry failed: ${d.lastError}`;e.debug(R,c);let C=this.deps.timer.now()-d.owedSinceMs;if(C>WS&&!this.warnedBackOutCleanups.has(d))this.warnedBackOutCleanups.add(d),e.warn(`${this.backOutCleanupLabel(d)} owed for ${C} ms (${d.attempts} retries): ${d.lastError}; retries continue with waits capped at 5 s`,c)}isBackedOutOwner(d,c){let R=this.deps.owner(),C=d.processGenerationToken??void 0,T=R.processGenerationToken??void 0;return d.sessionUuid===c&&d.pid===R.pid&&(C===void 0||T===void 0||C===T)}backOutCleanupLabel(d){return`[Bindings] Back-out cleanup for binding ${d.key.scopeKey}/${d.key.bindingIndex} session ${d.sessionUuid}`}}class Lo{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 Yu("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 C=await this.deviceManager.getBootedDevicesDetailed?.(d.platform,{signal:c.signal,bypassAndroidDeviceListCache:!0,skipForeignEnrichment:!0});if(c.signal?.throwIfAborted(),!C?.succeededPlatforms.has(d.platform))return;return C.devices.find((T)=>!T.foreignOwned&&T.platform===d.platform&&T.name===d.name&&le(T.deviceId))?.deviceId}catch(C){c.signal?.throwIfAborted(),e.warn(`[Bindings] cannot resolve ${R}: ${r(C)}`,C);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 nk||d!=="android"&&R instanceof Yu)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 si extends Error{}var VS=2000,Uo=ec+VS;class Ko{timer;assertAvailable;reserveCapacity;constructor(d,c=(C,T)=>tS(C,{signal:T}),R=xH){this.timer=d;this.assertAvailable=c;this.reserveCapacity=R}async reserve(d,c){let R=new AbortController,C=c.signal?AbortSignal.any([c.signal,R.signal]):R.signal,T=this.timer.now()+c.timeoutMs,B=()=>Math.max(0,T-this.timer.now()),O=(H)=>l(H,{timer:this.timer,timeoutMs:Math.min(B(),Uo),signal:c.signal,label:`Reserving ${d} boot capacity`,onTimeout:()=>R.abort(),timeoutError:()=>new si(`Timed out reserving ${d} boot capacity.`)}),x=!1,N;try{let H=c.resolveReplacingDeviceId,q=H?await O(()=>H({signal:C})):c.replacingDeviceId;C.throwIfAborted();let G=await O(async()=>{if(N=await this.reserveCapacity(d,{...c,replacingDeviceId:q,timeoutMs:Math.max(1,B()),signal:C}),C.aborted)N.release(),C.throwIfAborted();return N});return x=!0,{kind:"available",reservation:G}}catch(H){return this.refusal(d,H)}finally{if(!x)R.abort(),N?.release()}}async check(d,c){let R=Math.min(c.timeoutMs??Uo,Uo),C=new AbortController,T=c.signal?AbortSignal.any([c.signal,C.signal]):C.signal;try{return await l(()=>this.assertAvailable(d,T),{timer:this.timer,timeoutMs:R,signal:c.signal,label:`Checking ${d} boot capacity`,onTimeout:()=>C.abort(),timeoutError:()=>new si(`Timed out after ${R}ms checking ${d} boot capacity.`)}),{kind:"available"}}catch(B){return this.refusal(d,B)}finally{C.abort()}}refusal(d,c){if(c instanceof Nn){let{externalDevices:R,heldDevices:C,ownershipUnknown:T}=c.details;return{kind:"exhausted",limit:c.limit,booted:c.booted,retryAfterMs:c.retryAfterMs,...R&&R.length>0?{externalDevices:R}:{},...C&&C.length>0?{heldDevices:C}:{},...T?{ownershipUnknown:!0}:{}}}if(c instanceof Ve||c instanceof Jo||c instanceof si)return e.warn(`[Bindings] ${d} boot capacity is unknown: ${r(c)}`,c),{kind:"unknown",message:r(c)};throw c}}class Go{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((C)=>D(C)!==null);if(R)return{kind:"held",reason:`session ${D(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 C of c)try{await this.pool.assertNotClaimedByForeignDaemon(C.id,d.platform)}catch(T){return{kind:"held",reason:r(T)}}return{kind:"free"}}sessionsOn(d){return this.runtimesOf(d).flatMap((c)=>D(c)?[D(c)]:[])}hasUnresolvedSessionRuntime(){return this.pool.getAllDevices().some((d)=>d.platform==="android"&&D(d)!==null&&!d.avdName&&d.name.startsWith("Unknown ("))}runtimesOf(d){let c=ve(d);return this.pool.getAllDevices().filter((R)=>R.platform===d.platform&&(d.platform==="android"?(R.avdName??R.name)===c:R.id===c))}}function vu(d,c){let{runtime:R,deviceType:C}=d.spec;if(C===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:C}},boot:!0,readiness:"none",timeoutMs:c}}function yu(d){if(d.isAvailable===!1||!d.runtime||!d.deviceType)return null;return{runtime:d.runtime,deviceType:d.deviceType,displayCutout:"unknown"}}function ai(d){let c=d??{};if(c.structuredContent&&typeof c.structuredContent==="object")return{isError:c.isError===!0,payload:c.structuredContent};let R=c.content?.find((T)=>typeof T.text==="string")?.text,C={};if(R!==void 0)try{let T=JSON.parse(R);C=T&&typeof T==="object"?T:{}}catch(T){e.debug(`[Bindings] tool response text is not JSON: ${r(T)}`),C={message:R}}return{isError:c.isError===!0,payload:C}}function we(d){return typeof d==="string"&&d.length>0?d:void 0}function Wo(d){return typeof d==="number"&&Number.isFinite(d)?d:void 0}function bu(d){return Array.isArray(d)?d.filter((c)=>typeof c==="string"):[]}function Ru(d){return d!==null&&typeof d==="object"&&!Array.isArray(d)}function JS(d){let c=d.lifecycle;if(!Ru(c)||!Ru(c.device))return{};let R=c.device,C=we(R.name),T=[we(R.stableId),we(R.runtimeDeviceId)].find((O)=>O!==void 0&&O!==C),B=c.state==="created_not_ready"&&c.phase==="readiness"&&R.platform==="ios"&&T&&C?{platform:"ios",stableId:T,name:C}:void 0;return B?{retainedDevice:B}:{}}function jS(d,c){let R=d.error??{},C=we(R.code)??"platform_command_failed",T=we(R.message)??we(d.message)??c,B=typeof R.retryable==="boolean"?R.retryable:void 0,O=Wo(R.limit),x=Wo(R.booted),N=Wo(R.retryAfterMs),H=bu(R.externalDevices),q=bu(R.heldDevices);return new Ue(C,T,B,{...JS(d),...N!==void 0?{retryAfterMs:N}:{},...O!==void 0&&x!==void 0?{capacity:{limit:O,booted:x,...H.length>0?{externalDevices:H}:{},...q.length>0?{heldDevices:q}:{}}}:{}})}function YS(d,c){let R=d.device??{},C=d.readiness??{},T=we(R.identity?.stableId);if(!T)throw new Ue("platform_command_failed",`provisionDevice '${c}' returned no stable device identity.`);return{device:{stableId:T,transportId:we(R.runtime?.deviceId)??null,name:we(R.name)??c},created:d.created===!0,sessionUuid:we(d.sessionId)??"",readiness:{mode:we(C.mode)??"none",status:we(C.status)??"unknown"},lifecycle:XS(d)}}function XS(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 eb(d,c){return Math.max(1,Math.min(c,Math.floor(d)))}class jo{deps;constructor(d){this.deps=d}async readExistingSpec(d){if(d.platform==="watchos")return yu(d);if(d.platform==="ios"){if(d.isAvailable===!1||!d.runtime||!d.deviceType)return null;return{runtime:d.runtime,deviceType:d.deviceType,displayCutout:Yb("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:Yb("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=eb(d.deadlineMs-this.deps.timer.now(),ww),R=d.platform,C=R==="watchos"?vu(d,c):{...await this.exactProvisionArgs({...d,platform:R},c)},T=await this.deps.invokeTool("provisionDevice",C,d.signal),{isError:B,payload:O}=ai(T);if(B)throw jS(O,`provisionDevice '${d.name}' failed`);return YS(O,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((C)=>d.deviceId?C.deviceId===d.deviceId:C.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 tb=100,ib=5000;class zo{journal;timer;intervalMs;stopped=!1;running;stopping;controller=new AbortController;cancelWait;constructor(d,c,R=ib){this.journal=d;this.timer=c;this.intervalMs=R}start(){if(!this.stopped)this.running??=this.loop()}stop(d=tb){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 nb={listInstalledPackages:async(d)=>(await uu(void 0,void 0,d)).map((c)=>c.packageName)},ob={listProfileIds:async(d)=>(await nR(void 0,d)).map((c)=>c.id)};function sb(d={},c){let R=process.platform==="darwin"?new oa(new F(null)):void 0;return{deviceManager:d.deviceManager??(c?new oi().withForeignAndroidSerialSource(c):new oi),androidConfigReader:d.androidConfigReader??new Kr,androidImageCatalog:d.androidImageCatalog??nb,androidProfileCatalog:d.androidProfileCatalog??ob,iosRuntimeCatalog:d.iosRuntimeCatalog??(process.platform==="darwin"?new F(null):void 0),watchInventory:d.watchInventory??R,watchCatalog:d.watchCatalog??R,checkBootCapacity:d.checkBootCapacity,reserveBootCapacity:d.reserveBootCapacity}}var di=async(d,c,R)=>await wf().callInternal(d,c,{signal:R});function ku(d){let c=(x)=>Kl(d.pool,x),R=d.invokeTool??di,C=new WeakMap,T=new WeakMap,B=(x)=>{let N=C.get(x);if(!N){let H=sb(d.tooling,d.pool.foreignSerials?{foreignSerials:(J,X)=>d.pool.foreignSerials(J,X)}:void 0),{deviceManager:q,androidConfigReader:G}=H,W=new Lo(q,H.watchInventory),V=new Go(d.pool,d.executions),Y=d.resourceBudgetPolicy?new ao({registry:async()=>x,policy:d.resourceBudgetPolicy,inventory:W,timer:d.timer}):void 0;N=new _o({registry:x,inventory:W,...Y?{resourceBudget:Y}:{},isBusy:c,matcher:new Qi(G),resolver:new Yi(H.iosRuntimeCatalog,{androidImageCatalog:H.androidImageCatalog,androidProfileCatalog:H.androidProfileCatalog,watchCatalog:H.watchCatalog}),provisioner:d.tooling?.provisioner??new jo({invokeTool:R,deviceManager:q,androidConfigReader:G,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:TH(Qa,d.executions)}:{},capacity:new Ko(d.timer,H.checkBootCapacity,H.reserveBootCapacity),timer:d.timer,journal:{owner:d.journal.owner,inFlight:d.journal.inFlight}}),C.set(x,N)}return N};return{acquisition:new Fo({registry:d.registry,reconcile:(x,N)=>lN(N.key,()=>B(x).reconcile(N)),sessions:d.sessions,owner:d.owner,timer:d.timer}),startJournalRedrive:(x)=>{let N=T.get(x);if(!N)N=new zo(B(x).journal,d.timer),T.set(x,N),N.start();return N},journalFor:(x)=>B(x).journal}}var Xo="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",Au="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 Qo{dependencies;constructor(d){this.dependencies=d}async resetWithTiming(d,c,R,C={}){ab(d,c);let T=this.dependencies.policy;switch(T.mode){case"erase":return this.erase(d,c,R,{...C,mode:"erase"});case"keep-booted":if(T.fallback==="destroy")return e.info(`[SessionBroker] watch ${d.deviceId} keep-booted release destroys: ${Xo}`),{outcome:"pending",mode:"keep-booted",phases:{},fallbackReason:Xo};return this.erase(d,c,R,{...C,mode:"keep-booted",fallbackReason:Xo});case"minimal":return e.info(`[SessionBroker] watch ${d.deviceId} minimal release destroys: ${Au}`),{outcome:"pending",mode:"minimal",phases:{},fallbackReason:Au}}}async erase(d,c,R,{signal:C,runResetBoot:T,mode:B,fallbackReason:O}){let x={},N=async()=>{C?.throwIfAborted(),await R(),C?.throwIfAborted()};try{await N();let H=()=>this.reservedEraseAndBoot(d,c,N,{phases:x,signal:C});await(T?T(H):H()),await N()}catch(H){throw new wi(r(H),{outcome:"pending",mode:B,phases:x,fallbackReason:r(H)},{cause:H})}return B==="erase"?{outcome:"clean",mode:B,phases:x}:{outcome:"fallback:erase",mode:B,phases:x,...O?{fallbackReason:O}:{}}}async reservedEraseAndBoot(d,c,R,C){let T=await this.dependencies.reserveBoot?.({replacingDeviceId:d.deviceId,timeoutMs:qe,reason:"reset",signal:C.signal}),B=()=>this.eraseAndBoot(d,c,R,C);try{await(T?T.run(B):B())}finally{T?.release()}}async eraseAndBoot(d,c,R,{phases:C,signal:T}){if((await this.expectedWatch(d,c,T,"start watch reset")).isRunning)await R(),await this.measure(C,"stop",()=>this.dependencies.stopDevice(d));let O=await this.expectedWatch(d,c,T,"erase watch");if(O.state!=="Shutdown")throw new t(`Cannot erase Apple Watch simulator '${d.deviceId}': it is ${O.state}, not Shutdown`);if(await R(),await this.measure(C,"erase",()=>this.dependencies.simctl.eraseSimulator(d.deviceId)),await R(),await this.measure(C,"boot",()=>this.dependencies.lifecycle.boot(O,{timeoutMs:qe,signal:T})),!(await this.expectedWatch(d,c,T,"confirm erased watch")).isRunning)throw new t(`Apple Watch simulator '${d.deviceId}' did not report Booted after its erase`)}async expectedWatch(d,c,R,C){let T=await this.dependencies.lifecycle.findWatch({deviceId:d.deviceId},R);if(T.runtimeId!==c.runtime||T.deviceType!==c.deviceType)throw new t(`Cannot ${C}: Apple Watch simulator '${d.deviceId}' is ${T.deviceType??"an unknown device type"} on ${T.runtimeId??"an unknown runtime"}, not ${c.deviceType} on ${c.runtime}`);return T}async measure(d,c,R){let C=this.dependencies.timer.now();try{return await R()}finally{d[c]=this.dependencies.timer.now()-C}}}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 db(d){let c=iN(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 cb(d,c=qo){let R=c.iosBootInstrumentation();return R.reserveBoot?R.reserveBoot(d):Promise.resolve({run:(C)=>C(),markReplacedDeviceGone:()=>{},release:()=>{}})}function Iu(d,c){let R=db(d);if(!R)return;let C=new F(null),T=new Qo({policy:R,timer:c,simctl:C,lifecycle:new iR(C,new oa(C),{run:(B,O)=>qo.iosBootInstrumentation().run(B,O)}),reserveBoot:cb,stopDevice:async(B)=>{let O=ai(await di("killDevice",{device:B},void 0));if(O.isError||O.payload.success===!1)throw new t("Provider watch shutdown did not confirm a clean teardown")}});return(B,O,x,N)=>T.resetWithTiming(B,O,x,N)}function Xe(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 Zi(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:Xe({platform:"ios",scopeKey:c.scopeKey,allocationIndex:c.allocationIndex,stableDeviceId:R})}:{sessionUuid:d.sessionUuid,deviceId:d.transportId??R,incarnation:Xe({platform:"android",resourceId:c.resourceId,stableDeviceId:R,bootId:d.bootId??null})}}class es{journal;scope;constructor(d,c){this.journal=d;Ll(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:_n("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((C)=>JSON.stringify([C.kind,C.key])));return d.filter((C)=>!R.has(JSON.stringify([C.kind,C.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((C)=>C.kind===d&&C.key===c)?.value??{state:"absent"}}}var Pu=Wr(()=>f({name:y(),durationMs:A().finite().nonnegative(),children:Tu.optional()})),Tu=Wr(()=>Ne([z(Pu),kt(y(),Pu)])),ub=f({provision:f({timing:Tu.nullable().optional()})});function Mu(d){let c=ub.safeParse(d);if(!c.success||!c.data.provision.timing)return;let R={},C=(T)=>{for(let B of Object.values(T)){if(B.name==="provisionExactDevice")R.createMs=B.durationMs;if(B.name==="bootDevice")R.bootMs=B.durationMs;if(B.name==="ensureCtrlProxy iOS"||B.name==="ensureAccessibilityService")R.automationReadyMs=B.durationMs;if(B.children)C(B.children)}};return C(c.data.provision.timing),R}class ts{dependencies;managesResetBootSlots=!0;androidDevices=new Map;scope;scopeKey;isExecOwnerLive;constructor(d){this.dependencies=d;this.scope={...d.scope},this.scopeKey=Cd(this.scope),this.isExecOwnerLive=d.isExecOwnerLive??Qa}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=In(d),C=this.requestedDevice(R),T=this.dependencies.timer??i,B=T.now()+(c.preparationTimeoutMs??Po),O=(W,V=0)=>{let Y=this.bindingConfig(d,C,{...c,preparationTimeoutMs:Math.max(1,W)});return this.dependencies.brokerDeviceAcquisition.acquire(V>0?{...Y,createRetryReserveMs:V}:Y,{livenessOwnerToken:c.livenessOwnerToken,...c.signal?{signal:c.signal}:{}})},x=B-T.now(),N=R.platform==="ios"?Math.min(x/3,Ia):0,H=await O(x,N);if(this.canRetryReadiness(H,d,R)&&!this.preparationStopped(B,c.signal)){if(await this.waitForRetry(Math.min(B-T.now(),25),c.signal),!this.preparationStopped(B,c.signal))H=await O(B-T.now())}let q=await this.readySessionId(H,d,R);await this.captureBaselinesHoldingLease(d,H,R,{sessionId:q,signal:c.signal,deadlineMs:B,deviceProfileOptions:c});let G=H.bindings.find((W)=>W.bindingIndex===d.allocationIndex);return{sessionId:q,profile:await DX(R,G,this.dependencies.androidConfigReader),timing:Mu(G?.lifecycle)}}async applyDeviceProfile(d,c,R,C){let T=C.deviceProfile;if(!T)return;let B=this.androidDevices.get(d.resourceId)?.device??pb(c),x=await(this.dependencies.manufacturerProfileApplier??U$).apply(B,T,R,C.signal);if(x.status==="route_to_real_device")throw new t(x.message);e.info(`[SessionBroker] ${x.message}`)}async captureBaselinesHoldingLease(d,c,R,C){let{sessionId:T}=C,B=this.dependencies.leaseKeepalive?.hold({taskId:d.requestId,ownerKey:"session-broker",sessionUuid:T});try{if(await this.captureAndroidBaseline(d,c,R,C),R.platform==="ios"&&this.dependencies.captureIosBaseline)await this.capturePoolEntryBaseline(d,T,C);await this.applyDeviceProfile(d,c,T,C.deviceProfileOptions)}finally{B?.()}}async captureAndroidBaseline(d,c,R,C){let{sessionId:T}=C,B=this.dependencies.resetBaseline?.android;if(R.platform!=="android"||!B||!B.canCapture)return;this.androidDevices.delete(d.resourceId);try{let O=c.bindings[0],x=O?.device;if(!x?.transportId||typeof O?.assignmentGeneration!=="number")throw new t("Android reset baseline requires the acquired emulator serial");let N={platform:"android",name:x.name,deviceId:x.transportId};this.androidDevices.set(d.resourceId,{device:N,generation:O.assignmentGeneration,stableDeviceId:x.stableId});let H=await lN(this.key(d),()=>B.capture(d.resourceId,N,R,{sessionId:T,fresh:O.disposition==="created"||O.disposition==="replaced",signal:C.signal,timeoutMs:Math.max(0,C.deadlineMs-(this.dependencies.timer??i).now()),timer:this.dependencies.timer??i,stableDeviceId:x.stableId,assertOwned:async()=>{C.signal?.throwIfAborted();let q=await this.dependencies.registry.getAssignment(this.key(d));if(!q||!Dd(q,{generation:O.assignmentGeneration,stableDeviceId:x.stableId})||q.state!=="ready"||q.deviceName!==N.name||q.execOwner?.sessionUuid!==T||q.settler!==null||await this.hasOpenJournal(this.key(d)))throw new t("Android baseline capture lost exclusive binding ownership")}}));if(H)this.bindSessionMutationRecorder(O,d,R,H.bootId)}catch(O){await this.handleAndroidBaselineCaptureFailure(d.resourceId,B,C,O)}}async handleAndroidBaselineCaptureFailure(d,c,R,C){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(C)}`,C)}async capturePoolEntryBaseline(d,c,R){let C=this.dependencies.timer??i,T=new AbortController,B=Ge(T.signal,R.signal)??T.signal,O;try{if(B.throwIfAborted(),this.preparationStopped(R.deadlineMs,B))throw new t("iOS reset baseline capture exceeded preparation deadline");let x=this.key(d),N=await this.dependencies.registry.getAssignment(x);if(!N?.stableDeviceId||N.execOwner?.sessionUuid!==c)throw new t("iOS baseline capture requires the acquired execution binding");let H=async()=>{if(B.throwIfAborted(),this.preparationStopped(R.deadlineMs,B))throw new t("iOS reset baseline capture exceeded preparation deadline");let q=await this.dependencies.registry.getAssignment(x);if(!q||!Dd(q,N)||q.state!=="ready"||q.execOwner?.sessionUuid!==c||q.settler!==null||await this.hasOpenJournal(x))throw new t("iOS baseline capture lost execution binding ownership")};O=H,await l(()=>this.dependencies.captureIosBaseline({scope:{...this.mutationScope(d,N),sessionUuid:c},assertOwned:H,signal:B}),{timer:C,signal:B,timeoutMs:Math.max(0,R.deadlineMs-C.now()),label:"iOS pool-entry baseline capture",timeoutError:()=>new DOMException("iOS reset baseline capture exceeded preparation deadline","TimeoutError"),onTimeout:()=>T.abort(new DOMException("iOS baseline preparation deadline","TimeoutError"))}),await H()}catch(x){if(e.warn(`Skipping iOS pool-entry baseline; release erases if app baseline is unavailable: ${r(x)}`,x),R.signal?.throwIfAborted(),this.preparationStopped(R.deadlineMs,R.signal))throw u(x,"iOS reset baseline capture exceeded preparation deadline");if(!O)throw u(x,"Cannot capture iOS pool-entry baseline after ownership loss");await O()}}preparationStopped(d,c){return c?.aborted===!0||(this.dependencies.timer??i).now()>=d}canRetryReadiness(d,c,R){let C=d.bindings.find((O)=>O.bindingIndex===c.allocationIndex);if(!C?.failure)return!1;let T=C.failure,B=T.code==="readiness_incomplete"||T.code==="timeout"||T.code==="provision_failed"&&T.provision?.code==="timeout";return[R.platform==="ios",d.outcome==="failed",d.scope.scopeKey===this.scopeKey,d.bindings.length===1,C.sessionUuid===null,T.retryable,T.retainedDevice?.platform==="ios",B].every(Boolean)}async waitForRetry(d,c){let R=this.dependencies.timer??i,C;try{await l(()=>new Promise((T)=>{C=R.setTimeout(T,d)}),{timer:R,signal:c,label:"Managed device readiness retry"})}catch(T){throw new ha({code:c?.aborted?"cancelled":"session_preparation_failed",retryable:c?.aborted===!0,message:c?.aborted?"The binding acquisition was cancelled.":r(T)})}finally{if(C!==void 0)R.clearTimeout(C)}}async readySessionId(d,c,R){let C=d.bindings.find((H)=>H.bindingIndex===c.allocationIndex);if([d.outcome==="ready",d.scope.scopeKey===this.scopeKey,d.bindings.length===1].every(Boolean)&&this.isReadyBinding(C,R))return this.bindSessionMutationRecorder(C,c,R),C.sessionUuid;let B=C===void 0?null:C.sessionUuid;if(typeof B==="string"&&B.length>0)await this.dependencies.brokerExecutionRelease.releaseExecution(B);let{code:O,retryable:x,message:N}=d.failure??C?.failure??{code:"session_preparation_failed",retryable:!1,message:"Managed device preparation did not return an automation-ready session"};throw new ha({code:O,retryable:x,message:N})}bindSessionMutationRecorder(d,c,R,C=null){if(!this.dependencies.bindMutationRecorder||R.platform==="watchos")return;try{this.dependencies.bindMutationRecorder(Zi({platform:R.platform,sessionUuid:d.sessionUuid,resource:c,stableDeviceId:d.device.stableId,transportId:d.device.transportId,assignmentGeneration:d.assignmentGeneration,bootId:C}))}catch(T){e.warn("Failed to bind broker device mutation recorder; acquiring without recording",T)}}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"?mI:{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 C=In(d),T=this.dependencies.resetBaseline?.ios,B=this.dependencies.resetBaseline?.android,O=this.dependencies.resetBaseline?.watch,x=this.dependencies.isCurrentReset;if(!x||!this.hasReset(C.platform))return"pending";let N=this.key(d),H=await this.dependencies.registry.getAssignment(N);if(!H?.stableDeviceId||!H.deviceName)throw new t("Reset requires a current bound native device");let q=H.deviceName,G={generation:H.generation,stableDeviceId:H.stableDeviceId},W=async()=>{if(c?.throwIfAborted(),!await x(d))throw new t("Clean reset no longer owns its durable resource revision");let Y=await this.dependencies.registry.getAssignment(N);if(!(Y&&Dd(Y,G)&&Y.state==="ready"&&Y.execOwner===null&&Y.settler===null&&Y.deviceName===q&&this.belongsToResource(Y,C,this.requestedSpec(C)))||await this.hasOpenJournal(N))throw new t("Clean reset lost exclusive native binding ownership")};await W();let V=await lN(N,async()=>{if(C.platform==="watchos"&&O)return O({platform:"watchos",deviceId:G.stableDeviceId,name:q},C,W,{signal:c,runResetBoot:R});if(C.platform==="ios"&&T)return T({platform:"ios",deviceId:G.stableDeviceId,name:q},C,W,{signal:c,context:{resource:d,scope:this.mutationScope(d,H),runResetBoot:R}});if(!B||C.platform!=="android")throw new t("Android reset dispatch requires an Android reset implementation and profile");if(!B.canCapture)throw new t("Android reset is destruction-only: no androidResetMode reset strategy is configured");let Y=this.androidResetTarget(d,H,q);return B.reset(d.resourceId,Y,C,{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 C=this.androidDevices.get(d.resourceId);if(!C)throw new t("Android reset baseline was not captured at acquisition");let T=[];if(!this.sameReleasedBinding(c,C))T.push("generation");if(C.stableDeviceId!==c.stableDeviceId)T.push("stableDeviceId");if(C.device.name!==R)T.push("deviceName");if(c.stableDeviceId!==R)T.push("avdName");if(T.length>0)throw e.warn(`Android reset acquired transport identity mismatch: ${T.join(", ")}`,{resourceId:d.resourceId,fields:T,acquired:{generation:C.generation,stableDeviceId:C.stableDeviceId,deviceName:C.device.name},expected:{generation:c.generation,stableDeviceId:c.stableDeviceId,deviceName:R}}),new t(`Android reset lacks its original acquired transport identity (mismatched: ${T.join(", ")})`);return C.device}mutationScope(d,c){if(!c.stableDeviceId)throw new t("iOS mutation scope requires an exact bound device");return{deviceId:c.stableDeviceId,incarnation:Xe({platform:"ios",scopeKey:d.scopeKey,allocationIndex:d.allocationIndex,stableDeviceId:c.stableDeviceId})}}async destroy(d,c){c?.throwIfAborted(),this.assertResource(d,"destroying");let R=In(d);if(R.platform==="android")await this.dependencies.resetBaseline?.android?.forget(d.resourceId),this.androidDevices.delete(d.resourceId);let C=this.requestedSpec(R),T=this.key(d);if(await this.redriveOpenJournal(T,c)==="pending")return"pending";c?.throwIfAborted();let B=await this.destroyableAssignment(T,R,C);if(typeof B==="string")return B;c?.throwIfAborted();let O=await this.drainAssignment(T,B,R,C);return c?.throwIfAborted(),typeof O==="string"?O:this.deleteAssignment(T,O,c)}async destroyableAssignment(d,c,R){let C=await this.dependencies.registry.getAssignment(d);if(!C||C.stableDeviceId===null)return this.confirmNoBinding(d);return this.belongsToResource(C,c,R)?C:"pending"}async drainAssignment(d,c,R,C){if(!c.execOwner)return c;if(!Ec(c.execOwner,this.dependencies.bindingJournal.owner))return this.isExecOwnerLive(c.execOwner)?"pending":c;if(!(await this.release(c.execOwner.sessionUuid)).settled)return"pending";let B=await this.dependencies.registry.getAssignment(d);if(!B)return this.confirmNoBinding(d);return[this.sameReleasedBinding(B,c),B.state==="ready",B.settler===null,B.execOwner===null,this.belongsToResource(B,R,C)].every(Boolean)?B:"pending"}sameReleasedBinding(d,c){return Dd(d,c)||Dd(d,{...c,generation:c.generation+1})}async deleteAssignment(d,c,R){if(c.stableDeviceId===null)return this.confirmNoBinding(d);let C=c.stableDeviceId;R?.throwIfAborted();let T=await this.dependencies.registry.openBindingJournal(d,{kind:"replace",phase:"deleting",owner:this.dependencies.bindingJournal.owner,target:{oldStableId:C,oldName:c.deviceName,newName:null,newStableId:null,requestedSpec:c.requestedSpec,resolvedSpec:c.resolvedSpec,specFingerprint:c.specFingerprint},assignment:{kind:"state",expected:{generation:c.generation,stableDeviceId:C},state:"replacing"}});if(T.kind!=="opened"&&T.kind!=="journal_open")return"pending";R?.throwIfAborted();let B=await this.dependencies.bindingJournal.redriveBinding(d,{signal:R});if(R?.throwIfAborted(),B.kind==="blocked"||await this.hasOpenJournal(d))return"pending";let O=await this.dependencies.registry.getAssignment(d);return!O||O.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:_f,...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=Yr(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!==_f||d.platform!==c.platform)return!1;let C=d.requestedSpec;if(!C||typeof C!=="object")return!1;let T=C;return T.runtime===R.runtime&&T.deviceType===R.deviceType&&T.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 pb(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 Ot(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 ci(d,c,R,{state:C,action:T,timeoutMs:B,signal:O}){let x;try{x=B!==void 0?await d.readSimulatorTarget(c,B,O):await d.readSimulatorTarget(c)}catch(H){throw u(H,`Cannot ${T}: fresh iOS simulator inventory failed`)}if(!x||x.udid!==c)throw new t(`Cannot ${T}: fresh iOS simulator inventory did not prove one exact target '${c}'`);let N=PC(x.runtime,x.os_version);if(![x.isAvailable===!0,x.deviceTypeIdentifier===R.simulatorDeviceTypeIdentifier,x.runtime===R.runtimeId,GF(N,R.osVersion)===0,x.state===C].every(Boolean))throw new t(`Cannot ${T}: simulator '${c}' lacks authoritative ${C} identity, runtime, type, OS, or availability evidence`)}var mb=60000;class ns{dependencies;timer;deferredBoots=new Set;constructor(d,c=i){this.dependencies=d;this.timer=c}async reset(d,c,R,C){return await this.runReset(d,c,R,{phases:{},signal:C}),"clean"}async resetWithTiming(d,c,R,C){let T={};try{return await this.runReset(d,c,R,{phases:T,signal:C})}catch(B){throw new wi(r(B),{outcome:"pending",mode:"erase",phases:T,fallbackReason:r(B)},{cause:B})}}async runReset(d,c,R,{phases:C,signal:T}){let B=async()=>{T?.throwIfAborted(),await R(),T?.throwIfAborted()};Ot(d,c);let O=this.deferredBoots.delete(d.deviceId);await this.readExpectedTarget(d.deviceId,c,O?"Shutdown":"Booted","start reset"),await B();let x;try{x=await this.reserveResetBoot(d.deviceId,B,T)}catch(H){if(O)this.deferredBoots.add(d.deviceId);throw u(H,"Cannot reserve iOS reset boot slot")}let N=()=>this.eraseAndBoot(d,c,B,{phases:C,deferredBoot:O,signal:T});try{return await(x?x.run(N):N())}finally{x?.release()}}async reserveResetBoot(d,c,R){let C=this.timer.now(),T=C+qe,B=te({initialDelayMs:1000,maxDelayMs:8000}),O=0,x=0;for(;;){R?.throwIfAborted();let N=this.timer.now();try{return await this.dependencies.iosBootInstrumentation.reserveBoot?.({replacingDeviceId:d,timeoutMs:T-this.timer.now(),reason:"reset",signal:R})}catch(H){if(H instanceof Nn){await this.waitResetCapacity({error:H,deviceId:d,startedAt:C,owned:c,delayMs:B.delayForAttempt(++x)}),T+=this.timer.now()-N;continue}let q=B.delayForAttempt(++O);if(!(H instanceof Ve)||T-this.timer.now()<=q)throw u(H,"Cannot reserve iOS reset boot slot");if(await this.timer.sleep(q),await c(),this.timer.now()>=T)throw u(H,"Cannot reserve iOS reset boot slot")}}}async waitResetCapacity(d){let{error:c,deviceId:R,startedAt:C,owned:T,delayMs:B}=d,O=C+mb;if(this.timer.now()+B>O||this.timer.now()>=O)throw new pI(R,this.timer.now()-C,c);if(await this.timer.sleep(B),await T(),this.timer.now()>=O)throw new pI(R,this.timer.now()-C,c)}async eraseAndBoot(d,c,R,{phases:C,deferredBoot:T,signal:B}){if(this.dependencies.iosBootInstrumentation.reserveBoot)await R();if(!T)await this.measureStep(d.deviceId,"stop",C,()=>this.dependencies.stopDevice(d));await this.readExpectedTarget(d.deviceId,c,"Shutdown","erase simulator"),await R(),await this.measureStep(d.deviceId,"erase",C,()=>this.dependencies.simctl.eraseSimulator(d.deviceId));let O=await this.measureStep(d.deviceId,"boot",C,()=>this.bootAdmitted(d.deviceId,c,R,B));if(O.platform!=="ios"||O.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:C}}async bootAdmitted(d,c,R,C){let T=!1;try{return await this.dependencies.iosBootInstrumentation.run({udid:d,runtime:c.runtimeId,timeoutMs:qe,reason:"reset",signal:C},async()=>(T=!0,await R(),this.dependencies.simctl.bootSimulator(d)))}catch(B){if(B instanceof Nn||!T&&B instanceof Ve)this.deferredBoots.add(d);throw u(B,"Cannot boot erased iOS simulator")}}async measureStep(d,c,R,C){let T=this.timer.now(),B=!1;e.info(`[SessionBroker] iOS baseline reset ${c} started for ${d}`);try{let O=await C();return B=!0,O}finally{R[c]=this.timer.now()-T,e.info(`[SessionBroker] iOS baseline reset ${c} ${B?"completed":"failed"} for ${d} after ${this.timer.now()-T}ms`)}}async readExpectedTarget(d,c,R,C){await ci(this.dependencies.simctl,d,c,{state:R,action:C})}}function on(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 rs(d,c,R){let C=new Set(Jb),T=[...c.dirty],B=[...d].sort((O,x)=>x.sequence-O.sequence).map((O)=>({source:"journal",mutation:O}));for(let O of c.changes.filter((x)=>!x.journaled)){let x=R.baselineRevert?.(O,c.changes)??on(O);if(x){if(!B.some((N)=>N.mutation.kind===x.kind&&N.mutation.key===x.key))B.push({source:"baseline",mutation:x})}else T.push(`Unjournaled ${O.kind}:${O.key}`)}for(let O of B){if(O.mutation.priorValue.state==="unobservable"){T.push(`Unobservable prior value ${O.mutation.kind}:${O.mutation.key}`);continue}if(!C.has(O.mutation.kind)||!R.canRevert(O.mutation))T.push(`Unsupported ${O.mutation.kind}:${O.mutation.key}`)}return T.length>0?{status:"non_revertible",reasons:T}:{status:"revertible",steps:B}}class ss{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:C,...T}){let{reuseCount:B,signal:O,runResetBoot:x}=T;this.assertInput(d,c,C,B);let N={},H=async()=>{O?.throwIfAborted(),await R(),O?.throwIfAborted()};await H(),await this.assertSettled(C,H,O);let q=JSON.stringify([C.deviceId,C.incarnation,C.sessionUuid]),G=this.eraseReasons.get(q)??"maxUses reached";if(!this.eraseReasons.has(q)&&(B+1)%this.dependencies.maxUses!==0){let W={scope:C,signal:O??new AbortController().signal,assertOwned:async()=>{W.signal.throwIfAborted(),await H(),W.signal.throwIfAborted()},recordPhase:(J,X)=>{N[J]=(N[J]??0)+X}},V=(J,X)=>this.cleaningStep(W,O,J,{phases:N,operation:X}),Y=await this.loadJournal(W,V,N);try{if(this.assertCompleteRecording(C.sessionUuid),await V("inventory",()=>ci(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=Y.find(Xb);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(Y,W,V),await V("sanitize",()=>this.dependencies.mutations.sanitize(W)),await H(),await this.checkHealth(d,c,W,{phases:N,signal:O})}catch(J){e.warn(`iOS keep-booted cleaning failed: ${r(J)}`,J),await H(),G=this.fallbackReason(J),e.warn(`iOS erase fallback: ${G}`,J),this.eraseReasons.set(q,G)}if(!this.eraseReasons.has(q))return await H(),await this.dependencies.journal.deleteSession(C),await H(),{outcome:"clean",mode:"keep-booted",phases:N}}return await H(),await this.assertSettled(C,H,O),this.nonCleanOutcome({device:d,profile:c,scope:C,assertOwned:H,phases:N,signal:O},G,x)}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:C,profile:T,scope:B,assertOwned:O,phases:x,signal:N}=d;try{let H=()=>this.dependencies.erase.resetWithTiming(C,T,O,N),q=await(R?R(H):H());if(await O(),q.outcome!=="clean")throw new t("iOS erase fallback did not confirm a clean baseline");return await this.dependencies.journal.deleteSession(B),await O(),this.dependencies.recordingGaps?.clear(B.sessionUuid),this.eraseReasons.delete(JSON.stringify([B.deviceId,B.incarnation,B.sessionUuid])),{outcome:"fallback:erase",mode:"erase",phases:{...x,...q.phases},fallbackReason:c}}catch(H){throw e.warn(`iOS erase fallback failed: ${r(H)}`,H),new wi(r(H),{outcome:"pending",mode:"erase",phases:{...x,...H instanceof wi?H.reset.phases:{}},fallbackReason:`${c}; erase: ${r(H)}`},{cause:H instanceof wi?H.cause:H})}}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(C){throw new wi(r(C),{outcome:"pending",mode:"keep-booted",phases:R,fallbackReason:r(C)},{cause:C})}}async replayJournal(d,c,R){let C=[...d].sort((T,B)=>B.sequence-T.sequence).map((T)=>({entry:T,plan:rs([T],{dirty:[],changes:[]},this.dependencies.mutations)}));for(let{entry:T,plan:B}of C)if(!["installed-app","app-group"].includes(T.kind)&&B.status==="non_revertible"&&!this.sanitizeCovers(T,c))throw new t(`iOS journaled mutation ${T.kind}:${T.key} (${T.toolName}) cannot be journal-reverted or sanitized; erase required`);for(let{entry:T,plan:B}of C){if(["installed-app","app-group"].includes(T.kind)){e.warn(`iOS reset handles ${T.kind}:${T.key} through app inventory cleaning`);continue}if(B.status==="non_revertible"){e.warn(`iOS reset skipped journal revert: ${B.reasons.join("; ")}`);continue}await R(`revert:${T.kind}:${T.key}`,()=>this.dependencies.mutations.revert(T,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!Xb(d);if(d.kind==="preference")return w1(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:C,operation:T}){let B=mW({baseMs:this.dependencies.budgetMs??30000,ceilingMs:this.dependencies.budgetCeilingMs??120000},this.dependencies.hostLoad??pW());try{return await this.cleaningAttempt(d,c,R,{phases:C,operation:T,first:B,timeoutMs:B.budgetMs})}catch(O){if(!this.isBudgetTimeout(O)||c?.aborted)throw O;return e.warn(`Retrying iOS reset ${R}: ${r(O)}`,O),await this.waitForAbandonedStep(d.scope.deviceId,EC(B),O,c),this.cleaningAttempt(d,c,R,{phases:C,operation:T,first:B,timeoutMs:EC(B)})}}async cleaningAttempt(d,c,R,{phases:C,operation:T,first:B,timeoutMs:O}){let x=new AbortController;d.signal=Ge(x.signal,c)??x.signal;let N=new DOMException(`iOS reset ${R} timed out after ${O}ms (${fW(B)})`,"TimeoutError");return l(()=>this.measure(d.scope.deviceId,R,C,async()=>{await d.assertOwned();let H=await T();return await d.assertOwned(),H}),{timer:this.dependencies.timer,timeoutMs:O,signal:c,label:`iOS reset ${R}`,timeoutError:()=>N,onTimeout:()=>{this.budgetTimeouts.add(N),x.abort(N)}})}async waitForAbandonedStep(d,c,R,C){await l(Promise.allSettled([...this.pending.get(d)??[]]),{timer:this.dependencies.timer,timeoutMs:c,signal:C,label:"iOS reset abandoned step settlement",timeoutError:()=>R})}async checkHealth(d,c,R,{phases:C,signal:T}){let B=this.dependencies.timer.now();try{await this.cleaningStep(R,T,"health-probe",{phases:C,operation:async()=>{if(await ci(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{C.health=(C.health??0)+this.dependencies.timer.now()-B}}async measure(d,c,R,C){let T=this.dependencies.timer.now(),B=Promise.resolve().then(C),O=this.pending.get(d)??new Set;this.pending.set(d,O),O.add(B);try{return await B}finally{if(O.delete(B),O.size===0)this.pending.delete(d);R[c]=(R[c]??0)+this.dependencies.timer.now()-T}}assertInput(d,c,R,C){if(Ot(d,c),Ll(R,R.sessionUuid),d.deviceId!==R.deviceId||!Number.isSafeInteger(C)||C<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(C){throw new wi(r(C),{outcome:"pending",mode:"keep-booted",phases:{}},{cause:C})}}}var fb="light",vb="large",yb={kind:"clipboard",key:"pasteboard",priorValue:{state:"present",value:""},toolName:"minimal-reset"},Sb=30000,bb=1e4;class as{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:C,reuseCount:T,signal:B}){if(Ot(d,c),Ll(C,C.sessionUuid),d.deviceId!==C.deviceId||!Number.isSafeInteger(T)||T<0)throw new t("iOS minimal reset requires the exact mutation scope and durable use count");let O={},x=JSON.stringify([C.deviceId,C.incarnation,C.sessionUuid]),N=this.failures.get(x);if(N!==void 0)return this.pending(O,N);if((T+1)%this.dependencies.maxUses===0)return this.pending(O,"maxUses reached");try{await this.clean(C,R,O,B)}catch(H){if(B?.aborted)throw H;await R();let q=r(H);return e.warn(`iOS minimal cleaning failed; simulator will be destroyed: ${q}`,H),this.failures.set(x,q),this.pending(O,q)}return await R(),await this.dependencies.journal.deleteSession(C),await R(),this.dependencies.recordingGaps?.clear(C.sessionUuid),{outcome:"clean",mode:"minimal",phases:O}}pending(d,c){return{outcome:"pending",mode:"minimal",phases:d,fallbackReason:c}}async clean(d,c,R,C){let T=this.dependencies.recordingGaps?.reasonFor(d.sessionUuid);if(T!==void 0)throw new t(`iOS device mutation recording failed (${T}); the session's apps are unknown`);let B=[...await this.dependencies.journal.list(d)].sort((N,H)=>H.sequence-N.sequence),O=d.deviceId,x=(N,H)=>this.step({scope:d,assertOwned:c,phases:R,callerSignal:C},N,H);for(let N of B.filter((H)=>H.kind==="installed-app"))await x(`uninstall:${N.key}`,(H)=>this.dependencies.mutations.revert(N,H));if(B.some((N)=>N.kind==="shared-file"&&v8(N.key)))await x("files-fixture",(N)=>this.simctl(["uninstall",O,pE],N));await x("keychain",(N)=>this.simctl(["keychain",O,"reset"],N)),await x("privacy",(N)=>this.simctl(["privacy",O,"reset","all"],N)),await x("appearance",(N)=>this.simctl(["ui",O,"appearance",fb],N)),await x("content-size",(N)=>this.simctl(["ui",O,"content_size",vb],N)),await x("pasteboard",(N)=>this.dependencies.mutations.revert(yb,N))}async simctl(d,c){let R=await this.dependencies.simctl.executeCommandArgs(d,bb,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:C},T,B){let O=new AbortController,x=Ge(O.signal,C)??O.signal,N=this.dependencies.budgetMs??Sb,H={scope:d,signal:x,assertOwned:async()=>{x.throwIfAborted(),await c(),x.throwIfAborted()},recordPhase:(q,G)=>{R[q]=(R[q]??0)+G}};await l(async()=>{await H.assertOwned(),await B(H),await H.assertOwned()},{timer:this.dependencies.timer,timeoutMs:N,signal:C,label:`iOS minimal reset ${T}`,timeoutError:()=>new DOMException(`iOS minimal reset ${T} timed out after ${N}ms`,"TimeoutError"),onTimeout:()=>O.abort()})}}import{realpath as xb,rm as _b}from"fs/promises";import{homedir as Fb}from"os";import{posix as Db}from"path";function ds(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 Eu(d,c){let R=vB;return["spawn",d,"notifyutil","-1",R,"-s",R,c?"1":"0","-g",R,"-p",R]}import{isDeepStrictEqual as wb}from"util";var fs=["media","shared-file","keyboard","accessibility"],us={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 xu(d){return Object.keys(us).map((c)=>({...us[c],value:{state:"present",value:d[c]}}))}function _u(d){return fs.every((c)=>d?.completeKinds.includes(c))}function mi(d,c){let{kind:R,key:C}=us[c],T=d.observations.find((B)=>B.kind===R&&B.key===C);return T?.value.state==="present"?T.value.value:void 0}function ls(d){return Array.isArray(d)?d.filter((c)=>typeof c==="string"):[]}function Bu(d){let c={};if(d!==null&&typeof d==="object"&&!Array.isArray(d)){for(let[R,C]of Object.entries(d))if(typeof C==="boolean"||typeof C==="number"||typeof C==="string")c[R]=C}return c}function Fu(d){return{photos:ls(mi(d,"photos")),documents:ls(mi(d,"documents")),safariDocuments:ls(mi(d,"safariDocuments")),keyboard:Bu(mi(d,"keyboard")),accessibility:Bu(mi(d,"accessibility"))}}function sn(d,c){return d.filter((R)=>!c.includes(R))}function gs(d,c){let R=[],C=sn(c.photos,d.photos).length,T=sn(d.photos,c.photos).length;if(C>0)R.push(`iOS reset cannot revert ${C} added photo(s)`);if(T>0)R.push(`iOS reset cannot restore ${T} removed photo(s)`);let B=[];for(let[O,x,N,H]of[["documents","Documents",d.documents,c.documents],["safari-documents","Safari Documents",d.safariDocuments,c.safariDocuments]]){let q=sn(N,H).length;if(q>0)R.push(`iOS reset cannot restore ${q} removed ${x} file(s)`);let G=sn(H,N);if(G.length>0)B.push({area:O,names:G})}return{unrevertible:R,removals:B,keyboard:Ou(d.keyboard,c.keyboard),accessibility:Ou(d.accessibility,c.accessibility)}}function Ou(d,c){return[...new Set([...Object.keys(d),...Object.keys(c)])].sort().filter((R)=>!wb(d[R],c[R])).map((R)=>({key:R,prior:d[R]}))}function vs(d){return d.unrevertible.length===0&&d.removals.length===0&&d.keyboard.length===0&&d.accessibility.length===0}var Le={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:b(n().min(1)).min(1),calendarSystem:n().min(1),"force-24-hour-time":h(),"force-12-hour-time":h()},kb=s({AppleLocale:Le.locale.optional(),AppleLanguages:Le.language.optional(),AppleCalendar:Le.calendarSystem.optional(),AppleICUForce24HourTime:Le["force-24-hour-time"].optional(),AppleICUForce12HourTime:Le["force-12-hour-time"].optional()}),an={locale:"AppleLocale",language:"AppleLanguages",calendarSystem:"AppleCalendar","force-24-hour-time":"AppleICUForce24HourTime","force-12-hour-time":"AppleICUForce12HourTime"},Ab={"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."},Nu={contentSize:"content-size",increaseContrast:"increase-contrast"},Ib={reduceMotion:"ReduceMotionEnabled",boldText:"EnhancedTextLegibilityEnabled"};function ys(d){return Object.hasOwn(Nu,d)?Nu[d]:d}function $u(d){return Object.entries(Ib).find(([c])=>c===d)?.[1]}function Tb(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 Ku(d){return Object.entries(an).find(([c])=>c===d)?.[1]}async function Mb(d){let c=await ip(d);if(!(c instanceof Map))throw new t("iOS global settings export is not a dictionary");let R=kb.parse(Object.fromEntries(c));return Object.entries(an).map(([C,T])=>{let B=R[T];return{kind:"device-setting",key:C,value:B===void 0?{state:"absent"}:{state:"present",value:B}}})}function Eb(d){let c=d.priorValue;if(c.state!=="present")return c.state==="absent"&&(Ku(d.key)!==void 0||$u(d.key)!==void 0);let R=ys(d.key);return Object.entries(Le).find(([T])=>T===R)?.[1]?.safeParse(c.value).success??!1}var Lu=["keychain","permission","location","status-bar","clipboard"];function Ob(d,c){let R=g1(d.key);return d.kind==="shared-file"&&R!==void 0&&c?.baseline?.completeKinds.includes("installed-app")===!0&&!c.baseline.observations.some((C)=>C.kind==="installed-app"&&C.key.toLowerCase()===R.toLowerCase())}class Ss{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 Eb(d);case"biometric-enrollment":return ds(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(),Kb(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((T)=>{let B=nn(T);if(!B)throw new t("iOS baseline app inventory contains an unidentified bundle");return{kind:"installed-app",key:B,value:{state:"present",value:pp().parse(T)}}}),C=["installed-app"];try{let T=await this.captureSettings(d);R.push(...T),C.push("device-setting")}catch(T){await this.inventoryFailure(T,d,"device-setting")}try{R.push(...xu(await this.dependencies.residue.read(d.scope.deviceId,d.signal))),C.push(...fs)}catch(T){await this.inventoryFailure(T,d,"out-of-band residue")}return{observations:R,completeKinds:C,unobservable:Jb.filter((T)=>(T in Ab)||!C.includes(T))}}async inventoryFailure(d,c,R){if(e.warn(`iOS ${R} inventory is unobservable: ${r(d)}`,d),c.signal.throwIfAborted(),await c.assertOwned(),Kb(d)==="retryable")throw u(d,`iOS ${R} inventory is temporarily unavailable`)}async captureSettings(d){let c=d.scope.deviceId,R=Le.appearance.parse((await this.command(d,["ui",c,"appearance"])).stdout.trim()),C=Le["content-size"].parse((await this.command(d,["ui",c,"content_size"])).stdout.trim()),T=Le["increase-contrast"].parse((await this.command(d,["ui",c,"increase_contrast"])).stdout.trim()),B=await this.command(d,["spawn",c,"defaults","export","-g","-"]);return[...["appearance","nightMode"].map((O)=>({kind:"device-setting",key:O,value:{state:"present",value:R}})),{kind:"device-setting",key:"content-size",value:{state:"present",value:C}},{kind:"device-setting",key:"increase-contrast",value:{state:"present",value:T}},...await Mb(B.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,C=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 T=this.timer.now();try{await this.dependencies.pasteboard.write(R,typeof C==="string"?C:"",c.signal)}finally{c.recordPhase?.("simctl:pbcopy",this.timer.now()-T)}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(C){if(R[0]!=="spawn"||R[3]!=="delete"||!Lb(C))throw u(C,"iOS reset command failed");e.debug(`iOS reset preference already absent: ${r(C)}`),c.signal.throwIfAborted(),await c.assertOwned()}}async revertBiometricEnrollment(d,c){let R=ds(d);if(R===void 0)throw new t("iOS cannot restore an unreadable biometric enrollment");let C=await this.command(c,Eu(c.scope.deviceId,R));if(mR(C.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,C=ys(d.key);if(["appearance","nightMode","content-size","increase-contrast"].includes(C))return["ui",c,C==="content-size"?"content_size":C==="increase-contrast"?"increase_contrast":"appearance",String(R)];let T=$u(d.key);if(T)return Tb(c,T,R);let B=Ku(d.key);if(!B)throw new t(`Unsupported iOS setting ${d.key}`);return["spawn",c,"defaults",R===void 0?"delete":"write",".GlobalPreferences",B,...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,[C,T]=d.key.split(":");return["spawn",c,"defaults",R===void 0?"delete":"write",C,T,...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 Ob(d,c);if(["installed-app","app-group",...Lu,"certificate","media"].includes(d.kind))return!0;return d.kind==="device-setting"&&(["appearance","nightMode","content-size","increase-contrast"].includes(ys(d.key))||Object.hasOwn(an,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 C=new Set(d.baseline?.observations.filter((O)=>O.kind==="installed-app"&&O.value.state==="present").map((O)=>O.key)),T=R.filter((O)=>O.ApplicationType==="User").filter((O)=>{let x=nn(O);if(!x)throw new t("iOS reset app inventory contains an unidentified bundle");return!C.has(x)}),B=T.length>0?await this.appGroupCleanup(d):void 0;for(let O of T){let x=nn(O);await this.terminate(x,d),await this.clearAppGroups(x,d,B),await this.command(d,["uninstall",d.scope.deviceId,x])}for(let O of Lu)await this.revert({kind:O,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(),!_u(d.baseline)||!d.baseline)throw new t("iOS reset requires a residue baseline; erase required");let c=Fu(d.baseline),R=async(T)=>{let B=this.timer.now();try{let O=await this.dependencies.residue.read(d.scope.deviceId,d.signal);return await d.assertOwned(),O}finally{d.recordPhase?.(T,this.timer.now()-B)}},C=gs(c,await R("residue:inspect"));if(C.unrevertible.length>0)throw new t(`${C.unrevertible.join("; ")}; erase required`);if(vs(C))return;for(let{area:T,names:B}of C.removals)await d.assertOwned(),await this.dependencies.residue.removeEntries(d.scope.deviceId,T,B,d.signal);for(let[T,B]of[[O5,C.keyboard],[M5,C.accessibility]])for(let{key:O,prior:x}of B)await this.revert({kind:"preference",key:`${T}:${O}`,priorValue:x===void 0?{state:"absent"}:{state:"present",value:x},toolName:"baseline-reset"},d);if(!vs(gs(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 O=this.timer.now();try{return await this.dependencies.privacyGrants.readServiceRows(c,gte,d.signal)}catch(x){throw u(x,"iOS privacy grant verification failed")}finally{d.recordPhase?.("tcc:privacy-verify",this.timer.now()-O)}},C=await R();if(await d.assertOwned(),d.signal.throwIfAborted(),C.length===0)return;let T=[...new Set(C.map((O)=>O.client))].sort();e.warn(`iOS privacy grants survived global reset; resetting clients: ${T.join(", ")}`);for(let O of T)await this.command(d,["privacy",c,"reset","all",O]);let B=await R();if(await d.assertOwned(),d.signal.throwIfAborted(),B.length>0)throw new t("iOS privacy grants survived reset: "+B.map((O)=>`${O.service}:${O.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(an).map((R)=>[R,{state:"absent"}]))};for(let[R,C]of Object.entries(c)){let T=d.baseline?.observations.find((O)=>O.kind==="device-setting"&&O.key===R)??(R==="appearance"?d.baseline?.observations.find((O)=>O.kind==="device-setting"&&O.key==="nightMode"):void 0),B={kind:"device-setting",key:R,priorValue:T?.value??C,toolName:"baseline-reset"};if(!this.canRevert(B))e.warn(`iOS reset using simulator default for unsupported baseline setting ${R}`),B.priorValue=C;await this.revert(B,d)}}async command(d,c){let R=this.timer.now();try{d.signal.throwIfAborted(),await d.assertOwned();let C=await this.dependencies.simctl.executeCommandArgs(c,1e4,d.signal);if(C.error)throw new t(`iOS reset ${c[0]} failed: ${C.error}`);return await d.assertOwned(),d.signal.throwIfAborted(),C}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 C=await this.appGroups(d,c);if(Object.keys(C).length===0)return;let T=R??await this.appGroupCleanup(c);this.excludeSharedGroups(C,T);for(let B of Object.values(C)){if(await c.assertOwned(),T.removedPaths.has(B))continue;let{isAbsolute:O,normalize:x,sep:N}=Db,H=`${N}${c.scope.deviceId}${N}data${N}Containers${N}Shared${N}AppGroup${N}`;if(!O(B)||x(B)!==B||!B.includes(H)||B.slice(B.indexOf(H)+H.length).includes(N)||B.endsWith(N)||await this.dependencies.files.realpath(B)!==B)throw new t("iOS reset refused an unproven app-group container path");await c.assertOwned();let q=this.timer.now();try{await this.dependencies.files.remove(B),T.removedPaths.add(B)}finally{c.recordPhase?.("app-group-remove",this.timer.now()-q)}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((C)=>C.kind==="installed-app"&&C.value.state==="present"&&C.value.value!==null&&typeof C.value.value==="object"&&!Array.isArray(C.value.value)&&C.value.value.ApplicationType==="User")??[]){let C=await this.appGroups(R.key,d);for(let[T,B]of Object.entries(C))c.baselineIds.add(T),c.baselinePaths.add(B)}return c}excludeSharedGroups(d,c){for(let[R,C]of Object.entries(d))if(R.startsWith("group.com.apple.")||c.baselineIds.has(R)||c.baselinePaths.has(C))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(!Om(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"]),C={};for(let T of R.stdout.split(`
23
+ `).filter((B)=>B.trim()!=="")){let B=T.split("\t");if(B.length!==2||!B[0]||!B[1]||Object.hasOwn(C,B[0]))throw new t("iOS reset received invalid app-group inventory");C[B[0]]=B[1]}return C}}function bs(d,c){let R=new Set,C=new Bw({timer:c});return new Ss({simctl:d,privacyGrants:C,trustStore:C,residue:new N5({simctl:d,files:DW,deviceSetRoot:Lw(Fb())}),files:{realpath:xb,remove:(T)=>_b(T,{recursive:!0,force:!1})},pasteboard:{assertSettled:(T)=>{if(R.has(T))throw u(new DOMException("iOS pasteboard child teardown remains unconfirmed","TimeoutError"),"Cannot redrive iOS reset")},write:async(T,B,O)=>{O.throwIfAborted();let x=await d.startCommandArgs(["pbcopy",T],{stdio:["pipe","ignore","pipe"]}),N=MT(x,[]);R.add(T),x.once("exit",()=>R.delete(T));let H=()=>{x.kill("SIGTERM")},q=(W)=>{H(),G=W},G;O.addEventListener("abort",H,{once:!0}),x.stdin?.on("error",q);try{if(O.aborted||!x.stdin)H();else x.stdin.end(B);if(await Hn(x,N.exitPromise,{timer:c,signal:null,timeoutMs:1e4,forceKillTimeoutMs:1000}),O.throwIfAborted(),G||!x.stdin||N.exitState.exitCode!==0)throw new t("iOS reset could not restore the pasteboard",{cause:G})}catch(W){if(W instanceof rp)throw u(new DOMException(r(W),"TimeoutError"),"iOS pasteboard teardown remains unconfirmed");throw u(W,"iOS reset pasteboard command failed")}finally{if([x.exitCode!==null,x.signalCode!==null,x.pid===void 0].some(Boolean))R.delete(T);O.removeEventListener("abort",H),x.stdin?.off("error",q)}}}},c)}function Gu(d){return{probe:async(c,R)=>{let C=ge.registry.peek(c.deviceId);if(!C)return!1;return new QT(void 0,d,{deviceId:c.deviceId,useRemoteRunner:()=>!1,getHost:()=>"127.0.0.1"}).checkHealthEndpointOnPortForDevice(C.getServicePort(),c.deviceId,5000,{signal:R,requireDeviceId:!0})}}}async function dn(d,c,R){if(R.signal.throwIfAborted(),await R.assertOwned(),await d.getBaseline(R.scope))return;let C=await c.capture(R);if(await R.assertOwned(),R.signal.throwIfAborted(),C.completeKinds.length===0&&C.observations.length===0)throw new t("Device baseline capture returned no observable inventory");await d.captureBaseline(R.scope,C)}var Wu=4,cn=2000,ws=2000,Nb=te({initialDelayMs:250,multiplier:2,maxDelayMs:2000});function pt(d,c,R=Wu){return Math.min(d,Math.max(cn,Math.floor(d/2**(R-c+2))))}function Ds(d){if(!(d instanceof Error)||d.name==="AbortError")return!1;return d instanceof dt||/timed out after \d+ms/.test(d.message)}function un(d,c){let R=d.now(),C=c-R;return R+Math.min(C,Math.max(cn,Math.floor(C/4)))}async function Vu(d,c){await d.timer.sleep(Math.min(Nb.delayForAttempt(c),Math.max(0,d.deadlineMs-d.timer.now()))),d.signal?.throwIfAborted()}async function xt(d,c){let R=c.attempts??Wu;for(let C=1;;C++){c.signal?.throwIfAborted();let T=c.deadlineMs-c.timer.now();if(T<=0)throw new t(`${c.label} exceeded the reset budget`);let B=Math.min(T,Math.max(c.minAttemptMs??0,pt(T,C,R)));try{let O=await d(B);return c.signal?.throwIfAborted(),O}catch(O){if(c.signal?.throwIfAborted(),!Ds(O)||C>=R||c.timer.now()>=c.deadlineMs)throw O;e.warn(`${c.label} timed out; retrying (attempt ${C+1})`,O)}await Vu(c,C)}}async function pn(d,c){for(let R=1;;R++){c.signal?.throwIfAborted();let C=c.deadlineMs-c.timer.now();if(C<=0)return!1;let T=await d(pt(C,Math.min(R,2)));if(c.signal?.throwIfAborted(),c.timer.now()>=c.deadlineMs)return!1;if(T)return!0;await Vu(c,R)}}var ks=600000,Ju=3;function ju(d,c){return d.fullBaseline?!c.madeHostSideChanges():c.canReset()}function Hb(d){return Ds(d)}function zu(d,c){let R=!0,C=!1,T=!1,B=d.onSessionExecutionEnded((O,x)=>{if(O.includes(c)&&x.admitted)R=!1,C||=e7(x.toolName),T||=QZ(x.toolName)});return{canReset:()=>R,madeOpaquePersistentChanges:()=>C,madeHostSideChanges:()=>T,close:B}}class Is{dependencies;baselines=new Map;constructor(d){this.dependencies=d}get canCapture(){return this.dependencies.strategy!==void 0}async capture(d,c,R,C){let{sessionId:T}=C;if(this.closeBaseline(d),!this.dependencies.strategy)return;let B=this.dependencies.watchSession(T),O=C.timer??i,x=O.now()+(C.timeoutMs??2000),N=new AbortController,H=C.signal?AbortSignal.any([C.signal,N.signal]):N.signal,q=(W,V,Y)=>{H.throwIfAborted();let J=x-O.now();if(J<=0)throw new t("Android reset baseline capture exceeded preparation deadline");return l(async()=>{await C.assertOwned?.(),H.throwIfAborted();let X=await W(Y===void 0?Math.min(2000,J):Math.min(J,Math.max(2000,Math.floor(J/Y))));return H.throwIfAborted(),await C.assertOwned?.(),X},{timer:O,timeoutMs:J,signal:H,label:V,timeoutError:()=>new t("Android reset baseline capture exceeded preparation deadline"),onTimeout:()=>N.abort(new t("Android reset baseline capture exceeded preparation deadline"))})},G=async(W,V,Y=!1)=>{for(let J=1;;J++)try{let X=Y?Ju-J+1:void 0;return await q(W,V,X)}catch(X){if(!(J<Ju&&!H.aborted&&x-O.now()>0&&Hb(X)))throw X;e.warn(`${V} timed out; retrying (attempt ${J+1})`)}};try{await G((J)=>this.assertTarget(c,R,H,{timeoutMs:J}),"Android reset baseline target verification",!0);let W=await G((J)=>this.packages(c,H,J),"Android reset baseline package inventory"),V=this.dependencies.strategy.handlesSessionMutations?await G((J)=>this.bootIdentity(c,H,J),"Android reset boot identity"):void 0,Y=Xe({platform:"android",resourceId:d,stableDeviceId:C.stableDeviceId,bootId:V??null});if(this.dependencies.strategy.capture){if(this.dependencies.strategy.fullBaseline&&!C.assertOwned)throw new t("Android snapshot capture requires exclusive binding ownership");await this.dependencies.strategy.capture(c,{fresh:C.fresh,resourceId:d,sessionId:T,incarnation:Y,signal:H,timeoutMs:Math.max(0,x-O.now()),assertOwned:async()=>{if(await C.assertOwned?.(),await this.assertTarget(c,R,H,{timeoutMs:Math.max(1,x-O.now()),allowPendingName:!0}),V)await this.assertBootIdentity(c,V,H);await C.assertOwned?.()}})}return this.baselines.set(d,{device:{...c},profile:{...R},packages:W,activity:B,sessionId:T,incarnation:Y,stableDeviceId:C.stableDeviceId,bootId:V,timer:O}),{bootId:V??null}}catch(W){throw B.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:C,signal:T}){let B={outcome:"pending",mode:"none",phases:{}},O=this.dependencies.timer??this.baselines.get(d)?.timer??i,x=this.dependencies.resetTimeoutMs??ks;if(!Number.isSafeInteger(x)||x<=0)throw new t("Android reset timeout must be a positive integer in milliseconds");let N=O.now()+x,H=new AbortController,q=T?AbortSignal.any([T,H.signal]):H.signal,G=async()=>{q.throwIfAborted(),await C(),q.throwIfAborted()};try{return await l(()=>this.resetWithinDeadline(d,c,R,{assertOwned:G,signal:q,deadlineMs:N,timing:B,timer:O}),{timer:O,timeoutMs:x,signal:q,label:"Android baseline reset",onTimeout:()=>H.abort(new t("Android baseline reset deadline exceeded"))})}catch(W){if(H.abort(W),W instanceof wi)throw W;throw new wi(u(W,"Android baseline reset failed").message,{...B,outcome:"pending"},{cause:W})}finally{this.closeBaseline(d)}}async restoreFoldPosture(d,c,R,C){if(c.archetype==="foldable"){if(C.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,C),C.throwIfAborted(),await R()}}requireBaseline(d,c,R){let C=this.baselines.get(d);if(!C||C.device.deviceId!==c.deviceId||C.device.name!==c.name||C.profile.systemImagePackage!==R.systemImagePackage||C.profile.profileId!==R.profileId||C.profile.memoryMb!==R.memoryMb)throw new t("Android reset lacks the original session baseline");return C}async resetWithinDeadline(d,c,R,{assertOwned:C,signal:T,deadlineMs:B,timing:O,timer:x}){let N=this.dependencies.strategy;if(!N)throw await this.forget(d),new t("Android reset cannot prove restoration of unobservable state");let H=this.requireBaseline(d,c,R),q={deadlineMs:B,timer:x,assertOwned:C},G=async()=>{if(await C(),!N.handlesSessionMutations&&!ju(N,H.activity))throw new t("Android session mutations cannot be restored by this reset");if(await this.assertTarget(c,R,T,{timeoutMs:Math.max(1,B-x.now()),requireBoot:!N.handlesSessionMutations,allowPendingName:!0,budget:q}),H.bootId)await this.assertBootIdentity(c,H.bootId,T,q);await C()};try{if(await G(),!N.fullBaseline&&!N.handlesSessionMutations)await this.assertPackagesMatch(c,H.packages,"Android reset detected untracked package inventory changes",{signal:T,budget:q});let W=(Y)=>this.healthCheck(c,R,Y?.signal??T,Wb(q,Y)),V=await N.reset(c,H.packages,N.fullBaseline?async()=>{if(await C(),!N.handlesSessionMutations&&!ju(N,H.activity))throw new t("Android session mutations cannot be restored by this reset")}:G,{resourceId:d,sessionId:H.sessionId,incarnation:H.incarnation,opaquePersistentChanges:H.activity.madeOpaquePersistentChanges(),foldPostureRestored:R.archetype==="foldable"&&this.dependencies.postureReset!==void 0,signal:T,timeoutMs:B-x.now(),deadlineMs:B,assertOwned:C,assertBindingOwned:C,rebindIncarnation:async()=>{await C(),await this.assertTarget(c,R,T,{timeoutMs:Math.max(1,B-x.now()),allowPendingName:!0,budget:q});let Y=await this.bootIdentity(c,T,void 0,q);return await C(),H.bootId=Y,H.incarnation=Xe({platform:"android",resourceId:d,stableDeviceId:H.stableDeviceId,bootId:Y??null}),H.incarnation},healthCheck:W,resetTiming:O});if(Object.assign(O,V),await G(),await this.restoreFoldPosture(c,R,C,T),await G(),!N.handlesSessionMutations)await this.assertPackagesMatch(c,H.packages,"Android reset did not restore the original package inventory",{signal:T,budget:q});return await W(),await G(),V??"clean"}finally{this.closeBaseline(d)}}async healthCheck(d,c,R,C){if(await C.assertOwned(),await this.assertTarget(d,c,R,{timeoutMs:Math.max(1,C.deadlineMs-C.timer.now()),allowPendingName:!0,budget:C}),await C.assertOwned(),await this.packages(d,R,void 0,C),await C.assertOwned(),!await this.checkCtrlProxy(d,C,R))throw new t("Android reset CtrlProxy health check failed");await C.assertOwned()}async assertTarget(d,c,R,{timeoutMs:C=2000,requireBoot:T=!0,allowPendingName:B=!1,budget:O}={}){let x=Yr(c.systemImagePackage);if(![d.platform==="android",/^emulator-\d+$/.test(d.deviceId),d.name.trim().length>0,x?.apiLevel===c.apiLevel,x?.abi===c.abi,x?.tag===c.flavor].every(Boolean))throw new t("Android reset requires an exact emulator and system-image profile");let H=await this.readWithinBudget((q)=>this.dependencies.inventory({signal:R,timeoutMs:q,targetDeviceId:d.deviceId}),R,C,O);if(R?.throwIfAborted(),!Gb(H,d,c,B))throw new t("Fresh Android inventory did not prove the exact online reset target");if(T)await this.assertBoot(d,R,Vb(C,O),O)}async assertBoot(d,c,R=2000,C){let T=await this.readWithinBudget((B)=>this.dependencies.adb(d).executeCommand("shell getprop sys.boot_completed",{timeoutMs:B,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,C);if(T.stdout.trim()!=="1"||Ke(T.stdout,T.stderr))throw new t("Android reset target has not completed boot")}async bootIdentity(d,c,R=2000,C){c?.throwIfAborted();let T=await this.readWithinBudget((O)=>this.dependencies.adb(d).executeCommand("shell cat /proc/sys/kernel/random/boot_id",{signal:c,timeoutMs:O,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,C);c?.throwIfAborted();let B=T.stdout.trim();if(T.error||T.stderr.trim()||!/^[a-f\d]{8}-(?:[a-f\d]{4}-){3}[a-f\d]{12}$/i.test(B))throw new t("Android reset cannot read emulator boot identity");return B}async assertBootIdentity(d,c,R,C){if(await this.bootIdentity(d,R,void 0,C)!==c)throw new t("Android reset target changed emulator boot identity")}async checkCtrlProxy(d,c,R){let C=new AbortController,T=R?AbortSignal.any([R,C.signal]):C.signal,B=un(c.timer,c.deadlineMs),O=()=>new t("Android reset CtrlProxy health check failed");return l(()=>pn(async(x)=>{await c.assertOwned();let N=await this.dependencies.ctrlProxyReady(d,{signal:T,timeoutMs:x,noRetry:!0});return await c.assertOwned(),N},{timer:c.timer,deadlineMs:B,signal:T,label:"Android reset CtrlProxy health check"}),{timer:c.timer,timeoutMs:Math.max(0,B-c.timer.now()),signal:R,label:"Android reset CtrlProxy health check",timeoutError:O,onTimeout:()=>C.abort(O())})}readWithinBudget(d,c,R,C){if(!C)return d(R);return xt(async(T)=>{await C.assertOwned(),c?.throwIfAborted();let B=await d(T);return await C.assertOwned(),B},{timer:C.timer,deadlineMs:C.deadlineMs,signal:c,label:"Android reset adb"})}async assertPackagesMatch(d,c,R,{signal:C,budget:T}={}){let B=await this.packages(d,C,void 0,T);if(B.size!==c.size||[...c].some((O)=>!B.has(O)))throw new t(R)}async packages(d,c,R=2000,C){let T=await this.readWithinBudget((x)=>this.dependencies.adb(d).executeCommand("shell pm path android",{timeoutMs:x,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,C);if(c?.throwIfAborted(),!T.stdout.trim().startsWith("package:")||T.stderr.trim())throw new t("Android reset package manager is not responsive");let B=await this.readWithinBudget((x)=>this.dependencies.adb(d).executeCommand("shell pm list packages -3",{timeoutMs:x,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,R,C);if(c?.throwIfAborted(),B.stderr.trim()||Ke(B.stdout,B.stderr))throw new t("Android reset package manager is not responsive");let O=new Set;for(let x of B.stdout.split(`
24
+ `)){let N=x.trim();if(!N)continue;if(!/^package:[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/.test(N))throw new t("Android reset received an invalid package inventory");O.add(N.slice(8))}return O}}function Ub(d,c,R,C){return[d.platform==="android",d.deviceId===c.deviceId,C||d.name===c.name,d.isRunning===!0,d.isRunningStateKnown!==!1,C||d.runtimeId===R.systemImagePackage,C||d.deviceType===R.profileId,C||d.apiLevel===R.apiLevel].every(Boolean)}function Gb(d,c,R,C){let T=d.filter((x)=>x.deviceId===c.deviceId||x.name===c.name),B=T[0];if(T.length!==1||!B)return!1;let O=C&&ia(B.name,c.deviceId);return Ub(B,c,R,O)}function Wb(d,c){return{...d,deadlineMs:Math.min(d.deadlineMs,c?.deadlineMs??d.deadlineMs),assertOwned:c?.assertOwned??d.assertOwned}}function Vb(d,c){return c?d:Math.min(2000,d)}import{isDeepStrictEqual as gn}from"util";import{createHash as Xu}from"crypto";var mn=["device-setting","account"],jb={"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"},ew=["global","secure","system"],Ps=["/sdcard/Download","/sdcard/DCIM","/sdcard/Pictures","/sdcard/Movies","/sdcard/Documents"],Cs="/sdcard/Download",Ts="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 Qu(d){let c=[],R=(B,O,x)=>{c.push({kind:B,key:O,value:x===null?{state:"absent"}:{state:"present",value:x}})},C=await Fs(d);await aw(d,R,C),await iw(d,R,C),await rw(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[B,O]of Es(await d("shell dumpsys account"),C))R("account",Ms(B),O);await ow(d,R);let T=Jb.filter((B)=>!mn.some((O)=>O===B));return{completeKinds:[...mn],observations:c,unobservable:T,unobservableReasons:Object.fromEntries(T.map((B)=>[B,jb[B]??"No complete Android observation and restoration contract is available"]))}}function Ms(d){return`user:${d}`}function Es(d,c){let R=d.split(/\r?\n/),C=new Map;for(let T of c){let B=R.findIndex((N)=>new RegExp(`^User UserInfo\\{${T}:[^\\n]*\\}:\\s*$`).test(N)),O=/^\s*Accounts: (\d+)\s*$/.exec(R[B+1]??"")?.[1];if(B<0||O===void 0)throw new t(`Android account inventory is unreadable for user ${T}`);let x=R.slice(B+2,B+2+Number(O)).map((N)=>N.trim());if(x.length!==Number(O)||x.some((N)=>!/^Account \{.+\}$/.test(N)))throw new t(`Android account inventory is malformed for user ${T}`);C.set(T,Bs(x))}return C}function Bs(d){return Xu("sha256").update(JSON.stringify([...d].sort())).digest("hex")}async function iw(d,c,R){for(let C of ew)for(let T of C==="global"?[0]:R){let B=await d(`shell settings --user ${T} list ${C}`);Os(B,C,T,c)}}function Os(d,c,R,C){let T=new Set;for(let B of d.split(`
25
+ `).filter(Boolean)){let O=B.indexOf("="),x=B.slice(0,O);if(O<1||!/^[A-Za-z0-9_]\S*$/.test(x)||T.has(x))throw new t(`Android baseline ${c} settings inventory is malformed`);T.add(x),C("device-setting",R===0?`${c}:${x}`:`${c}:user:${R}:${x}`,B.slice(O+1))}}async function rw(d,c){c("device-setting","display:density",gi(await d("shell wm density"),"density")),c("device-setting","display:size",gi(await d("shell wm size"),"size")),c("device-setting","display:night-mode",Ns(await d("shell cmd uimode night")))}async function ow(d,c){let C=(await d("shell find /sdcard/ -mindepth 1 -maxdepth 1 -print")).split(`
26
+ `).filter(Boolean).sort();if(new Set(C).size!==C.length||C.some((T)=>!Qe(T)||T.slice(8).includes("/")))throw new t("Android baseline shared-storage root inventory is malformed");c("shared-file","roots",Xu("sha256").update(JSON.stringify(C)).digest("hex")),await sw(d,c);for(let T of Ps){let B=`if [ -d ${S(T)} ]; then find ${S(T)} -type f -exec sha256sum {} \\;; elif [ -e ${S(T)} ]; then exit 1; fi`,O=await d(`shell sh -c ${S(B)}`,30000);for(let x of O.split(`
27
+ `).filter(Boolean)){let N=/^([a-fA-F0-9]{64}) (.+)$/.exec(x),H=N?.[2];if(!N?.[1]||!H||!H.startsWith(`${T}/`)||!Qe(H))throw new t("Android baseline shared-file inventory is malformed");c("shared-file",H,N[1].toLowerCase())}}}async function sw(d,c){let R=Cs,C=`if [ -d ${S(R)} ]; then find ${S(R)} -mindepth 1 -maxdepth 1 -print; elif [ -e ${S(R)} ]; then exit 1; fi`,T=(await d(`shell sh -c ${S(C)}`)).split(`
28
+ `).filter(Boolean).sort();if(new Set(T).size!==T.length||T.some((B)=>!B.startsWith(`${R}/`)||!Qe(B)||B.slice(R.length+1).includes("/")))throw new t("Android baseline Downloads entry inventory is malformed");c("shared-file",Ts,JSON.stringify(T))}async function Fs(d){let c=await d("shell pm list users"),R=oW(c).map((T)=>T.userId),C=c.split(`
29
+ `).filter((T)=>T.trim());if(C[0]?.trim()!=="Users:"||C.length!==R.length+1||!R.includes(0)||R.some((T)=>!Number.isSafeInteger(T))||new Set(R).size!==R.length||C.slice(1).some((T)=>!/^\s*UserInfo\{\d+:[^:]+:[a-fA-F0-9]+\}(?: running)?\s*$/.test(T)))throw new t("Android baseline user inventory is malformed");return R.sort((T,B)=>T-B)}function fi(d){let c=d.split(`
30
+ `).filter((R)=>R.trim()).map((R)=>{let C=/^package:([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)$/.exec(R.trim());if(!C?.[1])throw new t("Android baseline package inventory is malformed");return C[1]});if(new Set(c).size!==c.length)throw new t("Android baseline package inventory has duplicates");return c.sort()}async function aw(d,c,R){let C=new Map;if(!new Set(fi(await d("shell pm list packages -s -u"))).has("android"))throw new t("Android baseline system package inventory is incomplete");let B=new Set;for(let O of R){c("installed-app",`users:${O}`,!0);let x=fi(await d(`shell pm list packages --user ${O}`)),N=fi(await d(`shell pm list packages -3 --user ${O}`));if(!x.includes("android")||N.some((H)=>!x.includes(H)))throw new t("Android baseline package inventory is incomplete");C.set(O,x);for(let H of x)c("installed-app",`user:${O}:${H}`,!0);for(let H of N)B.add(H)}for(let O of[...B].sort())await dw(d,c,O,R.filter((x)=>C.get(x)?.includes(O)))}async function dw(d,c,R,C){let T=await d(`shell dumpsys package ${S(R)}`),B=new RegExp(`^\\s*Package \\[${R.replaceAll(".","\\.")}\\] \\([^\\n]+\\):\\s*$`,"m").exec(T),O=B?T.slice(B.index+B[0].length).split(/^\s*Package \[/m)[0]:"",x=/^\s*lastUpdateTime=(.+)$/m.exec(O)?.[1],N=/^\s*versionCode=(\d+)\b/m.exec(O)?.[1],H=/^\s*codePath=(.+)$/m.exec(O)?.[1];if(!x||!N||!H)throw new t(`Android baseline cannot read package identity for ${R}`);c("installed-app",`identity:${R}`,JSON.stringify([x,N,H]));for(let q of C){let G=Bn(T,R,q);if(!G||!new RegExp(`^\\s*User ${q}:.*\\binstalled=true\\b`,"m").test(O))throw new t(`Android baseline cannot read permissions for ${R} user ${q}`);for(let[W,V]of G.runtimePermissions)c("permission",`runtime:${q}:${R}:${W}`,V.state==="granted"),c("permission",`runtime-flags:${q}:${R}:${W}`,JSON.stringify(V.raw))}}function gi(d,c){let R=d.split(`
31
+ `),C=c==="density"?"[0-9]+":"[0-9]+x[0-9]+",T=new RegExp(`^Physical ${c}: ${C}$`),B=new RegExp(`^Override ${c}: (${C})$`);if(!R[0]||!T.test(R[0])||R.length>2)throw new t(`Android baseline display ${c} is unreadable`);if(R.length===1)return null;let O=B.exec(R[1]);if(!O?.[1])throw new t(`Android baseline display ${c} is unreadable`);return O[1]}function Ns(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 qs(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 Us(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===Cb||["density","nightMode"].includes(d.key))}function lw(d){let c=d.observations.find((R)=>R.kind==="shared-file"&&R.key===Ts);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((C)=>typeof C==="string")?new Set(R):void 0}catch(R){e.debug("Android baseline Downloads inventory is not JSON",R);return}}function pw(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 mw(d){let c;try{c=JSON.parse(d.key)}catch(C){e.debug("Android journal file key is not JSON; not a user_files scope",C);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 fw(d){let c=d.trim(),R=`${Cs}/${c}`;return c.length>0&&!/[/\\]/.test(c)&&Qe(R)?R:void 0}function tp(d,c){let R=c?mw(d):void 0;if(!c||!R)return;let C=fw(R.namespace),T=lw(c);return(R.user===0||R.user==="default"&&pw(c))&&C!==void 0&&T!==void 0&&!T.has(C)&&!c.observations.some((B)=>B.kind==="shared-file"&&B.key.startsWith(`${C}/`))?C:void 0}function np(d,c){if(!c||d.kind!=="shared-file"&&d.kind!=="media")return!1;let R=d.kind==="shared-file"?g1(d.key):void 0;return R!==void 0?!SP(c,R):tp(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 hw(d){let c=new Set(d.filter((T)=>T.kind==="device-setting"&&T.priorValue.state==="absent"&&/^(?:global|system|secure):/.test(T.key)).map((T)=>T.key)),R=new Set(d.flatMap((T)=>(T.kind in Zu)?[T.kind]:[])),C=new Set([...R].flatMap((T)=>Zu[T]??[]));return(T)=>c.has(T)||C.has(T.replace(/^(\w+):user:\d+:/,"$1:"))}var gw=/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/,vw=["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 Sw(d){return vw.some((c)=>d===c||d.startsWith(`${c}.`))}function bw(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 C=/^([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)\/[A-Za-z0-9_.$]+$/.exec(R);if(!C?.[1])throw new t("Android cleaning cannot read the URL handler inventory");return C[1]})}async function op(d,c,R,{revert:C,journalEntries:T=[]}){let B=new Set(T.flatMap((O)=>tp(O,d)??[]));await new sp(d,c,R,{revert:C,journal:{sessionCreated:hw(T),userFilesNamespaces:[...B].sort(),launches:kw(T)}}).clean()}function kw(d){let c=new Set,R=new Set;for(let C of d){let T=P8(C);if(T===null)throw new t("Android cleaning cannot read a journaled app launch");let B=C.kind==="opened-url"?C.key.trim():"";if(T!==void 0)c.add(T);else if(B.startsWith("package:"))c.add(B.slice(8));else if(B)R.add(B)}return{packages:c,urls:R}}class sp{baseline;context;command;prior;revert;journal;constructor(d,c,R,{revert:C,journal:T}){this.baseline=d;this.context=c;this.command=R;this.revert=C,this.journal=T,this.prior=new Map(d.observations.map((B)=>[`${B.kind}:${B.key}`,B.value]))}restore(d,c,R){return this.revert({kind:d,key:c,priorValue:R,toolName:"keep-booted-cleaning"})}async clean(){let d=await Fs(this.command),c=await this.sessionStartedPreinstalledApps(d);await this.cleanPackages(d);for(let[R,C]of c)await this.restore("preference",`app-data:${R}:${C}`,{state:"absent"});await this.cleanDisplay();for(let R of["global","system","secure"])for(let C of R==="global"?[0]:d)await this.cleanSettings(R,C);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((B)=>B.kind==="account"&&/^user:\d+$/.test(B.key)).map((B)=>Number(B.key.slice(5)));if(c.length===0)throw new t("Android baseline has no per-user account inventory");let R=Es(await this.command("shell dumpsys account"),d),C=Bs([]),T=[...new Set([...c,...d])].sort((B,O)=>B-O).filter((B)=>(this.baselineString("account",Ms(B))??C)!==(R.get(B)??C));if(T.length>0)throw new t(`Android cleaning found changed accounts for user ${T.join(", ")}; accounts cannot be restored in place`)}async sessionStartedPreinstalledApps(d){let c=[];for(let R of d){let C=new Set(this.journal.launches.packages);for(let O of this.journal.launches.urls){let x=await this.command(`shell cmd package query-activities --components --user ${R} -a android.intent.action.VIEW -d ${S(O)}`);for(let N of Rw(x))C.add(N)}let T=[...C].filter((O)=>gw.test(O)&&bw(this.prior,R,O)).sort(),B=T.find(Sw);if(B)throw new t(`Android cleaning cannot clear data of core package ${B} the session started`);c.push(...T.map((O)=>[R,O]))}return c}async removeNamespaceDirectory(d){let c=S(d),R=S(d.slice(7)),C=`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 ${S(C)}`)}async readDisplay(){let d=gi(await this.command("shell wm density"),"density"),c=gi(await this.command("shell wm size"),"size"),R=Ns(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,C]of d){let T=this.prior.get(`device-setting:${R}`);if(T&&!gn(C,T))await this.restore("device-setting",R,T)}let c=[...await this.readDisplay()].filter(([R,C])=>{let T=this.prior.get(`device-setting:${R}`);return T&&!gn(C,T)}).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=fi(await this.command(`shell pm list packages -3 --user ${c}`));for(let C of R)await this.cleanPackage(c,C)}}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 C=await this.command(`shell dumpsys package ${S(c)}`),T=Bn(C,c,d);if(!T)throw new t(`Android cleaning cannot read runtime permissions for ${R}`);for(let[B,O]of T.runtimePermissions){let x=`runtime:${d}:${c}:${B}`,N=this.prior.get(`permission:${x}`);if(O.state==="granted"&&!(N?.state==="present"&&N.value===!0))await this.restore("permission",x,{state:"present",value:!1})}}async readSettings(d,c){let R=new Map;return Os(await this.command(`shell settings --user ${c} list ${d}`),d,c,(C,T,B)=>{R.set(T,B===null?{state:"absent"}:{state:"present",value:B})}),R}async cleanSettings(d,c){let R=await this.readSettings(d,c),C=new Map,T=c===0?`${d}:`:`${d}:user:${c}:`,B=this.baseline.observations.filter((x)=>x.kind==="device-setting"&&x.key.startsWith(T)&&(c!==0||!x.key.startsWith(`${d}:user:`))),O=0;for(let x of new Set([...R.keys(),...B.map((N)=>N.key)])){let N=this.prior.get(`device-setting:${x}`),H=N??{state:"absent"};if(gn(R.get(x)??{state:"absent"},H))continue;if(!N&&!this.journal.sessionCreated(x)){O++;continue}try{await this.restore("device-setting",x,H)}catch(q){if(e.warn(`Android cleaning could not restore setting ${x}`,q),await this.context.assertOwned(),this.context.signal.throwIfAborted(),C.set(x,H),qs(x))throw q}}if(C.size>0){let x=await this.readSettings(d,c),N=[...C].filter(([H,q])=>!gn(x.get(H)??{state:"absent"},q)).map(([H])=>H);if(N.length>0)throw new t(`Android cleaning settings remain dirty after failed restore: ${N.join(", ")}`)}}async cleanFiles(){for(let d of Ps){let c=`if [ -d ${S(d)} ]; then find ${S(d)} -type f -print; elif [ -e ${S(d)} ]; then exit 1; fi`,R=(await this.command(`shell sh -c ${S(c)}`)).split(`
33
+ `).filter(Boolean);for(let C of R){if(!C.startsWith(`${d}/`)||!Qe(C))throw new t("Android cleaning shared-file inventory is malformed");if(this.prior.get(`shared-file:${C}`)?.state!=="present")await this.restore("shared-file",C,{state:"absent"})}}}}var Aw=s({store:I("preference"),scope:I("systemProperty"),appId:ER(),suite:ER(),userId:ER(),key:n()}),Pw=s({value:n()}),Tw=/^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,255}$/;function xw(d){return d.startsWith("ro.")||d.startsWith("ctl.")||d==="sys.powerctl"}function yn(d){let c;try{c=JSON.parse(d)}catch(T){return e.debug("Preference journal key is not a JSON identity",T),null}let R=Aw.safeParse(c);if(!R.success)return null;let C=R.data.key;return Tw.test(C)&&!xw(C)?C:null}function ap(d){if(d.state==="absent")return"";if(d.state!=="present")return null;let c=Pw.safeParse(d.value);return c.success&&!/[\r\n\0]/.test(c.data.value)?c.data.value:null}class Ks{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>Nr)))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>Nr)throw new t("Android keep-booted capture requires a bounded preparation budget");let R=new AbortController,C=AbortSignal.any([c.signal,R.signal]),T=async()=>{C.throwIfAborted(),await c.assertOwned(),C.throwIfAborted()};try{await l(()=>this.captureSession(d,{...c,signal:C,assertOwned:T}),{timer:this.dependencies.timer,signal:C,timeoutMs:c.timeoutMs,label:"Android keep-booted baseline capture",onTimeout:()=>R.abort(new t("Android keep-booted capture budget exceeded"))})}catch(B){throw R.abort(B),await this.forget(c.resourceId),u(B,"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,C=this.sessions.get(c.resourceId),T=c.incarnation??c.resourceId;if(C&&(C.scope.deviceId!==d.deviceId||C.scope.incarnation!==T))throw new t("Android keep-booted resource changed emulator identity");let B={deviceId:d.deviceId,incarnation:T,sessionUuid:c.sessionId},O=await this.dependencies.journal.getBaseline(B),x=this.dependencies.port(d);if(this.sessions.set(c.resourceId,this.nextSession(B,C,O!==null)),!O){let N=new AbortController,H=AbortSignal.any([c.signal,N.signal]),q=Math.min(c.timeoutMs,this.budgetMs??c.timeoutMs);await l(()=>this.captureBaseline(x,B,{...c,signal:H,timeoutMs:q,assertOwned:async()=>{H.throwIfAborted(),await c.assertOwned(),H.throwIfAborted()}}),{timer:this.dependencies.timer,signal:H,timeoutMs:q,label:"Android keep-booted journal capture",onTimeout:()=>N.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 dn(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,C){let T=C.deadlineMs??this.dependencies.timer.now()+(C.timeoutMs??1/0),B=this.resetSession(d,C),O=this.dependencies.port(d),x=new AbortController,N=C.signal?AbortSignal.any([C.signal,x.signal]):x.signal,H=async()=>{N.throwIfAborted();let Y=pe(N);try{await U(Y,R)}catch(J){if(!Y?.aborted)x.abort(J);throw u(J,"Android keep-booted ownership fence failed")}N.throwIfAborted()},q={},G,W,V={scope:B.scope,deadlineMs:T,signal:N,assertOwned:H};try{await H();let Y=await this.whyEscalate(B,O,V,{context:C,phases:q});if(await H(),Y){W=Y;let J=this.dependencies.fallback;if(!J)throw new t(`Android keep-booted is non-clean (${Y}); baseline fallback or destruction is required`);e.warn(`Android keep-booted escalating to baseline (${Y})`);let X=Math.min(this.fallbackBudgetMs??Nr,T-this.dependencies.timer.now()-ws-1);if(X<=0)throw new t("Android keep-booted has no remaining fallback settlement budget");G={outcome:"pending",mode:"snapshot",phases:{}};let Z;try{await l(()=>(Z=this.measure("fallback",q,async()=>{let ee=J.fullBaseline?C.assertBindingOwned:H;if(!ee||J.fullBaseline&&!C.rebindIncarnation)throw new t("Android snapshot fallback requires incarnation rebinding");let oe=await J.reset(d,c,ee,{...C,signal:N,timeoutMs:X,assertOwned:ee,deadlineMs:this.dependencies.timer.now()+X,resetTiming:G});if(oe)G=oe;if(oe?.outcome==="pending")throw new t("Android snapshot fallback did not prove a clean reset");for(let[fe,ae]of Object.entries(G.phases))q[`snapshot:${fe}`]=ae;if(J.fullBaseline){let fe=await C.rebindIncarnation();await this.dependencies.journal.deleteResource(C.resourceId),B.scope={...B.scope,incarnation:fe},V.scope=B.scope,await this.captureBaseline(O,B.scope,{...C,incarnation:fe,signal:N,timeoutMs:X,assertOwned:H})}await H(),await this.measure("health",q,()=>C.healthCheck?.(V)??Promise.resolve()),await H()}),Z),{timer:this.dependencies.timer,signal:N,timeoutMs:X,label:"Android keep-booted fallback",onTimeout:()=>x.abort(new t("Android keep-booted fallback budget exceeded"))})}catch(ee){throw x.abort(ee),ee}finally{await this.drainOperation(Z)}await H(),this.dependencies.recordingGaps?.clear(V.scope.sessionUuid),B.uses=0;let re=G.mode;return{outcome:re==="wipe-data"?"fallback:wipe-data":"fallback:snapshot",mode:re,phases:q,fallbackReason:[Y,G.fallbackReason].filter(Boolean).join("; ")}}return await H(),{outcome:"clean",mode:"keep-booted",phases:q}}catch(Y){throw x.abort(Y),e.warn(`Android keep-booted reset failed: ${r(Y)}`,Y),this.resetFailure(Y,q,G,W)}}async whyEscalate(d,c,R,{context:C,phases:T}){if(d.uses>=this.maxUses)return"maxUses retirement";if(C.opaquePersistentChanges)return"opaque persistent changes (deviceSnapshot) cannot be journal-reverted";let B=this.dependencies.recordingGaps?.reasonFor(R.scope.sessionUuid);if(B!==void 0)return`device mutation recording failed (${B}); journal is incomplete`;let O=await this.dependencies.journal.listStrayIncarnations(R.scope);if(O.length>0)return`journaled mutations recorded under a different incarnation (${O.length}) cannot be journal-reverted`;let x=await this.dependencies.journal.list(R.scope),N=x.find((q)=>Xb(q)&&!(C.foldPostureRestored&&q.key===_n(...A8)));if(N)return`opaque journaled mutation (${N.toolName}) cannot be journal-reverted`;let H=x.filter((q)=>q.kind==="preference"&&!oG.includes(q.key)&&!dp(q,c));if(H.length>0){let q;try{q=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 G=H.find((W)=>!w1(W,q));if(G)return`journaled ${G.kind} (${G.toolName}) cannot be baseline-cleaned`}return await this.unrevertibleReason(x,c,R.scope)??this.cleanWithDeadline(c,R,C,T)}async unrevertibleReason(d,c,R){let C=d.filter((O)=>O.kind!=="opaque"&&O.kind!=="preference"&&!Us(O)&&!c.canRevert(O)),T=null;if(C.some((O)=>O.kind==="shared-file"||O.kind==="media"))try{T=await this.dependencies.journal.getBaseline(R)}catch(O){return e.warn("Android file baseline is unreadable; baseline fallback required",O),"journaled files have an unreadable baseline"}let B=C.find((O)=>!np(O,T));return B?`journaled mutation ${B.kind}:${B.key} (${B.toolName}) cannot be journal-reverted`:void 0}resetFailure(d,c,R,C){if(d instanceof wi)R=d.reset;for(let[T,B]of Object.entries(R?.phases??{}))c[`snapshot:${T}`]=B;return new wi(u(d,"Android keep-booted requires baseline fallback or destruction").message,{outcome:"pending",mode:R?.mode??"keep-booted",phases:c,fallbackReason:[C,R?.fallbackReason].filter(Boolean).join("; ")||void 0},{cause:d instanceof wi?d.cause:d})}async measure(d,c,R){let C=this.dependencies.timer.now();try{await R()}finally{c[d]=this.dependencies.timer.now()-C}}async cleanWithDeadline(d,c,R,C){let T=(R.deadlineMs??this.dependencies.timer.now()+(R.timeoutMs??Nr))-this.dependencies.timer.now(),B=this.dependencies.fallback?Math.floor(T/3):T,O=Math.min(T,Nr,this.budgetMs??Math.max(cn,B));if(O<=0)return"Android keep-booted cleaning budget exceeded";let x=new AbortController,N=AbortSignal.any([c.signal,x.signal]),H={...c,deadlineMs:this.dependencies.timer.now()+O,signal:N,assertOwned:async()=>{N.throwIfAborted(),await U(N,c.assertOwned),N.throwIfAborted()}},q;try{await l(()=>(q=this.clean(d,H,R,C),q),{timer:this.dependencies.timer,signal:N,timeoutMs:O,label:"Android keep-booted cleaning",onTimeout:()=>x.abort(new t("Android keep-booted cleaning budget exceeded"))});return}catch(G){return x.abort(G),e.warn("Android keep-booted cleaning failed",G),r(G)}finally{await this.drainOperation(q)}}async drainOperation(d){await l(Promise.allSettled(d?[d]:[]),{timer:this.dependencies.timer,timeoutMs:ws,label:"Android keep-booted command settlement"})}async clean(d,c,R,C){let T=await this.dependencies.journal.getBaseline(c.scope);if(!T)throw new t("Android keep-booted baseline is missing");await c.assertOwned();let B=[];await this.measure("journal",C,async()=>{B=await this.dependencies.journal.list(c.scope),await this.replayJournal(d,c,T,B)}),await this.measure("clean",C,()=>d.cleanBaseline(T,c,B)),await c.assertOwned(),await this.measure("health",C,()=>R.healthCheck?.(c)??Promise.resolve()),await c.assertOwned()}async replayJournal(d,c,R,C){for(let T of[...C].sort((B,O)=>O.sequence-B.sequence)){await c.assertOwned();let B=T.kind==="installed-app"&&T.priorValue.state==="absent"&&R.observations.some((O)=>O.kind===T.kind&&O.key===T.key&&O.value.state==="present");if(!_w(T,d)||B){e.warn(`Android keep-booted skipped journal revert ${T.kind}:${T.key}`);continue}try{await d.revert(T,c)}catch(O){if(e.warn(`Android keep-booted journal revert failed ${T.kind}:${T.key}`,O),await c.assertOwned(),T.kind!=="device-setting"||!Us(T)||qs(T.key)||yP(T.key)!==null)throw O}}}}function _w(d,c){return d.kind==="preference"?dp(d,c):c.canRevert(d)}function dp(d,c){return d.kind==="preference"&&yn(d.key)!==null&&c.canRevert(d)}function yi(d){return d.priorValue.state==="present"?d.priorValue.value:void 0}var Gs=(d)=>d?"enable":"disable",cp={airplaneMode:(d)=>`shell cmd connectivity airplane-mode ${Gs(d)}`,wifiEnabled:(d)=>`shell svc wifi ${Gs(d)}`,bluetoothEnabled:(d)=>`shell svc bluetooth ${Gs(d)}`,locationEnabled:(d)=>`shell cmd location set-location-enabled ${d}`},Nw=p(["off","none","priority","alarms"]),mp=s({level:a().int().min(0).max(100),charging:p(dD),faked:h()}),fp=s({status:a().int().min(0).max(6),override:h()});function $w(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 Hw(d){let c=mp.safeParse(d);if(!c.success)return null;let{level:R,charging:C,faked:T}=c.data;return(T?[...$w(C),`shell dumpsys battery set level ${R}`]:["shell dumpsys battery reset"]).map((B)=>({command:B}))}function qw(d){let c=p(fk).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 Uw(d){let c=fp.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 Kw(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 Gw(d,c){if(d.field==="inactive")return typeof c==="boolean"?[{command:`shell am set-inactive ${S(d.appId)} ${c}`}]:null;let R=p(lD).safeParse(c);return R.success?[{command:`shell am set-standby-bucket ${S(d.appId)} ${R.data}`}]:null}function hp(d,c){let R=yi(c);switch(d.field){case"battery":return Hw(R);case"doze":return qw(R);case"thermal":return Uw(R);case"dataSaver":return typeof R==="boolean"?[{command:`shell cmd netpolicy set restrict-background ${R}`}]:null;case"batterySaver":return Kw(c,R);case"standby":case"inactive":return Gw(d,R)}}function Ww(d){let c=mp.parse(d);return async(R)=>{let C=await R.readBattery();return(c.faked?C.level===c.level&&C.charging===c.charging:!C.faked)?null:"battery differs from its prior state"}}function Vw(d){let c=fp.parse(d);return async(R)=>{let C=await R.readThermal();return(c.override?C.override&&C.status===c.status:!C.override)?null:"thermal override differs from its prior state"}}function Jw(d){let c=p(fk).parse(d);return async(R,C)=>{let T,B=await hk({readDoze:async()=>{try{return await R.readDoze()}catch(O){throw T=u(O,"Android reset could not read back device state"),T}}},c,{...C,reading:await R.readDoze()});if(T)throw T;return B.settled?null:`Doze is ${B.reading.mode}, expected ${c}`}}function jw(d,c){switch(d.field){case"battery":return Ww(c);case"thermal":return Vw(c);case"doze":return Jw(c);case"dataSaver":return async(R)=>await R.readDataSaver()===c?null:"Data Saver differs from its prior state";case"batterySaver":return async(R)=>{let C=await R.readBatterySaver();return(c===void 0?(C??!1)===!1:C===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 gp(d){if(d.kind!=="device-setting")return null;let c=yP(d.key);return c&&hp(c,d)!==null?jw(c,yi(d)):null}function vp(d){let c=yi(d);if(Object.hasOwn(cp,d.key))return typeof c==="boolean"?[{command:cp[d.key](c)}]:null;if(d.key==="doNotDisturb"){let C=Nw.safeParse(c);return C.success?[{command:`shell cmd notification set_dnd ${C.data}`}]:null}let R=yP(d.key);return R?hp(R,d):null}var zw=s({delayMs:a().min(0).optional(),downloadKbps:a().min(0).optional(),uploadKbps:a().min(0).optional()});function Sp(d){let c=zw.safeParse(yi(d));if(d.key!=="device"||!c.success)return null;let{delayMs:R=0,downloadKbps:C=0,uploadKbps:T=0}=c.data,B=R>0?`${R}:${R}`:"none",O=C>0||T>0?`${T}:${C}`:"full";return[{command:`emu network delay ${B}`,success:"OK"},{command:`emu network speed ${O}`,success:"OK"},{command:"emu gsm data on",success:"OK"},{command:"shell svc wifi enable"}]}var Yw=s({instant:n().refine((d)=>Number.isFinite(Date.parse(d))),automaticTime:h()});function bp(d,c){let R=Yw.safeParse(yi(d));if(d.key!=="device"||!R.success)return null;let C=Math.floor(c/1000),T=Math.ceil(ll/1000),B=[`cur=$(date +%s); diff=$((cur - ${C}))`,`if [ "$diff" -gt ${T} ] || [ "$diff" -lt -${T} ]; then settings put global auto_time 0 && date -u @${C}; fi`,`settings put global auto_time ${R.data.automaticTime?1:0}`].join("; ");return[{command:`shell sh -c ${S(B)}`}]}var Dp={fontScale:["system:font_scale"],timeFormat:["system:time_12_24"],textDirection:["global:debug.force_rtl","global:force_rtl"],increaseContrast:["secure:high_text_contrast_enabled"],reduceMotion:xM.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"]},Xw=/^[+]?(?:\d+(?:\.\d*)?|\.\d+)$/;function Qw(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((C)=>C==="null"||Xw.test(C))?R.map((C)=>C==="null"?null:C):null}function tR(d,c,R){if(c.state==="absent")return Array.from({length:R},()=>null);if(c.state!=="present")return null;if(d==="fontScale")return Qw(c.value);if(d==="timeFormat")return c.value==="12"||c.value==="24"?[c.value]:null;return Zw(c.value,R)}function kp(d){if(!Object.hasOwn(Dp,d.key))return null;let c=Dp[d.key],R=tR(d.key,d.priorValue,c.length);return R?c.map((C,T)=>{let B=R[T];return{kind:"device-setting",key:C,priorValue:B===null?{state:"absent"}:{state:"present",value:B},toolName:d.toolName}}):null}var Ap="posted-notifications-cancelled",rR=1e4,Si=/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/;class Vs{adb;timer;dozeBackoff;certifiableKinds=mn;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)??vp(d),clock:(d)=>this.timezoneCommands(d)??this.settingCommands(d)??bp(d,this.timer.now()),"network-condition":(d)=>Sp(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=te({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,C=d.kind==="installed-app"&&d.key.startsWith("identity:")?d.key.slice(9):R?.[2];if(d.priorValue.state==="absent"&&C){let B=c.find((O)=>O.kind==="installed-app"&&O.priorValue.state==="absent"&&/^user:\d+:/.test(O.key)&&(!R||O.key.startsWith(`user:${R[1]}:`))&&O.key.endsWith(`:${C}`));if(B)return{kind:B.kind,key:B.key,priorValue:B.priorValue,toolName:"baseline-diff"}}let T={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(T)?T:on(d)}capture(d){return Qu((c,R)=>this.execute(c,d,{timeoutMs:R}))}async cleanBaseline(d,c,R=[]){await op(d,c,(T,B)=>this.execute(T,c,{timeoutMs:B}),{revert:(T)=>this.revert(T,c),journalEntries:R});let C=await this.execute("shell cmd clipboard clear",c,{optionalClipboard:!0});if(this.unsupportedClipboard(C))e.warn("Android cleaning skipped unsupported clipboard clear");else if(this.failedOutput(C))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 Ke(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:C,success:T,confirms:B,timeoutMs:O,retryable:x,wakeSleptScreen:N}of R){let H=await this.execute(C,c,{timeoutMs:O,optionalClipboard:d.kind==="clipboard",retryable:x});if(d.kind==="clipboard"&&this.unsupportedClipboard(H)){e.warn("Android cleaning skipped unsupported journal clipboard clear");continue}if(!this.confirmed(H,{success:T,confirms:B}))throw new t("Android reset command failed to confirm success");if(N)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 pk({execute:async(c)=>eW(await this.execute(c.map(Vo).join(" "),d),""),isScreenOn:async()=>/mWakefulness=Awake/.test(await this.execute("shell dumpsys power | grep mWakefulness=",d))})}async wakeBeforeReadBack(d){try{await Y1({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=gp(d);if(!R)return;let C=this.powerClient(c),T;try{T=await U(c.signal,()=>R(C,{timer:this.timer,backoff:this.dozeBackoff,budgetMs:c.deadlineMs===void 0?3000:Math.max(0,Math.min(3000,c.deadlineMs-this.timer.now()))}))}catch(B){throw u(B,"Android reset could not read back device state")}if(T!==null)throw new t(`Android reset could not confirm ${d.key} was restored: ${T}`)}async packageAbsent(d,c){let R=/^user:(\d+):(.+)$/.exec(d);if(!R)throw new t("Android reset requires a user-scoped package key");let C=await this.execute(`shell pm list packages --user ${R[1]}`,c);if(!ko(C,"android")||C.split(`
34
+ `).some((T)=>!/^package:[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/.test(T.trim())))throw new t("Android reset cannot confirm package absence");return!ko(C,R[2])}async execute(d,c,{timeoutMs:R=2000,optionalClipboard:C=!1,retryable:T=!0}={}){try{let B=async(x)=>(await c.assertOwned(),c.signal.throwIfAborted(),this.adb.executeCommand(d,{signal:c.signal,timeoutMs:x,maxBuffer:4194304,noRetry:!0,waitForProcessSettlementAfterAbort:!0})),O=c.deadlineMs===void 0?await B(R):await xt((x)=>B(T?x:Math.min(c.deadlineMs-this.timer.now(),Math.max(R,pt(c.deadlineMs-this.timer.now(),3)))),{timer:this.timer,deadlineMs:c.deadlineMs,signal:c.signal,label:"Android reset command",minAttemptMs:R,attempts:T?void 0:1});if(c.signal.throwIfAborted(),await c.assertOwned(),C&&this.unsupportedClipboard(`${O.stdout}
35
+ ${O.stderr}`))return`${O.stdout}
36
+ ${O.stderr}`;if(O.error||O.stderr.trim())throw new t("Android reset command failed");return O.stdout.replace(/\r?\n$/,"")}catch(B){throw u(B,"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&&Si.test(R[2])?[{command:`shell am force-stop --user ${R[1]} ${S(R[2])}`},{command:`shell pm uninstall --user ${R[1]} ${S(R[2])}`,retryable:!1,success:"Success",timeoutMs:1e4}]:null}runtimePermissionCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0,C=/^runtime:(\d+):([A-Za-z0-9_.]+):([A-Za-z0-9_.]+)$/.exec(d);return C&&Si.test(C[2])&&typeof R==="boolean"?[{command:`shell pm ${R?"grant":"revoke"} --user ${C[1]} ${S(C[2])} ${S(C[3])}`}]:null}appOpsCommands({key:d,priorValue:c}){let R=c.state==="present"?c.value:void 0,C=c.state==="absent",T=/^appops:(\d+):([A-Za-z0-9_.]+):([A-Za-z0-9_]+)$/.exec(d);return T&&Si.test(T[2])&&(C||typeof R==="string"&&["allow","ignore","deny","default","foreground"].includes(R))?[{command:`shell cmd appops set --user ${T[1]} ${S(T[2])} ${S(T[3])} ${C?"default":R}`}]:null}settingCommands(d){let{key:c,priorValue:R}=d,C=R.state==="present"?R.value:void 0,T=R.state==="absent",B=/^(global|secure|system):(?:(?:user:(\d+)):)?(?!user:)([A-Za-z0-9_][A-Za-z0-9_.:-]*)$/.exec(c);if(!B||!T&&typeof C!=="string")return null;if(["global:airplane_mode_on","global:wifi_on","global:mobile_data","global:zen_mode"].includes(c)&&!T)return this.connectivityCommands(d);return[{command:T?`shell settings --user ${B[2]??"0"} delete ${B[1]} ${B[3]}`:`shell settings --user ${B[2]??"0"} put ${B[1]} ${B[3]} ${S(C)}`}]}settingsBackedCommands(d){let c=kp(d);if(!c)return null;let R=c.map((C)=>this.settingCommands(C));return R.every((C)=>C!==null)?R.flat():null}appLocaleCommands({key:d,priorValue:c}){let R=y1(d),C=b8(c);if(R===null||!Si.test(R)||!C)return null;let{userId:T,locales:B}=C;return[{command:`shell cmd locale set-app-locales ${S(R)} --user ${T} --locales ${S(B)}`,success:""},{command:`shell cmd locale get-app-locales ${S(R)} --user ${T}`,success:`Locales for ${R} for user ${T} are [${B}]`}]}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 T={"0":"off","1":"priority","2":"none","3":"alarms"};return Object.hasOwn(T,R)?[{command:`shell cmd notification set_dnd ${T[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),C=c.state==="present"?c.value:void 0,T=c.state==="absent";return T||typeof C==="string"&&(R==="density"?/^\d+$/:/^\d+x\d+$/).test(C)?[{command:`shell wm ${R} ${T?"reset":C}`}]:null}screenStateCommands({key:d,priorValue:c}){return d===Cb&&w8(c)?[{command:"shell input keyevent KEYCODE_WAKEUP"},{command:"shell wm dismiss-keyguard"}]:null}volumeCommands({key:d,priorValue:c}){let R=R8(d,c);return R===null?null:[{command:`shell sh -c ${S(R)}`,success:nG,timeoutMs:rR}]}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 ${S(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&&Si.test(R[2])?[{command:`shell am force-stop --user ${R[1]} ${S(R[2])}`},{command:`shell pm clear --user ${R[1]} ${S(R[2])}`,retryable:!1,success:"Success"}]:null}systemPropertyCommands({key:d,priorValue:c}){let R=yn(d),C=ap(c);return R===null||C===null?null:[{command:`shell setprop ${R} ${S(C)}`,success:""},{command:`shell getprop ${R}`,success:C}]}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 ${S(R)}`}]}postedNotificationCommands({key:d}){let c=S8(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 ${S(`|${c}|`)}; then exit 1; fi`,`echo ${Ap}`].join("; ");return[{command:`shell am force-stop ${S(c)}`},{command:`shell sh -c ${S(R)}`,success:Ap}]}notificationChannelCommands({key:d,priorValue:c}){let R=FE(d);if(R===void 0||c.state!=="absent")return null;let C=(T)=>v1(T)==="absent";return[{command:lM(R,"delete"),confirms:C},{command:lM(R,"query"),confirms:C},{command:`shell am force-stop ${S(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 ${S(d)}) && [ "$target" = "$root"${S(d.slice(7))} ] && [ ! -L ${S(d)} ] && rm -f -- ${S(d)}`;return[{command:`shell sh -c ${S(R)}`},{command:`shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d ${S(`file://${d}`)}`}]}}import{readFile as dR,rm as cR}from"fs/promises";import{resolve as Pp}from"path";class Js{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 C=await R("identity",(B)=>this.port.identity(d,B)),T=this.baselines.get(c.resourceId);if(T?.deviceId===d.deviceId&&this.matches(T.identity,C))return;if(c.fresh!==!0)throw new t("Android baseline capture requires a freshly created emulator, not unqualified adoption");if(this.forget(c.resourceId),T)await R("invalidate",(B)=>this.port.snapshot("delete",d,B));await this.save(d,c.resourceId,C,R)})}reset(d,c,R,C){let T=C.resetTiming??{outcome:"pending",mode:"snapshot",phases:{}};return T.mode="snapshot",this.bounded({...C,assertOwned:R,resetTiming:T},async(B)=>{let O=this.baselines.get(C.resourceId);try{if(C.opaquePersistentChanges)throw new t("Android session made opaque persistent changes a snapshot load cannot revert");let N=await B("identity",(H)=>this.port.identity(d,H));if(!O||O.deviceId!==d.deviceId||!this.matches(O.identity,N))throw new t("Android snapshot baseline is missing or incompatible");return await this.changeIncarnation(d,B,async(H)=>{await B("load",(G)=>this.port.snapshot("load",d,G)),await H(),await B("restore readiness",(G)=>this.port.waitForRestore(d,G)),await B("health",(G)=>this.port.health(d,G));let q=await B("restored identity",(G)=>this.port.identity(d,G));if(!this.matches(N,q))throw new t("Android snapshot restored an incompatible identity")}),T.outcome="clean",T}catch(N){e.warn("Android snapshot reset unavailable; attempting wipe-data replacement",N),T.mode="wipe-data",T.fallbackReason=r(N)}if(this.forget(C.resourceId),O)try{await B("invalidate",(N)=>this.port.snapshot("delete",d,N))}catch(N){e.warn("Android baseline invalidation failed; never reload it, require wipe-data",N)}let x;try{if(await B("reserve replacement boot",async(H)=>{x=await this.port.reserveBoot({replacingDeviceId:d.deviceId,signal:H.signal,timeoutMs:H.timeoutMs});try{await H.assertOwned()}catch(q){throw x.release(),u(q,"Android replacement boot lost ownership")}}),!x)throw new t("Android replacement boot was not reserved");let N=x;await N.run(()=>this.replace(d,C.resourceId,B,N))}finally{x?.release()}return T.outcome="fallback:wipe-data",T})}replace(d,c,R,C){return this.changeIncarnation(d,R,async(T)=>{await R("stop",(O)=>this.port.stop(d,O)),await T(),C.markReplacedDeviceGone(),await R("wipe-data launch",(O)=>this.port.launchWiped(d,O)),await R("readiness",(O)=>this.port.ready(d,O)),await R("wipe-data health",(O)=>this.port.health(d,O));let B=await R("wipe-data identity",(O)=>this.port.identity(d,O));await this.save(d,c,B,R)})}async changeIncarnation(d,c,R){let C=!1,T=!1,B=!1,O=async()=>{if(!B)B=!0,await this.incarnation.invalidate(d)};try{await c("prepare incarnation",async()=>{C=!0,await this.incarnation.prepareForIncarnationChange(d)}),await R(O),T=!0}finally{if(C)try{await O()}finally{await this.incarnation.settleIncarnationChange(d,{ready:T})}}}async save(d,c,R,C){await C("save",(B)=>this.port.snapshot("save",d,B));let T=await C("saved identity",(B)=>this.port.identity(d,B));if(!this.matches(R,T))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,C=new AbortController,T=d.signal?AbortSignal.any([C.signal,d.signal]):C.signal,B=d.timeoutMs??0,O=this.timer.now()+B,x=async()=>{T.throwIfAborted(),await d.assertOwned?.(),T.throwIfAborted()},N=async(H,q)=>{let G=this.timer.now();try{let W=O-this.timer.now();if(W<=0)throw new t("Android snapshot reset deadline exceeded");return await l(async()=>{await x();let V=await q({signal:T,timeoutMs:W,assertOwned:x});return await x(),V},{timer:this.timer,timeoutMs:W,signal:T,label:`Android snapshot ${H}`,timeoutError:()=>new t("Android snapshot reset deadline exceeded"),onTimeout:()=>C.abort(new t("Android snapshot reset deadline exceeded"))})}finally{if(R)R.phases[H]=(R.phases[H]??0)+this.timer.now()-G}};try{if(!Number.isFinite(B)||B<=0||!d.assertOwned)throw new t("Android snapshot reset requires a finite positive deadline");return await c(N)}catch(H){if(C.abort(H),R)throw new wi(u(H,"Android snapshot baseline reset failed; destroy required").message,{...R,outcome:"pending"},{cause:H});throw u(H,"Android snapshot baseline reset failed; destroy required")}}}var oR=2,sR=te({initialDelayMs:500,multiplier:2,maxDelayMs:2000});async function Ip(d,c){let{stopper:R,timer:C,signal:T,deadlineMs:B,assertOwned:O}=c,x=0;for(let N=1;;N++){await l(C.sleep(sR.delayForAttempt(N)),{timer:C,signal:T,label:"Android emulator liveness watch"}),await O();try{let H=await R.identify(d,{signal:T,deadlineMs:B});x=H.kind==="absent"||H.kind==="mismatch"?x+1:0}catch(H){T.throwIfAborted(),e.debug(`Android emulator liveness probe failed: ${r(H)}`),x=0}if(x>=oR)throw new t(`Android emulator process for ${d.serial} (${d.avdName}) exited during snapshot restore`)}}import{createHash as aR}from"crypto";class js{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 C=await this.dependencies.imageMetadata(R.systemImagePath,c.signal);await c.assertOwned();let T=await this.retryStep(c,async(O)=>(await c.assertOwned(),this.dependencies.emulator.executeCommand(["-version"],O,c.signal)));if(await c.assertOwned(),T.error||!T.stdout.trim())throw new t("Android baseline lacks emulator version");let B=await this.dependencies.readiness.ctrlProxyIdentity(d,c.signal);return await c.assertOwned(),{avdName:d.name,systemImage:`${R.systemImagePackage}:${aR("sha256").update(C).update(JSON.stringify(R.hardware??{})).digest("hex")}`,emulatorVersion:T.stdout.trim(),ctrlProxyVersion:B}}async snapshot(d,c,R){R=this.remainingStep(R),await this.dependencies.console.runExclusive(c.deviceId,async()=>{let C=await this.dependencies.adb.create(c).execute(cg(d,R6).split(" "),{timeoutMs:R.timeoutMs,signal:R.signal,noRetry:!0,waitForProcessSettlementAfterAbort:!0,beforeDispatch:()=>this.assertTarget(c,R,!0)});R.signal.throwIfAborted();let T=dg(d,R6,C);if(!T.ok&&!(d==="delete"&&hB(T.errorMessage)))throw new t(T.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 T=await this.fencedAdb(d,c).executeCommand("shell getprop sys.boot_completed");if(T.stdout.trim()!=="1"||Ke(T.stdout,T.stderr))throw new t("Android snapshot target has not completed boot");if(!(await this.dependencies.clockRegistry.runExclusive(d.deviceId,async(O,x)=>{await this.assertTarget(d,c);let N=AbortSignal.any([c.signal,x]),H=new lp(this.fencedAdb(d,{...c,signal:N,timeoutMs:R-this.dependencies.timer.now()}),N),q=await H.ensureRoot();if(!q.success)throw new t(q.error);return cD(d,H,{initialAutomaticTime:1,clockChangedByUs:!0,rootedByUs:q.rootedByUs},{hostClock:this.dependencies.timer,invalidate:this.dependencies.invalidate,mutationSignal:N})})).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 C=this.dependencies.timer,T=un(C,R),B=new AbortController,O=AbortSignal.any([c.signal,B.signal]),x=()=>new t("Android snapshot CtrlProxy health check failed");return l(()=>pn(async(N)=>{await c.assertOwned();let H=await this.dependencies.ctrlProxyReady(d,{signal:O,timeoutMs:N,noRetry:!0});return await c.assertOwned(),H},{timer:C,deadlineMs:T,signal:O,label:"Android snapshot CtrlProxy health check"}),{timer:C,signal:c.signal,timeoutMs:Math.max(0,T-C.now()),label:"Android snapshot CtrlProxy health check",timeoutError:x,onTimeout:()=>B.abort(x())})}async stop(d,c){c=this.remainingStep(c);let R=this.dependencies.timer.now()+c.timeoutMs;await this.assertTarget(d,c);let C=await this.dependencies.processStopper.identify({serial:d.deviceId,avdName:d.name},{signal:c.signal,deadlineMs:R});if(await c.assertOwned(),C.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 T,B=()=>pt(R-this.dependencies.timer.now(),2),O=()=>{if(this.dependencies.timer.now()>=R)throw new t("Android reset emulator process did not exit before the deadline"+(T===void 0?"":`: ${r(T)}`))};for(;;){await c.assertOwned(),c.signal.throwIfAborted(),O();let x=!1;try{if(!(await this.dependencies.inventory({signal:c.signal,timeoutMs:B(),targetDeviceId:d.deviceId})).some((H)=>H.deviceId===d.deviceId||H.name===d.name)&&this.dependencies.timer.now()<R)x=!(await this.dependencies.emulator.getListedNonDeviceStatesAmong([d.deviceId],{signal:c.signal,timeoutMs:B()})).has(d.deviceId)}catch(N){c.signal.throwIfAborted(),e.debug("Android reset exit inventory poll failed; continuing to wait",N),T=N}if(await c.assertOwned(),c.signal.throwIfAborted(),O(),x&&await this.processExited(d,c,R))return;O(),await this.dependencies.timer.sleep(Math.min(100,R-this.dependencies.timer.now()))}}async processExited(d,c,R){let C=await this.dependencies.processStopper.identify({serial:d.deviceId,avdName:d.name},{signal:c.signal,deadlineMs:R});if(await c.assertOwned(),C.kind==="absent")return await this.dependencies.clearQuickBoot(d,c),await c.assertOwned(),!0;if(C.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:C}=this.dependencies,T=new AbortController,B=AbortSignal.any([c.signal,T.signal]),O=R.now()+c.timeoutMs;try{await l([this.dependencies.emulator.waitForEmulatorReady(d.name,c.timeoutMs,null,{targetDeviceId:d.deviceId,signal:B,options:{skipWakeAndUnlock:!0}}),Ip({serial:d.deviceId,avdName:d.name},{stopper:C,timer:R,signal:B,deadlineMs:O,assertOwned:c.assertOwned})],{timer:R,signal:c.signal,label:"Android snapshot restore readiness"})}finally{T.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:(C,T)=>{let B=C.startsWith("shell date -u @");return this.retryStep(c,async(O)=>{await c.assertOwned(),c.signal.throwIfAborted();let x=c.timeoutMs,N=await R.executeCommand(C,{...T,timeoutMs:B?Math.min(x,Math.max(T?.timeoutMs??0,pt(x,3))):O,signal:c.signal,noRetry:!0,beforeDispatch:()=>c.assertOwned()});return await c.assertOwned(),N},{minAttemptMs:T?.timeoutMs,attempts:B?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 xt(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 C=await this.retryStep(c,async(T)=>(await c.assertOwned(),this.dependencies.emulator.resolveAvdNameForSerial(d.deviceId,{signal:c.signal,timeoutMs:T,consoleExclusiveOwner:R,throwOnTimeout:!0})));if(await c.assertOwned(),C!==d.name)throw new t("Android snapshot reset serial no longer hosts its owned AVD")}}function lR(d){return{recordingGaps:d.recordingGaps??new no,lock:d.hostLock??Il(d.owner)}}async function Tp(d){let{recordingGaps:c,lock:R}=lR(d);R.acquire();let C;try{let T=Cd(vy);await TR(d.registry,T),await CR(d,T);let B=await d.registry.ensureScope(vy);if(B.kind!=="ready")throw new t(`Session broker's private ownership scope is unavailable: ${B.kind}`);let O=d.registry.sessionBrokerStore(T),x=iN(d.config),N=d.registry.deviceMutationJournal(),H=RR(d.config,d.androidReset,d.timer,{journal:N,recordingGaps:c}),q=H?.ios,G=q?(Z,re,ee,{signal:oe,context:fe}={})=>{let ae=()=>q.resetWithTiming(Z,re,ee,oe);return fe?.runResetBoot?fe.runResetBoot(ae):ae()}:void 0,W;if(q)({resetIosBaseline:G,captureIosBaseline:W}=gR(d,x,{erase:q,journal:N,recordingGaps:c,store:O},G));let V=d.mutationSessions?(Z)=>{let re=d.mutationSessions.peekSession(Z.sessionUuid);if(!re||re.sessionId!==Z.sessionUuid||re.assignedDevice!==Z.deviceId)throw new t("Broker mutation scope must match the live native session and device");re.mutationRecorder=new es(N,Z)}:void 0,Y=new ts({androidConfigReader:new Kr,scope:vy,timer:d.timer,leaseKeepalive:BR(d),brokerDeviceAcquisition:d.acquisition,brokerExecutionRelease:d.release,registry:d.registry,bindingJournal:d.journal,bindMutationRecorder:V,...H?{resetBaseline:{ios:G,android:H.android,watch:H.watch},captureIosBaseline:W,isCurrentReset:(Z)=>PR(O,Z)}:{}});C=new OG({store:O,devices:Y,timer:d.timer,owner:d.owner,limits:d.config.limits,catalog:d.catalog??ql(d.config),defaults:(Z)=>{let re=d.config.defaults[Z];if(!re)throw new t(`Session-broker execution is not configured for ${Z} on this host`);return re},sessionDisposition:d.sessionDisposition,reuseCleanDevices:x.mode!=="off",reuseAndroidCleanDevices:d.config.reuseAndroidCleanDevices,idleTtlMs:{android:d.config.androidIdleTtlMs}}),await C.recoverReceipts();let J=(Z)=>hR(d,O,T,{bindMutationRecorder:V,sessionUuid:Z});await pR(O,J,c);let X=new Mp(C,T,R,{timer:d.timer,avdSnapshotCleanup:to(d.avdSnapshotCleanup,d.registry,d.timer),mutations:{recordingGaps:c,recorderFor:J}});if(!d.deferStart)X.start();return X}catch(T){throw await uR(C,R),u(T,"Session broker startup failed")}}async function uR(d,c){try{await d?.close()}catch(R){e.warn("Failed to close broker after startup failure",R)}finally{c.release()}}async function pR(d,c,R){let C;try{C=await d.listRecoverableRequests()}catch(T){e.warn("Cannot list recoverable session requests for mutation recorder recovery",T);return}for(let T of C){if(T.state!=="active"||!T.sessionId)continue;try{await c(T.sessionId)}catch(B){R.mark(T.sessionId,`recorder recovery: ${r(B)}`),e.warn(`Cannot recover mutation recorder for session ${T.sessionId}`,B)}}}async function fR(d,c){let R=await d.getSession(c);if(R?.state!=="active"||!R.resourceId)return"not-recordable";let C=await d.getResource(R.resourceId);return C&&In(C).platform==="watchos"?"not-recordable":C}async function hR(d,c,R,{bindMutationRecorder:C,sessionUuid:T}){if(!C||!d.mutationSessions)return;let B=d.mutationSessions.peekSession(T);if(!B)return;let O=await fR(c,T);if(O==="not-recordable")return;let x=O?await d.registry.getAssignment({scopeKey:R,bindingIndex:O.allocationIndex}):null;wR(x,T,B.stableDeviceId??B.assignedDevice),C(SR(T,B.assignedDevice,O,x));let N=d.mutationSessions.peekSession(T)?.mutationRecorder;if(!N)throw new t("Broker mutation recorder recovery did not attach a recorder to the active session");return N}function gR(d,c,R,C){let{erase:T,journal:B,recordingGaps:O,store:x}=R;if(c.mode==="keep-booted")return vR(d,c,T,{journal:B,recordingGaps:O,store:x});if(c.mode==="minimal")return{resetIosBaseline:yR(d,c.maxUses,B,{recordingGaps:O,store:x}),captureIosBaseline:void 0};return{resetIosBaseline:C,captureIosBaseline:void 0}}function vR(d,c,R,{journal:C,recordingGaps:T,store:B}){let O=bs(new F(null),d.timer),x=new ss({recordingGaps:T,journal:C,mutations:O,simctl:new F(null),timer:d.timer,health:Gu(d.timer),erase:R,maxUses:c.maxUses,fallback:c.fallback,budgetMs:$s(g.IOS_RESET_STEP_BUDGET_MS),budgetCeilingMs:$s(g.IOS_RESET_STEP_BUDGET_MAX_MS)});return{captureIosBaseline:(N)=>dn(C,O,N),resetIosBaseline:async(N,H,q,{signal:G,context:W}={})=>{let V=W?.resource.requestId?await B.getRequest(W.resource.requestId):void 0;if(!W||!V?.sessionId)throw new t("iOS keep-booted reset requires its durable released session identity");return x.resetWithTiming(N,H,q,{scope:{...W.scope,sessionUuid:V.sessionId},reuseCount:W.resource.reuseCount??0,signal:G,runResetBoot:W.runResetBoot})}}}function yR(d,c,R,{recordingGaps:C,store:T}){let B=new F(null),O=new as({recordingGaps:C,journal:R,mutations:bs(B,d.timer),simctl:B,timer:d.timer,maxUses:c,budgetMs:$s(g.IOS_RESET_STEP_BUDGET_MS)});return async(x,N,H,{signal:q,context:G}={})=>{let W=G?.resource.requestId?await T.getRequest(G.resource.requestId):void 0;if(!G||!W?.sessionId)throw new t("iOS minimal reset requires its durable released session identity");return O.resetWithTiming(x,N,H,{scope:{...G.scope,sessionUuid:W.sessionId},reuseCount:G.resource.reuseCount??0,signal:q})}}function SR(d,c,R,C){if(!R)throw new t("Recovered broker session has no resource");return Zi({platform:In(R).platform,sessionUuid:d,resource:R,stableDeviceId:C.stableDeviceId??c,transportId:c,assignmentGeneration:C.generation,bootId:null})}function wR(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 RR(d,c,R,{journal:C,recordingGaps:T}){if(d.reuseAndroidCleanDevices&&d.defaults.android&&!c)throw new t("Android baseline reset requires the daemon readiness ports");let B=iN(d).mode!=="off";return B||d.reuseAndroidCleanDevices?{ios:B?DR():void 0,watch:Iu(d,R),android:d.reuseAndroidCleanDevices&&d.defaults.android?kR(c,R,d,{journal:C,recordingGaps:T}):void 0}:void 0}function DR(){return new ns({simctl:new F(null),iosBootInstrumentation:qo.iosBootInstrumentation(),stopDevice:async(d)=>{let c=ai(await di("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:C,recordingGaps:T}){let B=new Kr,O=IR(d.inventory,c),x;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");x=new Js(new js({emulator:new ii({timer:c}),adb:v,config:B,console:xs,clockRegistry:$m,processStopper:yf(c),clearQuickBoot:async(H,q)=>{let G=await B.resolveAvdDirectory(H.name);if(await q.assertOwned(),!G)throw new t("Android reset cannot locate its owned AVD to remove dirty quick-boot state");await cR(Pp(G,QS,Hp),{recursive:!0,force:!0}),await q.assertOwned()},capacity:{reserveBoot:(H)=>{if(!qo.androidColdBootAdmitter())throw new t("Android snapshot replacement requires boot admission before stopping");return xH("android",H)}},admitColdBoot:async(H,q)=>{let G=qo.androidColdBootAdmitter();if(!G)throw new t("Android snapshot wipe-data reset requires boot admission wiring");return await q.assertOwned(),G.admit({avdName:H.name,timeoutMs:q.timeoutMs,signal:q.signal})},readiness:d.snapshot,inventory:O,ctrlProxyReady:d.ctrlProxyReady,imageMetadata:async(H,q)=>{let G=rl();if(!G)throw new t("Android snapshot reset requires installed system-image metadata");return dR(Pp(G.androidHome,H,"source.properties"),{encoding:"utf8",signal:q})},timer:c,invalidate:(H)=>Ls(H,"Android broker baseline reset")}),c,$U)}let N=AR(R,{recordingGaps:T,journal:C,timer:c,snapshot:x,port:(H)=>new Vs(v.create(H))});return new Is({postureReset:new io(v),timer:c,resetTimeoutMs:R.androidResetTimeoutMs,inventory:async(H)=>{let q=await O(H);return Promise.all(q.map(async(G)=>{H?.signal?.throwIfAborted();let W=await B.readConfig(G.name);return H?.signal?.throwIfAborted(),{...G,isRunning:!0,runtimeId:W?.systemImagePackage,deviceType:W?.deviceName,apiLevel:W?.apiLevel}}))},adb:(H)=>v.create(H),watchSession:(H)=>zu(j,H),ctrlProxyReady:d.ctrlProxyReady,strategy:N})}function AR(d,{snapshot:c,...R}){return d.androidResetMode==="keep-booted"?new Ks({...R,maxUses:d.androidKeepBootedMaxUses,fallback:c,fallbackBudgetMs:c?d.androidResetTimeoutMs??ks:void 0}):c}function IR(d,c){return(R)=>{R.signal?.throwIfAborted();let C=new AbortController,T=R.signal?AbortSignal.any([R.signal,C.signal]):C.signal;return l(()=>d({...R,signal:T}),{timer:c,timeoutMs:R.timeoutMs,signal:R.signal,label:"Android baseline reset inventory",onTimeout:()=>C.abort()})}}async function PR(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 CR(d,c){let R=d.liveSessionIds?.()??[];if(R.length===0)return;let C=await d.registry.sessionBrokerStore(c).listRequests(),T=new Set(C.flatMap((B)=>B.sessionId?[B.sessionId]:[]));for(let B of await d.registry.snapshotManagedDevices())if(B.scopeKey===c&&B.execSessionUuid)T.add(B.execSessionUuid);if(R.some((B)=>!T.has(B)))throw new t("Session-broker mode requires prior generic sessions to be drained before startup")}async function TR(d,c){let R=await d.sessionBrokerStore(c).listLiveResources(),C=new Set(R.filter((O)=>O.state!=="destroyed").map((O)=>O.allocationIndex)),T=(await d.snapshotManagedDevices()).some((O)=>O.scopeKey!==c||O.holder!=="session_broker"||O.bindingIndex===null||!C.has(O.bindingIndex)),B=(await d.listOpenBindingJournal()).some((O)=>O.scopeKey!==c||!C.has(O.bindingIndex));if(T||B)throw new t("Session-broker mode requires prior or unaccounted managed allocations to be drained; existing inventory remains untouched")}var MR=3600000;class Mp{broker;scopeKey;lock;avdSnapshotCleanup;stopped=!1;lastPruneAtMs;running;closing;wake;timer;mutations;constructor(d,c,R,{timer:C,mutations:T,avdSnapshotCleanup:B}){this.broker=d;this.scopeKey=c;this.lock=R;this.timer=C,this.mutations=T,this.avdSnapshotCleanup=to(B)}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<MR)return;this.lastPruneAtMs=d;try{if(await this.broker.pruneReceipts()>=DG)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,OX);this.wake=()=>{this.timer.clearTimeout(R),c()}})}}function BR(d){let{mutationSessions:c,timer:R}=d;return c?new NE({sessions:()=>c,timer:R}):void 0}var Ep=xe+fl,Bp=Ep+Ep,OR=At,xR=It,_R=Pt,FR=5000,Op=60000,NR=3;class Ys{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 Oe({timer:d.timer??i,initialDelayMs:OR,maxDelayMs:xR,maxBlockedWaitMs:_R,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((C)=>!this.recoveredSessions.has(C)));let R=[];for(let C of d)R.push(...await this.reownInline(C));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 C=Promise.withResolvers(),T=this.deps.timer??i;R={settled:C.promise,resolve:C.resolve,device:this.deps.deviceOf?.(d)??"unknown device",timeout:T.setTimeout(()=>this.resolveUnknownHold(d),Bp)},this.releaseHolds.set(d,R),this.expediteRetry(d)}return{settled:R.settled,capMs:Bp}}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,Op-(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 C=this.episode(d);e.debug(c,R);let T=(this.deps.timer??i).now()-C.sinceMs;if(this.ownership.get(d)==="unconfirmed"&&!C.warned&&T>FR)C.warned=!0,e.warn(`[Bindings] Session ${d} ownership unconfirmed for ${T} ms (${C.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>=NR&&(this.deps.timer??i).now()-R.sinceMs>=Op)return this.settleOwnership(d,"lost"),!1;return!0}automationRefusal(d){switch(this.ownershipState(d)){case"unconfirmed":{let c=this.episode(d);return new $P(d,c.attempts===0?0:(this.deps.timer??i).now()-c.sinceMs)}case"lost":return new hH(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(C){e.warn(`[Bindings] Ownership-${c} hook failed for ${d}`,C)}}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 C=new AbortController;this.retryExpedites.set(d,C);try{if(await this.pacing.wait(this.pacing.delay(R),c,C.signal),!this.needsRetry(d))return;let T=await this.attempt(d,C.signal);if(!this.acceptResult(d,T.outcome,c))return;if(this.settleOwnership(d,T.outcome),T.outcome==="retry")this.logRetry(d,T.error)}catch(T){let B=this.canAttempt(d,c);if(!B&&!this.closed&&!c.aborted)e.debug(`[Bindings] Re-own retry no longer admitted for ${d}: ${r(T)}`);if(!B)return;this.logRetry(d,T)}finally{this.retryExpedites.delete(d)}}}attempt(d,c){let R=this.attempts.get(d);if(R)return R;let C=this.episode(d),T=this.pacing.run(async()=>{if(this.retryExpedites.delete(d),!this.canAttempt(d,C.stop.signal))return{assignments:[],outcome:"retry"};if(C.attempts===0){if(C.sinceMs=(this.deps.timer??i).now(),this.ownership.get(d)==="unconfirmed")this.startDeadline(d)}C.attempts++,C.inFlight=!0;try{return await this.boundedAttempt(d,C.stop.signal)}finally{C.inFlight=!1}},(B)=>B.outcome!=="retry",C.stop.signal,c).finally(()=>{this.attempts.delete(d)});return this.attempts.set(d,T),T}async boundedAttempt(d,c){let R=new AbortController,C=AbortSignal.any([this.closing.signal,c,R.signal]);try{return await l(()=>this.reownSession(d,C,c),{timer:this.deps.timer??i,timeoutMs:xe,signal:C,onTimeout:()=>R.abort(Error(`Re-owning session ${d} attempt timed out`)),label:`Re-owning session ${d}`})}finally{R.abort()}}async registryStep(d,c,R,C){let T=!1;try{return await l(()=>{let B=c.get(d);if(!B)B=R(),c.set(d,B);return B.then((O)=>(T=!C.aborted,O),(O)=>{throw T=!C.aborted,O})},{timer:this.deps.timer??i,signal:C,label:`Re-owning session ${d} registry step`})}finally{if(T)c.delete(d)}}async readCurrentAssignments(d,c,R){let C=this.ownerClaims.get(d);if(C){let B=await this.registryStep(d,this.ownerClaims,()=>C,R);if(!this.closed)e.debug(`[Bindings] Session ${d} retained claim completed (${B.kind}); checking current ownership`)}let T=()=>this.registryStep(d,this.ownerReads,()=>c.findExecutionAssignments(d),R);if(this.ownerReads.has(d)){if(await T(),!this.closed)e.debug(`[Bindings] Session ${d} retained ownership read completed; checking current ownership`)}return await T()}async reownSession(d,c,R){let C={assignments:[],outcome:"retry"},T=await this.registryStep(d,this.registryOpens,()=>this.deps.registry(),c);if(!this.isAdmitted(d,c))return C;let B=await this.readCurrentAssignments(d,T,c);if(!this.isAdmitted(d,c))return C;if(C.outcome="confirmed",B.length===0)C.outcome="lost";let O=this.deps.owner();for(let x of B){if(!this.isAdmitted(d,c))return{...C,outcome:"retry"};if(x.execOwner&&Ec(x.execOwner,O))continue;let N;try{N=await this.registryStep(d,this.ownerClaims,()=>T.claimExecution({scopeKey:x.scopeKey,bindingIndex:x.bindingIndex},{generation:x.generation,stableDeviceId:x.stableDeviceId},{...O,sessionUuid:d},{supersedesSessionUuid:d}),c)}catch(H){if(this.isAdmitted(d,R))this.markUnconfirmed([d]);throw H}if(!this.isAdmitted(d,c))return{...C,outcome:"retry"};if(N.kind==="claimed")C.assignments.push(N.assignment);else this.markUnconfirmed([d]),this.recordRefusal(C,N.kind,x,d)}return C}recordRefusal(d,c,R,C){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(C))return}else if(d.outcome!=="lost")d.outcome="retry";d.error=Error(`Binding ${R.bindingIndex} of ${R.scopeKey} was not re-owned for session ${C}: ${c}`)}}class Qs{options;constructor(d){this.options=d}async retire(d){let{timer:c,devices:R,isOwnerLive:C}=this.options,T=new AbortController,B=this.options.signal?AbortSignal.any([T.signal,this.options.signal]):T.signal;try{await d.withLegacyRows(async(O,x)=>{await l(async()=>{this.assertOwnersDead(O,C);let N=new Map(O.devices.map((H)=>[JSON.stringify(H),H]));for(let H of N.values()){B.throwIfAborted(),this.assertOwnersDead(O,C);let q=await R.inspect(H,B);if(B.throwIfAborted(),!q)continue;if(!Xa(q.name))throw new t(`Refusing to retire non-product device '${q.name}'; reconcile its legacy registry row manually.`);if(q.isRunningStateKnown===!1)throw new t(`Running state of legacy device '${q.name}' is unconfirmed`);if(q.isRunning){this.assertOwnersDead(O,C),await R.stop(q,B),B.throwIfAborted();let G=await R.inspect(H,B);if(G&&(G.isRunning||G.isRunningStateKnown===!1))throw new t(`Shutdown of legacy device '${q.name}' is unconfirmed`)}}B.throwIfAborted(),this.assertOwnersDead(O,C)},{timer:c,signal:B,timeoutMs:this.options.timeoutMs??30000,label:"Legacy slot device retirement",onTimeout:()=>T.abort()}),B.throwIfAborted(),await x()})}catch(O){throw(this.options.warn??e.warn)(`[Daemon] Legacy slot device retirement deferred: ${r(O)}`,O),u(O,"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 xp(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 Zs{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}),C=await this.manager.getBootedDevicesDetailed(d.platform,{signal:c,bypassAndroidDeviceListCache:!0,bypassIosDeviceListCache:!0,skipPhysicalIosDiscovery:!0});this.assertComplete(d,R,C);let T=(N)=>d.stableId?(d.platform==="android"?N.name:N.deviceId)===d.stableId:N.name===d.name,B=R.devices.find(T),O=C.devices.find((N)=>T(N)&&(d.platform!=="android"||le(N.deviceId)));if(C.transitionalSimulators?.some((N)=>T(N.device)))throw new t("Legacy simulator is transitioning; retry retirement after it settles");if(d.platform==="android"&&!O&&B?.isRunningStateKnown===!1)throw new t("Legacy Android running state is unconfirmed");if(d.platform==="android"&&!O)await this.assertAndroidStopped(d,c);return this.currentDevice(d,B,O)}currentDevice(d,c,R){let C=R??c;if(!C)return;return{...c,...R,name:C.name,platform:d.platform,isRunning:R!==void 0||c?.isRunning===!0,isRunningStateKnown:c?.isRunningStateKnown}}assertComplete(d,c,R){let C=d.platform==="ios"?R.succeededSources?.has("ios-simulator"):R.succeededPlatforms.has("android");if(!c.succeededPlatforms.has(d.platform)||!C)throw new t(`Cannot confirm legacy ${d.platform} device inventory; retry with the platform tooling available`);if(d.platform==="android"&&R.devices.some(wn))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),C=await this.android.processes.read({signal:c});if(!C.value)throw new t(`Cannot confirm legacy emulator process absence: ${C.error??"process table unavailable"}`);for(let T of R){if(!le(T.deviceId)||T.state==="device")continue;let B=IC(T.deviceId),O=C.value.filter(Wh).map((x)=>Pm(x.command)).filter((x)=>x.port===B);if(O.length!==1||!O[0].avdName||Xa(O[0].avdName))throw new t("Cannot confirm legacy shutdown while an Android emulator is offline or unauthorized")}if(C.value.some((T)=>this.mayBeTargetProcess(T,d)))throw new t("Legacy emulator process is still running; retry retirement after it exits")}mayBeTargetProcess(d,c){if(!Wh(d))return!1;let{avdName:R}=Pm(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 Np(d,c){if(c.isLive(d))return"live";try{let R=await c.getSession(d),C=c.timer.now();return R&&R.status==="released"&&R.release_reason&&po(R.release_reason)&&R.released_at_ms!==null&&uy(R,C)===void 0&&HM(R,C)?"recoverable-handoff":"gone"}catch(R){return e.warn(`Session ${d} disposition lookup failed: ${r(R)}`,R),"recoverable-handoff"}}class ea{open;options;controller=new AbortController;backoff;task;retryWait;constructor(d,c){this.open=d;this.options=c;this.backoff=c.backoff??te({initialDelayMs:5000,maxDelayMs:300000})}start(){if(this.controller.signal.aborted)return;this.task??=this.run().catch((d)=>{if(d instanceof zr)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 C=this.options.timer.setTimeout(()=>{this.retryWait=void 0,R()},c);this.retryWait={handle:C,resolve:R}})}return!1}async tryOpen(d,c){try{return await this.open(this.controller.signal),!0}catch(R){if(R instanceof zr)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 LR(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 ta{host;brokerExecutionRelease;sessionBrokerService;sessionBrokerConfig;bindingExecOwnerLiveness;bindingJournalInFlight=new Zt;bindingRedrive;maintainedRegistries=new WeakSet;registryClosing=!1;unsupportedRegistrySchema;constructor(d){this.host=d}installManagedExecutionRelease(){let d=new Ur({registry:()=>this.host.openBindingRegistry(),journal:{inFlight:this.bindingJournalInFlight},work:j,sessions:Ki(this.host.services.sessionManager(),DM(()=>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,C,{snapshot:T,...B})=>d.onSessionReleased(T,B))}bindingOwnerLiveness(){return this.bindingExecOwnerLiveness??=TH(Qa,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||xf()}bindingJournalOwner(){return{daemonId:this.host.identity.daemonSessionId(),...kH(()=>this.host.identity.processGenerationToken())}}installBrokerDeviceAcquisition(){let d=Ki(this.host.services.sessionManager(),DM(()=>this.host.services.devicePool())),c=ku({registry:()=>this.host.openBindingRegistry(),discardAndroidSnapshotOnExit:()=>_X(this.sessionBrokerConfig),resourceBudgetPolicy:{limit:()=>this.sessionBrokerConfig?.limits.totalDeviceCap??null},sessions:{claimLivenessOwnership:(R,C)=>this.host.services.sessionManager().claimLivenessOwnership(R,C),adoptManagedExecutionLivenessPolicy:(R,C)=>this.host.services.sessionManager().adoptManagedExecutionLivenessPolicy(R,C),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 Ys({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((C)=>C.sessionId===R)?.deviceId??null,onOwnershipLost:(R)=>{this.host.cancelAndReleaseSession(R,"binding-ownership-lost",{cutCallsLearnRelease:!0}).catch((C)=>{e.warn(`[Daemon] Lost managed execution ${R} release failed`,C)})},onOwnershipConfirmed:(R)=>{this.warmConfirmedManagedExecution(R).catch((C)=>{e.warn(`[Daemon] Confirmed managed execution ${R} iOS warm-up failed`,C)})}})),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 ea((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((T)=>(this.startBindingRegistryMaintenance(T),T));let C=Qb({writerVersion:ei,migrate:this.host.lifecycle.sessionBrokerConfigPath()!==void 0||this.host.identity.socketBindCommitted(),timer:this.host.services.timer(),isExecOwnerLive:this.bindingOwnerLiveness(),legacyDeviceRetirement:new Qs({signal:d,timer:this.host.services.timer(),isOwnerLive:Qa,devices:new Zs(new oi,{processes:new Df(new ne,{timer:this.host.services.timer(),processTableSupported:process.platform!=="win32",procFs:process.platform==="linux"?wy:void 0}),readStates:async(T)=>{let B=v.create(null),O=B.getDeviceStates;if(!O)throw new t("Android device-state discovery is unavailable for legacy retirement");return O.call(B,{signal:T,throwOnMissingAdb:!0})}})})});return this.host.setBindingRegistry(C),C.then((T)=>{if(!this.registryClosing)this.host.services.daemonState().setBindingRegistrySchemaProbe(T);if(this.host.deviceClaimMirrors().registryOpened(T.deviceClaims()),!c?.quiet)this.startBindingRegistryMaintenance(T)},()=>{return}),C.catch((T)=>{if(T instanceof zr)this.host.deviceClaimMirrors().skip(),this.unsupportedRegistrySchema=T;if(e.debug(`[Daemon] Binding registry open failed: ${r(T)}`),this.host.bindingRegistry()===C)this.host.setBindingRegistry(void 0)}),C}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&&E(K.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(),C=await IX(this.host.lifecycle.sessionBrokerConfigPath());if(this.sessionBrokerConfig=C,this.sessionBrokerService=await Tp({deferStart:!0,config:C,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:(T)=>Np(T,{isLive:(B)=>this.host.services.sessionManager().peekSession(B)!==null,getSession:(B)=>this.host.readPersistedSession(B),timer:this.host.services.timer()}),liveSessionIds:()=>this.host.services.sessionManager().getAllSessions().map((T)=>this.host.services.sessionManager().ownershipSessionUuid(T.sessionId)),androidReset:LR(()=>this.host.services.deviceReadiness())}),this.host.services.daemonState().setSessionBrokerService(this.sessionBrokerService),!this.bindingRedrive&&E(K.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 $R=3,HR=[1000,5000,30000,120000,300000],qR=2000;class na{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)=>Nt.current(c)),this.retryDelays=d.retryDelaysMs??HR}skip(){this.skipped=!0;for(let d of this.intents.values())this.clearRetry(d);this.intents.clear()}claimed(d,c,R,C){if(this.skipped)return;let T=this.intents.get(d),B=T?.kind==="claim"&&T.owner.pid===c.pid&&T.owner.ownerToken===c.ownerToken;this.record(d,{kind:"claim",owner:c,claimedAtMs:B?T.claimedAtMs:this.options.timer.now(),...R===void 0?{}:{stillHeld:R},...C===void 0?{}:{isLiveForeignOwner:C}})}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 C=this.skipped?void 0:await this.readStore();if(!C||this.skipped||this.disposed)return{outcome:"unavailable"};try{for(let B=0;B<$R;B++){let O=await this.acquireOnce(C,d,c,R);if(O)return O}let T=await C.get(this.options.platform,d);return T?{outcome:"refused",ownerPid:T.pid}:{outcome:"unavailable"}}catch(T){return e.warn(`[DeviceClaims] Cannot claim ${d} in the host-wide table; the claim files decide: ${r(T)}`,T),{outcome:"unavailable"}}}async acquireOnce(d,c,R,C){let T=await d.get(this.options.platform,c),B=T?.pid===R.pid&&T.ownerToken===R.ownerToken;if(T&&!B&&await this.isLiveOwner(T,C))return{outcome:"refused",ownerPid:T.pid};let O=B?T.claimedAtMs:this.options.timer.now();if(!await d.replaceIf(T,this.claimRow(c,R,O)))return;return this.recordAcquired(c,R,O),{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)??Nt.compare(d.pid,d.processGenerationToken)}recordAcquired(d,c,R){let C=this.intents.get(d);if(C)this.clearRetry(C);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:qR,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 C=c??this.options.store();if(!C){this.probeRegistry(),this.scheduleRetry(d,R);return}let T=R.version,B=this.issue(C,d,R).then(()=>{if(this.intents.get(d)?.version===T)this.confirm(d,R)},(O)=>{if(e.warn(`[DeviceClaims] Cannot ${R.kind==="claim"?"record":"remove"} the claim on ${d} in the host-wide table: ${r(O)}`,O),this.intents.get(d)?.version===T)this.scheduleRetry(d,R)}).finally(()=>{this.inFlight.delete(d);let O=this.intents.get(d);if(O&&O.version!==T)this.write(d)});this.inFlight.set(d,B)}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 C=await d.get(this.options.platform,c),T=C?.pid===R.owner.pid&&C.ownerToken===R.owner.ownerToken;if(R.acquired){if(C&&!T||!await d.replaceIf(C,this.claimRowFor(c,R,C)))this.dropIntent(c,R);return}if(C&&!T&&await this.heldByLiveForeignOwner(C,R))throw Error(`the row names live owner pid ${C.pid}; the claim file decides this claim until it is gone`);if(!await d.replaceIf(C,this.claimRowFor(c,R,C)))throw Error("the row changed while it was being written")}claimRowFor(d,c,R){let C=R?.pid===c.owner.pid&&R.ownerToken===c.owner.ownerToken;return this.claimRow(d,c.owner,C?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 C=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,...C===void 0?{}:{processGenerationToken:C},...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 Lp(d){let c,R;return()=>{let C=d();if(C!==c)c=C,R=void 0,C?.then((T)=>{if(c===C)R=T.deviceClaims()},()=>{return});return R}}function $p(d,c={}){let R=c.registry??AO,C=c.controllerFor??j$,T=c.timer??i,B=async(x,N,H)=>{if(H.aborted){e.warn(`[statusBar] Release cap expired before the status bar clear for session ${x} on ${N} could start; left the override in place`);return}let q=R.takeOwnedBy(N,x),G=q?C(q.device):null;if(!G)return;await Je(()=>G.clear(H))},O=(x,N,H)=>{let q=R.hasDeviceWork(N);if(!q&&R.get(N)?.sessionId!==x)return;if(H?.deviceIdentityReplaced){if(e.debug(`[statusBar] Cleanup for session ${x} on replaced serial ${N}: skipped status bar clear`),R.takeOwnedBy(N,x),q)R.runOnDevice(N,async()=>{R.takeOwnedBy(N,x)});return}let G=new AbortController,W=l(()=>R.runOnDevice(N,()=>B(x,N,G.signal)),{timer:T,timeoutMs:br,unref:!0,label:"Status bar clear",onTimeout:()=>G.abort()}).catch((V)=>{e.warn(`[statusBar] Failed to clear status bar override on ${N}: ${r(V)}`,V)});d.registerPendingDeviceCleanup(N,W,{name:"clear status bar override",leftover:"the released session's status bar override"})};d.onSessionRelease((x,N,H,q)=>{if(q?.upgradeOnly)return;O(x,N,q)}),d.onSessionDeviceUnbound(O)}function qp(d,c=AO){c.forget(d)}function Up(d,c={}){let R=c.registry??Al,C=c.shellFor??nE,T=c.timer??i,B=(O,x,N)=>{let H=R.takeOwnedBy(x,O);if(!H)return;if(N?.deviceIdentityReplaced){e.debug(`Kill-profile restore for session ${O} on replaced serial ${x}: skipped device writes`);return}d.registerPendingDeviceCleanup(x,h9(H,C,T),{name:"restore kill profile",leftover:"the released session's battery, Doze, standby-bucket and appop changes"})};d.onSessionRelease((O,x,N,H)=>{if(H?.upgradeOnly)return;B(O,x,H)}),d.onSessionDeviceUnbound(B)}function Kp(d,c={}){let R=c.registry??Pb,C=c.consoleFor??AU,T=c.timer??i,B=(O,x,N)=>{let H=R.takeOwnedBy(x,O);if(!H)return;if(N?.deviceIdentityReplaced){e.debug(`Sensor restore for session ${O} on replaced serial ${x}: skipped emulator sensor writes`);return}d.registerPendingDeviceCleanup(x,nJ(H,C,T),{name:"restore emulator sensors",leftover:"the released session's emulator sensor values"})};d.onSessionRelease((O,x,N,H)=>{if(H?.upgradeOnly)return;B(O,x,H)}),d.onSessionDeviceUnbound(B)}function Gp(d,c=pf){let R=(C,T,B)=>{let O=c.stopOwnedBy(T,C);if(!O)return;if(B?.deviceIdentityReplaced){e.debug(`Audio injections for session ${C} on replaced serial ${T} stopped`);return}d.registerPendingDeviceCleanup(T,O,{name:"stop emulator audio injection",leftover:"audio the released session was injecting into the emulator microphone"})};d.onSessionRelease((C,T,B,O)=>{if(O?.upgradeOnly)return;R(C,T,O)}),d.onSessionDeviceUnbound(R)}function Jp(d,c=pf,R=i){return(C)=>{let T=c.stopOwnerless(C);if(!T)return;$b(d,C,T,{timer:R,capMs:br,label:"stop sessionless emulator audio injection"})}}var UR=5000;async function KR(d,c,R,C=Ls){let T=c(d.device),B=[];for(let O of d.actions)try{await Je(()=>l(()=>mG(T,O),{timer:R,timeoutMs:UR,label:`Restore display-profile ${O.facet}`}))}catch(x){B.push(O.facet),e.warn(`Failed to restore display-profile ${O.facet} on ${d.device.deviceId}: ${r(x)}`,x)}if(d.actions.some((O)=>["screenSize","cutout","navigationMode"].includes(O.facet)))C(d.device.deviceId,"Display geometry restored");return B}function jp(d,c={}){let R=c.registry??xl,C=c.portsFor??iE,T=c.timer??i,B=c.invalidate??Ls,O=(x,N,H)=>{let q=R.takeOwnedBy(N,x);if(!q)return;if(H?.deviceIdentityReplaced){e.debug(`Display-profile restore for session ${x} on replaced serial ${N}: skipped device writes`);return}d.registerPendingDeviceCleanup(N,KR(q,C,T,B),{name:"restore display profile",leftover:"the released session's screen size, display, overlay, force-dark and posture changes"})};d.onSessionRelease((x,N,H,q)=>{if(q?.upgradeOnly)return;O(x,N,q)}),d.onSessionDeviceUnbound(O)}function zp(d,c={}){let R=c.registry??af,C=c.clientFor??a9,T=c.timer??i,B=(O,x,N)=>{let H=R.takeOwnedBy(x,O);if(!H)return;if(N?.deviceIdentityReplaced){e.debug(`Keyboard-profile restore for session ${O} on replaced serial ${x}: skipped device writes`);return}d.registerPendingDeviceCleanup(x,c9(H,C,T),{name:"restore keyboard profile",leftover:"the released session's AutoMobile keyboard behaviour profile"})};d.onSessionRelease((O,x,N,H)=>{if(H?.upgradeOnly)return;B(O,x,H)}),d.onSessionDeviceUnbound(B)}function Yp(d,c=B$){d.onSessionRelease((R,C)=>{let T={deviceId:C,sessionUuid:R};if(!c.hasActiveConditions(T))return;d.registerPendingDeviceCleanup(C,c.restore(T),{name:"restore device condition",leftover:"the released session's device-condition fixtures"})}),d.onSessionDeviceUnbound((R,C)=>{let T={deviceId:C,sessionUuid:R};if(!c.hasActiveConditions(T))return;d.registerPendingDeviceCleanup(C,c.restore(T),{name:"restore device condition",leftover:"the unbound session's device-condition fixtures"})})}function Xp(d,c=qg){let R=(C,T,B,O)=>{if(O){c.forgetOwnerOnDevice(C,T);return}if(!c.hasOwnedMappings(C,T))return;d.registerPendingDeviceCleanup(T,c.releaseOwnerOnDevice(C,T),{name:"remove adb reverse mappings",leftover:B})};d.onSessionRelease((C,T,B,O)=>{if(O.upgradeOnly)return;R(C,T,"the released session's adb reverse mappings",O.deviceIdentityReplaced)}),d.onSessionDeviceUnbound((C,T,B)=>R(C,T,"the unbound session's adb reverse mappings",B?.deviceIdentityReplaced))}function Qp(d,c,R=j){let C=new Set,T=async(O,x)=>{let N=x==="cli-idle-timeout"?d.getTerminalReleaseSnapshot(O.baseSessionId)?.cliIdleTimeoutMs:void 0;JE(R,O,new Ja(O.sessionId,x,N)).catch((H)=>{e.warn(`[DeviceLabelMap] Failed to cancel executions of ${O.sessionId}`,H)}),await As({manager:d,pool:c},O.deviceId,O.sessionId,{reason:x})},B=async(O,x,N)=>{let H=d.getSession(x);if(!H)return;let q={sessionId:x,baseSessionId:O,deviceId:H.assignedDevice,excludeExecutionId:Be()?.execution?.executionId};try{if(Jt(N))await T(q,N);else await OP(d,c,q,R);e.info(`[DeviceLabelMap] Released label session ${x} with its base ${O}`)}catch(G){e.warn(`[DeviceLabelMap] Failed to release label session ${x} with its base ${O}`,G)}};return d.onSessionRelease((O,x,N,H)=>{if(H?.upgradeOnly)return;let q=d.takeDerivedLabelSessions(O,N);if(q.length===0)return;let G=Promise.resolve().then(()=>Promise.all(q.map((W)=>B(O,W,N)))).then(()=>{return});C.add(G),G.finally(()=>C.delete(G))}),{settled:async()=>{while(C.size>0)await Promise.all(C)}}}function Zp(d,c,R,{shutdown:C,snapshot:T,upgradeOnly:B}){let O=d.takeRecordingIds(c);if(C.fallbacks?.has(c))return;if(R==="daemon-shutdown")C.announced?.add(c);let x={...O.length>0?{recordingIds:O}:{},...B?{upgradeOnly:!0}:{}};d.emit(c,R,T,Object.keys(x).length>0?x:void 0)}var GR=Ee([n(),a(),ER()]),WR=s({settingDefaults:s({name:n(),sessionId:n(),values:voe(p(Bb),GR)})});class ra{db;constructor({db:d}={}){this.db=d}getDb(){return this.db??ke()}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=WR.parse(JSON.parse(c.config_json))}catch(C){return e.warn(`Ignoring unreadable device setting defaults for ${d}: ${r(C)}`,C),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((C)=>C.column("device_id").doUpdateSet({platform:R.platform,config_json:R.config_json,updated_at:m`(datetime('now'))`})).execute()}async delete(d){await this.getDb().deleteFrom("device_configs").where("device_id","=",d).execute()}}function em(d,c={}){let R=(C,T)=>{(c.monitor?.()??vc()).stopMonitoring(T)};d.onSessionRelease((C,T,B,O)=>{if(!O?.upgradeOnly)R(C,T)}),d.onSessionDeviceUnbound(R)}var VR=(d)=>new H$(v.create(d));function tm(d,c={}){let R=c.registry??oE,C=c.appLinksFor??VR,T=(B,O,x)=>{let N=R.takeOwnedBy(O,B);if(N.length===0)return;if(x?.deviceIdentityReplaced){e.debug(`[appLinks] Restore for session ${B} on replaced serial ${O}: skipped pm writes`);return}d.registerPendingDeviceCleanup(O,P9(N,C),{name:"restore App Links state",leftover:"the released session's App Links verification and user selections"})};d.onSessionRelease((B,O,x,N)=>{if(N?.upgradeOnly)return;T(B,O,N)}),d.onSessionDeviceUnbound(T)}function im(d,c={}){let R=c.registry??hU,C=c.adbFor??((B)=>v.create(B)),T=(B,O,x)=>{let N=R.takeOwnedBy(O,B);if(N.traces.length===0&&N.deviceFiles.length===0)return;if(x?.deviceIdentityReplaced){e.info(`[profiling] Session ${B}'s ${O} was replaced; not cleaning up`);return}let H={name:O,platform:"android",deviceId:O},q=Je(async()=>gU(O,N,C(H),{timer:c.timer??i})).catch((G)=>(e.warn(`[profiling] Cleaning up session ${B}'s profiling state threw: ${r(G)}`,G),{deviceId:O,stoppedTraces:[],removedFiles:[],errors:[r(G)]}));d.registerPendingDeviceCleanup(O,q,{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((B,O,x,N)=>{if(!N?.upgradeOnly)T(B,O,N)}),d.onSessionDeviceUnbound(T)}function nm(d,c={}){let R=c.registry??Gg,C=(T,B)=>{R.clearOwnedBy(B,T)};d.onSessionRelease((T,B,O,x)=>{if(!x?.upgradeOnly)C(T,B)}),d.onSessionDeviceUnbound(C)}var JR={sync:(d)=>A2(d),resolveSessionKey:(d)=>AI(d)};function rm(d,c,R=JR){let C=(T,B)=>{if(!c.passiveWorkPolicy().allows("android","appearance-sync",B))return;let O=c.devicePool().getDevice(B);if(O?.platform!=="android")return;R.sync({deviceId:O.id,name:O.id,platform:"android",incarnation:O.incarnation,sessionKey:R.resolveSessionKey(T)})};d.onSessionCreated((T)=>{C(T.sessionId,T.assignedDevice)}),d.onDeviceOwnershipChange((T,B)=>{if(B!=="full")return;let O=d.getSessionForDevice(T);if(O)C(O,T)})}function jR(d,c,R){let C=new Set([R,d.ownershipSessionUuid(R),d.getBaseSessionOfDerivedLabel(R)].filter((T)=>T!==void 0));return(T)=>{for(let B of C)c.markMutationUnrecorded(B,T)}}function om(d,c,R){Xte(d),Bc(d,{timer:c,gapMarkerFor:(N)=>jR(d,R,N)}),$p(d),tm(d),Up(d),Kp(d),Gp(d),jp(d),zp(d),Yp(d),Xp(d),em(d),mX(d),fX(d),im(d),nm(d),Nc(d,{...St,markDeviceNeedsRecorderRecovery:xc(d)}),d.onDeviceOwnershipChange((N,H)=>{if(H==="full")R.deviceDataStreamServer()?.invalidateDeviceFrames(N);else R.deviceDataStreamServer()?.invalidateInitialDeviceFrames(N)}),d.setManagedExecutionRecoveryListener((N,H)=>R.managedExecutionReowner()?.noteRecovering(N,H)),d.setLateRehydrationListener((N)=>R.reownRehydratedManagedExecutions(N)),d.setActiveSessionExecutionChecker((N,H)=>R.hasActiveSessionExecution(N,H)),d.setSessionExecutionDeadlineLookup((N,H)=>R.latestSessionExecutionDeadlineMs(N,{onSessionClock:!0,...H})),j.setSessionClockOffsetProvider(()=>d.sessionNow()-c.now()),d.setExpiryReleaseExecutionCanceller((N,H,q,G)=>R.cancelExecutionsForExpiryRelease(N,H,q,G));let C=Fc(d),T=Oc(d,{timer:c}),B=Jp(d),O=new PG(new ra,new xP,(N)=>d.getSessionForDevice(N),{timer:c});iX(O),sX(O);let x=oX(d,O,c);d.setDeviceAcquisitionExecutionCanceller((N,H)=>{j.cancelSessionlessDeviceUse(N,{excludeExecutionId:Be()?.execution?.executionId}),R.socketServer()?.liftSessionlessStrokesOn(N),C(N,H),T(N),B(N),x(N,H)}),d.onSessionCreated((N)=>{me.clearReleasedSession(N.sessionId),R.setupNavigationGraphUpdateListener(me.getInstanceForSession(N.sessionId))}),rm(d,R),d.onSessionRelease((N,H,q,G)=>{if(G?.upgradeOnly)return;R.deviceReadiness().clearExplicitDevicePin(H);let W=me.findInstanceForSession(N);if(W)R.navigationGraphListenerManagers.delete(W);me.releaseSession(N),Ie.clearCache(H),ms.invalidate(H),k.getExistingInstance(H)?.releaseSessionBinding(N),_.getExistingInstance(H)?.releaseSessionBinding(N)}),Qp(d,DM(()=>R.devicePool())),d.onSessionDeviceUnbound((N,H)=>{R.socketServer()?.liftStrokesHeldByOn(N,H),R.deviceReadiness().clearExplicitDevicePin(H);let q=me.getInstanceForSession(N);me.resetSession(N),R.navigationGraphListenerManagers.delete(q),R.setupNavigationGraphUpdateListener(me.getInstanceForSession(N)),Ie.clearCache(H),ms.invalidate(H),k.getExistingInstance(H)?.releaseSessionBinding(N),_.getExistingInstance(H)?.releaseSessionBinding(N)}),d.onSessionRelease((N,H,q,{snapshot:G,...W})=>{if(Zp({takeRecordingIds:_c,emit:(...V)=>hi.emit(...V)},N,q,{shutdown:{fallbacks:R.shutdownFallbackReleaseNotifications(),announced:R.shutdownReleaseNotifications()},snapshot:G,upgradeOnly:W?.upgradeOnly}),R.shutdownFallbackReleaseNotifications()?.has(N))return;if(G.terminal)NH(N).catch((V)=>{e.warn(`[Appearance] Failed to drop config of released session ${N}`,V)})})}function sm(d,c,R){return d.onSessionExecutionEnded((C,{admitted:T})=>{let B=new Set(C.map((O)=>rt(O,c)??O));for(let O of B)c.recordToolCallEnded(O,{admitted:T});R.sessionExecutionsEnded(new Set([...C,...B]))})}function sa({tracker:d,sessionManager:c,devicePool:R},C,T){let{recoveryOnly:B,...O}=T??{};if(B)return R.isSessionRecoveryInFlight(C);let x=rt(C,c)??C;return O.sessionClockStartedAtOrBefore===void 0&&R.isSessionRecoveryInFlight(C)||d.hasActiveSessionUuidExecutions(C,O)||d.hasActiveAutolockSessionExecutions(C,O)||x!==C&&(d.hasActiveSessionUuidExecutions(x,O)||d.hasActiveAutolockSessionExecutions(x,O))}function aa({tracker:d,sessionManager:c,devicePool:R},C,T={}){if(R.isSessionRecoveryInFlight(C))return Number.POSITIVE_INFINITY;let B=rt(C,c)??C,O=d.getLatestSessionExecutionDeadlineMs(C,T);if(B===C)return O;let x=d.getLatestSessionExecutionDeadlineMs(B,T);if(O===void 0||x===void 0)return O??x;return Math.max(O,x)}function dm(d,c,R,C={}){let T=C.excludeReads?{excludeReads:!0}:{};return{hasActiveExecutions:(B)=>sa({tracker:d,sessionManager:c,devicePool:R},B,T),latestExecutionDeadlineMs:(B)=>aa({tracker:d,sessionManager:c,devicePool:R},B,{onSessionClock:!0,...T})}}function cm(d,c,R){return d.getAllDevices().filter((C)=>C.platform==="android"&&c.allows("android","appearance-sync",C.id)).map((C)=>({deviceId:C.id,name:C.id,platform:"android",incarnation:C.incarnation,sessionKey:AI(R.getSessionForDevice(C.id)??void 0)}))}var Rn=1000;function zR(d,c){return d.attachClaimMirror(c),d}class da{host;unsubscribeSessionExecutionEnded=null;constructor(d){this.host=d}createDevicePool(d,c){let R=new WU(this.sessionExecutionProbe({excludeReads:!0}),this.host.services.timer(),VU,()=>this.host.services.sessionManager().sessionNow()),C=Lp(()=>this.host.bindingRegistry()),T=(O)=>this.host.deviceClaimMirrors().register(new na({platform:O,store:C,whenOpen:async()=>(await this.host.bindingRegistry())?.deviceClaims(),registryFileExists:xf,openRegistry:()=>this.host.startBackgroundRegistryUpgrade(),timer:this.host.services.timer(),daemonSessionId:this.host.identity.daemonSessionId()})),B=T("android");return YU.create({deviceClaimMirrors:{android:B,ios:T("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:zR(new Cf(void 0,void 0,void 0,{timer:this.host.services.timer(),forwardEvidence:this.host.foreignCtrlProxyForwardEvidence()}),B)}:{},managedExecutionOwnership:()=>this.host.lifecycle.managedExecutionReowner(),missingDeviceMisses:this.host.lifecycle.deviceDisconnectMisses(),installedAppsRepository:this.host.services.installedAppsRepository(),deviceSessionRepository:this.host.services.deviceSessionRepository(),releaseSessionForDisconnectedDevice:(O,x,N,{shouldCommit:H,releaseOptions:q}={})=>this.host.cancelAndReleaseSession(O,N,{shouldCommit:H,deferFailureFallback:!0,releaseOptions:q}),ownerDisconnect:{release:async(O,x)=>{let N=R.keeps(O);if(N)return N;await this.host.cancelAndReleaseSession(O.sessionId,x,{expectedSession:O,cutCallsLearnRelease:!0})}},onDeviceReady:(O)=>this.host.onDeviceReadyForSessionRegistry(O),recoveryPolicy:d,onDeviceFramesInvalidated:(O)=>{this.host.lifecycle.deviceDataStreamServer()?.invalidateDeviceFrames(O),Xs().deviceIdentityChanged(O)},onDeviceIncarnationAssigned:(O)=>this.host.lifecycle.recorderDeviceIncarnationListener()?.(O),onDeviceRemoved:(O,x)=>{if(Xs().deviceRemoved(O),Jte(O),dk.retireDevice(O),qp(O),rn.getInstance().retireDevice(O),oE.retireDevice(O),Al.retireDevice(O),Pb.retireDevice(O),xl.retireDevice(O),QR.retireDevice(O),Gg.retireDevice(O),af.retireDevice(O),ms.invalidate(O),this.host.services.deviceReadiness().clearExplicitDevicePin(O),this.host.services.deviceSessionRegistry().onDeviceDisconnected(O),this.host.lifecycle.deviceDataStreamServer()?.removeDeviceFrames(O),x==="android")k.evictAfterDeviceRemoval(O).catch((N)=>{e.warn(`[Daemon] Failed to stop Android CtrlProxy for removed device ${O}: ${r(N)}`,N)});if(x==="ios")ge.evictAfterDeviceRemoval(O).catch((N)=>{e.warn(`[Daemon] Failed to stop iOS CtrlProxy for removed device ${O}: ${r(N)}`)})},onDeviceStateChanged:this.host.deviceStateChangeNotifier(),emulatorLossIncidentStore:new lO({timer:this.host.services.timer(),idGenerator:this.host.services.idGenerator()}),ambientExecutionIdReader:L$,cancelDeviceSessionExecutions:Object.assign((O,x,N)=>this.cancelAndDrainDeviceSessionExecutions(O,x,N),{cancelDeviceExecutions:(O,x,N)=>this.cancelAndDrainDeviceExecutions(O,x,N)}),idGenerator:this.host.services.idGenerator(),deviceSessionContinuityEnabled:r0(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=sm(j,this.host.services.sessionManager(),this.host.services.devicePool())}configureSessionLifecycleCallbacks(){om(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,C)=>this.cancelExecutionsForExpiryRelease(d,c,R,C)})}getAppearanceSyncTargets(){return cm(this.host.services.devicePool(),this.host.services.passiveWorkPolicy(),this.host.services.sessionManager())}hasActiveSessionExecution(d,c){return sa({tracker:j,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 dm(j,this.host.services.sessionManager(),c,d)}latestSessionExecutionDeadlineMs(d,c={}){return aa({tracker:j,sessionManager:this.host.services.sessionManager(),devicePool:this.host.services.devicePool()},d,c)}cancelExecutionsForExpiryRelease(d,c,R,C){JE(j,{sessionId:d,baseSessionId:rt(d,this.host.services.sessionManager()),deviceId:C,excludeExecutionId:R.excludeExecutionId},c).catch((T)=>{e.warn(`[Daemon] Failed to cancel executions of released session ${d}: ${r(T)}`,T)})}async cancelAndReleaseSession(d,c="explicit-release",R){let{allowExpired:C=!1,expectedSession:T,shouldCommit:B}=R??{},O=async(x)=>{if(B?.()===!1)return!1;let N=T?.assignedDevice??this.host.services.devicePool().getAllDevices().find((G)=>D(G)===d)?.id??null,H=null,q=!1;if(await As({manager:this.host.services.sessionManager(),pool:this.host.services.devicePool()},N,d,{deferFailureFallback:R?.deferFailureFallback,release:async()=>{if(T)H=await this.host.services.sessionManager().releaseSession(d,c,{expectedOwner:{session:T,deviceId:T.assignedDevice}});else if(B){let G=await this.host.services.sessionManager().releaseSessionUnlessSuperseded(d,c,{commitFence:B,allowExpired:C,...R?.releaseOptions});if(G.superseded)return e.info(`Kept session ${d}: a newer identity confirmation superseded its release (reason=${c})`),q=!0,null;H=G.deviceId}else H=await this.host.services.sessionManager().releaseSession(d,c,{allowExpired:C,...R?.releaseOptions});if(!this.isSessionDeviceAssigned(H,d))H=null;return H}}),q)return!1;if(!H||this.isSessionDeviceAssigned(H,d))return e.info(`Cancelled session ${d} (${x} executions); no device freed (reason=${c})`),!1;return e.info(`Cancelled session ${d} (${x} executions) and released device ${H} (reason=${c})`),!0};if(R?.cutCallsLearnRelease){let x=j.getActiveDeviceSessionExecutionCount(d);return this.host.services.sessionManager().cancelExecutionsCutByRelease(d,c),O(x)}return uX(d,c,O)}isSessionDeviceAssigned(d,c){return d!==null&&D(this.host.services.devicePool().getDevice(d))===c}async cancelAndDrainDeviceExecutions(d,c,R){let C=await j.cancelDeviceExecutions(d,c,R);if(C===0)return 0;if(!await j.waitForDeviceExecutionsToEnd(d,Rn,R))e.warn(`[Daemon] Timed out after ${Rn}ms draining cancelled executions for device ${d}`);return C}async cancelAndDrainDeviceSessionExecutions(d,c,R){let C=await j.cancelDeviceSessionExecutions(d,c,R);if(C===0)return 0;if(!await j.waitForDeviceSessionExecutionsToEnd(d,Rn,R))e.warn(`[Daemon] Timed out after ${Rn}ms draining cancelled executions for device session ${d}`);return C}}async function lm(d,c,R,C=dZ){if(d.timedOut)return e.info("[Appearance] Startup rehydration timed out; keeping per-session appearance rows"),[];let T=new Set(d.skipped.filter(({reason:B})=>B!=="not-recoverable").map(({sessionUuid:B})=>B));try{let B=[...R.liveDaemonSessionIds].some((x)=>x!==R.ownDaemonSessionId),O=await C(async(x)=>T.has(x)||eD(c.findSession(x))||await YR(x,R,B));if(O.length>0)e.info(`[Appearance] Dropped ${O.length} stale per-session appearance rows`);return O}catch(B){return e.warn(`[Appearance] Startup appearance-row sweep failed: ${r(B)}`,B),[]}}async function YR(d,c,R){try{let C=await c.getPersistedSession(d);if(C===void 0)return R;return C.status==="active"}catch(C){return e.warn(`[Appearance] Could not read session ${d} during startup sweep; keeping its row: ${r(C)}`,C),!0}}function eD(d){return d!==null&&d!==void 0}import{createServer as iA}from"http";import{AsyncLocalStorage as tD}from"async_hooks";var pm=new tD;function mm(d,c){return pm.run(d,c)}function hm(){return pm.getStore()}var iD=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,nD=/^(?:[a-z][a-z0-9_*/-]{0,255}|[a-z0-9][a-z0-9_*/-]{0,240}@[a-z][a-z0-9_*/-]{0,13})$/,rD=/^[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]$/,um=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,sD=/^(?:[\x21\x23-\x24\x26-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]|%[0-9a-fA-F]{2})*$/;function Dn(d){return d.replace(/^[ \t]+|[ \t]+$/g,"")}function aD(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 C of c){let T=Dn(C);if(T==="")continue;let B=T.indexOf("="),O=T.slice(0,B),x=T.slice(B+1);if(B<0||!nD.test(O)||!rD.test(x)||R.has(O))return;R.add(O)}return d}function uD(d,c){let R=d.indexOf("=");if(R<0)return c&&um.test(Dn(d));return um.test(Dn(d.slice(0,R)))&&sD.test(Dn(d.slice(R+1)))}function pD(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((C)=>C.split(";").every((T,B)=>uD(T,B>0)))?d:void 0}function gm(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d,R=c[vq];if(typeof R!=="string"||R.length!==55)return;let C=iD.exec(R);if(!C||/^0+$/.test(C[1])||/^0+$/.test(C[2]))return;return Object.freeze({traceparent:R,traceId:C[1],parentId:C[2],traceFlags:C[3],tracestate:aD(c[bq]),baggage:pD(c[Sq])})}var ca=600000,vm=15000;class la{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=j.prepareForDaemonRestart();if(c!=="accepted")return{accepted:!1,reason:c};if(!this.deps.onRestartAccepted)return j.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),j.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,C=j.prepareForDaemonMaintenance(R);if(C!=="accepted")return{accepted:!1,reason:C};let T=this.deps.idGenerator.next();return this.maintenanceAdmissionToken=T,this.maintenanceAdmissionExpiresAt=this.deps.timer.now()+ca,this.maintenanceAdmissionExpiryTimer=this.deps.timer.setTimeout(()=>this.releaseDaemonMaintenanceAdmission(T),ca),this.maintenanceAdmissionAbortController=new AbortController,this.maintenanceRestartConsumed=!1,{accepted:!0,maintenanceToken:T}}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")),j.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=j.prepareForAdmittedDaemonRestart();if(R!=="accepted")return{accepted:!1,reason:R};if(!this.deps.onRestartAccepted)return j.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"};this.maintenanceRestartConsumed=!0;try{return this.deps.onRestartAccepted(),{accepted:!0}}catch(C){return e.warn("Failed to initiate a maintenance-admitted daemon restart",C),j.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 C=this.deps.currentIdentity();if(!dX(this.deps.liveAcceptanceStartupSecret,C,R,d.acceptanceCapability))return{accepted:!1,reason:"acceptance_capability_invalid"};let T=this.acceptanceRestartSessionRefusal(R);if(T)return T;let B=j.prepareForDaemonRestart();if(B!=="accepted")return{accepted:!1,reason:B==="active_operations"?"active_operations":"restart_pending"};let O=this.deps.idGenerator.next(),x=Math.min(vm,R.expiresAt-this.deps.timer.now());return this.acceptanceRestartAdmissionToken=O,this.acceptanceRestartAdmissionOwnerSessionId=c,this.acceptanceRestartAdmissionCommitted=!1,this.acceptanceRestartAdmissionExpiresAt=this.deps.timer.now()+x,this.acceptanceRestartAdmissionExpiryTimer=this.deps.timer.setTimeout(()=>this.releaseAcceptanceRestartAdmission(O),x),{accepted:!0,restartToken:O}}acceptanceRestartSessionRefusal(d){let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"session_not_found"};let R=c.find((C)=>C.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((C)=>C.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);j.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||!hD(c.expiresAt)||!mD(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 mD(d){return!(!d||typeof d!=="object"||typeof d.androidSiblingAvdName!=="string"||typeof d.androidDuplicateSerial!=="string"||typeof d.iosSameNameSiblingUdid!=="string")}function hD(d){return typeof d==="number"&&Number.isFinite(d)}function Sm(d,c){let R=c?.aborted?c.reason:d instanceof xr?d:void 0;if(R===void 0)return;return{name:R instanceof Error?R.name:"Error",message:r(R)}}var ym=-32602;function gD(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 C=Object.fromEntries(Object.entries(R));return typeof C.code==="string"&&typeof C.retryable==="boolean"?C:void 0}function vD(d){if(!(d instanceof Error))return;let c=(B)=>Reflect.get(d,B),R=c("sessionUuid");if(typeof R!=="string")return;let C=c("remainingMs");if(d.name==="SessionSuspectError"&&typeof C==="number")return{code:Hl,retryable:!0,details:{sessionUuid:R,remainingMs:C}};let T=c("release");if(d.name!=="TerminalSessionError"||T===null||typeof T!=="object")return;return{code:Oo,retryable:!1,nextAction:Qn,details:{sessionUuid:R,...yD(T)}}}function yD(d){let c=Reflect.get(d,"releaseReason"),R=typeof c==="string"?c:void 0,C=Reflect.get(d,"ownerPid"),T=Reflect.get(d,"cliIdleTimeoutMs");return{...R===void 0?{}:{reason:R},...ui(R),...Fl(R,typeof T==="number"?T:void 0),...typeof C==="number"?{ownerPid:C}:{}}}function wm(d){let{code:c}=Rm(d);return c===Hl||c===Oo}function Rm(d){let c=vD(d);if(c)return c;let R=jE(d);if(R)return{code:Oo,retryable:!1,nextAction:Qn,details:lG(R)};let C=gD(d);if(!C)return _p(d)??{};let{code:T,retryable:B,retryAfterMs:O,nextAction:x,...N}=C;return{...typeof T==="string"?{code:T}:{},...typeof B==="boolean"?{retryable:B}:{},...typeof O==="number"?{retryAfterMs:O}:{},...typeof x==="string"?{nextAction:x}:{},...Object.keys(N).length>0?{details:N}:{}}}function SD(d){let c=zY(d);return c===void 0?{}:{code:Vp,details:{toolName:c}}}function bi(d,c){return{...Rm(d),...d instanceof zs?{overloadFailure:d.failure}:{},...d instanceof xr&&d.code?{code:d.code}:{},...d instanceof xr&&d.code===Cu?{retryable:!0}:{},...d instanceof he&&"code"in d&&d.code===ym?{code:ym}:{},...WY(d)?{code:Du}:{},...SD(d),...jY(d)?{code:Wp}:{},...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:C,admissionStillHolds:T=!0}={}){if(!T||!this.deps.isSocketLive(d))return await this.cancelOne(c,R,d),"cancelled";let B=this.bySocket.get(d)??new Map;return B.set(_t.key(c.deviceId,R),{targetDevice:c,gestureId:R,...C!==void 0?{holderSessionId:C}:{}}),this.bySocket.set(d,B),"owned"}onEndAcked(d,c,R){let C=this.bySocket.get(d);if(!C)return;if(C.delete(_t.key(c,R)),C.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:C}of c.values())await this.cancelOne(R,C,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,C]of this.bySocket){for(let[T,B]of C)if(d(B))C.delete(T),c.push({...B,socketSessionId:R});if(C.size===0)this.bySocket.delete(R)}await Promise.all(c.map(({targetDevice:R,gestureId:C,socketSessionId:T})=>this.cancelOne(R,C,T)))}async cancelIfDeviceChangedHands(d,c,R,C){let T=this.bySocket.get(d)?.get(_t.key(c,R));if(!T||T.holderSessionId===C)return!1;return this.onEndAcked(d,c,R),await this.cancelOne(T.targetDevice,R,d),!0}async cancelOne(d,c,R){try{await this.deps.cancelGesture(d,c)}catch(C){e.warn(`Failed to cancel orphaned gesture ${c} on ${d.deviceId} owned by socket ${R}: ${r(C)}`)}}}class ua{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 I7(JSON.parse(JSON.stringify(d)))}class kn{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 ma(d){return d!==void 0&&d.trim().length>0}function An(d){let c=kD(d),R=c(see,"boundSessionUuid"),C=c(cee,"releasedSessionUuid"),T=c(aee,"toolSelectionProfileUuid"),B=C!==void 0&&C.trim()===R?.trim();return{...ma(R)&&!B?{initialSessionToolBinding:R}:{},...ma(C)?{initialReleasedSession:C}:{},...ma(T)?{initialToolSelectionProfile:T}:{}}}function kD(d){if("headers"in d){let{headers:c}=d;return(R)=>RD(c,R)}return(c,R)=>DD(d[R])}function Pn(d,c,R){return E2({...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:KY()})}var ID=Uc("MCP client relay",()=>import("./chunk-km0dy5vc.js"));function fa(d){let c=new AD(d);return{run:(R)=>c.runInAsyncScope(R)}}class Dm{deps;root;inFlight=new Map;accepting=!0;constructor(d){this.deps=d;this.root=d.serverScope??fa("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??ID,{LoopbackMcpClient:R}=c.loaded()??await c.load();if(!this.accepting)throw new pa(gb);let C={requestScopeId:this.deps.idGenerator.next(),requestMcpSessionId:d.sessionKey,trustedForwarder:!0,...d.taskOwnerKey!==void 0&&{taskOwnerKey:d.taskOwnerKey}},T=(W)=>this.root.run(W),B=T(()=>this.deps.createServer(An(d),C)),[O,x]=L7.createLinkedPair(),N=new R({name:"auto-mobile-daemon-client",version:"1.0.0"},{capabilities:{}}),H=N.close.bind(N),q,G={requestScopeId:C.requestScopeId,close:(W)=>(q??=this.closeForward(G,C,B,{closeClient:H,reason:W}),q)};N.close=()=>G.close(),this.inFlight.set(C.requestScopeId,G);try{await T(()=>B.connect(new kn(x,(W)=>W()))),await N.connect(new kn(O,T))}catch(W){throw await G.close(),W}return N}async closeForward(d,c,R,{closeClient:C,reason:T}){try{await this.deps.cancelScopeExecutions(c.requestScopeId,T??this.deps.closeReason())}finally{if(this.inFlight.get(c.requestScopeId)===d)this.inFlight.delete(c.requestScopeId);let B=await Promise.allSettled([C(),R.close()]);for(let O of B)if(O.status==="rejected")e.warn(`In-process MCP forward ${c.requestScopeId} teardown failed: ${wp(O.reason)}`);if(c.requestMcpSessionId===void 0)this.deps.forgetScopeBindings(c.requestScopeId)}}}var ga="mcp_forward_closed";function Cn(d){return new Dm({idGenerator:d.idGenerator??L,refreshResources:_$,createServer:(c,R)=>Pn(d.base(),c,R),cancelScopeExecutions:(c,R)=>j.cancelSessionExecutions(c,R),forgetScopeBindings:(c)=>Wk(c),closeReason:d.closeReason??(()=>ga)})}class mt extends t{}var Im=2000,va=100,ya=3,Cm=250;function Tm(d){if(d===null||typeof d!=="object"||Array.isArray(d))return null;let c=d.id;return typeof c==="string"?c:null}function Mm(d,c){return d?.aborted===!0&&(c?.message==="Daemon MCP client disconnected"||d.reason instanceof mt)}function Em(d){if(d)e.error(`Original MCP request failure cause: ${d.name}: ${d.message}`)}function Bm(d,c){return d===void 0?c.now():d}function xm(d){return structuredClone(d??{})}var _m=new Set(["getAndroid","getApple","startDevice","provisionDevice"]),Fm=1000,Sa=1000,Nm=1000;function PD(d,c){let R=`${d}.bind.lock`;return{acquire:()=>_i(R,{ownerToken:c,ownerGeneration:Nt}),release:()=>vi(R,process.pid,c)}}var CD={getOwnerStatus(){let d=So();if(!d||d.pid===process.pid)return"unknown";return nt(d.pid,{debugLog:e.debug})?"live":"dead"}};function Lm(d,c,R){return{reachability:d.reachability??new Cw,ownerLiveness:d.ownerLiveness??CD,bindLock:d.bindLock??PD(c,R)}}var Hm=(d,c)=>wf().getRegisteredTool(d)?.isDeviceReadOnlyCall?.(c)===!0,qm=":read",ba="device:",wa=900000,Ze=(d)=>typeof d==="string"&&d.trim().length>0;function Um(d,c){return d instanceof mt||c&&d instanceof Error&&d.message==="Daemon MCP client disconnected"}function He(d){d?.throwIfAborted()}class Ra{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 ua;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=Hm;mcpClientFactory=(d,c,R)=>this.callbacks().createMcpClient(d,c,R);releaseToolCallRecording=eM;forgetSessionToolBindings=(d)=>Wk(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,C){this.callbacks=c;this.shapeToolCallError=R;this.inboundFrameLimit=C;let[T=Ct,B=w.daemonState(),O=i,x=null,N={},H=L,q={},G=v]=d;this.socketPath=T,this.daemonState=B,this.clearConnectionDevicePin=N.clearConnectionDevicePin,this.timer=O,this.requestTimeoutEnv=N.requestTimeoutEnv,this.onFrameTrace=N.onFrameTrace,this.mcpDispatcher=N.mcpDispatcher??Cn({base:()=>({acceptanceDiscoveryCapability:N.acceptanceDiscoveryCapability})}),this.idGenerator=H;let W=Lm(q,T,L.next());this.socketReachability=W.reachability,this.socketOwnerLiveness=W.ownerLiveness,this.socketReclaimLock=W.bindLock,this.adbClientFactory=G,this.featureFlagService=x,this.handshakeEnforced=N.enforce??uee,this.sessionToolSelectionService=N.sessionToolSelectionService,this.daemonIdentity=N.identity??JH(),this.identityStartedAt=Bm(N.identityStartedAt,this.timer),this.processGenerationToken=N.processGenerationToken,this.startupOptions=xm(N.startupOptions),this.onRepublishIdentity=N.onRepublishIdentity,this.identityDbPath=N.dbPath,this.identityPidFilePath=N.pidFilePath,this.startupCompletion=N.startupCompletion,this.observeStartupCompletion(),this.identitySockets=N.sockets,this.identityProcessStartedAt=N.processStartedAt,this.onRestartAccepted=N.onRestartAccepted,this.liveAcceptanceStartupSecret=N.liveAcceptanceStartupSecret,this.acceptanceDiscoveryCapability=N.acceptanceDiscoveryCapability,this.restartAdmission=new la({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: "${T}"`)}observeStartupCompletion(){this.startupCompletion?.then(()=>{this.startupCompleted=!0},(d)=>{e.debug(`Daemon startup completion rejected: ${r(d)}`)})}}import{createServer as TD}from"net";import{unlink as MD}from"fs/promises";import{existsSync as ED}from"fs";import BD from"path";class Da{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async start(){if(this.callbacks.beginAccepting(),!Qd())await Zd();if(await su(BD.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(ED(this.state.socketPath))await this.callbacks.reclaimExistingSocketBeforeBind();this.state.server=TD(this.callbacks.connectionHandlerWithFanOut()),await new Promise((d,c)=>{this.state.server.listen(this.state.socketPath,()=>{this.state.socketFileIdentity=zV(this.state.socketPath),e.info(`Unix socket server listening on ${this.state.socketPath}`),DL(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=kr.subscribe((d)=>{this.callbacks.broadcastListChanged(d)}),this.state.resourceUpdatedUnsubscribe?.(),this.state.resourceUpdatedUnsubscribe=zS.subscribe((d)=>{this.callbacks.broadcastResourceUpdated(d)}),this.state.sessionReleaseUnsubscribe?.(),this.state.sessionReleaseUnsubscribe=hi.subscribe((d,c,R,C)=>{this.callbacks.clearBoundMcpClientsForReleasedSession(d),this.callbacks.liftStrokesHeldBy(d),this.callbacks.broadcastSessionReleased(d,c,R,C?.recordingIds)}),this.state.sessionDeviceReboundUnsubscribe?.(),this.state.sessionDeviceReboundUnsubscribe=uH.subscribe((d)=>this.callbacks.broadcastSessionDeviceRebound(d)),(d)=>this.callbacks.handleConnection(d)}async reclaimExistingSocketBeforeBind(){let d=await this.state.socketReachability.probe(this.state.socketPath,Nm);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 MD(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(uw(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:Sa,label:"Session release notification drain",timeoutError:()=>c})}catch(C){if(C!==c)throw C;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=uw(this.state.socketFileIdentity,this.state.socketPath),R=this.callbacks.closeListeningServer(c);for(let T of this.state.pendingSocketRequests)if(!T.admitted)this.callbacks.writeShutdownSocketResponse(T);await this.callbacks.drainActiveRequestHandlers();for(let T of this.state.pendingSocketRequests)this.callbacks.writeShutdownSocketResponse(T);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 T of this.state.forwardKeyIdleTimers.values())this.state.timer.clearTimeout(T);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:Fh,...$N(BN(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(),Sa);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:Fm,label:"Unix socket request drain",timeoutError:()=>c})}catch(C){if(C!==c)throw C;R=!1}if(!R)e.warn(`Timed out waiting for ${d.length} in-flight Unix socket request handler(s) to finish during shutdown`)}}var OD="input/";function xD(d){return d.startsWith(OD)}function Km(d,c){return xD(d)||c.has(d)}async function Wm(d,c,R,{socketSessionId:C,input:T}){return c.handler==="gesture"?await d.gesture(R,c.gestureKind,C,T):await d[c.handler](R,C,T)}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??{},[Uu]: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(([C,T])=>{let B=C==="result"?R:JSON.stringify(T);return B===void 0?[]:[`${JSON.stringify(C)}:${B}`]}).join(",")+`}
38
+ `}function FD(d){if(d==="tools/list")return"tools";return d==="resources/list"?"resources":void 0}class Tn{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=FD(d.request.method);if(!R)return await c();d.signal?.throwIfAborted();let{route:C}=d,T=JSON.stringify([R,d.socketSessionId,C.clientKey,C.sessionUuid,C.toolSelectionProfileUuid,C.releasedSessionUuid]),B=this.entries.get(T);if(R==="resources"&&B?.generation===kr.generation(R)){if(!await this.awaitWarmRefresh(d))return B.result;d.signal?.throwIfAborted()}let O=kr.generation(R);if(B?.generation===O)return this.entries.delete(T),this.entries.set(T,B),B.result;this.entries.delete(T);let x=await c();return d.signal?.throwIfAborted(),this.retain(R,T,O,{result:x,socketSessionId:d.socketSessionId}),x}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(C){if(C!==R)throw C;return e.debug(`[DiscoveryCache] ${R.message}; the refresh keeps running.`),!1}}retain(d,c,R,{result:C,socketSessionId:T}){if(R!==kr.generation(d)||!C||typeof C!=="object")return;if(Jm.set(C,JSON.stringify(C)),this.entries.set(c,{generation:R,result:C,socketSessionId:T}),this.entries.size>Tn.MAX_ENTRIES){let B=this.entries.keys().next().value;if(B!==void 0)this.entries.delete(B)}}}function zm(d,c,R){let C={type:"daemon_notification",method:L4[R]};for(let T of d)if(c.hasSocket(T))c.write(T,C)}function Xm(d,c,R){for(let[C,T]of d){if(!c.hasSocket(C))continue;for(let B of R(T))c.write(C,{type:"daemon_notification",method:eC,uri:B})}}function Qm(d,c,R){let C=R.params?.uri;if(typeof C!=="string"||C.length===0)return{id:R.id,type:"mcp_response",success:!1,error:"Resource subscription requires params.uri"};if(R.method===cA){let T=d.get(c)??new Set;T.add(C),d.set(c,T)}else{let T=d.get(c);if(T?.delete(C),T?.size===0)d.delete(c)}return{id:R.id,type:"mcp_response",success:!0,result:{}}}function Zm(d,c,R,C){let{releasedSessionId:T,reason:B,release:O,recordingIds:x}=C,N={type:"daemon_notification",method:ML,sessionId:T,...B!==void 0?{reason:B}:{},...ui(B),...O!==void 0?{release:O}:{},...x&&x.length>0?{recordingIds:x}:{}};for(let H of d){if(!c.hasSocket(H))continue;let q=Promise.withResolvers();R.add(q.promise),c.write(H,N,()=>{R.delete(q.promise),q.resolve()})}}function ef(d,c,R){let{requestId:C,progressToken:T,progress:B,total:O,message:x}=R;if(!d.hasSocket(c))return;d.write(c,{type:"daemon_notification",method:hS,requestId:C,progressToken:T,progress:B,...O!==void 0?{total:O}:{},...x!==void 0?{message:x}:{}})}function tf(d,c,R,C){let T={type:"daemon_notification",method:eN,...C};for(let B of d){if(!c.hasSocket(B))continue;let O=Promise.withResolvers();R.add(O.promise),c.write(B,T,()=>{R.delete(O.promise),O.resolve()})}}class of{#t;get signal(){return this.#t}adopt(d){this.#t=d}}function Mn(d,c,R,C=process.env){let T=KN(d,C),B=new AbortController;return{id:d.id,socketSessionId:c,receivedAtMs:R,totalTimeoutMs:T,deadline:new Kf(R,T),signal:B.signal,cancellation:B,owner:new of}}var ND=0,ka=0;function Aa(){return++ND}function sf(){return ka}class Pa{pending=[];runningLanes=new Set;runningCount=0;barrierRunning=!1;get pendingCount(){return this.pending.length}run(d,c,R){return new Promise((C,T)=>{let B=d!==void 0&&(this.runningLanes.has(d)||this.pending.some((G)=>G.lane===d)),O,x=()=>{if(O!==void 0)R?.timer.clearTimeout(O);R?.signal.removeEventListener("abort",H)},N=(G)=>{let W=this.pending.indexOf(q);if(W<0)return;this.pending.splice(W,1),x(),T(G),this.pump()},H=()=>N(R?.signal.reason),q={lane:d,run:()=>{if(x(),R&&R.timer.now()>=R.deadlineMs)return T(R.timeoutError(B)),Promise.resolve();return c().then(C,T)}};if(this.pending.push(q),R){if(R.signal.addEventListener("abort",H,{once:!0}),R.signal.aborted){H();return}let G=R.deadlineMs-R.timer.now();if(G<=0){N(R.timeoutError(B));return}O=R.timer.setTimeout(()=>N(R.timeoutError(B)),G)}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)ka=Math.max(ka,Aa()),this.barrierRunning=!1;else this.runningLanes.delete(d.lane);this.pump()})}}var LD=new Set(["getAndroid","getApple","startDevice","provisionDevice","setActiveDevice","setToolEnabled"]),df=["sessionUuid","device",$o,fm,eu];function Ca(d){let c=d.params?.name;if(d.method!=="tools/call"||typeof c!=="string"||LD.has(c))return;let R=HD(d.params?.arguments);if(R!==void 0)return`device:${R}`;if(tt(c,d.params?.arguments))return"host:inventory";return}function tt(d,c){return zN(d)&&$D(c)}function $D(d){return d===void 0||typeof d==="object"&&d!==null&&!Array.isArray(d)&&!("deviceId"in d)&&!df.some((c)=>(c in d))}function HD(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 df.some((R)=>(R in d))?void 0:c}var qD=f({id:y(),type:P(["mcp_request","daemon_request"]),method:y(),params:hr().optional()}).passthrough();function cf(d){return qD.safeParse(d).success}var UD=f({platform:P(["android","ios"])}).passthrough();function lf(d){let c=UD.safeParse(d);return c.success?c.data.platform:void 0}var Ta=16777216;class Ma{admitted=0;headEnd=0;drainedAtSample=0;watchdog;socket;timer;onStalled;maxQueuedBytes;stallTimeoutMs;constructor(d,c,R,{maxQueuedBytes:C=16777216,stallTimeoutMs:T=60000}={}){this.socket=d,this.timer=c,this.onStalled=R,this.maxQueuedBytes=C,this.stallTimeoutMs=T}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 WD=new Set(["EPIPE","ECONNRESET","ERR_STREAM_DESTROYED","ECONNABORTED"]);function VD(d){return"code"in d&&typeof d.code==="string"&&WD.has(d.code)}class Ba{socket;sessionId;timer;maxInboundFrameBytes;guard;idleTimeout;peerEndGrace;started=!1;handlers;constructor(d,c,R,C){this.socket=d;this.sessionId=c;this.timer=R;this.maxInboundFrameBytes=C}outboundWriteGuard(){if(!this.guard)this.guard=new Ma(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(TC)}start(d){let{socket:c,sessionId:R,timer:C}=this;if(this.started=!0,this.handlers=d,c.setTimeout(TC),c.on("timeout",()=>this.onIdleTimeout(d)),c.on("drain",()=>this.refreshIdle()),c.on("drain",()=>this.guard?.flushed()),d.trace){let O=d.trace.bind(d);c.on("drain",()=>O("socket_drain")),c.on("pause",()=>O("socket_pause")),c.on("end",()=>O("socket_end")),c.on("finish",()=>O("socket_finish"))}let T=C.now(),B=new qc(this.maxInboundFrameBytes,{onLine:(O)=>d.onLine(O,T),onOverflow:()=>d.onOverflow()});c.on("data",(O)=>{if(B.hasOverflowed)return;this.refreshIdle(),T=C.now(),B.push(O)}),c.on("end",()=>{if(c.destroyed||this.peerEndGrace)return;this.peerEndGrace=C.setTimeout(()=>{if(!c.destroyed)e.debug(`Daemon RPC socket ${R} peer closed with ${c.writableLength} bytes unflushed; destroying`),c.destroy()},iee)}),c.on("close",(O)=>{if(this.peerEndGrace)C.clearTimeout(this.peerEndGrace);if(this.idleTimeout)C.clearTimeout(this.idleTimeout);this.started=!1,this.guard?.dispose(),d.trace?.("socket_close",{hadError:O}),d.onClose(O)}),c.on("error",(O)=>{if(VD(O))e.debug(`Socket peer closed for ${R}: ${r(O)}`);else e.error(`Socket error for ${R}:`,O);if(d.onError(O),!c.destroyed)c.destroy()})}armIdleTimeout(){return this.timer.setTimeout(()=>this.onIdleTimeout(this.handlers),TC)}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 ${TC}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 Oa{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 Pa,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:(C,T)=>{if(C.trim())this.callbacks.trackRequestHandler(this.callbacks.processSocketRequestLine(c,d,C,T))},onOverflow:()=>this.callbacks.rejectOversizedFrame(c,d),hasLiveRequest:()=>this.callbacks.hasLiveSocketRequest(d),trace:this.state.onFrameTrace?(C,T)=>this.callbacks.traceFrame(C,"*",{details:T}):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 Ba(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,C){let T=null,B,O,x,N=(W)=>{},H=!1,q=()=>H&&this.state.clientSockets.get(d)===c&&!c.destroyed,G=(W)=>{if(O?.terminal)return;if(O)this.callbacks.writeTerminalSocketResponse(O,W,B);else this.callbacks.writeFrame(c,d,W,{deviceId:B});H=!0};try{let W;try{W=JSON.parse(R)}catch(ee){throw x=-32700,u(ee,"Parse error in daemon socket request")}if(T=Tm(W),!cf(W))throw x=-32600,new t("Invalid daemon socket request");let V=W,Y=[os,cw,fT].includes(V.method),J=Mn(V,d,C,this.state.requestTimeoutEnv),X={id:V.id,sessionId:d,socket:c,admitted:Y,terminal:!1,idleDeadline:Y?void 0:J.deadline};if(O=X,this.state.pendingSocketRequests.add(X),this.announceResolvedBudget(c,d,V,{resolvedMs:J.totalTimeoutMs,controlFrame:Y}),B=this.state.onFrameTrace?this.callbacks.frameDeviceId(V):void 0,this.state.onFrameTrace)this.callbacks.traceFrame("frame_parsed",V.id,{deviceId:B});(()=>{try{if(V.method==="tools/call"&&this.state.daemonState.isInitialized())N=this.state.daemonState.getDevicePool().beginMcpToolCall?.(d)??N}catch(ee){e.warn(`Could not begin MCP tool-call ownership claim: ${r(ee)}`,ee)}})();let re=await this.callbacks.handleRequest(d,c,V,{receivedAtMs:C,handling:{onAdmitted:(ee)=>{X.admitted=!0,X.idleDeadline=Y?void 0:ee},context:J}});if(re)G(re);else this.state.pendingSocketRequests.delete(X),this.state.controlConnections.get(c)?.responseFlushed()}catch(W){if(Um(W,c.destroyed))e.debug(`Client cancelled request ${T} from ${d}`);else e.error(`Error processing request ${T} from ${d}:`,W);let V={id:T,type:"mcp_response",success:!1,error:r(W),...x===void 0?{}:{code:x},...bi(W,void 0)};G(V)}finally{N(q())}}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"||!a1(c)||!this.state.daemonState.isInitialized?.())return d;let R=QK(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:C,details:T}={}){if(this.state.onFrameTrace)this.state.onFrameTrace({event:d,atMs:this.state.timer.now(),wallMs:performance.now(),requestId:c,deviceId:R,error:C,...T})}releaseSocketSession(d,c){if(this.state.clientSockets.get(d)!==c)return;this.callbacks.abortMcpRequests(d),this.callbacks.forgetSocketDiscovery(d),this.callbacks.trackRequestHandler(j.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(!j.hasActiveSessionExecutions(d))return;j.waitForSessionExecutionsToEnd(d,wa).then((c)=>{if(this.state.forgetSessionToolBindings(d),!c)e.warn(`Socket ${d} still had executions ${wa}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 C=c.get(d);if(!C)return;c.delete(d);for(let T of C)T.abort(Error(R))}mcpRequestSignal(d,c=this.state.clientSockets.get(d),R){let C=new AbortController,T=()=>C.abort(R?.reason);if(R?.aborted)T();else R?.addEventListener("abort",T,{once:!0});let B=this.state.mcpRequestAbortControllers.get(d)??new Set;B.add(C),this.state.mcpRequestAbortControllers.set(d,B);let O=this.state.clientSockets.get(d);if(!c||O!==c||c.destroyed)C.abort(Error("Daemon MCP client disconnected"));return{signal:C.signal,dispose:()=>{if(R?.removeEventListener("abort",T),B.delete(C),B.size===0&&this.state.mcpRequestAbortControllers.get(d)===B)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 C=this.state.clientSockets.get(d);if(C)this.callbacks.writeFrame(C,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,C){Zm(this.state.notificationSubscribers,this.notificationTransport,this.state.pendingSessionReleaseWrites,{releasedSessionId:d,reason:c,release:R,recordingIds:C})}pushProgressNotification(d,c){ef(this.notificationTransport,d,c)}announceResolvedBudget(d,c,R,{resolvedMs:C,controlFrame:T}){if(T||R.type!=="mcp_request"||R.acceptsRequestBudget!==!0||C===R.timeoutMs)return;this.callbacks.writeFrame(d,c,{type:"daemon_notification",method:QN,requestId:R.id,timeoutMs:C})}writeFrame(d,c,R,{onFlushed:C,deviceId:T}={}){if(this.state.onFrameTrace&&R.type==="mcp_response"){this.callbacks.traceFrame("response_write_started",R.id??"null",{deviceId:T}),this.callbacks.writeFrameData(d,c,R,{onFlushed:(B)=>{this.callbacks.traceFrame("response_write_callback",R.id??"null",{deviceId:T,error:B?.message,details:{writableLengthInCallback:d.writableLength}}),C?.()},onWritten:(B,O)=>{this.callbacks.traceFrame("response_write_returned",R.id??"null",{deviceId:T,details:{byteLength:O,writableLengthAfterWrite:B}})}});return}this.callbacks.writeFrameData(d,c,R,{onFlushed:C})}writeFrameData(d,c,R,{onFlushed:C,onWritten:T}){if(d.destroyed){C?.(Error("socket destroyed"));return}try{let B=jm(R),O=Buffer.byteLength(B),x=this.callbacks.connectionFor(d,c).outboundWriteGuard(),N=x.admit(O);if(N!==void 0){let q=new On(N,Ta);e.warn(`Daemon RPC socket ${c} write queue exceeded limit; queuedBytes=${N}, limitBytes=${Ta}; destroying`),C?.(q),d.destroy();return}let H=d.write(B,(q)=>{if(!q&&!d.destroyed&&d.writableLength===0)this.state.controlConnections.get(d)?.refreshIdle(),x.flushed();C?.(q)});if(x.written(),T)T(d.writableLength,O);if(!H)this.state.controlConnections.get(d)?.startBackpressureIdle(),e.debug(`Daemon RPC socket ${c} backpressured; awaiting drain`)}catch(B){if(C?.(B instanceof Error?B:Error(r(B))),e.warn(`Daemon RPC write failed for ${c}: ${B}`),!d.destroyed)d.destroy()}}}var ye=(d)=>so((c)=>Boolean(c),{message:d});function Ft(d){return(c)=>{let R=c!==null&&typeof c==="object"&&!Array.isArray(c)?c:{},C=d.safeParse(R);if(!C.success)throw Error(C.error.issues[0].message);return C.data}}var mf=Ft(f({key:ye("setFeatureFlag requires 'key' (string) and 'enabled' (boolean) params"),enabled:so((d)=>typeof d==="boolean",{message:"setFeatureFlag requires 'key' (string) and 'enabled' (boolean) params"}),config:so(()=>!0)})),_a="setSessionToolEnabled requires sessionUuid, a user-configurable toolName, and enabled boolean params",ff=Ft(f({sessionUuid:ye(_a),toolName:so((d)=>Boolean(d)&&wf().isUserConfigurableTool(d),{message:_a}),enabled:so((d)=>typeof d==="boolean",{message:_a})})),uf="updateService requires 'deviceId' (string) and 'platform' (string) params",hf=Ft(f({deviceId:ye(uf),platform:ye(uf).refine((d)=>d==="android"||d==="ios",(d)=>({message:`Invalid platform: ${d}. Must be 'android' or 'ios'.`})),force:hr()}).transform(({deviceId:d,platform:c,force:R})=>({deviceId:d,platform:c,force:R===!0}))),Ri="setKeyValue requires deviceId, appId, fileName, key, and type params",gf=Ft(f({platform:so(()=>!0),deviceId:ye(Ri),appId:ye(Ri),fileName:ye(Ri),key:ye(Ri),type:ye(Ri),value:so(()=>!0)})),Fn="removeKeyValue requires deviceId, appId, fileName, and key params",vf=Ft(f({platform:so(()=>!0),deviceId:ye(Fn),appId:ye(Fn),fileName:ye(Fn),key:ye(Fn)})),Fa="clearKeyValueFile requires deviceId, appId, and fileName params",Sf=Ft(f({platform:so(()=>!0),deviceId:ye(Fa),appId:ye(Fa),fileName:ye(Fa)}));var JD={"ide/status":"startupProbe","ide/ping":"startupProbe","ide/updateService":"deviceMutation","ide/setKeyValue":"deviceMutation","ide/removeKeyValue":"deviceMutation","ide/clearKeyValueFile":"deviceMutation"};function bf(d){return new Set(Object.entries(JD).filter(([,c])=>c===d).map(([c])=>c))}var Rf=bf("startupProbe"),Na=bf("deviceMutation"),it={"ide/setFeatureFlag":mf,"ide/setSessionToolEnabled":ff,"ide/updateService":hf,"ide/setKeyValue":gf,"ide/removeKeyValue":vf,"ide/clearKeyValueFile":Sf};var Re=(d,c)=>so(d,{message:c}),ft=(d,c)=>so((R)=>R===void 0||d(R),{message:c}),La=(d)=>typeof d==="string",Ha=(d)=>typeof d==="string"&&d.length>0,ot=(d)=>typeof d==="number"&&Number.isFinite(d),Af=(d)=>typeof d==="number"&&Number.isInteger(d),Pf=(d)=>typeof d==="boolean",Di=(d)=>Re((c)=>c==="android"||c==="ios",`${d} requires platform 'android' or 'ios'`),Lt=(d)=>ft(La,`${d} deviceId must be a string when provided`),ki=(d)=>ft(Ha,`${d} frameContext must be a non-empty string when provided`),kf=["home","back","menu","power","volume_up","volume_down","recent","app_switch"],jD=f({platform:Di("input/tap"),x:Re(ot,"input/tap requires numeric x and y params"),y:Re(ot,"input/tap requires numeric x and y params"),duration:ft(Af,"input/tap duration must be an integer number of milliseconds when provided"),deviceId:Lt("input/tap"),frameContext:ki("input/tap")}).transform(({platform:d,deviceId:c,x:R,y:C,duration:T,frameContext:B})=>({platform:d,deviceId:c,x:R,y:C,duration:T,frameContext:B})),Ln="input/swipe requires numeric startX, startY, endX, and endY params",zD=f({platform:Di("input/swipe"),startX:Re(ot,Ln),startY:Re(ot,Ln),endX:Re(ot,Ln),endY:Re(ot,Ln),durationMs:ft((d)=>Af(d)&&d>=1&&d<=60000,"input/swipe durationMs must be integer milliseconds between 1 and 60000"),deviceId:Lt("input/swipe"),frameContext:ki("input/swipe")}).transform(({platform:d,deviceId:c,startX:R,startY:C,endX:T,endY:B,durationMs:O,frameContext:x})=>({platform:d,deviceId:c,startX:R,startY:C,endX:T,endY:B,durationMs:O??300,frameContext:x})),YD=["platform","deviceId","text","submit","mode","frameContext","sessionUuid"],XD=f({platform:Di("input/typeText"),text:Re(Ha,"input/typeText requires non-empty string text param"),submit:ft(Pf,"input/typeText submit must be a boolean when provided"),deviceId:Lt("input/typeText"),frameContext:ki("input/typeText"),mode:ft((d)=>d==="append",'input/typeText mode must be "append" when provided')}).transform(({platform:d,deviceId:c,text:R,submit:C,mode:T,frameContext:B})=>({platform:d,deviceId:c,text:R,submit:C??!1,append:T==="append",frameContext:B})),QD=f({platform:Di("input/pressButton"),button:so(La,{message:"input/pressButton requires button"}).refine((d)=>kf.includes(d),{message:`input/pressButton button must be one of: ${kf.join(", ")}`}),deviceId:Lt("input/pressButton"),frameContext:ki("input/pressButton")}).transform(({platform:d,deviceId:c,button:R,frameContext:C})=>({platform:d,deviceId:c,button:R==="app_switch"?"recent":R,responseButton:R,frameContext:C})),ZD=["platform","deviceId","key","frameContext","sessionUuid"],ek=f({platform:Di("input/key"),key:so(La,{message:"input/key requires key"}).refine(s9,{message:`input/key key must be one of: ${bO.join(", ")}`}),deviceId:Lt("input/key"),frameContext:ki("input/key")}).transform(({platform:d,deviceId:c,key:R,frameContext:C})=>({platform:d,deviceId:c,key:R,frameContext:C}));function Tf(d){let c=`${d} requires numeric x and y params`;return f({platform:Re((R)=>R==="android",`${d} is only supported on platform 'android'`),gestureId:Re(Ha,`${d} requires a non-empty gestureId`),x:Re(ot,c),y:Re(ot,c),deviceId:Lt(d),cancel:ft(Pf,`${d} cancel must be a boolean when provided`)}).transform(({platform:R,deviceId:C,gestureId:T,x:B,y:O,cancel:x})=>({platform:R,deviceId:C,gestureId:T,x:B,y:O,cancel:x===!0}))}function ht(d,c,R){return(C)=>{if(!C||typeof C!=="object"||Array.isArray(C))throw Error(`${d} requires params object`);if(R){let B=Object.keys(C).filter((O)=>!R.includes(O));if(B.length>0)throw Error(`${d} unsupported params: ${B.join(", ")}`)}let T=c.safeParse(C);if(!T.success)throw Error(T.error.issues[0].message);return T.data}}var $n=ht("input/tap",jD),qn=ht("input/swipe",zD),Un=ht("input/typeText",XD,YD),Kn=ht("input/pressButton",QD),Gn=ht("input/key",ek,ZD),tk=new Map(["input/gestureStart","input/gestureMove","input/gestureEnd"].map((d)=>[d,ht(d,Tf(d))]));function $t(d,c){return(tk.get(c)??ht(c,Tf(c)))(d)}var Mf=[{method:"input/tap",handler:"tap",parse:$n,dispatchHeld:!0},{method:"input/swipe",handler:"swipe",parse:qn,dispatchHeld:!0},{method:"input/typeText",handler:"typeText",parse:Un,dispatchHeld:!0},{method:"input/pressButton",handler:"pressButton",parse:Kn,dispatchHeld:!0},{method:"input/key",handler:"key",parse:Gn,dispatchHeld:!0},{method:"input/gestureStart",handler:"gesture",gestureKind:"start",parse:(d)=>$t(d,"input/gestureStart"),dispatchHeld:!1},{method:"input/gestureMove",handler:"gesture",gestureKind:"move",parse:(d)=>$t(d,"input/gestureMove"),dispatchHeld:!1},{method:"input/gestureEnd",handler:"gesture",gestureKind:"end",parse:(d)=>$t(d,"input/gestureEnd"),dispatchHeld:!1}],rk=new Map(Mf.map((d)=>[d.method,d]));function Ef(d){return rk.get(d)}var Ht=new Set(Mf.filter((d)=>d.dispatchHeld).map((d)=>d.method)),Wn={start:"input/gestureStart",move:"input/gestureMove",end:"input/gestureEnd"};async function Bf(d,c,R,C){let T=HN(c.tasks)?.declared===!0,B=await d.callTool({name:c.params.name,arguments:R,...T&&{_meta:O6()}},C);return T?VZ(B)??B:B}async function Of(d,c,R){if(!QH(c.method))throw Error(`Unsupported daemon method: ${c.method}`);let C={...c.params};delete C._meta;let T=HN(c.tasks)?.declared===!0,B=await d.request({method:c.method,params:{...C,...T&&{_meta:O6()}}},HZ,R);return qZ(B)}function Nf(d,c){let R=WZ(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 De extends Error{charsSent;constructor(d,c){super(d);this.charsSent=c;this.name="InputTypeTextAppendError"}}class Ut extends Error{failure;constructor(d){super(ZN(d));this.failure=d;this.name="ReleasedBoundSessionError"}}function ok(d,c,R,C){return d?.context??Mn(c,R,C)}class qa{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async handleRequest(d,c,R,{receivedAtMs:C=this.state.timer.now(),handling:T}={}){let B=ok(T,R,d,C),O=this.state.sessions.get(d);if(!O)return{id:R.id,type:"mcp_response",success:!1,error:"Session not found",code:rc};if(!this.state.acceptingRequests)return this.callbacks.shuttingDownBeforeStartResponse(R);let x=this.callbacks.rejectOnHandshakeMismatch(R);if(x)return x;if(R=this.callbacks.withCanonicalToolCallDeviceIds(R),R.method===fT)return this.state.notificationSubscribers.add(d),{id:R.id,type:"mcp_response",success:!0,result:{subscribed:!0}};if([cA,e0].includes(R.method))return this.callbacks.handleResourceSubscription(d,R);if(R.method===os){let X=await UM(R,this.state.daemonState);return{id:R.id,type:"mcp_response",...X}}let N=this.callbacks.unqueuedRequest(O,c,R,B);if(N)return N;let{totalTimeoutMs:H,deadline:q}=B,G=this.callbacks.registerRequestCancellation(O,B),W=this.callbacks.socketAdmissionCancellation(R,d,c,G.signal),V,Y=()=>this.runAdmittedRequest({request:R,sessionId:d,ownerSocket:c,receivedAtMs:C,context:B,cancellation:G,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 O.requestQueue.run(Ca(R),()=>{if(!this.state.acceptingRequests)return Promise.resolve(this.callbacks.shuttingDownBeforeStartResponse(R));if(T?.onAdmitted?.(q),this.state.onFrameTrace)this.callbacks.traceFrame("admission_granted",R.id,{deviceId:J});return this.callbacks.isProvisionDeviceCall(R)?this.callbacks.runProvisionBarrier(Y,G.signal,()=>this.callbacks.mcpForwardFailureResponse({error:G.signal.reason,request:R,sessionId:d,ownerSocket:c,signal:G.signal})):Ht.has(R.method)?this.callbacks.runCancellableInputHandler((X)=>(V=X,Y()),W.signal):this.callbacks.runCancellableQueuedHandler(Y,G.signal)},{timer:this.state.timer,deadlineMs:q.value,signal:W.signal,timeoutError:(X)=>new xr({toolName:R.method==="tools/call"?R.params?.name??R.method:R.method,timeoutMs:H,origin:"UnixSocketServer.handleRequest",code:Cu,detail:X?`timed out in queue (waiting in queue for ${Ca(R)})`:"timed out in queue before admission"})}).then(async(X)=>X&&!X.success?await this.callbacks.provisionCancellationReply(R,X,G.signal.aborted?G.signal:B.owner.signal)??X:X).finally(()=>{W.dispose(),G.dispose()})}unqueuedRequest(d,c,R,C){if(R.method===cw)return this.callbacks.cancelSocketRequest(d,R);if(QH(R.method))return this.callbacks.relayTaskRequest(d,c,R,C);return}async relayTaskRequest(d,c,R,C){let T=d.sessionId,B=this.callbacks.registerRequestCancellation(d,C),O=this.callbacks.mcpRequestSignal(T,c,B.signal);try{await this.callbacks.waitForStartup(R,C.deadline,O.signal);let x=await this.callbacks.forwardMcpRequest({request:R,route:this.callbacks.sharedMcpForwardRoute(`method:${R.method}`),socketSessionId:T,signal:O.signal,totalTimeoutMs:C.totalTimeoutMs,deadline:C.deadline});return{id:R.id,type:"mcp_response",success:!0,result:x}}catch(x){return Nf(x,R)??this.callbacks.mcpForwardFailureResponse({error:x,request:R,sessionId:T,ownerSocket:c,signal:O.signal})}finally{O.dispose(),B.dispose()}}runProvisionBarrier(d,c,R){let C=d();return this.callbacks.trackRequestHandler(C.then(()=>{},()=>{})),new Promise((T,B)=>{let O=()=>T(R());if(c.aborted)O();else c.addEventListener("abort",O,{once:!0});C.then(T,B).finally(()=>c.removeEventListener("abort",O))})}shuttingDownBeforeStartResponse(d){return{id:d.id,type:"mcp_response",success:!1,error:Fh,...$N(BN())}}isProvisionDeviceCall(d){return d.method==="tools/call"&&d.params?.name==="provisionDevice"}async provisionCancellationReply(d,c,R){let C=this.state.forwardedCallKeys.get(d);if(!c||!this.callbacks.isProvisionDeviceCall(d)||C===void 0||!(R?.reason instanceof mt))return;let T=await $$.await(C,PO+Im,this.state.timer);return T===void 0?void 0:{id:d.id,type:"mcp_response",success:!0,result:T}}mcpForwardFailureResponse({error:d,request:c,sessionId:R,ownerSocket:C,signal:T}){let B=r(d),O=Sm(d,T);if(Mm(T,O)){if(e.debug(`MCP forward abandoned for ${R}: ${O?.message}`),C.destroyed)return}else{let x=d instanceof Error?d.stack:"no stack";e.error(`Error forwarding request to MCP server: ${B}`),Em(O),e.error(`Error stack: ${x}`),e.error(`Full error: ${JSON.stringify(d)}`)}return{id:c.id,type:"mcp_response",success:!1,error:B,...d instanceof Ut?{boundSessionLoss:d.failure}:{},...bi(d,O),...(d instanceof De||d instanceof Ja)&&d.charsSent!==void 0?{charsSent:d.charsSent}:{}}}async waitForStartup(d,c,R){if(!this.state.startupCompletion||this.state.startupCompleted)return;let C=c.value-this.state.timer.now(),T=()=>new t(`Daemon still starting; retry ${d.method} after startup completes`);if(C<=0)throw T();let B=this.state.startupCompletion.then(void 0,(O)=>{throw new t(`Daemon startup failed: ${r(O)}`,{cause:O})});await l(B,{timer:this.state.timer,timeoutMs:C,signal:R,label:"Daemon startup",timeoutError:T})}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:`${cw} requires a non-empty string params.requestId`};let C=d.requestCancellations.get(R);if(!C)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 T=new mt(`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} ${T.message}`),C.abort(T),{id:c.id,type:"mcp_response",success:!0,result:{cancelled:!0}}}requireRemainingMcpForwardBudget(d,c,R,C){let T=this.callbacks.remainingMcpForwardBudget({deadline:R}),B=Math.max(0,c-T);if(T>0&&(B===0||T>va))return T;let O=d.method==="tools/call"?d.params?.name??d.method:d.method;if(T<=0)throw new xr({toolName:O,timeoutMs:c,origin:"UnixSocketServer.handleRequest",detail:`spent ${c-T}ms ${C}`,...C==="waiting in queue"?{code:Cu}:{}});if(B>0){let x={code:"daemon_overloaded",retryable:!0,retryAfterMs:Cm,reason:"insufficient_forward_budget",queueWaitMs:B,remainingTimeoutMs:Math.max(0,T)};throw new zs(`Daemon overloaded while handling ${O}: spent ${B}ms ${C}, leaving ${x.remainingTimeoutMs}ms of the ${c}ms deadline. Retry after ${x.retryAfterMs}ms.`,x)}throw new xr({toolName:O,timeoutMs:c,origin:"UnixSocketServer.handleRequest",detail:`spent ${c-T}ms ${C}`})}socketAdmissionCancellation(d,c,R,C){if(!Ht.has(d.method))return{signal:C,dispose:()=>{}};return this.callbacks.mcpRequestSignal(c,R,C)}async runCancellableInputHandler(d,c){let R=new AbortController,C=!1,T=()=>{if(!C)R.abort(c?.reason)};if(c?.addEventListener("abort",T,{once:!0}),c?.aborted)T();try{return await this.callbacks.runCancellableQueuedHandler(()=>d(()=>{R.signal.throwIfAborted(),C=!0,c?.removeEventListener("abort",T)}),R.signal)}finally{c?.removeEventListener("abort",T)}}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:C,receivedAtMs:T,context:B,cancellation:O}=d,{deadline:x,owner:N}=B;try{if(c.method.startsWith("daemon/")){let q=await UM(c,this.state.daemonState,{signal:O.signal,context:{socketSessionId:R}});return{id:c.id,type:"mcp_response",...q}}if(!Rf.has(c.method))N.adopt(O.signal),await this.callbacks.waitForStartup(c,x,O.signal);let H=await this.callbacks.runLocalSocketRequest(c,R,C,{cancelSignal:O.signal,receivedAtMs:T,onOwnerSignal:(q)=>N.adopt(q),onInputDispatch:d.onInputDispatch});if(H!==void 0)return{id:c.id,type:"mcp_response",success:!0,result:H};return await this.runAdmittedMcpForward(d)}catch(H){return this.callbacks.mcpForwardFailureResponse({error:H,request:c,sessionId:R,ownerSocket:C,signal:N.signal})}}async runAdmittedMcpForward(d){let{request:c,sessionId:R,ownerSocket:C,context:T,cancellation:B}=d,{totalTimeoutMs:O,deadline:x}=T,N,H=()=>{};try{if(c.method==="tools/call")await this.callbacks.restoreSelectorSessions(c.params?.arguments,R),N=this.callbacks.beginMcpSessionOwnerCall(c.params?.arguments,R,B.signal);let q=this.callbacks.getMcpForwardRoute(c,R),G=q instanceof Promise?await q:q,W=this.callbacks.mcpRequestSignal(R,C,B.signal);H=W.dispose,T.owner.adopt(W.signal);let V=await this.callbacks.runMcpForwardForCurrentRoute(G,c,R,{fn:async(Y)=>{let J=this.callbacks.requireRemainingMcpForwardBudget(c,O,x,"waiting in queue"),X=Math.max(0,O-J),Z=this.callbacks.describeMcpForwardRequest(c);e.debug(`[McpForward] start executionKey=${Y.executionKey} clientKey=${Y.clientKey} socketSession=${R} requestId=${c.id} ${Z} queueWaitMs=${X} remainingTimeoutMs=${J}`);let re=this.state.timer.now();try{let ee=this.callbacks.wasRequestSessionActive(c),oe=await this.callbacks.forwardMcpRequest({request:c,route:Y,socketSessionId:R,signal:W.signal,totalTimeoutMs:O,deadline:x});if(this.callbacks.isMcpRequestOwnerCurrent(R,W.signal))this.callbacks.recordBoundMcpClientKey(c,R,Y,{sessionWasActiveBeforeForward:ee,response:oe});return oe}finally{e.debug(`[McpForward] end executionKey=${Y.executionKey} clientKey=${Y.clientKey} socketSession=${R} requestId=${c.id} ${Z} forwardMs=${this.state.timer.now()-re}`)}},chainWait:{remainingMs:()=>this.callbacks.remainingMcpForwardBudget({deadline:x}),timeoutError:(Y)=>new xr({toolName:c.method==="tools/call"?c.params?.name??c.method:c.method,timeoutMs:O,origin:"UnixSocketServer.handleRequest",detail:`spent ${O-this.callbacks.remainingMcpForwardBudget({deadline:x})}ms waiting in queue for ${Y}`,code:Cu})}});if(_6(V))return{id:c.id,type:"mcp_response",success:!1,error:Fh,...$N(NZ(V))};return{id:c.id,type:"mcp_response",success:!0,result:V}}finally{N?.(),H()}}}class Ua{timer;idGenerator;flights=new at;joinable=new Map;constructor(d,c){this.timer=d;this.idGenerator=c}read(d,c,R=0){let{request:C,route:T}=d;if(C.method!=="tools/call"||C.tasks!==void 0||!tt(C.params?.name,C.params?.arguments))return;let B={...C.params?.arguments};delete B[qu],delete B[Hu];let O=Cr({name:C.params?.name,args:B,toolSelectionProfileUuid:T.toolSelectionProfileUuid??T.sessionUuid}),x=d.deadline.value-this.timer.now();if(x<=0)return Promise.reject(this.timeoutError(d));return l(()=>this.joinFlight(O,d,c,R),{timer:this.timer,signal:d.signal,timeoutMs:x,label:`Host inventory ${C.params?.name}`,timeoutError:()=>this.timeoutError(d)})}timeoutError(d){return new xr({toolName:d.request.params?.name??"host inventory",timeoutMs:d.totalTimeoutMs,origin:"UnixSocketServer.handleRequest",detail:"waiting for shared host inventory"})}joinFlight(d,c,R,C){let T=this.selectFlight(d,c,C);return this.flights.run(T.startOrder,async()=>{try{return await R(this.sharedContext(c,T))}finally{if(this.joinable.get(d)===T)this.joinable.delete(d)}},c.signal)}selectFlight(d,c,R){let C=this.joinable.get(d);if(C&&C.startOrder>R&&C.deadlineMs>=c.deadline.value)return C;let T=this.timer.now(),B=Math.max(sA,c.totalTimeoutMs,c.deadline.value-T),O={startOrder:Aa(),deadlineMs:T+B,timeoutMs:B};return this.joinable.set(d,O),O}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 Kf(c.deadlineMs-c.timeoutMs,c.timeoutMs)}}}import{AsyncLocalStorage as sk}from"async_hooks";var Ga=new sk;function Lf(d,c,R){return Ga.run({sessionKey:d,...R!==void 0&&{taskOwnerKey:R}},c)}function $f(){return Ga.getStore()?.sessionKey}function Hf(){return Ga.getStore()?.taskOwnerKey}var qf=300000;function Uf(d,c,R,{idleCloseKey:C,chainWait:T}={}){if(C){let q=d.idleCloseKeys.get(c)??new Set;q.add(C),d.idleCloseKeys.set(c,q)}let B=d.tails.get(c),O=B??Promise.resolve(),N=(B&&T?ak(d.timer,c,B,T):O).then(()=>{if(C)d.onAcquired(C);return R()}),H=Promise.all([O,N.then(()=>{return},()=>{return})]).then(()=>{return});return d.tails.set(c,H),H.finally(()=>{if(d.tails.get(c)===H){d.tails.delete(c);let q=d.idleCloseKeys.get(c);d.idleCloseKeys.delete(c);for(let G of q??[])d.onDrained(G)}}),N}async function ak(d,c,R,C){try{await l(R,{timer:d,timeoutMs:Math.max(0,C.remainingMs()),label:`MCP forward wait for ${c}`})}catch(T){throw e.warn(`[McpForward] chain wait expired executionKey=${c}: ${r(T)}`),C.timeoutError(c)}}class Wa{state;resolveCallbacks;discoveryCache;inventoryForward;constructor(d,c){this.state=d;this.resolveCallbacks=c;this.inventoryForward=new Ua(d.timer,d.idGenerator),this.discoveryCache=new Tn(()=>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=MZ(this.state.daemonIdentity,I6(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:I6(d)}}}runKeyedMcpForward(d,c,R,C){return Uf({tails:this.state.mcpForwardTails,idleCloseKeys:this.state.mcpForwardIdleCloseKeys,timer:this.state.timer,onAcquired:(T)=>this.callbacks.clearForwardKeyIdleTimer(T),onDrained:(T)=>this.callbacks.scheduleForwardKeyIdle(T)},d,c,{idleCloseKey:R,chainWait:C})}async runMcpForwardForCurrentRoute(d,c,R,{fn:C,chainWait:T}){if(c.method==="tools/call"&&tt(c.params?.name,c.params?.arguments))return await C(d);let B=[d.executionKey],O=d;for(;;){let x=O,N=await this.callbacks.runKeyedMcpForward(x.executionKey,()=>this.callbacks.runMcpForwardAttempt(x,c,R,C),void 0,T);if(N.kind==="done")return N.value;if(O=N.route,B.push(O.executionKey),B.length>ya+1)throw new t(`MCP request ${c.id} was re-routed more than ${ya} times while waiting to run (execution keys: ${B.join(" -> ")}). The target device or session kept changing; retry once it is stable.`);e.debug(`[McpForward] rekey requestId=${c.id} initialExecutionKey=${x.executionKey} currentExecutionKey=${O.executionKey}`)}}async runMcpForwardAttempt(d,c,R,C){let T=this.callbacks.getMcpForwardRoute(c,R),B=T instanceof Promise?await T:T;if(B.executionKey!==d.executionKey)return{kind:"reroute",route:B};if(d.sessionUuid!==void 0&&B.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} -> ${B.clientKey}`),{kind:"done",value:await C(B)};return{kind:"done",value:await C(d)}}async forwardMcpRequest(d){d.signal?.throwIfAborted();let c=this.inventoryForward.read(d,(T)=>this.forwardUncachedMcpRequest(T),sf());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 C=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"),C}async forwardUncachedMcpRequest(d){let c=await Lf(d.socketSessionId,()=>this.state.mcpClientFactory(d.route.sessionUuid,d.route.toolSelectionProfileUuid,d.route.releasedSessionUuid),HN(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 V3(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)||Ir(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:C,deadline:T,originalTimeoutMs:B,signal:O}){O?.throwIfAborted();let x=this.callbacks.mcpRequestOptions(R,O),N=Vm({mcpClient:d,request:c,timeoutMs:R,options:x,admitted:(H,q)=>this.callbacks.withAdmittedBoundSession(H,q),readAdmissionArgs:(H)=>this.callbacks.boundSessionAdmissionArgs(H)});if(N)return await N;switch(c.method){case"tools/call":{let H=c.progressToken,q=this.state.idGenerator.next();this.state.forwardedCallKeys.set(c,q),i9(q,T);let G=()=>B2(q),W=x;if(H!==void 0){let V=new AbortController,Y=(re)=>this.state.timer.setTimeout(()=>V.abort(`Request timed out after ${Math.max(re,0)}ms`),Math.max(re,0)),J=Y(R),X=Math.max(T.ceiling-this.state.timer.now(),R),Z=q;G=()=>{this.state.timer.clearTimeout(J),B2(Z)},W={...x,signal:this.callbacks.combineMcpRequestSignals(O,V.signal),timeout:X,maxTotalTimeout:X,onprogress:(re)=>{this.state.timer.clearTimeout(J),T.extendOnProgress(this.state.timer.now(),B),J=Y(T.value-this.state.timer.now()),this.callbacks.pushProgressNotification(C,{requestId:c.id,progressToken:H,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,C,R);return this.callbacks.traceCallTool(c,()=>Bf(d,c,this.callbacks.withLiveDeadlineKey(V,q),W))},C).catch(async(V)=>{let Y=eE(q);if(!Y?.hasPending())return this.callbacks.textForwardFailure(q,c.params.name,V);let J=Y.timeoutError(V),X=T.value-this.state.timer.now();if(X>0)try{await l(Y.settled(),{timeoutMs:X,timer:this.state.timer,label:"Dispatched text settlement"})}catch(Z){e.debug("Dispatched text settlement wait ended",Z)}return this.state.shapeToolCallError(J,{toolName:c.params.name,source:"MCP"})})}finally{G()}}default:return await Of(d,c,x)}}textForwardFailure(d,c,R){let C=eE(d)?.timeoutError(R);if(C)return this.state.shapeToolCallError(C,{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,[av]:c}}withSocketSessionAutolockKey(d,c,R){let C=this.state.timer.now()+R;if(d===null||d===void 0)return{__mcpSessionId:c,...this.callbacks.oneShotCliMarker(c),[Uu]:R,[Nh]:C};if(!d||typeof d!=="object"||Array.isArray(d))return d;let T={...d},B=this.callbacks.honoursBoundSessionMarker(T,c);if(delete T[Hu],delete T[fm],delete T[qu],this.callbacks.recordOneShotCliConnection(c,T),delete T[pT],delete T[$o],delete T[eu],B)delete T.sessionUuid;return{...T,__mcpSessionId:c,...this.callbacks.oneShotCliMarker(c),[Uu]:R,[Nh]:C}}recordOneShotCliConnection(d,c){let R=c[uT]===!0;delete c[uT];let C=this.state.sessions.get(d);if(R&&C)C.oneShotCli=!0}oneShotCliMarker(d){return this.state.sessions.get(d)?.oneShotCli?{[pT]:!0}:{}}async createMcpClient(d,c,R){return await this.state.mcpDispatcher.connect({boundSessionUuid:d,toolSelectionProfileUuid:c,releasedSessionUuid:R,sessionKey:$f(),taskOwnerKey:Hf()})}scheduleForwardKeyIdle(d){this.callbacks.clearForwardKeyIdleTimer(d);let c=this.state.timer.setTimeout(()=>{this.callbacks.onForwardKeyIdle(d)},qf);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 Va{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),C=(T)=>tt(d.params?.name,d.params?.arguments)?{...T,executionKey:"host:inventory"}:this.callbacks.withDeviceReadLane(T,d,c);return R instanceof Promise?R.then(C):C(R)}return this.callbacks.withAdmittedBoundSession(this.callbacks.boundSessionAdmissionArgs(d),(R)=>this.callbacks.getAdmittedMcpForwardRoute(d,c,R))}withDeviceReadLane(d,c,R){let C=c.params?.name,T=c.params?.arguments;if(!d.executionKey.startsWith(ba)||typeof C!=="string"||!this.callbacks.isDeviceReadToolCall(C,T))return d;let B=d.executionKey.slice(ba.length),O=this.callbacks.getDeviceHolderSession(B);if(!O)return d;let x=this.state.daemonState.getSessionManager(),N=(G)=>G?rt(G,x):void 0,H=N(O);if([d.sessionUuid,this.callbacks.getSessionUuid(T),this.callbacks.getDeviceLabelSession(T),this.callbacks.resolveImplicitAutolockSession(R,T),this.state.daemonState.getDevicePool().resolveOwnedDeviceSessionForMcpSession?.(R,B)].some((G)=>N(G)===H))return d;return{...d,executionKey:`${d.executionKey}${qm}`}}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 C=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,C);if(d.method==="ide/getNavigationGraph")return this.callbacks.getNavigationGraphForwardRoute(d,c,C);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 B=this.callbacks.getSessionUuid(d.params),O=this.callbacks.getToolSelectionProfileUuid(d.params);if(B)return this.callbacks.sessionScopedForwardRoute(c,B,void 0,{toolSelectionProfileUuid:O});if(O)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,O,void 0);return R??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}let C=this.callbacks.getSessionUuid(d.params),T=this.callbacks.getToolSelectionProfileUuid(d.params);if(C)return this.callbacks.sessionScopedForwardRoute(c,C,void 0,{toolSelectionProfileUuid:T});if(T)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,T,void 0);return R??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getNavigationGraphForwardRoute(d,c,R){let C=this.callbacks.getSessionUuid(d.params),T=this.callbacks.getRequestArgumentScopeKey(d.params);if(C)return this.callbacks.sessionScopedForwardRoute(c,C,T);if(T)return R?{...R,executionKey:T}:this.callbacks.sharedMcpForwardRoute(T);return R??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getResourceReadForwardRoute(d,c){let R=this.callbacks.getSessionUuid(d.params);if(R){let T=d.params?.[eu]===R?R:void 0;return this.callbacks.sessionScopedForwardRoute(c,R,void 0,{releasedSessionUuid:T===R?T:void 0})}let C=d.params?.uri;return this.callbacks.sharedMcpForwardRoute(typeof C==="string"?`resource:${C}`:"resource:unknown")}beginMcpSessionOwnerCall(d,c,R){let C=this.callbacks.ownedSessionsOwnerToken(d);if(C===void 0||!this.callbacks.isMcpRequestOwnerCurrent(c,R))return;try{if(!this.state.daemonState.isInitialized())return;let T=this.state.daemonState.getDevicePool().beginMcpSessionOwnerCall?.(c,C);return()=>{try{T?.()}catch(B){e.warn(`Unable to end MCP session owner call: ${r(B)}`,B)}}}catch(T){e.warn(`Unable to begin MCP session owner call: ${r(T)}`,T);return}}getToolsCallForwardRoute(d,c,R){return this.callbacks.withAdmittedBoundSession(d,(C)=>this.callbacks.getAdmittedToolsCallForwardRoute(d,c,R,C),c)}getAdmittedToolsCallForwardRoute(d,c,R,C){let T=this.callbacks.getRequestArgumentScopeKey(d),B=this.callbacks.getBoundMcpClientRoute(c,C),O=this.callbacks.getSessionUuid(d),x=this.callbacks.getToolSelectionProfileUuid(d)??B?.toolSelectionProfileUuid;if(this.callbacks.isUnboundDeviceAcquisitionTool(R,O))return this.callbacks.acquisitionMcpForwardRoute(c,R,x);if(this.callbacks.hasImplicitDeviceSelector(d))return this.callbacks.selectorMcpForwardRoute(c,d,T,x);if(O)return this.callbacks.profileReaffirmForwardRoute({args:d,socketSessionId:c,toolName:R,sessionUuid:O,toolSelectionProfileUuid:x,scopedKey:T,boundRoute:B})??this.callbacks.sessionScopedForwardRoute(c,O,T,{toolSelectionProfileUuid:x});if(x)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,x,T);if(T){if(B)return{...B,executionKey:T};return this.callbacks.sharedMcpForwardRoute(T)}if(B)return this.callbacks.hostInventoryOrBoundRoute(B,R,d);let N=this.callbacks.getImplicitAutolockScopeKey(c,d);if(N)return this.callbacks.sharedMcpForwardRoute(N);return this.callbacks.sharedMcpForwardRoute(`socket:${c}`)}hostInventoryOrBoundRoute(d,c,R){return tt(c,R)?{...d,executionKey:"host:inventory"}:d}isUnboundDeviceAcquisitionTool(d,c){return typeof d==="string"&&_m.has(d)&&!c}profileReaffirmForwardRoute(d){let{args:c,socketSessionId:R,toolName:C,sessionUuid:T,toolSelectionProfileUuid:B,scopedKey:O,boundRoute:x}=d;if(C!==bt||T!==B)return;let N=this.callbacks.getAcquiredDeviceSessionUuid(c,T)??x?.sessionUuid;if(!N||!this.callbacks.hasActiveDaemonSession(N))return;return this.callbacks.sessionScopedForwardRoute(R,N,O,{toolSelectionProfileUuid:B})}getAcquiredDeviceSessionUuid(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return;let R=d[$o];return Ze(R)&&R!==c?R:void 0}selectorMcpForwardRoute(d,c,R,C){let T=R??this.callbacks.getImplicitAutolockScopeKey(d,c)??`socket:${d}`;return C?this.callbacks.toolSelectionProfileScopedForwardRoute(d,C,T):this.callbacks.sharedMcpForwardRoute(T)}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 C=`socket:${d}:acquisition:${c}`;return{executionKey:C,clientKey:R?`${C}:tool-selection:${R}`:C,toolSelectionProfileUuid:R}}sessionMcpClientKey(d,c,R,C){let T=R?`:tool-selection:${R}`:"";return`socket:${d}:session:${c}${T}${C?":released-resource":""}`}toolSelectionProfileMcpClientKey(d,c){return`socket:${d}:tool-selection:${c}`}sessionScopedForwardRoute(d,c,R,{toolSelectionProfileUuid:C,releasedSessionUuid:T}={}){return{executionKey:R??`session:${c}`,clientKey:this.callbacks.sessionMcpClientKey(d,c,C,T),sessionUuid:c,toolSelectionProfileUuid:C,releasedSessionUuid:T}}toolSelectionProfileScopedForwardRoute(d,c,R){return{executionKey:R??`tool-selection:${c}`,clientKey:this.callbacks.toolSelectionProfileMcpClientKey(d,c),toolSelectionProfileUuid:c}}}class Za{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(N){e.warn(`Unable to declare MCP session owner token: ${r(N)}`,N)}let C=this.callbacks.selectorSessionIds(d);if(!C)return;let T=this.state.daemonState.getDevicePool(),B=this.state.clientSockets.get(c),O=await T.restoreOwnedDeviceSessionsForMcpSession?.(C,c,R)??[];if(this.callbacks.releaseBindingsIfSocketDisconnected(c,B,T))return;let x=new Set(O.map((N)=>N.sessionId));await T.restoreAutolockSessionsForMcpSession?.(C.filter((N)=>!x.has(N)),c),this.callbacks.releaseBindingsIfSocketDisconnected(c,B,T),this.callbacks.failIfCallTargetsRefusedRestore(d,O)}failIfCallTargetsRefusedRestore(d,c){let R=d&&typeof d==="object"&&!Array.isArray(d)?d:{};for(let{sessionId:C,deviceId:T,reason:B}of c)if(e.warn(`[McpForward] skipped restoring owned session ${C} on ${T}: ${B}`),R.sessionUuid===C||R.deviceId===T)throw NC(T)}ownedSessionsOwnerToken(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[qu];return typeof c==="string"&&c.trim()!==""?c:void 0}selectorSessionIds(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[fm];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:C,response:T}){if(d.method!=="tools/call")return;if(uo(d.params?.name))return;let B=this.callbacks.getSessionUuid(d.params?.arguments);if(!B){this.callbacks.recordGeneratedToolSelectionProfile(d,T,c,R);return}if(this.callbacks.isReleasedBoundSession(d.params?.arguments,c)&&this.callbacks.isRetryableSessionRecoveryResult(T,B))return;this.callbacks.recordSessionBoundMcpClientKey(c,R,R.sessionUuid??B,{sessionWasActiveBeforeForward:C,toolName:d.params?.name,args:d.params?.arguments})}holdsSession(d,c){let R=c.split(":",1)[0]??c,C=this.state.boundMcpClientKeysBySocketSession.get(d)?.sessionUuid;if(C!==void 0&&(C===c||C===R))return!0;if(!this.state.daemonState.isInitialized())return!1;let T=this.state.daemonState.getDevicePool();return T.isSessionOwnedByConnection?.(c,d)===!0||T.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[$o]!==R)return!1;if(R===void 0||!c||!this.state.daemonState.isInitialized())return!0;let C=this.state.daemonState.getSessionManager(),T=C.ownershipSessionUuid?.(R)??R,B=C.peekSession?.(T)?.livenessOwnerToken;return!B||this.callbacks.ownedSessionsOwnerToken(d)===B||!this.callbacks.isSessionOwnedByOtherConnection(R,c)}isRetryableSessionRecoveryResult(d,c){if(!d||typeof d!=="object"||!("isError"in d)||d.isError!==!0)return!1;let R=Sn(d)?.payload.error;return R?.code==="session_recovery_pending"&&R.retryable===!0&&R.sessionUuid===c}recordSessionBoundMcpClientKey(d,c,R,{sessionWasActiveBeforeForward:C,toolName:T,args:B}){if(this.callbacks.isReleasedBoundSession(B,d)){this.callbacks.clearBoundMcpClientKey(d);return}if(this.callbacks.isSessionOwnedByOtherConnection(R,d))return;if(this.callbacks.targetsOneCallOnly(B,R))return;let O=this.callbacks.hasActiveDaemonSession(R);if((C||T==="executePlan")&&!O){this.callbacks.clearBoundMcpClientKey(d);return}this.state.boundMcpClientKeysBySocketSession.set(d,{clientKey:c.clientKey,executionKey:c.executionKey,sessionUuid:R,toolSelectionProfileUuid:c.toolSelectionProfileUuid,requiresLiveDaemonSession:C||O})}targetsOneCallOnly(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return!1;let R=d[$o];return Ze(R)&&R!==c}recordGeneratedToolSelectionProfile(d,c,R,C){let T=this.callbacks.getGeneratedToolSelectionProfileUuid(d,c);if(!T)return!1;return this.state.boundMcpClientKeysBySocketSession.set(R,{clientKey:C.clientKey,executionKey:C.executionKey,toolSelectionProfileUuid:T,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[Hu];return Ze(c)?c:void 0}getGeneratedToolSelectionProfileUuid(d,c){if(d.params?.name!==bt)return;return Ff(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 Ut({code:XN,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,C=this.callbacks.getSessionUuid(R);return C!==void 0&&this.callbacks.honoursBoundSessionMarker(R,c)&&!this.callbacks.hasActiveDaemonSession(C)}boundSessionAdmissionArgs(d){let c=this.callbacks.getSessionUuid(d.params);return d.method==="resources/read"&&c!==void 0&&d.params?.[eu]===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 C=this.callbacks.getSessionUuid(d);return this.callbacks.admitReleasedBoundSession(C).then(()=>c(C))}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 Ut({code:XN,sessionUuid:d,reason:c?.releaseReason??"session-not-found",...ui(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),C=typeof d.device==="string"&&d.device.length>0;if(R&&C)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),C=this.state.daemonState.getDevicePool().resolveAutolockSessionForMcpSession?.(d,R);if(!C)return;return C}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 C=R[c];return typeof C==="string"&&C.length>0?C: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 ck}from"crypto";class ed{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 C=this.ports.acceptanceDiscoveryCapability();return{structuredSessionNotFound:!0,structuredToolErrorCodes:!0,version:this.ports.daemonIdentity().version,pid:process.pid,launchNonce:E(g.DAEMON_LAUNCH_NONCE),buildId:this.ports.daemonIdentity().build.buildId,entryScript:this.ports.daemonIdentity().build.entryScript,acceptanceCapabilityFingerprint:C?ck("sha256").update(C).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:EL(this.ports.identitySockets()??{}),unavailableSockets:I5(),effectiveDebug:Jl(),options:this.ports.startupOptions(),...ad(this.ports.processGenerationToken()),activeProvisioning:j.hasActiveToolExecution("provisionDevice",{scope:"global"}),releaseVersion:en(Ce()),android:{ctrlProxy:{expectedSha256:wv(),url:Am()}},ios:{xcTestService:{expectedSha256:Iw(),expectedAppHash:SW,url:Ew()}}}}async ideUpdateService(d,c,R){let C=it["ide/updateService"](d.params),{devices:T,deviceId:B}=await this.ports.resolveIdeActionDevices(C.platform,C.deviceId,R?.signal);await this.ports.reconcileDiscoveryObservation(T,"socket:ide/updateService"),this.ports.assertDeviceActionable(B,"to update the accessibility service");let O=T.find((x)=>x.deviceId===B);if(!O)throw Error(`Device not found: ${C.deviceId}`);if(await this.ports.daemonState().getDevicePool().isShutdownReserved?.(O.deviceId))throw Error(`Device '${O.deviceId}' is shutting down.`);if(await this.assertIdeMutationOwnership(d,O,"ide/updateService",{force:C.force,ideMutation:R}),C.platform==="android"){R?.signal.throwIfAborted(),R?.dispatching(),k.resumeAfterDeviceStart(O.deviceId);let N=await ce.getInstance(O).ensureCompatibleVersion({allowDownloadWhenInstalled:!0,bypassVersionCheckCache:!0});return{success:new Set(["compatible","upgraded","installed","reinstalled"]).has(N.status),message:`Accessibility service ${N.status}${N.error?`: ${N.error}`:""}`,status:N}}else{let x=ge.getInstance(O);return R?.signal.throwIfAborted(),R?.dispatching(),_.resumeAfterDeviceStart(O.deviceId),await x.forceRestart(),{success:!0,message:"CtrlProxy iOS restarted"}}}async ideSetKeyValue(d,c,R){let C=it["ide/setKeyValue"](d.params);await this.ports.assertSocketToolEnabled(C.deviceId,"setKeyValue");let{platform:T,client:B,device:O}=await this.resolveKeyValueMutationClient(C.platform,C.deviceId,d,{action:"ide/setKeyValue",ideMutation:R}),{appId:x,fileName:N,key:H}=C,q=!1,G;if(C.value===null||C.value===void 0)({usedDirectFileFallback:q,resolution:G}=await this.ports.runIdeKeyValueMutation(T,O,x,{fileName:N,ideMutation:R,viaSdk:(J)=>B.removePreference(x,N,H,{onDispatch:J}),viaDirectFile:(J)=>uE(J,O.deviceId,{appId:x,fileName:N},H)}));else{let J={key:H,value:C.value,type:C.type};vU(T,J.type),{usedDirectFileFallback:q,resolution:G}=await this.ports.runIdeKeyValueMutation(T,O,x,{fileName:N,ideMutation:R,viaSdk:(X)=>B.setPreference(x,N,J,{onDispatch:X}),viaDirectFile:(X)=>SU(X,O.deviceId,{appId:x,fileName:N},J)})}let W=G?.resolvedStore,V=G?.effectiveValueDiffers,Y=bU(q?Rb(x,N):void 0,V);return{success:!0,...W?{resolvedStore:W}:{},...V?{effectiveValueDiffers:V}:{},...Y?{warning:Y}:{}}}async ideRemoveKeyValue(d,c,R){let C=it["ide/removeKeyValue"](d.params);await this.ports.assertSocketToolEnabled(C.deviceId,"removeKeyValue");let{platform:T,client:B,device:O}=await this.resolveKeyValueMutationClient(C.platform,C.deviceId,d,{action:"ide/removeKeyValue",ideMutation:R}),{appId:x,fileName:N,key:H}=C,{usedDirectFileFallback:q,resolution:G}=await this.ports.runIdeKeyValueMutation(T,O,x,{fileName:N,ideMutation:R,viaSdk:(Y)=>B.removePreference(x,N,H,{onDispatch:Y}),viaDirectFile:(Y)=>uE(Y,O.deviceId,{appId:x,fileName:N},H)}),W=G?.resolvedStore,V=q?Rb(x,N):void 0;return{success:!0,...W?{resolvedStore:W}:{},...V?{warning:V}:{}}}async ideClearKeyValueFile(d,c,R){let C=it["ide/clearKeyValueFile"](d.params);await this.ports.assertSocketToolEnabled(C.deviceId,"clearKeyValueFile");let{platform:T,client:B,device:O}=await this.resolveKeyValueMutationClient(C.platform,C.deviceId,d,{action:"ide/clearKeyValueFile",ideMutation:R}),{appId:x,fileName:N}=C,{usedDirectFileFallback:H,resolution:q}=await this.ports.runIdeKeyValueMutation(T,O,x,{fileName:N,ideMutation:R,viaSdk:(V)=>B.clearPreferenceStore(x,N,{onDispatch:V}),viaDirectFile:(V)=>wU(V,O.deviceId,x,{fileName:N})}),G=q?.resolvedStore,W=H?Rb(x,N):void 0;return{success:!0,...G?{resolvedStore:G}:{},...W?{warning:W}:{}}}async assertIdeMutationOwnership(d,c,R,{force:C=!1,ideMutation:T}={}){let B=c.deviceId,O=AW(d.method,d.params);if(!this.ports.daemonState().isInitialized())return;await this.assertFrameTargetProven(c,R,()=>O),this.ports.assertBrokerConnectionControl(T?.socketSessionId,R,{deviceId:B,requesterSessionUuid:O});let x=this.ports.daemonState().getSessionManager();await Tv({action:R,deviceId:B,platform:c.platform,requesterSessionUuid:O,sessionManager:x,gate:this.ports.daemonState().getDevicePool()}),await km({deviceId:B,platform:c.platform,gate:this.ports.daemonState().getDevicePool()});let N=x.getSessionForDevice?.(B)??void 0;if(!C)ou({action:R,deviceId:B,ownerSessionUuid:N,requesterSessionUuid:O,sessionManager:x,remedy:"pass the holding session's sessionUuid, or wait for the holder to release the device."});if(N)await this.admitIdeMutationOnHolderSession(j.startExecution(R,void 0,N),{deviceId:B,holderSessionUuid:N,force:C},T)}async admitIdeMutationOnHolderSession(d,c,R){R?.track(d,!c.force);try{if(j.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 j.markSessionAdmitted(d.id)}finally{if(!R)j.endExecution(d.id)}}async runTrackedIdeMutation(d,c,R){let C=new AbortController,T,B,O,x=R?AbortSignal.any([R,C.signal]):C.signal,N={socketSessionId:d,signal:x,admit:(H)=>{O=H},dispatching:()=>{if(O)j.markSessionAdmitted(O.id)},track:(H,q)=>{if(T=H,!q)return;B=H;let G=H.abortController.signal;if(G.aborted){C.abort(G.reason);return}G.addEventListener("abort",()=>C.abort(G.reason),{once:!0})}};try{return x.throwIfAborted(),await U(x,()=>c(N))}catch(H){throw Fp(B?.cancelReason)??H}finally{if(T)j.endExecution(T.id)}}async listBootedDevicesForIdeAction(d,c,R){R?.throwIfAborted();let C=Tt.getInstance(),T=Bl(await C.getBootedDevicesDetailed(d),this.ports.daemonState()?.isInitialized()?this.ports.daemonState().getDevicePool().getAllDevices?.():void 0);if(!T.devices.map((B)=>B.deviceId).includes(c)&&TN(T,d,c)){let B=T.discoveryErrors?.[d];throw d==="android"?new Gr(B):new Ve(d,B)}return R?.throwIfAborted(),T.devices}async resolveIdeActionDevices(d,c,R){let C=await this.canonicalFrameDiscovery(d,await this.ports.listBootedDevicesForIdeAction(d,c,R),c);return{devices:C.devices,deviceId:C.deviceId??c}}async canonicalFrameDiscovery(d,c,R){return await OM(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 C=this.ports.daemonState().getSessionManager();await MM(this.ports.daemonState().getDevicePool(),d,c,{heldBySession:Boolean(C.getSessionForDevice?.(d.deviceId)),sessions:MP(C),requester:R,sessionManager:C})}canonicalFrameDeviceId(d){return Cp(this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool():void 0,d)}async resolveKeyValueMutationClient(d,c,R,{action:C,ideMutation:T}){let B=d??"android";if(B!=="android"&&B!=="ios")throw Error(`Invalid platform: ${B}. Must be 'android' or 'ios'.`);let{devices:O,deviceId:x}=await this.ports.resolveIdeActionDevices(B,c,T?.signal);await this.ports.reconcileDiscoveryObservation(O,"socket:ide/keyValueMutation"),this.ports.assertDeviceActionable(x,"to mutate stored values");let N=O.find((q)=>q.deviceId===x);if(!N)throw Error(`Device not found: ${c}`);await this.assertIdeMutationOwnership(R,N,C,{ideMutation:T}),T?.signal.throwIfAborted();let H=B==="ios"?_.getInstance(N):k.getInstance(N,this.ports.adbClientFactory());return{platform:B,client:H,device:N}}async runIdeKeyValueMutation(d,c,R,C){let T=!1,{fileName:B}=C,O=()=>{if(T)return;T=!0,C.ideMutation?.dispatching()};if(d!=="android")return C.ideMutation?.signal.throwIfAborted(),{usedDirectFileFallback:!1,resolution:await C.viaSdk(O)||void 0};let x;return{...await RU(R,B,()=>this.ports.adbClientFactory().create(c),{viaSdk:async()=>{C.ideMutation?.signal.throwIfAborted(),x=await C.viaSdk(O)||void 0},viaDirectFile:(H)=>(C.ideMutation?.signal.throwIfAborted(),O(),C.viaDirectFile(H).catch(mM))}),resolution:x}}}function Gf(d){return new Map([["ide/listFeatureFlags",async()=>({flags:await d.requireFeatureFlagService().listFlags()})],["ide/setFeatureFlag",async(c,R)=>{let C=d.requireFeatureFlagService(),T=it["ide/setFeatureFlag"](c.params);return d.assertBrokerHostMutation(R,"ide/setFeatureFlag"),await C.setFlag(T.key,T.enabled,T.config)}],["ide/setSessionToolEnabled",async(c,R)=>{let C=it["ide/setSessionToolEnabled"](c.params);return d.assertBrokerControl(R,"ide/setSessionToolEnabled",{requesterSessionUuid:C.sessionUuid}),await d.sessionToolSelection().setEnabled(C.sessionUuid,C.toolName,C.enabled),d.emitToolsListChanged(),{sessionUuid:C.sessionUuid,toolName:C.toolName,enabled:C.enabled}}],["ide/ping",async()=>({ok:!0,timestamp:d.now()})]])}function Wf(d){return new Map([[$1,async(c)=>await d.republishIdentity(c.params)],[U1,async(c)=>d.restart.prepareDaemonRestart(c.params)],[H1,async(c)=>d.restart.prepareDaemonMaintenance(c.params)],[q1,async(c)=>d.restart.completeDaemonMaintenance(c.params)],[V1,async(c)=>d.restart.restartAdmittedDaemon(c.params)],[W1,async(c,R)=>d.restart.restartAcceptanceSession(c.params,R)],[z1,async(c,R)=>d.restart.commitAcceptanceRestart(c.params,R)],[j1,async(c,R)=>d.restart.releaseAcceptanceRestart(c.params,R)]])}function Vf(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 C=r(c),T=d==="input/key"?ja.indeterminateError(c):d==="input/tap"?fn(C):new t(`${d==="input/swipe"?"Swipe":"Button press"} outcome is indeterminate: the request was dispatched but no result was confirmed (${C}). Do not retry automatically.`);return Object.assign(T,{requestDispatched:!0})}class id{ports;constructor(d){this.ports=d}requireCurrentFrameContext(d,c,R){if(c===void 0)return;if(Rt()?.getCurrentFrameContext(d)!==c)throw Error(`${R} frameContext is stale or unavailable; observe a fresh frame before retrying`)}inputRequester(d,c){let R=AW(d.method,d.params);return()=>{if(R||!c||!this.ports.daemonState().isInitialized())return R;let C=lf(d.params);if(!C)return;return this.ports.daemonState().getDevicePool().resolveAutolockSessionForMcpSession?.(c,C)}}async resolveInputTargetDevice(d,c,R,{action:C,bypassAndroidDeviceListCache:T=!1,requester:B}){let O=await this.ports.selectInputTargetDevice(d,c,R,{action:C,bypassAndroidDeviceListCache:T});return await this.ports.assertFrameTargetProven(O,C,B),this.ports.assertBrokerConnectionInputTarget(R,C,O.deviceId),this.ports.captureInputTargetOwner(O),O}assertBrokerConnectionInputTarget(d,c,R){this.ports.assertBrokerConnectionControl(d,c,{deviceId:R})}assertBrokerConnectionControl(d,c,R){if(!this.ports.daemonState().isInitialized())return;let C=this.ports.daemonState().getSessionManager(),T=iv({binding:this.ports.daemonState().getBrokerConnectionScopes?.().get(d),action:c,deviceId:R.deviceId,requesterSessionUuid:R.requesterSessionUuid,grantedDeviceOf:(B)=>C.getSession(B)?.assignedDevice});if(T)throw T}assertBrokerConnectionHostMutation(d,c){if(!this.ports.daemonState().isInitialized())return;let R=ZS({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:C,bypassAndroidDeviceListCache:T=!1}){let{devices:B,deviceId:O}=await this.ports.discoverInputTargetDevices(d,C,T,c);if(O){let H=B.find((q)=>q.deviceId===O);if(!H)throw Error(`Device not found: ${c}`);return H}let x=this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool().resolveAutolockSessionForMcpSession?.(R,d):void 0,N=x?this.ports.daemonState().getSessionManager().getSession(x)?.assignedDevice:void 0;if(N){let H=B.find((q)=>q.deviceId===N);if(!H)throw Error(`Device not found: ${N}`);return H}if(B.length===1)return B[0];if(B.length===0)throw Error(`No booted ${d} devices found for ${C}`);throw Error(`${C} requires deviceId when multiple ${d} devices are booted`)}async runTrackedKeyedDeviceInput(d,c,R,C){let T=`device:${c.deviceId}`;return await this.ports.runTrackedDeviceInput(d,c,async(B,O)=>this.ports.runKeyedMcpForward(T,()=>(B?.throwIfAborted(),this.ports.runHeldInputOperation(d,B,R,()=>{C?.onDispatch?.(),O?.()})),T,C?.chainWait),{ownerSignal:C?.ownerSignal,requester:C?.requester})}inputDeviceGate(d,c,R,{budgetStartMs:C,input:T}){let B=()=>R-(this.ports.timer().now()-C);return{onDispatch:T?.onDispatch,ownerSignal:T?.signal,requester:T?.requester,chainWait:{remainingMs:B,timeoutError:(O)=>new xr({toolName:d,timeoutMs:R,origin:c,detail:`spent ${R-B()}ms waiting in queue for ${O}`,code:Cu})}}}async runHeldInputOperation(d,c,R,C){if(!Ht.has(d)||d==="input/typeText")return R(c,C);let T=!1,B=()=>{if(!T)C(),T=!0};try{let O=await R(c,B);return c?.throwIfAborted(),O}catch(O){if(T&&c?.aborted)throw Vf(d,O);if(c?.reason instanceof DOMException&&c.reason.name==="AbortError")o(c);throw c?.throwIfAborted(),O}}dispatchFencedInput(d,c,R,{send:C,onDispatch:T}){return this.ports.runHeldInputOperation(`input/${d.toLowerCase()}`,c,(B,O)=>this.ports.holdDispatchedInputRequest(c,R,C,{onDispatch:O,label:`${d} request`}),()=>T?.())}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 Tv({action:d,deviceId:c.deviceId,platform:c.platform,requesterSessionUuid:R?.(),sessionManager:this.ports.daemonState().getSessionManager(),gate:this.ports.daemonState().getDevicePool()}),await km({deviceId:c.deviceId,platform:c.platform,gate:this.ports.daemonState().getDevicePool()})}async runTrackedDeviceInput(d,c,R,{ownerSignal:C,requester:T}){this.ports.assertDeviceActionable(c.deviceId,"to run");let B=this.ports.daemonState().isInitialized()?this.ports.daemonState().getSessionManager():void 0,O=B?.getSessionForDevice?.(c.deviceId)??void 0;if(await this.ports.assertInputBindingGate(d,c,T),ou({action:d,deviceId:c.deviceId,ownerSessionUuid:O,requesterSessionUuid:O?T?.():void 0,sessionManager:B}),O)this.ports.daemonState().getDevicePool().assertSessionReadyForAutomation?.(O);let x=this.ports.inputTargetOwners().get(c);if(x!==void 0&&x!==O)throw new Gc(x,c.deviceId,`Session ${x} no longer owns device '${c.deviceId}' (it was rebound or released after this input resolved its target); the input was not sent.`);let N=j.startExecution(d,void 0,O),H=N.abortController.signal;try{j.bindDeviceExecution(N.id,c.deviceId),H.throwIfAborted(),await this.ports.admitInputAsControlCall(N,c.deviceId,O,C);let q=()=>j.markSessionAdmitted(N.id);if(!O)j.markSessionlessDeviceUse(N.id,c.deviceId);let G=(W)=>Ht.has(d)?this.ports.runCancellableInputHandler((V)=>R(W,()=>{V(),q()}),W):R(W,q);return await this.ports.answeringSessionRelease(N,()=>jd({execution:{...Ul(N),deviceBinding:{bindDeviceExecution:(W)=>j.bindDeviceExecution(N.id,W)}}},()=>this.ports.runFencedInputOperation(H,C,G)))}finally{j.endExecution(N.id)}}async admitInputAsControlCall(d,c,R,C){if(!R)return;let T=d.abortController.signal;await xL({deviceId:c,holderSessionUuid:R,sessionManager:this.ports.daemonState().getSessionManager(),execution:Ul(d),signal:C?AbortSignal.any([T,C]):T}),await this.ports.answeringSessionRelease(d,async()=>d.abortController.signal.throwIfAborted())}async answeringSessionRelease(d,c){try{return await c()}catch(R){let C=Fp(d.cancelReason);if(C&&R instanceof Error&&"requestDispatched"in R&&R.requestDispatched===!0){let T=new Ja(C.sessionUuid,C.releaseReason,C.details.idleTimeoutMs),B=d.toolName==="input/typeText"||R instanceof De?"the text request":"the request";if(T.message=`${C.message} Cancellation arrived after ${B} had been dispatched; its outcome is indeterminate.`,R instanceof De)T.charsSent=R.charsSent;throw T}throw C??R}}runFencedInputOperation(d,c,R){let C=c?AbortSignal.any([d,c]):d;return C.throwIfAborted(),U(C,()=>R(C))}async discoverInputTargetDevices(d,c,R,C){let T=await Tt.getInstance().getBootedDevicesDetailed(d,{bypassAndroidDeviceListCache:R}),B=await this.ports.canonicalFrameDiscovery(d,T.devices,C);if(await this.ports.reconcileDiscoveryObservation(B.devices,`socket:${c}`),!T.succeededPlatforms.has(d))throw Error(`Unable to discover booted ${d} devices for ${c}`);return B}}class nd{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async runLocalSocketRequest(d,c,R,{cancelSignal:C,receivedAtMs:T,onOwnerSignal:B,onInputDispatch:O}){if(!Km(d.method,Na))return await this.callbacks.handleLocalSocketRequest(d,{socketSessionId:c});let x=this.callbacks.mcpRequestSignal(c,R,C);B(x.signal);try{return await this.callbacks.handleLocalSocketRequest(d,{socketSessionId:c,signal:x.signal,receivedAtMs:T,onInputDispatch:O})}finally{x.dispose()}}async handleLocalSocketRequest(d,{socketSessionId:c,signal:R,receivedAtMs:C,onInputDispatch:T}={}){if(d.method.startsWith("input/"))R?.throwIfAborted();let B={onDispatch:T,signal:R,receivedAtMs:C,requester:d.method.startsWith("input/")?this.callbacks.inputRequester(d,c):void 0},O=Ef(d.method);if(O)return await this.callbacks.dispatchInputRoute(O,d,c,B);return await this.callbacks.dispatchIdeSocketRequest(d,c,R)}async dispatchInputRoute(d,c,R,C){return await Wm(this.inputRouteHandlers,d,c,{socketSessionId:R,input:C})}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,C)=>this.callbacks.handleInputGesture(d,c,R,C)};async dispatchIdeSocketRequest(d,c,R){if(!Na.has(d.method))return await this.callbacks.handleIdeSocketRequest(d,c);return R?.throwIfAborted(),await this.callbacks.runTrackedIdeMutation(c,(C)=>this.callbacks.handleIdeSocketRequest(d,c,C),R)}ideDeviceRoutes=new ed({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,C)=>this.callbacks.runIdeKeyValueMutation(d,c,R,C)});ideRouteHandlers=new Map([...Gf({requireFeatureFlagService:()=>this.callbacks.requireFeatureFlagService(),sessionToolSelection:()=>this.state.sessionToolSelectionService??Fd(),assertBrokerHostMutation:(d,c)=>this.callbacks.assertBrokerConnectionHostMutation(d,c),assertBrokerControl:(d,c,R)=>this.callbacks.assertBrokerConnectionControl(d,c,R),emitToolsListChanged:()=>kr.emit("tools"),now:()=>this.state.timer.now()}),...Wf({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 C=this.ideRouteHandlers.get(d.method);return C?await C(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,C){return await this.ideDeviceRoutes.runIdeKeyValueMutation(d,c,R,C)}async assertSocketToolEnabled(d,c){let C=wf().getRegisteredTool(c)?.defaultEnabled??!1;if(!this.state.daemonState.isInitialized()){await sK(c,C,[void 0],{sessionToolSelectionService:this.state.sessionToolSelectionService,remediationMethodName:u6});return}let T=this.state.daemonState.getSessionManager(),B=T.getSessionForDevice?.(this.callbacks.canonicalFrameDeviceId(d))??void 0,O=rt(B,T);await sK(c,C,[O,B],{sessionToolSelectionService:this.state.sessionToolSelectionService,remediationMethodName:u6})}inputDeviceGatingInstance;get inputDeviceGating(){return this.inputDeviceGatingInstance??=new id({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,C){return await this.inputDeviceGating.resolveInputTargetDevice(d,c,R,C)}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:C,bypassAndroidDeviceListCache:T=!1}){return await this.inputDeviceGating.selectInputTargetDevice(d,c,R,{action:C,bypassAndroidDeviceListCache:T})}async runTrackedKeyedDeviceInput(d,c,R,C){return await this.inputDeviceGating.runTrackedKeyedDeviceInput(d,c,R,C)}inputDeviceGate(d,c,R,{budgetStartMs:C,input:T}){return this.inputDeviceGating.inputDeviceGate(d,c,R,{budgetStartMs:C,input:T})}async runHeldInputOperation(d,c,R,C){return await this.inputDeviceGating.runHeldInputOperation(d,c,R,C)}dispatchFencedInput(d,c,R,{send:C,onDispatch:T}){return this.inputDeviceGating.dispatchFencedInput(d,c,R,{send:C,onDispatch:T})}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,C={}){return await this.inputDeviceGating.runTrackedDeviceInput(d,c,R,C)}async admitInputAsControlCall(d,c,R,C){return await this.inputDeviceGating.admitInputAsControlCall(d,c,R,C)}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,C){return await this.inputDeviceGating.discoverInputTargetDevices(d,c,R,C)}mcpRequestOptions(d,c){return c?{timeout:d,signal:c}:{timeout:d}}combineMcpRequestSignals(d,c){return d?AbortSignal.any([d,c]):c}}function rd(d,c){if(c.signal?.aborted)return c.signal.reason;let{deviceId:R,holderSessionId:C}=c,T=(B)=>`${d} on device '${R}' was lifted: ${B} before the stroke's start was acknowledged.`;return C?new Gc(C,R,T(`session ${C} no longer holds the device`)):new ct(d,R,void 0,{message:T("a session acquired the device")})}var jf=5000;class od{ports;constructor(d){this.ports=d}async handleInputGesture(d,c,R,C){let T=Wn[c],B=this.ports.parseInputGestureParams(d.params,T),O,{targetDevice:x,result:N}=await this.ports.runInputRoute(d,R,C,{action:T,origin:"UnixSocketServer.handleInputGesture",args:B,checksFrame:!1,around:(H,q)=>this.ports.liftingStrokeOnSessionRefusal(c,R,H,{gestureId:B.gestureId,run:q}),dispatch:async({targetDevice:H,signal:q,dispatching:G,remainingTimeoutMs:W})=>{G?.();let V=k.getInstance(H,v);if(c!=="start")return this.ports.forwardGestureFrame(V,c,B,W);return O=this.ports.captureStrokeAdmission(H.deviceId,q),this.ports.forwardGestureStart(V,B,W,O)}});if(!N.success)throw Error(N.error??`${T} failed on ${B.platform}`);if(R)await this.ports.trackAckedGestureFrame(c,R,x,{gestureId:B.gestureId,startAdmission:O});return{action:T,platform:B.platform,deviceId:x.deviceId,success:!0,gestureId:B.gestureId,point:{x:B.x,y:B.y},...c==="end"?{cancel:B.cancel}:{}}}async trackAckedGestureFrame(d,c,R,{gestureId:C,startAdmission:T}){if(d==="end"){this.ports.ownedGestures().onEndAcked(c,R.deviceId,C);return}if(d!=="start")return;let B=!T||this.ports.strokeAdmissionStillHolds(T);if(await this.ports.ownedGestures().onStartAcked(c,R,C,{holderSessionId:T?.holderSessionId,admissionStillHolds:B}),T&&!B)throw rd(Wn.start,T)}async liftingStrokeOnSessionRefusal(d,c,R,{gestureId:C,run:T}){try{return await T()}catch(B){if(d!=="start"&&wm(B)){try{await this.ports.cancelGestureOnDevice(R,C)}catch(O){e.warn(`Failed to lift gesture ${C} on ${R.deviceId} after its session refused a frame: ${r(O)}`)}if(c)this.ports.ownedGestures().onEndAcked(c,R.deviceId,C)}else if(d!=="start"&&c)await this.ports.ownedGestures().cancelIfDeviceChangedHands(c,R.deviceId,C,this.ports.getSessionForDevice(R.deviceId));throw B}}captureStrokeAdmission(d,c){let R=Be()?.execution?.executionId,C=R?j.getAdmittedSessionUse(R):void 0;return{deviceId:d,...C!==void 0?{holderSessionId:C}:{},holderIncarnation:this.ports.getSessionIncarnation(C),...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,C){let T=await this.ports.forwardGestureFrame(d,"start",c,R);if(!T.success||this.ports.strokeAdmissionStillHolds(C))return T;try{await d.requestGestureEnd(c.gestureId,0,0,{cancel:!0,timeoutMs:jf})}catch(B){e.warn(`Failed to lift gesture ${c.gestureId} on ${C.deviceId} whose holder left before its start was acked: ${r(B)}`)}throw rd(Wn.start,C)}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()=>k.getInstance(d,v).requestGestureEnd(c,0,0,{cancel:!0,timeoutMs:jf}),`device:${d.deviceId}`)}forwardGestureFrame(d,c,R,C){let{gestureId:T,x:B,y:O,cancel:x}=R;switch(c){case"start":return d.requestGestureStart({gestureId:T,x:B,y:O,timeoutMs:C});case"move":return d.requestGestureMove(T,B,O,{timeoutMs:C});case"end":return d.requestGestureEnd(T,B,O,{cancel:x,timeoutMs:C})}}}class sd{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}remainingBudgetAfterProbe(d,c,R,C){let T=c-(this.state.timer.now()-d);if(T<=0)throw new xr({toolName:R,timeoutMs:c,origin:`UnixSocketServer.${C}`,detail:"iOS screen-scale probe consumed the request budget"});return T}async toIosRunnerCoordinates(d,c,R,{probeTimeoutMs:C,validateCanonicalCoordinates:T}){let B=d.getScreenScaleMetadata();if(B)return this.state.confirmedLegacyScaleDevices.delete(c),T?.(B),R.map((N)=>C5(N,B.nativeScale));if(this.state.confirmedLegacyScaleDevices.has(c))return R;let O;try{O=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,C)}catch(N){throw u(N,`Could not determine iOS screen scale for ${c}; the input coordinate scale probe failed`)}if(!O)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 x=d.getScreenScaleMetadata();if(!x)return this.state.confirmedLegacyScaleDevices.add(c),R;return T?.(x),R.map((N)=>C5(N,x.nativeScale))}requireCoordinatesWithinKnownScreenGeometry(d,c){if(!c)return;let[R,C]=d;if(R<0||R>=c.pixelWidth||C<0||C>=c.pixelHeight)throw Error(`input/tap coordinates x=${R}, y=${C} 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:KN(d)}}remainingInputBudgetMs(d,c,R,C){let T=this.state.timer.now()-R,B=C-T;if(B<=0)throw new xr({toolName:d,timeoutMs:C,origin:c,detail:`spent ${T}ms waiting in queue`});return B}async runInputRoute(d,c,R,C){let{queueEnterMs:T,totalTimeoutMs:B}=this.callbacks.inputRouteClock(d,R),{args:O}=C,x=await this.callbacks.resolveInputTargetDevice(O.platform,O.deviceId,c,{action:C.action,bypassAndroidDeviceListCache:C.bypassAndroidDeviceListCache??!1,requester:R?.requester}),N=()=>this.callbacks.runTrackedKeyedDeviceInput(d.method,x,async(q,G)=>{He(q);let W=C.reresolve?await C.reresolve(x):x;if(C.checksFrame)this.callbacks.requireCurrentFrameContext(x.deviceId,O.frameContext,C.action);let V=this.callbacks.remainingInputBudgetMs(d.method,C.origin,T,B);return await C.dispatch({targetDevice:x,executionDevice:W,signal:q,dispatching:G,remainingTimeoutMs:V,queueEnterMs:T,totalTimeoutMs:B})},this.callbacks.inputDeviceGate(d.method,C.origin,B,{budgetStartMs:T,input:R})),H=await(C.around?C.around(x,N):N());return{targetDevice:x,result:H}}async handleInputTap(d,c,R){let C=this.callbacks.parseInputTapParams(d.params),{targetDevice:T,result:B}=await this.callbacks.runInputRoute(d,c,R,{action:"input/tap",origin:"UnixSocketServer.handleInputTap",args:C,checksFrame:!0,dispatch:async({targetDevice:O,signal:x,dispatching:N,remainingTimeoutMs:H,queueEnterMs:q,totalTimeoutMs:G})=>{if(C.platform==="android"){let X=k.getInstance(O,v);return this.callbacks.requireCoordinatesWithinKnownScreenGeometry([C.x,C.y],X.getScreenScaleMetadata?.()??null),await this.callbacks.dispatchFencedInput("Tap",x,H,{send:(Z,re)=>X.requestTapCoordinates({x:C.x,y:C.y,duration:C.duration,timeoutMs:H,frameContext:C.frameContext,onDispatch:re,signal:Z}),onDispatch:N})}let W=_.getInstance(O),[V,Y]=await this.callbacks.toIosRunnerCoordinates(W,O.deviceId,[C.x,C.y],{probeTimeoutMs:H,validateCanonicalCoordinates:(X)=>this.callbacks.requireCoordinatesWithinKnownScreenGeometry([C.x,C.y],X)}),J=this.callbacks.remainingBudgetAfterProbe(q,G,d.method,"handleInputTap");return He(x),await this.callbacks.dispatchFencedInput("Tap",x,J,{send:(X,Z)=>W.requestTapCoordinates({x:V,y:Y,duration:C.duration,timeoutMs:J,frameContext:C.frameContext,signal:X,onDispatch:Z}),onDispatch:N})}});if(!B.success)throw Error(B.error??`input/tap failed on ${C.platform}`);return{action:"input/tap",platform:C.platform,deviceId:T.deviceId,success:!0,coordinates:{x:C.x,y:C.y}}}async handleInputSwipe(d,c,R){let C=this.callbacks.parseInputSwipeParams(d.params),{targetDevice:T,result:B}=await this.callbacks.runInputRoute(d,c,R,{action:"input/swipe",origin:"UnixSocketServer.handleInputSwipe",args:C,checksFrame:!0,dispatch:async({targetDevice:O,signal:x,dispatching:N,remainingTimeoutMs:H,queueEnterMs:q,totalTimeoutMs:G})=>{if(C.platform==="android"){let re=k.getInstance(O,v);return await this.callbacks.dispatchFencedInput("Swipe",x,H,{send:(ee,oe)=>re.requestSwipe({x1:C.startX,y1:C.startY,x2:C.endX,y2:C.endY,duration:C.durationMs,timeoutMs:H,contextOptions:C.frameContext,onDispatch:oe,signal:ee}),onDispatch:N})}let W=_.getInstance(O),[V,Y,J,X]=await this.callbacks.toIosRunnerCoordinates(W,O.deviceId,[C.startX,C.startY,C.endX,C.endY],{probeTimeoutMs:H}),Z=this.callbacks.remainingBudgetAfterProbe(q,G,d.method,"handleInputSwipe");return He(x),await this.callbacks.dispatchFencedInput("Swipe",x,Z,{send:(re,ee)=>W.requestDrag({x1:V,y1:Y,x2:J,y2:X,pressDurationMs:0,dragDurationMs:C.durationMs,holdDurationMs:0,timeoutMs:Z,frameContext:C.frameContext,signal:re,onDispatch:ee}),onDispatch:N})}});if(!B.success)throw Error(B.error??`input/swipe failed on ${C.platform}`);return{action:"input/swipe",platform:C.platform,deviceId:T.deviceId,success:!0,start:{x:C.startX,y:C.startY},end:{x:C.endX,y:C.endY},durationMs:C.durationMs}}async handleInputGesture(d,c,R,C){return await this.inputStrokes.handleInputGesture(d,c,R,C)}async trackAckedGestureFrame(d,c,R,{gestureId:C,startAdmission:T}){return await this.inputStrokes.trackAckedGestureFrame(d,c,R,{gestureId:C,startAdmission:T})}async liftingStrokeOnSessionRefusal(d,c,R,{gestureId:C,run:T}){return await this.inputStrokes.liftingStrokeOnSessionRefusal(d,c,R,{gestureId:C,run:T})}captureStrokeAdmission(d,c){return this.inputStrokes.captureStrokeAdmission(d,c)}strokeAdmissionStillHolds(d){return this.inputStrokes.strokeAdmissionStillHolds(d)}async forwardGestureStart(d,c,R,C){return await this.inputStrokes.forwardGestureStart(d,c,R,C)}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,C){return this.inputStrokes.forwardGestureFrame(d,c,R,C)}async handleInputPressButton(d,c,R){let C=this.callbacks.parseInputPressButtonParams(d.params),{targetDevice:T,result:B}=await this.callbacks.runInputRoute(d,c,R,{action:"input/pressButton",origin:"UnixSocketServer.handleInputPressButton",args:C,checksFrame:!0,dispatch:async({targetDevice:O,signal:x,dispatching:N,remainingTimeoutMs:H,queueEnterMs:q,totalTimeoutMs:G})=>await new En(O,null,this.state.timer,{holdRequest:(V,Y,J,X)=>this.callbacks.holdDispatchedInputRequest(V,q+G-this.state.timer.now(),J,{onDispatch:X,label:"Button press request"})}).press(C.button,{timeoutMs:H,frameContext:C.frameContext,signal:x,onDispatch:N})});if(!B.success)throw Error(B.error??`input/pressButton failed on ${C.platform}`);return{action:"input/pressButton",platform:C.platform,deviceId:T.deviceId,success:!0,button:C.responseButton}}async handleInputKey(d,c,R){let C=this.callbacks.parseInputKeyParams(d.params);if(C.platform==="ios")throw Error(o9);let{targetDevice:T,result:B}=await this.callbacks.runInputRoute(d,c,R,{action:"input/key",origin:"UnixSocketServer.handleInputKey",args:C,checksFrame:!0,dispatch:async({targetDevice:O,signal:x,dispatching:N,remainingTimeoutMs:H,queueEnterMs:q,totalTimeoutMs:G})=>await this.callbacks.executeSocketInputKey(new ja(O,{adbFactory:v,timer:this.state.timer}),{key:C.key,frameContext:C.frameContext,totalTimeoutMs:G,remainingTimeoutMs:H,signal:x,dispatching:N})});if(!B.success)throw Error(B.error??`input/key failed on ${C.platform}`);return{action:"input/key",platform:C.platform,deviceId:T.deviceId,success:!0,key:C.key}}executeSocketInputKey(d,c){let{key:R,frameContext:C,totalTimeoutMs:T,remainingTimeoutMs:B,signal:O,dispatching:x}=c,N=!1,H=(q,G)=>d.press(R,B,C,{modifiers:[],signal:q,onDispatch:G});return this.callbacks.runHeldInputOperation("input/key",O,(q,G)=>this.callbacks.runInputOperationWithTimeout({toolName:"input/key",origin:"UnixSocketServer.handleInputKey",totalTimeoutMs:T,remainingTimeoutMs:B},()=>this.callbacks.holdDispatchedInputRequest(O,B,H,{onDispatch:()=>{N=!0,G?.()},label:"Key request"}),(W)=>N?ja.indeterminateError(W):void 0),()=>x?.())}inputStrokesInstance;get inputStrokes(){return this.inputStrokesInstance??=new od({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 zf({timer:d,signal:c,timeoutMs:R,label:C,send:T,onDispatch:B}){c?.throwIfAborted();let O=d.now()+R,x=new AbortController,N=!1,H,q=()=>{if(!N){x.abort(c?.reason);return}H=d.setTimeout(()=>{let W=new t(`${C} deadline expired after dispatch`);x.abort(W)},Math.max(0,O-d.now()))};c?.addEventListener("abort",q,{once:!0});let G=c?x.signal:void 0;try{let W=U(G,()=>T(G,()=>{G?.throwIfAborted(),N=!0,B?.()}));return await l(W,{timer:d,signal:G,label:C})}finally{if(H!==void 0)d.clearTimeout(H);c?.removeEventListener("abort",q)}}class dd{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async handleInputTypeText(d,c,R){let C=this.callbacks.parseInputTypeTextParams(d.params),T,B=(N)=>{T=N},{targetDevice:O,result:x}=await this.callbacks.runInputRoute(d,c,R,{action:"input/typeText",origin:"UnixSocketServer.handleInputTypeText",args:C,bypassAndroidDeviceListCache:C.append,reresolve:async(N)=>C.append&&C.platform==="android"?await this.callbacks.resolveInputTargetDevice(C.platform,N.deviceId,c,{action:"input/typeText",bypassAndroidDeviceListCache:!0,requester:R?.requester}):N,checksFrame:!0,dispatch:async({executionDevice:N,signal:H,dispatching:q,remainingTimeoutMs:G,totalTimeoutMs:W})=>{let V=C.submit?"done":void 0,Y=!1,J=()=>{R?.onDispatch?.(),Y=!0,q?.()};try{return await this.callbacks.runInputOperationWithTimeout({toolName:d.method,origin:"UnixSocketServer.handleInputTypeText",totalTimeoutMs:W,remainingTimeoutMs:G},()=>this.callbacks.executeInputTypeText(C.platform,N,C.text,{imeAction:V,timeoutMs:G,append:C.append,frameContext:C.frameContext,onConfirmedAppendCharsSent:B,signal:H,dispatching:J}),(X)=>C.append&&T!==void 0?new De(X.message,T):void 0)}catch(X){if(Y&&H?.aborted)throw this.callbacks.indeterminateTextError(X,H.reason,T);throw X}}});if(!x.success){if(C.append&&x.charsSent!==void 0)throw new De(x.error??`input/typeText failed on ${C.platform}`,x.charsSent);throw Error(x.error??`input/typeText failed on ${C.platform}`)}return{action:"input/typeText",platform:C.platform,deviceId:O.deviceId,success:!0,textLength:C.text.length,submitted:C.submit}}indeterminateTextError(d,c,R){let C=`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.`,T=R??(d instanceof De?d.charsSent:void 0),B=T===void 0?new t(C,{cause:d}):new De(C,T);return Object.assign(B,{requestDispatched:!0})}holdDispatchedInputRequest(d,c,R,{onDispatch:C,label:T="Text input request"}={}){return zf({timer:this.state.timer,signal:d,timeoutMs:c,label:T,send:R,onDispatch:C})}createSocketInputAdbFactory(d){return{create:(c,R)=>{let C=v.create(c,R);return new Proxy(C,{get:(T,B,O)=>{if(B==="execute")return(N,H={})=>{if(N[0]!=="shell"||N[1]!=="input")return C.execute(N,H);return this.callbacks.holdDispatchedInputRequest(H.signal,Math.min(H.timeoutMs??1/0,d.deadline()-this.state.timer.now()),(q,G)=>C.execute(N,{...H,signal:q,beforeDispatch:async(W)=>{await H.beforeDispatch?.(W),q?.throwIfAborted(),G()}}),{onDispatch:d.onDispatch,label:d.label})};let x=Reflect.get(T,B,O);return typeof x==="function"?x.bind(T):x}})}}}createSocketAppendTextInput(d){let c=0,R,C=this.callbacks.createSocketInputAdbFactory({deadline:()=>c,onDispatch:()=>R?.(),label:"Text input request"}),T=new cq(d,C,{timer:this.state.timer});return{appendText:(B,O={})=>(c=this.state.timer.now()+(O.timeoutMs??0),R=O.onDispatch,T.appendText(B,{timeoutMs:O.timeoutMs,beforeKeyEvents:O.beforeKeyEvents,signal:O.signal}))}}async executeInputTypeText(d,c,R,C){let{imeAction:T,timeoutMs:B,append:O=!1,frameContext:x,onConfirmedAppendCharsSent:N,signal:H,dispatching:q}=C,G=!1,W=()=>{if(!G)G=!0,q?.()},V=this.state.timer.now()+B,Y=d==="android"?{platform:d,client:k.getInstance(c,v)}:{platform:d,client:_.getInstance(c)},{client:J}=Y,X;if(O&&Y.platform==="android"){let Z=await this.callbacks.executeAndroidAppendText({targetDevice:c,text:R,deadline:V,totalTimeoutMs:B,frameContext:x,client:Y.client,signal:H,onDispatch:W});if(Z.charsSent!==void 0)N?.(Z.charsSent);if(He(H),!Z.success)return{success:!1,error:Z.error,...Z.charsSent!==void 0?{charsSent:Z.charsSent}:{}};X=Z.charsSent}else{let Z=O&&Y.platform==="ios"?Y.client:null,re=await this.callbacks.holdDispatchedInputRequest(H,V-this.state.timer.now(),(ee,oe)=>Z?Z.requestAppendText(R,B,void 0,{frameContext:x,abortSignal:ee,onDispatch:oe}):J.requestSetText(R,{timeoutMs:B,frameContext:x,abortSignal:ee,onDispatch:oe}),{onDispatch:W});if(He(H),!re.success)return{success:!1,error:re.error}}return await this.callbacks.runImeActionWithinBudget(J,T,V,{totalTimeoutMs:B,appendCharsSent:X,signal:H,onDispatch:W})}async executeAndroidAppendText(d){let{targetDevice:c,text:R,deadline:C,totalTimeoutMs:T,frameContext:B,client:O,signal:x,onDispatch:N}=d,H=C-this.state.timer.now();if(H<=0)return{success:!1,error:`input/typeText exceeded ${T}ms budget before append key events`};let q=B===void 0?void 0:()=>this.callbacks.validateAppendFrameContext(O,B,C,T),G=this.callbacks.getAppendTextInput(c),W=async(Y,J,X,Z)=>await Y.appendText(J,{timeoutMs:X,beforeKeyEvents:Z,signal:x,onDispatch:N}),V=await W(G.input,R,H,q);if(V.success||!G.fromCache||x?.aborted||V.failureSource==="runner")return V;return await this.callbacks.retryAppendTextWithRebuiltHelper(c,R,V,{deadline:C,beforeKeyEvent:q,run:W})}async retryAppendTextWithRebuiltHelper(d,c,R,C){let{deadline:T,beforeKeyEvent:B,run:O}=C,x=R.charsSent;if(x===void 0)return R;let N=c.slice(x);if(N.length===0)return R;this.callbacks.evictDeviceInputCache(d.deviceId);let H=T-this.state.timer.now();if(H<=0)return R;let q=await O(this.callbacks.getAppendTextInput(d).input,N,H,x===0?B:void 0);return q.charsSent===void 0?{success:q.success,...q.error!==void 0?{error:q.error}:{}}:{...q,charsSent:x+q.charsSent}}async validateAppendFrameContext(d,c,R,C){let T=R-this.state.timer.now();if(T<=0)return{success:!1,error:`input/typeText exceeded ${C}ms budget before append frame context validation`};let B=await d.validateFrameContext(c,T);return B.success?{success:!0}:{success:!1,error:B.error??"Frame context is stale or unavailable; observe a fresh frame before retrying",failureSource:"runner"}}async runImeActionWithinBudget(d,c,R,C){let{totalTimeoutMs:T,appendCharsSent:B,signal:O,onDispatch:x}=C,N=(q)=>B!==void 0?{...q,charsSent:B}:q;if(!c)return N({success:!0});He(O);let H=R-this.state.timer.now();if(H<=0)return N({success:!1,error:`input/typeText exceeded ${T}ms budget before submit`});try{let q=await this.callbacks.holdDispatchedInputRequest(O,H,(G,W)=>d.requestImeAction(c,H,void 0,{abortSignal:G,onDispatch:W}),{onDispatch:x});if(He(O),!q.success){let G=tv(c,q.error||"unknown error");return e.warn(`[input/typeText] ${G}`),N({...q,error:G})}return N(q)}catch(q){let G=tv(c,r(q)||"unknown error");if(e.warn(`[input/typeText] ${G}`,q),O?.aborted)throw q;if(B===void 0){if(q instanceof Error)throw q.message=G,q;throw new t(G,{cause:q})}return{success:!1,error:G,charsSent:B}}}async runInputOperationWithTimeout(d,c,R){let{toolName:C,origin:T,totalTimeoutMs:B,remainingTimeoutMs:O}=d,x=!1,N=c();try{return await l(N,{timer:this.state.timer,timeoutMs:O,label:"Input operation",timeoutError:()=>{x=!0;let H=new xr({toolName:C,timeoutMs:B,origin:T,detail:`operation exceeded remaining budget ${O}ms`});return R?.(H)??H}})}finally{if(x)await N.catch(()=>{return})}}parseInputTapParams(d){return $n(d)}parseInputSwipeParams(d){return qn(d)}parseInputTypeTextParams(d){return Un(d)}parseInputPressButtonParams(d){return Kn(d)}parseInputKeyParams(d){return Gn(d)}parseInputGestureParams(d,c){return $t(d,c)}evictDeviceInputCache(d){if(this.state.appendTextInputs.delete(d))e.debug(`[UnixSocketServer] Evicted cached append helper for device ${d}`)}getAppendTextInput(d){let c=Ji(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 C=this.state.appendTextFactory(d);return this.state.appendTextInputs.set(d.deviceId,{input:C,incarnationToken:c}),{input:C,fromCache:!1}}}function lk(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 uk(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 mk(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 gk(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 vk(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 yk(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 Sk(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 bk(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 wk(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 Yf(d,c){let R=new Da(d,()=>W),C=new Oa(d,()=>W),T=new qa(d,()=>W),B=new Wa(d,()=>W),O=new Va(d,()=>W),x=new Za(d,()=>W),N=new nd(d,()=>W),H=new sd(d,()=>W),q=new dd(d,()=>W),G={...lk(R),...uk(C),...mk(T),...gk(B),...vk(O),...yk(x),...Sk(N),...bk(H),...wk(q)},W={...G,...c};return{implementations:G,callbacks:W}}class Ii{runtime;operations;callbacks;constructor(...d){this.runtime=new Ra(d,()=>this.operations,Hs,()=>this.maxInboundFrameBytes);let c=Yf(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=jQ;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,C){return this.operations.runKeyedMcpForward(d,c,R,C)}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,C){return this.operations.runTrackedKeyedDeviceInput(d,c,R,C)}dispatchFencedInput(d,c,R,C){return this.operations.dispatchFencedInput(d,c,R,C)}runTrackedDeviceInput(d,c,R,C={}){return this.operations.runTrackedDeviceInput(d,c,R,C)}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:Ad(()=>this.callbacks.broadcastListChanged.bind(this),(c)=>{this.callbacks.broadcastListChanged=c}),waitForStartup:Ad(()=>this.callbacks.waitForStartup.bind(this),(c)=>this.callbacks.waitForStartup=c)}}}async function Xf(d){await d.writeEarlyOwnerRecord(),await d.initializeDatabase()}var Rk=200;class Qf extends xa{authenticator;auditRepository;constructor(d=Dt(JV),c=i,R=new am,C={}){super(d,c,"PerformanceStream");this.auditRepository=R,this.authenticator=C.authenticator??bn("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:C}=c,T=await this.auditRepository.listResultsSince(c),B=T.length>0?T[T.length-1]:void 0;return{success:!0,results:T,lastTimestamp:B?.timestamp??R,lastId:B?.id??C}}createPollQuery(d){let c=A$(d.startTime,"startTime"),R=A$(d.endTime,"endTime"),C=A$(d.sinceTimestamp,"sinceTimestamp"),T=k$(d.sinceId),B=T$(d.limit,Rk);return{startTime:c,endTime:R,limit:B,deviceId:d.deviceId?.trim()||void 0,sessionId:d.sessionId?.trim()||void 0,packageName:d.packageName?.trim()||void 0,sinceTimestamp:C,sinceId:T}}createErrorResponse(d,c){return{success:!1,error:c}}}var cd=new vn;function Zf(){return cd.instance?.getSocketPath()??Dt(JV)}async function eh(){await cd.start(()=>new Qf)}async function th(){await cd.stop()}var Dk=100,kk=new bR;function Ak(d){return typeof d==="object"&&d!==null&&"command"in d}class ih extends xa{authenticator;maxFrameBytes=GQ;repository;constructor(d=Dt(XV),c=i,R=kk,C={}){super(d,c,"FailuresStream");this.repository=R,this.authenticator=C.authenticator??bn("failuresStream",{allowObserverSessions:!0})}handleUntypedRequest(d){if(!Ak(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=Mg(d.sinceTimestamp,"sinceTimestamp"),R=k$(d.sinceId),C=T$(d.limit,Dk),T=Mg(d.startTime,"startTime"),B=Mg(d.endTime,"endTime"),O=jk(d.dateRange);if(O&&!T){let N=this.timer.now();B=B??N,T=B-zk(O)}let x=await this.repository.getNotificationsSince({sinceTimestamp:c,sinceId:R,startTime:T,endTime:B,limit:C,type:d.type,acknowledged:d.acknowledged});return{success:!0,notifications:x.notifications,lastTimestamp:x.lastTimestamp,lastId:x.lastId}}async handlePollGroups(d){let c=Mg(d.startTime,"startTime"),R=Mg(d.endTime,"endTime"),C=jk(d.dateRange);if(C&&!c){let B=this.timer.now();R=R??B,c=R-zk(C)}let T=await this.repository.getAggregatedGroups({startTime:c,endTime:R,type:d.type,severity:d.severity});return{success:!0,groups:T.groups,totals:T.totals}}async handlePollTimeline(d){let c=E$(d.aggregation),R=Mg(d.startTime,"startTime"),C=Mg(d.endTime,"endTime"),T=jk(d.dateRange),B=this.timer.now();if(T)C=C??B,R=C-zk(T);else C=C??B,R=R??C-86400000;let O=await this.repository.getTimelineData({startTime:R,endTime:C,aggregation:c});return{success:!0,dataPoints:O.dataPoints,previousPeriodTotals:O.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 ld=new vn;function nh(){return ld.instance?.getSocketPath()??Dt(XV)}async function rh(){await ld.start(()=>new ih)}async function oh(){await ld.stop()}var Ik=1n<<63n,Pk=1n<<62n,Ck=1n<<61n,Tk=1n<<59n,Mk=1n<<60n,ud=59n,l5=0b11n<<ud,sh=(1n<<ud)-1n;function ah(d=0,c=0){let R=Buffer.allocUnsafe(12);return R.writeInt32BE(1748121140,0),R.writeInt32BE(d,4),R.writeInt32BE(c,8),R}function Pi(d,{isConfig:c=!1,isKeyFrame:R=!1,rotation:C=null}={}){let T=d&sh;if(c){if(T|=Ik,C!==null)T|=Ck,T|=(BigInt(C)&0b11n)<<ud}if(R)T|=Pk;return T}function dh(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([dh(d,c.length),c])}function ch(d){return gt(Tk|BigInt(d)&sh,Buffer.alloc(0))}function lh(){return gt(Mk,Buffer.alloc(0))}var Ek=1n<<61n,Bk={downgraded_to_viewer:1,device_removed:2,identity_quarantined:3,daemon_shutdown:4,session_ended:5,device_restored:6};function pd(d){return dh(Ek|BigInt(Bk[d]),0)}var md=Buffer.from([0,0,0,1]),fd=30000,Ok=500,xk=8,hd=1000,uh=6000,Kt=9000;function Fk(d){return d.platform==="android"?v6:fZ}class gd{host;deps;captureRegistry;timer;outboundStalls;constructor(d,c,R,{timer:C,outboundStalls:T}){this.host=d;this.deps=c;this.captureRegistry=R;this.timer=C,this.outboundStalls=T}async createSource(d,c,R){let{device:C}=d,T=C.deviceId,B=()=>{if(this.host.getCapture(T)!==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(T,d)},O=(x,N)=>{let H=this.host.getCapture(T);if(H!==d||d.generation!==R||x.length===0)return;if(N){if(H.lastEncodedDataMs=this.timer.now(),H.firstEvidenceMs??=H.lastEncodedDataMs,H.encodedSinceSourceFrame=!0,!H.heartbeatTimer)this.startHeartbeat(T,H)}this.broadcast(T,x)};return this.captureRegistry.acquire({device:C,create:(x)=>this.deps.createCaptureSource({...x,onError:x.onError}),hasConsumers:d.pendingSubscribers.size>0||d.subscribers.size>0,flexibleHints:c.fps===void 0?["fps"]:[],options:{device:C,onData:(x)=>O(x,!0),onReplayData:(x)=>O(x,!1),onSourceFrame:B,onSourceIdle:()=>{if(this.host.getCapture(T)!==d||d.generation!==R||!d.encodedSinceSourceFrame)return;d.lastIdleMs=this.timer.now()},onEncodedAccessUnit:()=>{if(this.host.getCapture(T)!==d||d.generation!==R)return;for(let x of d.parser.flush())this.broadcastNal(T,d,x);this.cacheCompletedAccessUnits(d,d.keyFrameAssembler.flush()),d.keyFrameAuBytes=0,d.lastEncodedBoundarySequence=d.sourceFrameSequence},onIdleAttestationSupport:(x)=>{if(this.host.getCapture(T)===d&&d.generation===R&&C.platform==="ios")d.legacySimulatorHelper=!x},onRotation:(x)=>{let N=this.host.getCapture(T);if(N===d&&d.generation===R)N.rotation=x},onDroppedFrames:(x)=>{if(this.host.getCapture(T)!==d||d.generation!==R||!Number.isSafeInteger(x)||x<0||!this.sourceEvidenceIsRecent(d,this.timer.now()))return;let H=ch(x);for(let q of d.subscribers)this.writePacketToSubscriber(T,d,q,{packet:H,isConfig:!1,isKeyFrame:!1})},onError:(x)=>{if(this.host.getCapture(T)===d&&d.generation===R)e.warn(`[VideoStream] capture failed for ${T}: ${x}`),this.host.stopCapture(T)},bitrateBps:c.bitrateKbps?c.bitrateKbps*1000:void 0,size:c.size,quality:c.quality,fps:c.fps??Fk(C)}})}resetForNewEncoder(d){this.clearHeartbeatTimer(d),d.parser=new za,d.keyFrameAssembler=new nf,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 C of R.parser.push(c))this.broadcastNal(d,R,C)}broadcastNal(d,c,R){let C=Rs(R);this.cacheCompleteKeyFrame(c,R,C);let T=C===vd||C===bd;if(C===vd)c.sps=Buffer.from(R);if(C===bd)c.pps=Buffer.from(R);let B=C===Og,O=T?c.rotation:null,x=gt(Pi(this.deps.nowUs(),{isConfig:T,isKeyFrame:B,rotation:O}),Buffer.concat([md,R]));for(let N of c.subscribers)this.writePacketToSubscriber(d,c,N,{packet:x,isConfig:T,isKeyFrame:B})}cacheCompleteKeyFrame(d,c,R){let C=d.keyFrameAssembler.push(c);if(d.keyFrameAuBytes+=c.length,this.cacheCompletedAccessUnits(d,C),R===vd||R===bd)d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;if(d.keyFrameAuBytes>oO)d.keyFrameAssembler=new nf,d.keyFrameAuBytes=0}cacheCompletedAccessUnits(d,c){for(let R of c){let C=R.reduce((B,O)=>B+O.length,0);if(d.keyFrameAuBytes-=C,C>oO){d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;continue}let T=Buffer.concat(R.filter((B)=>Rs(B)!==vd&&Rs(B)!==bd).flatMap((B)=>[md,B]));if(R.some((B)=>Rs(B)===Og))d.latestKeyFrameAu=T,d.latestInterFrameAus=[],d.cachedGopBytes=T.length;else if(d.latestKeyFrameAu)if(d.cachedGopBytes+T.length>oO)d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;else d.latestInterFrameAus.push(T),d.cachedGopBytes+=T.length}}replayKeyFrame(d,c,R){if(!d.sps||!d.pps||!d.latestKeyFrameAu)return;this.writePacketToSubscriber(R,d,c,{packet:gt(Pi(this.deps.nowUs(),{isKeyFrame:!0}),d.latestKeyFrameAu),isConfig:!1,isKeyFrame:!0});for(let C of d.latestInterFrameAus)this.writePacketToSubscriber(R,d,c,{packet:gt(Pi(this.deps.nowUs(),{}),C),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<=Kt)this.replayKeyFrame(c,R,d.deviceId)}writePacketToSubscriber(d,c,R,{packet:C,isConfig:T,isKeyFrame:B}){if(R.destroyed){this.host.detach(R);return}if(this.shouldSkipPacket(c,R,T,B))return;if(!R.write(C)){e.debug(`[VideoStream] subscriber is behind on ${d}; dropping to next key frame`),c.backpressuredSubscribers.add(R),c.waitingForKeyFrame.add(R);let O=()=>{let N=this.outboundStalls.get(R);if(!N)return;this.timer.clearTimeout(N.timeout),this.outboundStalls.delete(R);let H=this.host.getCapture(d);if(H!==c||!H.subscribers.has(R))return;H.backpressuredSubscribers.delete(R),this.requestKeyFrameForWaitingSubscriber(d,R)},x=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??fd);this.outboundStalls.set(R,{timeout:x,onDrain:O}),R.once("drain",O)}}shouldSkipPacket(d,c,R,C){if(d.waitingForReplacement.has(c)||d.backpressuredSubscribers.has(c))return!0;if(!d.waitingForKeyFrame.has(c))return!1;if(!C)return!R;if(d.generation>0&&(!d.sps||!d.pps))return!0;return d.waitingForKeyFrame.delete(c),!1}requestKeyFrameForWaitingSubscriber(d,c,R=xk){let C=this.host.getCapture(d);if(!C)return;if(c.destroyed||!C.waitingForKeyFrame.has(c))return;if(C.waitingForReplacement.has(c))return;let T=C.source;if(!T?.requestKeyFrame)return;if(T.requestKeyFrame()||R<=0)return;this.timer.setTimeout(()=>this.requestKeyFrameForWaitingSubscriber(d,c,R-1),Ok)}replayParameterSets(d,c){let R=[d.sps,d.pps].filter((T)=>T!==null);if(R.length===0)return;let C=Buffer.concat(R.flatMap((T)=>[md,T]));c.write(gt(Pi(this.deps.nowUs(),{isConfig:!0,rotation:d.rotation}),C))}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 C of c.subscribers){if(C.destroyed||c.waitingForKeyFrame.has(C)||c.backpressuredSubscribers.has(C))continue;C.write(R)}},hd)}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<Kt)}hasFreshCompleteSourceEvidence(d,c){let{source:R,lastSourceDataMs:C,lastEncodedDataMs:T}=c;if(!R||C===null||T===null)return!1;let B=this.timer.now();if(this.sourceEvidenceIsRecent(c,B)&&c.lastIdleMs!==null)return!0;if(Math.max(B-C,B-T,0)>=uh&&(c.lastLivenessProbeMs===null||B-c.lastLivenessProbeMs>=uh))try{if(R.requestKeyFrame?.("probe"))c.lastLivenessProbeMs=B}catch(x){e.warn(`[VideoStream] liveness key-frame request failed for ${d}: ${x}`)}return this.sourceEvidenceIsRecent(c,B)}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)<=Kt}idleEvidenceIsRecent(d,c){return d.lastIdleMs!==null&&d.encodedSinceSourceFrame&&c-d.lastIdleMs<=Kt}producerEvidenceIsStale(d){let c=this.timer.now();return(d.lastSourceDataMs===null||c-d.lastSourceDataMs>Kt)&&(d.lastIdleMs===null||c-d.lastIdleMs>Kt)}clearHeartbeatTimer(d){if(d.heartbeatTimer)this.timer.clearInterval(d.heartbeatTimer),d.heartbeatTimer=null}}function ph(){return new vn}function Ci(d){return d!==null&&"setHasConsumers"in d&&typeof d.setHasConsumers==="function"}var Ti="to stream video",Nk=new Set(["low","medium","high"]),fh=5,hh=60,gh=1e6,vh=3000,yh=200,yd=5000;function Sd(d,c){return d!=="viewer"||c?.hasDeviceOwner===!1}function Jn(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 Vn(d,c,R){return Number.isInteger(d)&&d>=c&&d<=R}function Lk(d){return d===void 0||Nk.has(d)?null:`Unsupported quality "${d}"; expected low, medium, or high.`}function $k(d){return d===void 0||Vn(d,fh,hh)?null:`Invalid fps ${d}; expected an integer between ${fh} and ${hh}.`}function Hk(d){return d===void 0||Vn(d,1,gh)?null:`Invalid bitrateKbps ${d}; expected an integer between 1 and ${gh}.`}function qk(d){if(d===void 0)return null;let{width:c,height:R}=d??{};return Vn(c,2,Number.MAX_SAFE_INTEGER)&&Vn(R,2,Number.MAX_SAFE_INTEGER)?null:`Invalid size ${JSON.stringify(d)}; expected integer width/height >= 2.`}function jn(d){return Uk(d.platform)??Lk(d.quality)??$k(d.fps)??Hk(d.bitrateKbps)??qk(d.size)}function Uk(d){return d===void 0||d==="android"||d==="ios"?null:`Invalid platform ${JSON.stringify(d)}; expected "android" or "ios".`}function Sh(d,c){if(c instanceof Rp)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),...gc(c)}}async function bh(d,c,R="either",{timer:C=i,signal:T}={}){return iO(d,c,R,{timer:C,signal:T,source:"video-stream-resolve"})}async function Kk(d,c,R){return bh(d,c,R)}function wh(d=new oi){return{captureRegistry:cO(),ownershipChanges:()=>w.sessionManager()??null,deviceLifecycle:Xs,sessionReleases:hi,observerReleases:Iv,resolveDevice:(c,R)=>Kk(d,c,R),createCaptureSource:async(c)=>{let R=await LN();return aO({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 wd(){return zn.instance?.getSocketPath?.()??Dt(mL)}class Rh extends Dw{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=Dt(mL),R=i,{authenticator:C=bn("video-stream subscribe",{allowObserverSessions:!0}),admissionGate:T=_s}={}){super(c,R,"VideoStream",{idleTimeoutMs:0});this.deps=d;this.authenticator=C,this.admissionGate=T,this.pipeline=new gd({getCapture:(B)=>this.captures.get(B),detach:(B)=>this.detach(B),stopCapture:(B,O)=>this.stopCapture(B,O)},d,d.captureRegistry??k2(),{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,Ti)}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:yd,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 ${yd}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 C=jn(R);if(C){this.sendJson(d,{id:R.id,type:"video_stream_response",success:!1,error:C}),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,Ti);let T=await this.deps.resolveDevice(R.deviceId,R.platform);this.admissionGate.assertDeviceActionable(T.deviceId,Ti),ep(this.authenticator,{sessionUuid:R.sessionUuid,deviceId:T.deviceId,admitViewer:!0});let B=await this.attach(d,T,R);if(B)this.acknowledgeSubscriber(d,B,R)}catch(T){if(e.warn(`[VideoStream] subscribe failed: ${T}`),this.detach(d),!d.destroyed)this.sendJson(d,Sh(R.id,T)),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 ep(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:hd,subscriptionKind:this.socketSubscriptionKinds.get(d)}),d.destroyed){this.detach(d);return}d.write(ah(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",C={sessionUuid:this.socketSessionUuids.get(d),deviceId:c};try{let T=this.authenticator.resolveSubscriptionIdentity?.(C);if(!T){this.authenticator.authorize({...C,requireOwnership:!0});return}let B=tO({...T,kind:R});if(B.action==="end")this.endSubscriber(d,c,B.reason);else if(B.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(pd("downgraded_to_viewer"))}}catch(T){this.endSubscriber(d,c,"session_ended",{authorizationError:T})}}endDeviceSubscribers(d,c){let R=this.captures.get(d);if(!R)return;for(let C of[...R.pendingSubscribers,...R.subscribers]){let T=this.socketSubscriptionKinds.get(C)??"owner";this.endSubscriber(C,d,rO({kind:T,event:c}).reason)}}endSubscriber(d,c,R,C={}){if(!this.socketDeviceIds.has(d)&&!this.subscribing.has(d))return;let T=this.socketSubscriptionKinds.get(d),B=`[VideoStream] ending subscriber: deviceId=${c} kind=${T} reason=${R}`;if("authorizationError"in C||R==="device_removed"||R==="identity_quarantined")e.warn(B);else e.info(B);try{if(!d.destroyed){if(this.acknowledgedSubscribers.has(d))d.write(pd(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(O){if(e.warn(`[VideoStream] failed to end subscriber for ${c}: ${r(O)}`),!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 C=this.endingSockets.get(d);if(C)this.timer.clearTimeout(C.timeout),this.endingSockets.delete(d);d.off("close",c)},R=this.timer.setTimeout(()=>{d.destroy()},this.deps.outboundStallTimeoutMs??fd);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,Ti),!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 C=c.deviceId,T=this.pendingStops.get(C);if(T){if(await T,this.closed)throw new t("Video stream server is closed");if(d.destroyed)throw new t(`Video stream subscriber disconnected while stopping ${C}`)}ep(this.authenticator,{sessionUuid:R.sessionUuid,deviceId:C,admitViewer:!0});let B=this.authenticator.resolveSubscriptionIdentity?.({sessionUuid:R.sessionUuid,deviceId:C}),O=B?w$(B):"owner";if(this.socketSubscriptionKinds.set(d,O),!this.checkSubscriberActionable(d,C))return null;let x=this.captures.get(C);if(x){if(this.clearIdleTimer(x),this.updateDesiredHints({deviceId:C,capture:x,request:R,identity:B,subscriptionKind:O}),x.pendingSubscribers.add(d),Ci(x.source))x.source.setHasConsumers(!0);return this.socketDeviceIds.set(d,C),this.socketSessionUuids.set(d,R.sessionUuid),this.socketSubscriptionKinds.set(d,O),await x.startup,this.promoteSubscriber(x,d,!0),this.scheduleReconfigure(C,x),x}let N=Sd(O,B)?R:{},H={device:c,desiredHints:{quality:N.quality,fps:N.fps,bitrateKbps:N.bitrateKbps,size:N.size},appliedHints:{quality:N.quality,fps:N.fps,bitrateKbps:N.bitrateKbps,size:N.size},hintKind:O,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 za,keyFrameAssembler:new nf,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(C,H),this.socketDeviceIds.set(d,C),this.socketSessionUuids.set(d,R.sessionUuid),this.socketSubscriptionKinds.set(d,O),H.startup=(async()=>{try{let q=await this.pipeline.createSource(H,H.appliedHints,H.generation);if(this.captures.get(C)!==H||!this.hasSubscribers(H)&&!H.idleTimer)throw await q.stop().catch((G)=>{e.warn(`[VideoStream] failed to stop abandoned capture for ${C}: ${G}`)}),new t(`Video capture for ${C} was stopped during startup.`);if(H.source=q,Ci(q))q.setHasConsumers(this.hasSubscribers(H));if(await q.start(),this.captures.get(C)!==H||!this.hasSubscribers(H)&&!H.idleTimer)throw H.source=null,await q.stop().catch((G)=>{e.warn(`[VideoStream] failed to stop abandoned capture for ${C}: ${G}`)}),new t(`Video capture for ${C} was stopped during startup.`)}catch(q){if(this.pipeline.clearHeartbeatTimer(H),this.captures.get(C)===H)this.captures.delete(C);throw u(q,`Failed to start video capture for ${C}`)}})(),await H.startup,this.promoteSubscriber(H,d,!0),H}updateDesiredHints({deviceId:d,capture:c,request:R,identity:C,subscriptionKind:T}){if(!Sd(T,C))return;let B=T==="owner"&&c.hintKind==="viewer",O=B?{}:c.desiredHints;if(T==="owner")c.hintKind="owner";if(c.desiredHints={quality:R.quality??O.quality,fps:R.fps??O.fps,bitrateKbps:R.bitrateKbps??O.bitrateKbps,size:B?R.size:O.size},this.retainSharedHints(c,c.desiredHints),!Jn(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||!Jn(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)||Jn(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)})},yh)}retainSharedHints(d,c){if(!d.source||!qY(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 C=c.source;if(!C||this.captures.get(d)!==c)return;if(this.retainSharedHints(c,R))return;c.generation++,c.source=null,this.pipeline.resetForNewEncoder(c);try{if(await C.stop(),this.captures.get(d)!==c)return;let T=await this.pipeline.createSource(c,R,c.generation);if(this.captures.get(d)!==c){await T.stop();return}if(c.source=T,Ci(T))T.setHasConsumers(this.hasSubscribers(c));if(await T.start(),this.captures.get(d)!==c){await T.stop();return}c.appliedHints=R,e.info(`[VideoStream] ${d} shared capture quality changed`);let B=c.waitingForKeyFrame.values().next().value;if(B)this.pipeline.requestKeyFrameForWaitingSubscriber(d,B)}catch(T){if(e.warn(`[VideoStream] failed to reconfigure capture for ${d}: ${T}`),this.captures.get(d)===c)c.source??=C,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(Ci(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)},vh)}}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 C=this.captures.get(d);if(!C)return Promise.resolve();if(this.captures.delete(d),this.clearIdleTimer(C),this.pipeline.clearHeartbeatTimer(C),C.reconfigureTimer)this.timer.clearTimeout(C.reconfigureTimer),C.reconfigureTimer=null;for(let B of[...C.pendingSubscribers,...C.subscribers])this.detach(B),this.endSocketBounded(B);C.pendingSubscribers.clear(),C.subscribers.clear(),C.backpressuredSubscribers.clear(),C.waitingForKeyFrame.clear(),C.waitingForReplacement.clear();let T=(async()=>{try{try{if(c&&C.source)await VY(C.source,this.pipeline.producerEvidenceIsStale(C));else await C.source?.stop()}catch(B){e.warn(`[VideoStream] failed to stop capture for ${d}: ${B}`)}try{await C.startup}catch(B){e.debug(`[VideoStream] startup settled during stop for ${d}: ${B}`)}await C.reconfiguring}finally{this.pendingStops.delete(d)}})();return this.pendingStops.set(d,T),T}}async function Dh(d){await zn.start(()=>new Rh(wh(d?.getPlatformDeviceManager())))}async function kh(){await zn.stop()}function st(){return{control:Ct,appearance:h2(),"device-snapshot":p2(),"failures-push":vre(),"failures-stream":nh(),"observation-stream":pte(),"performance-push":Ite(),"performance-stream":Zf(),"telemetry-push":ate(),"device-gesture-recording":d2(),"video-recording":s2(),"video-stream":wd(),"webrtc-stream":v2()}}import Gk from"fs";import be from"path";var Vk="terminal-release-intents.jsonl",Ih="terminal-release-intents",Rd=".jsonl";function Ah(d,c){return be.join(d,Ih,`${encodeURIComponent(c)}${Rd}`)}function Jk(d,c,R){let C;try{C=JSON.parse(d)}catch(T){e.warn(`[TerminalReleaseJournal] Discarded corrupt line ${c} of ${R}: ${r(T)}`,T);return}if(typeof C==="object"&&C!==null){let T=C,{sessionId:B,reason:O,at:x}=T;if(typeof B==="string"&&B.length>0){if(T.lifted===!0)return{kind:"lifted",sessionId:B};if(typeof O==="string"&&O.length>0&&Number.isFinite(x))return{kind:"intent",intent:{sessionId:B,reason:O,at:x}}}}e.warn(`[TerminalReleaseJournal] Discarded corrupt line ${c} of ${R}: invalid journal record`);return}function Ph(d,c,R){let C=!1;for(let[T,B]of d.entries()){let O=Jk(B,T+1,R);if(O?.kind==="intent")c.set(O.intent.sessionId,O.intent);else if(O?.kind==="lifted")c.delete(O.sessionId);else C=!0}return C}function Yk(d){return`${JSON.stringify({sessionId:d,lifted:!0})}
39
+ `}function kd(d){return`${JSON.stringify({sessionId:d.sessionId,reason:d.reason,at:d.at})}
40
+ `}class Ch{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?[]:Eh(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(kd(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(),C=this.intents.get(d);if(!C||c!==void 0&&C.reason!==c)return;if(this.intents.delete(d),R&&this.compact(this.intents))return;try{this.appendDurable(Yk(d))}catch(T){e.warn(`[TerminalReleaseJournal] Failed to record the lifted fence of session ${d}: `+r(T),T)}}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,C]of c)this.intents.set(R,C);return!0}replay(d){let c=d.split(`
41
+ `),R=c.pop()??"",C=Ph(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(C||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(),kd).join(""));return!0}catch(c){return e.warn(`[TerminalReleaseJournal] Failed to compact ${this.filePath}: ${r(c)}`,c),!1}}}function Xk(d=Gk,c=process.platform){let R=(C,T)=>{let B=d.openSync(C,T);try{d.fsyncSync(B)}finally{d.closeSync(B)}};return{listNames(C){try{return d.readdirSync(C).sort(KD)}catch(T){if(T.code==="ENOENT")return[];throw T}},readText(C){try{return d.readFileSync(C,"utf-8")}catch(T){if(T.code==="ENOENT")return;throw T}},appendDurable(C,T,B=!0){let O=d.mkdirSync(be.dirname(C),{recursive:!0,mode:448}),x=d.openSync(C,"a",384);try{d.writeSync(x,T),d.fsyncSync(x)}finally{d.closeSync(x)}if(B&&c!=="win32"){if(R(be.dirname(C),"r"),O!==void 0){R(be.dirname(O),"r");let N=be.relative(O,be.dirname(C)),H=O;for(let q of N?N.split(be.sep):[])H=be.join(H,q),R(be.dirname(H),"r")}}},replaceDurable(C,T){let B=`${C}.${process.pid}.tmp`,O=d.openSync(B,"w",384);try{d.writeSync(O,T),d.fsyncSync(O)}finally{d.closeSync(O)}try{d.renameSync(B,C)}catch(x){throw d.rmSync(B,{force:!0}),x}if(c!=="win32")R(be.dirname(C),"r")},remove(C){d.rmSync(C,{force:!0})}}}var Qk=Xk();function Th(d){let c=d.dataDir??yp(),R=d.fileSystem??Qk,C=Ah(c,d.daemonSessionId);return tA(C,Zk(c,d,R),R),new Ch(C,R,(T)=>Ah(c,T))}function Zk(d,c,R){let C=new Set(c.liveDaemonSessionIds);C.delete(c.daemonSessionId);let T=C.size===0?[be.join(d,Vk)]:[],B=be.join(d,Ih),O;try{O=R.listNames(B)}catch(x){return e.warn(`[TerminalReleaseJournal] Failed to list ${B}; terminal releases of earlier daemons are applied by a later startup: ${r(x)}`,x),T}for(let x of O){if(!x.endsWith(Rd))continue;let N=eA(x.slice(0,-Rd.length));if(N!==void 0&&N!==c.daemonSessionId&&!C.has(N))T.push(be.join(B,x))}return T}function eA(d){try{return decodeURIComponent(d)}catch(c){e.debug(`[TerminalReleaseJournal] Ignoring journal file ${d}: ${r(c)}`);return}}function Eh(d,c){let R;try{R=c.readText(d)}catch(T){e.warn(`[TerminalReleaseJournal] Failed to read ${d}; its terminal releases are applied by a later startup: ${r(T)}`,T);return}let C=new Map;if(R!==void 0){let T=R.split(`
42
+ `),B=T.pop()??"";if(Ph(T,C,d),B.length>0)e.warn(`[TerminalReleaseJournal] Discarded a torn tail of ${d}`)}return Array.from(C.values())}function tA(d,c,R){for(let C of c){let T=Eh(C,R);if(T===void 0)continue;if(T.length>0)try{R.appendDurable(d,T.map(kd).join(""))}catch(B){e.warn(`[TerminalReleaseJournal] Failed to adopt ${C}; its terminal releases are applied by a later startup: ${r(B)}`,B);continue}try{R.remove(C)}catch(B){e.warn(`[TerminalReleaseJournal] Adopted but could not remove ${C}: ${r(B)}`,B)}}}function Xn(d,c,R){if(!c.isIosPassiveWorkEnabled())return[];let C=d.filter((B)=>B.platform==="ios"&&c.allows("ios","startup-warmup",B.id)),T=C.filter((B)=>R?.(B.id));if(T.length>0)e.info(`[Daemon] Skipping gated CtrlProxy iOS warm-up devices: ${T.map((B)=>B.id).join(", ")}`);return C.filter((B)=>!T.includes(B))}async function Oh(d,c,R){let C=Symbol("iOS startup budget");try{return await l(d,{timer:c,timeoutMs:R,unref:!0,label:"iOS startup budget",timeoutError:()=>C}),!0}catch(T){if(T!==C)throw T;return!1}}async function Zn(d,c){let R={ready:[],deferred:[]},C=c.pendingPrefetch();if(C!==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 Oh(C,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(T)=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Skipping CtrlProxy iOS startup for ${T}: daemon shutdown is in progress`);return}e.info(`[Daemon] Setting up CtrlProxy iOS for iOS device ${T}`);try{let B=c.verifyIosDevice(T,{skipCtrlProxyDownload:!0});if(!await Oh(B,c.timer,c.perDeviceTimeoutMs)){e.warn(`[Daemon] CtrlProxy iOS warm-up timed out for ${T}: phase=runner-setup after ${c.perDeviceTimeoutMs}ms; deferring to the resident startup`),R.deferred.push(T),B.then(()=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Deferred CtrlProxy iOS startup for ${T} completed after daemon shutdown began; ignoring`);return}e.info(`[Daemon] Deferred CtrlProxy iOS startup completed for ${T} after warm-up timeout`)},(O)=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Deferred CtrlProxy iOS startup for ${T} failed after daemon shutdown began; ignoring: ${r(O)}`);return}e.warn(`[Daemon] Deferred CtrlProxy iOS startup failed for ${T}: ${r(O)}`,O)});return}await B,e.info(`[Daemon] CtrlProxy iOS ready for iOS device ${T}`),R.ready.push(T)}catch(B){if(B instanceof JT)e.info(`[Daemon] Deferring CtrlProxy iOS setup for ${T} to the first tool call: ${B.message}`),R.deferred.push(T);else e.warn(`[Daemon] Failed to initialize CtrlProxy iOS for ${T}: ${B}`)}})),R}async function Id(d,c){if(await c(d))return d;let R=d>=tw&&d<=cv,C=R?Array.from({length:cv-d},(T,B)=>d+1+B):[];for(let T of C)if(await c(T))return T;if(!R)throw Error(`Port ${d} is not available (outside the fallback range ${tw}-${cv})`);throw Error(C.length===0?`Port ${d} is not available (no higher port in the fallback range ${tw}-${cv})`:`No available ports in range ${d}-${cv}`)}var xh={"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 Pd(d,c=()=>{}){for(let R of d)try{let C=R.run();if(C instanceof Promise)await C}catch(C){throw c(R.name),C}}function de(d,c){return{name:d,run:c}}class Td{host;sessionBrokerRecovery;androidAvdProvenanceWarmPromise;startupLiveDaemonSessionIds=new Set;constructor(d){this.host=d}applyRuntimeOptions(d){if(d.networkMockable)M.setNetworkMockableEnabled(!0);if(d.dismissKeyboardAfterInput)M.setDismissKeyboardAfterInputEnabled(!0);if(d.eventAllMarkers&&d.eventAllMarkers.length>0)M.setEventAllMarkers(d.eventAllMarkers);if(d.debugPerf)fL(!0);if(d.noUiPerfMode)M.setUiPerfMode(!1);if(d.noNavigationScreenshots)M.setNavigationScreenshotsEnabled(!1);if(d.noWaitForPollingOverhead)M.setWaitForPollingOverheadEnabled(!1);if(d.memPerfAudit)M.setMemPerfAuditMode(!0);if(d.predictiveUi)M.setPredictiveUiEnabled(!0)}applyAccessibilityOptions(d){if(d.rawElementSearch)M.setRawElementSearchEnabled(!0);if(d.skipCtrlProxyDownload)M.setSkipCtrlProxyDownload(!0);if(d.runnerReadinessTimeoutMs!==void 0)M.setRunnerReadinessTimeoutMs(d.runnerReadinessTimeoutMs);if(d.noA11yIncludeNotImportantViews)M.setA11yIncludeNotImportantViews(!1);if(d.noA11yReportViewIds)M.setA11yReportViewIds(!1);if(d.noA11yRetrieveInteractiveWindows)M.setA11yRetrieveInteractiveWindows(!1);if(d.noOcclusion)M.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:gN,label:"Post-bind startup failure stop",timeoutError:()=>d})}catch(c){e.warn(c===d?`Stopping after a failed startup exceeded ${gN}ms`:`Stopping after a failed startup failed: ${r(c)}`,c)}}processStartHost(){return{writeExitRecord:(d)=>cX(Ct,d,this.host.exitRecordFileSystem()),enterProcess:()=>this.host.enterDaemonProcess(),publishForwardLeaseOwner:()=>{pee(Ct)},writeEarlyOwnerRecord:()=>this.host.writeEarlyOwnerRecord(),openTerminalReleaseJournal:(d)=>Th(d),prepareHttpToken:()=>this.host.prepareHttpToken(),publishHttpToken:()=>this.host.publishHttpToken(),startHttpIngress:()=>this.host.startHttpIngress(),sweepStaleAppearanceConfigs:async(d)=>{await lm(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 BO;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 C=this.host.services.devicePool().getDevice(R);return C?{deviceId:C.id,name:C.name,platform:C.platform}:void 0},forceStopOrphanedCapture:(R,C,T)=>T?c.forceStopOrphanedCapture(R,C,T):c.forceStopOrphanedCapture(R,C),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(){Jie(hm),e.enableStdoutLogging();let d=g$();process.env[lb]??=GD(d),Zie(),process.chdir(d),e.info("Starting AutoMobile daemon..."),this.host.setupShutdownHandlers()}async startThroughSocketBind(){await Pd(this.startThroughSocketBindStages(),(d)=>{if(xh[d]==="incumbent window"&&!this.host.identity.socketBindCommitted())this.host.restoreIncumbentOwnerRecord()})}startThroughSocketBindStages(){let d=()=>this.host.startHost();return[de("enter process",()=>{d().enterProcess()}),de("entered daemon process",()=>{this.host.setEnteredDaemonProcess(!0)}),de("tool-call-end activity subscription",()=>{this.host.subscribeToolCallEndActivity()}),de("forward lease owner",()=>{d().publishForwardLeaseOwner()}),de("database prologue",()=>Et.runPhase("daemonDatabaseInitialization",()=>Xf({writeEarlyOwnerRecord:()=>d().writeEarlyOwnerRecord(),initializeDatabase:()=>this.host.initializeDatabase()}))),de("terminal release journal",()=>{this.host.services.sessionManager().attachTerminalReleaseJournal(d().openTerminalReleaseJournal({daemonSessionId:this.host.identity.daemonSessionId(),liveDaemonSessionIds:this.startupLiveDaemonSessionIds}))}),de("binding registry",()=>this.prepareStartupBindingRegistry()),de("daemon collaborators",()=>{this.host.services.sessionManager().assertDaemonCollaboratorsAttached()}),de("http token prepare",()=>{d().prepareHttpToken()}),de("http ingress",()=>d().startHttpIngress()),de("device discovery",async()=>{e.info("Initializing device pool..."),Et.startPhase("deviceDiscovery"),await this.host.initializeDevicePoolWithTimeout(5000),Et.endPhase("deviceDiscovery")}),de("session rehydration",()=>this.rehydrateStartupSessions()),de("session broker",async()=>{this.sessionBrokerRecovery=await this.host.installSessionBroker()}),de("iOS services",()=>Et.runPhase("iosServices",()=>this.host.initializeIosServices())),de("recorder teardown redrive",()=>d().redriveRecorderTeardowns()),de("control socket bind",async()=>{this.host.lifecycle.setSocketServer(await d().bindControlSocket())}),de("socket bind commit",()=>{this.host.identity.setSocketBindCommitted(!0)}),de("http token publish",()=>{d().publishHttpToken(),Et.endPhase("socketServerStart")}),de("background registry upgrade",()=>{if(e.info("Unix socket server started"),!this.host.lifecycle.sessionBrokerConfigPath()&&xf())this.host.startBackgroundRegistryUpgrade()})]}prepareStartupBindingRegistry(){if(this.host.lifecycle.sessionBrokerConfigPath()!==void 0)return xp({brokerConfigured:!0,registryExists:xf(),open:()=>this.host.openBindingRegistry()});if(xf())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 Et.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()));Et.startPhase("httpServerStart"),await this.host.services.httpIngress().start(),Et.endPhase("httpServerStart")}async bindControlSocket(){return e.info(`Daemon host: "${this.host.host()}", port: ${this.host.identity.port()}`),e.info(`MCP_STREAMABLE_PATH: "${nw}"`),e.info(`Creating UnixSocketServer at "${Ct}"`),this.host.lifecycle.setSocketServer(new Ii(Ct,void 0,void 0,sr.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:vr,sockets:st(),dbPath:up(),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..."),Et.startPhase("socketServerStart"),await this.host.lifecycle.socketServer().start(),this.host.recordControlSocketIdentity(),this.host.lifecycle.socketServer()}async startServicesAfterSocketBind(){Et.startPhase("auxiliarySocketServerStart"),await this.host.startAuxiliarySocket("video-recording",a2),await this.host.startAuxiliarySocket("device-gesture-recording",()=>l2(this.host.services.deviceReadiness())),await this.host.startAuxiliarySocket("device-snapshot",m2),await this.host.startAuxiliarySocket("appearance",g2),await this.host.startAuxiliarySocket("performance-stream",eh),await this.host.startAuxiliarySocket("observation-stream",()=>_W(this.host.services.timer())),this.host.configureDeviceDataStreamServer(),await this.host.startAuxiliarySocket("performance-push",_te),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("failures-stream",rh),await this.host.startAuxiliarySocket("failures-push",bre),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("telemetry-push",cte),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("webrtc-stream",b2),await this.host.startAuxiliarySocket("video-stream",()=>Dh(this.host.services.deviceReadiness())),Et.endPhase("auxiliarySocketServerStart"),w2({getTargets:()=>this.host.getAppearanceSyncTargets(),isEnabled:()=>this.host.services.passiveWorkPolicy().isAppearanceSyncEnabled(),beforeApply:(d)=>Ed(d,["nightMode"])}),Y5(),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 Pd(this.startAfterSocketBindStages())}startAfterSocketBindStages(){return[de("session broker recovery",()=>{this.sessionBrokerRecovery?.start()}),de("services after socket bind",()=>this.host.startHost().startServicesAfterSocketBind()),de("heartbeat monitor",()=>{this.host.startHeartbeatMonitor()}),de("maintenance monitors",()=>{this.host.startHost().startMaintenanceMonitors()}),de("startup report",()=>{Et.emit("daemon",{host:this.host.host(),port:this.host.identity.port(),socketPath:Ct,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 ${Ct}, HTTP port ${this.host.identity.port()}`)}),de("startup failure tracker reset",()=>{this.host.startupFailureTracker().reset()})]}warmAndroidAvdProvenanceCache(){this.androidAvdProvenanceWarmPromise=Promise.resolve().then(()=>hs.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 Id(d,(c)=>this.isPortAvailable(c))}async isPortAvailable(d){return new Promise((c)=>{let R=iA(),C=!1,T=i.setTimeout(()=>{if(!C)C=!0,R.close(()=>{}),c(!1)},1000);R.once("error",()=>{if(!C)C=!0,clearTimeout(T),c(!1)}),R.listen(d,this.host.host(),()=>{if(!C)C=!0,clearTimeout(T),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(C){if(C!==c)throw C;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((C)=>dr(C.platform));for(let C of R)this.host.services.deviceSessionRegistry().onDeviceConnected({deviceId:C.id,platform:C.platform,incarnation:C.incarnation});e.info(`Device pool initialized with ${c.length} devices: ${c.map((C)=>C.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=Xn(this.host.services.devicePool().getAllDevices(),this.host.services.passiveWorkPolicy(),(R)=>{let C=this.host.services.sessionManager().getSessionForDevice(R);return C!==null&&this.host.lifecycle.managedExecutionReowner()?.ownershipState(C)!==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 Zn(d.map((R)=>R.id),{timer:this.host.services.timer(),perDeviceTimeoutMs:5000,pendingPrefetch:()=>et.pendingPrefetch(),isShuttingDown:()=>this.host.lifecycle.shutdownInProgress(),verifyIosDevice:(R,C)=>c.verifyIosDevice(R,C)})}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(),cI,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 P$(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)M.setObserveResultIncludeElementsEnabled(!0);if(d.toolResultsNoStructuredContent)M.setToolResultsNoStructuredContentEnabled(!0);if(d.actionsDiffObserve)M.setActionsDiffObserveEnabled(!0);if(d.actionsCompactMetadata!==void 0)M.setActionsCompactMetadataEnabled(d.actionsCompactMetadata);if(c.actionsCompactMetadata=M.isActionsCompactMetadataEnabled(),d.actionsNoObserve)M.setActionsNoObserveEnabled(!0);if(d.toolOutputsDir)M.setToolOutputsDir(d.toolOutputsDir)}import{writeSync as nA}from"fs";import{mkdir as rA}from"fs/promises";import{dirname as oA,isAbsolute as aA}from"path";class Md{boundSocketIdentities=new Map;host;files;platform;databasePath;reportStartupFailure;constructor(d,c={stat:Bh},R=process.platform,{databasePath:C=up,reportStartupFailure:T=(B)=>{nA(2,`${B}
43
+ `)}}={}){this.host=d,this.files=c,this.platform=R,this.databasePath=C,this.reportStartupFailure=T}async persistPidFileData(d,c){await rA(oA(vr),{recursive:!0}),c?.throwIfAborted(),await fee(vr,d,c),this.host.setPidFileWritten(!0)}async writeEarlyOwnerRecord(){if(!Qd())await Zd();this.host.identity.incumbentOwnerGuard().captureIncumbentBeforeOverwrite();let d=this.host.identity.incumbentOwnerGuard().supersededOwnerForEarlyRecord(),c={pid:process.pid,launchNonce:E(g.DAEMON_LAUNCH_NONCE),daemonSessionId:this.host.identity.daemonSessionId(),socketPath:Ct,port:this.host.identity.port(),dbPath:this.databasePath(),startedAt:this.host.identity.generationStartedAt(),processStartedAt:this.host.identity.processStartedAt(),...ad(this.host.identity.processGenerationToken()),version:ei,launchLogPath:this.launchLogPath(),assetVersion:en(Ce()),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 ${vr} (dbPath ${c.dbPath})`)}async writePidFile(d){if(!Qd())await Zd();d?.throwIfAborted();let c=No(),R={pid:process.pid,launchNonce:E(g.DAEMON_LAUNCH_NONCE),daemonSessionId:this.host.identity.daemonSessionId(),socketPath:Ct,sockets:EL(st()),port:this.host.identity.port(),dbPath:this.databasePath(),startedAt:this.host.identity.generationStartedAt(),processStartedAt:this.host.identity.processStartedAt(),...ad(this.host.identity.processGenerationToken()),version:ei,launchLogPath:this.launchLogPath(),assetVersion:en(Ce()),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 ${vr}`)}republishIdentity(){return lX(this.host.identity.completeIdentityPublished(),{pid:process.pid,startedAt:this.host.identity.generationStartedAt(),processGenerationToken:this.host.identity.processGenerationToken()},{readRecord:()=>So(),writeRecord:()=>this.writePidFile(),isProcessRunning:(d)=>nt(d,{debugLog:e.debug})},EL(st()))}launchLogPath(){let d=E(g.DAEMON_LAUNCH_LOG_PATH);return d&&aA(d)?d:null}async cleanupDaemonFilesForShutdown(){if(!this.host.identity.socketBindCommitted())this.restoreIncumbentOwnerRecord();await pv(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(Ct)}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 C=ete(d,R);if(!C){if(R instanceof ol)this.reportHeldSocketFailure(R);throw R}e.warn(`[Daemon] ${C.code}: ${d} disabled at ${C.socketPath}`,R);return}tte(d),this.recordSocketIdentity(st()[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 C=So();return C&&C.pid!==process.pid?{expectedPid:process.pid,socketBindCommitted:d,socketPaths:c,socketFileIdentities:R}:{socketBindCommitted:d,socketPaths:c,socketFileIdentities:R}}}var er=3000,dA=3000,Bd=2,lA=1080,uA=2340,pA=1170,mA=2532;function $h(d,c,R){return d.filter((C)=>{if(c.allows(C.platform,"observation-stream",C.id))return!0;return R?.(C),!1})}async function Hh(d,c,R){let C=c.filter((x)=>d===null||x.id===d),T=R.maxConcurrency??Bd;if(!Number.isInteger(T)||T<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:x,subscriber:N}=R;await Promise.all(C.map(async(H)=>{try{let q=await x.request(H.id,()=>qh(H,R),N.signal,R.maxConcurrency);if(q&&!N.signal.aborted&&(R.isDeviceAllowed?.(H.id)??!0))Uh(H.id,q.frame,R,{...N,replay:q.replay})}catch(q){e.warn(`[Daemon] Failed to push initial observation frame for ${H.id}: ${r(q)}`,q)}}));return}let B=0;async function O(){while(B<C.length){let x=C[B++];await fA(x,R)}}await Promise.all(Array.from({length:Math.min(T,C.length)},()=>O()))}async function fA(d,c){try{let R=await qh(d,c);if(R)Uh(d.id,R,c)}catch(R){e.warn(`[Daemon] Failed to push initial observation frame for ${d.id}: ${r(R)}`,R)}}async function qh(d,c){let R={deviceId:d.id,name:d.name,platform:d.platform};if(d.platform!=="android"&&d.platform!=="ios")return;let C=c.streamServer.getLiveFrameGeneration?.(d.id),T=c.streamServer.getDeviceSessionUuid?.(d.id),B=d.platform==="android"?hA(c.androidClientFactory(R)):gA(c.iosClientFactory(R));if(!await B.client.ensureConnected())throw Error(`Failed to connect CtrlProxy to ${d.id}`);e.info(`[Daemon] Capturing initial observation frame for ${d.id}`);let O=c.streamServer.getCurrentFrameContextGeneration?.(d.id),x=await B.hierarchy();if(!x)throw Error(`No hierarchy available for initial observation frame on ${d.id}`);let N=x.hierarchy,H={hierarchy:N,frameContext:x.frameContext??N.frameContext,frameContextGeneration:O,liveFrameGeneration:C,deviceSessionUuid:T,recordHierarchy:(G)=>B.client.recordInitialObservationStreamHierarchy(N,G)},q=await Promise.resolve().then(()=>B.screenshot()).then((G)=>G,(G)=>{H.screenshotFailure={error:G};return});if(q){let G=d.platform==="android"?RA(N):DA(N);H.screenshot={...q,...G}}return H}function hA(d){return{client:d,hierarchy:async()=>{let c=await bA(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:Hte(c),frameContext:c.frameContext,rotation:c.rotation}:void 0}}}function gA(d){return{client:d,hierarchy:async()=>{let c=await wA(d);return c?{hierarchy:d.convertToViewHierarchyResult(c.hierarchy),frameContext:c.frameContext}:null},screenshot:async()=>{let c=await d.requestScreenshotWithoutObservationStreamPush(dA);return c.success&&c.data?{data:c.data,metadata:td(eR,c.format),frameContext:c.frameContext,rotation:c.rotation}:void 0}}}function Uh(d,c,R,C){if(!vA(d,c,R.streamServer))return;if(C&&!C.replay&&c.hierarchyDelivered){Lh(d,c,c.captureSequence??null,{streamServer:R.streamServer,subscriber:C});return}let T=R.streamServer.pushHierarchyUpdate(d,c.hierarchy,c.frameContext,C?{...C,liveFrameGeneration:c.liveFrameGeneration,deviceSessionUuid:c.deviceSessionUuid,captureSequence:c.captureSequence,frameContextGeneration:c.frameContextGeneration}:void 0);if(!C||c.captureSequence===void 0&&T!==null)c.recordHierarchy(T);if(T!==null)c.hierarchyDelivered=!0,c.captureSequence=T,c.frameContextGeneration=R.streamServer.getCurrentFrameContextGeneration?.(d);Lh(d,c,T,{streamServer:R.streamServer,subscriber:C})}function vA(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 Lh(d,c,R,{streamServer:C,subscriber:T}){let B=c.screenshot;if(B&&(!T||R!==null)&&(!T||T.replay||!c.screenshotDelivered)){if(C.pushScreenshotUpdate(d,B.data,{screenWidth:B.width,screenHeight:B.height,metadata:B.metadata,options:{...SA(R,c.frameContext,B.frameContext),...yA(c.hierarchy),initialFrameSubscriber:T?{...T,liveFrameGeneration:c.liveFrameGeneration,deviceSessionUuid:c.deviceSessionUuid}:void 0,rotation:B.rotation,...B.frameContext===void 0?{}:{frameContext:B.frameContext}}}))c.screenshotDelivered=!0}if(c.screenshotFailure)throw c.screenshotFailure.error}function yA(d){let c=Su(d);return c?{coordinateSpace:Fw,nativeScale:c.nativeScale}:{}}function SA(d,c,R){if(d===null||c!==void 0&&R!==void 0&&c!==R)return{};return{captureSequence:d}}async function bA(d){let c=await d.getLatestHierarchy(!1,er,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,er);return R?{hierarchy:R.hierarchy,frameContext:R.frameContext}:null}async function wA(d){let c=await d.getLatestHierarchy(!1,er,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,er);return R?{hierarchy:R.hierarchy,frameContext:R.frameContext}:null}function RA(d){return{width:d.screenWidth??lA,height:d.screenHeight??uA}}function DA(d){let c=Su(d);if(c)return{width:c.pixelWidth,height:c.pixelHeight};let R=d.screenScale??1;return{width:d.screenWidth?Math.round(d.screenWidth*R):pA,height:d.screenHeight?Math.round(d.screenHeight*R):mA}}var kA=1000,AA=20000,IA=60000;class Od{timer;maxConcurrency;getLiveFrameGeneration;getDeviceSessionUuid;captures=new Map;queue=[];recent;active=0;constructor(d=i,c=Bd,R=()=>0,C){this.timer=d;this.maxConcurrency=c;this.getLiveFrameGeneration=R;this.getDeviceSessionUuid=C;if(!Number.isInteger(c)||c<1)throw RangeError("Initial observation frame concurrency must be a positive integer");this.recent=new Zr(d,{ttlMs:kA,maxEntries:32})}request(d,c,R,C){if(C!==void 0){if(!Number.isInteger(C)||C<1)throw RangeError("Initial observation frame concurrency must be a positive integer");this.maxConcurrency=C}if(R.aborted)return Promise.resolve(void 0);let T=this.recent.get(d);if(T&&this.isFrameCurrent(d,T))return Promise.resolve({frame:T,replay:!0});this.recent.delete(d);let B=this.captures.get(d);if(!B)B={deviceId:d,run:c,started:!1,waiters:new Set},this.captures.set(d,B),this.queue.push(B);let O=B,x=O.started&&!this.isCaptureCurrent(O),N=new Promise((q,G)=>{let W=()=>{R.removeEventListener("abort",Y),O.waiters.delete(V)},V={complete:(J)=>{W(),q(J)},fail:(J)=>{W(),G(J)}},Y=()=>{if(V.complete(),!O.started&&O.waiters.size===0)this.captures.delete(d),this.queue.splice(this.queue.indexOf(O),1)};O.waiters.add(V),R.addEventListener("abort",Y,{once:!0})});this.drain();let H=()=>this.request(d,c,R,C);return x?N.then(H,(q)=>(e.warn(`[Daemon] Superseded initial observation capture failed for ${d}: ${r(q)}`,q),H())):N}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,C){if(!c)return;if(c.liveFrameGeneration=R,C!==void 0)c.deviceSessionUuid=C;return this.isFrameCurrent(d,c)?c:void 0}async capture(d){let c=this.timer.now(),R=!0,C=!1,T=!1,B=!1,O,x=()=>{if(B)return;if(B=!0,O!==void 0)this.timer.clearTimeout(O),O=void 0;this.active--,this.drain()},N=()=>{if(R=!0,C)x()};try{let H=this.getLiveFrameGeneration(d.deviceId),q=this.getDeviceSessionUuid?.(d.deviceId);d.liveFrameGeneration=H,d.deviceSessionUuid=q;let G=d.run();R=!1,G.then(N,(Y)=>{if(T&&!B)e.warn(`[Daemon] Initial observation capture rejected after its deadline for ${d.deviceId}: ${r(Y)}`,Y);N()});let W=await l(G,{timer:this.timer,timeoutMs:AA,label:`Initial observation frame for ${d.deviceId}`,onTimeout:()=>{T=!0,O=this.timer.setTimeout(()=>{if(!R&&!B)e.warn(`[Daemon] Initial observation capture slot backstop for ${d.deviceId} after ${this.timer.now()-c}ms; releasing its slot`),x()},Math.max(0,IA-(this.timer.now()-c)))}}),V=this.acceptCapturedFrame(d.deviceId,W,H,q);if(V?.screenshot&&d.waiters.size>0)this.recent.set(d.deviceId,V);for(let Y of[...d.waiters])Y.complete(V?{frame:V,replay:!1}:void 0)}catch(H){if(d.waiters.size===0)e.warn(`[Daemon] Initial observation capture failed for ${d.deviceId}: ${r(H)}`,H);for(let q of[...d.waiters])q.fail(H)}finally{if(this.captures.delete(d.deviceId),C=!0,R)x()}}}function xd(d){return{deviceId:d.id,name:d.name,platform:d.platform,iosVersion:d.iosVersion}}function PA(d,c){return Hc({hostRequestStartMs:d,readAndroidDeviceClockMs:async(R,C)=>(await v.create(xd(R)).getDeviceTimestampMsWithSource(void 0,C)).timestampMs,observe:(R,{minTimestamp:C,signal:T})=>new Ie(xd(R)).execute({skipWaitForFresh:!1,minTimestamp:C,signal:T}),viewerRead:{applies:c,observe:(R,C)=>new Ie(xd(R),void 0,{deviceReadOnly:!0}).executeDeviceRead(C,"none")}})}function Kh(d,c,R){d.setOnSubscriberConnected((C,T)=>{e.info(`[Daemon] IDE plugin subscribed to observation stream (device: ${C??"all"}), ensuring WebSocket connections...`);let B=R.devicePool().getAllDevices(),O=$h(B,R.passiveWorkPolicy(),(x)=>wt(x.platform,x.id,"connect"));if(Hh(C,O,{streamServer:d,coordinator:c,subscriber:T,isDeviceAllowed:(x)=>{let N=R.devicePool().getAllDevices().find((H)=>H.id===x);return!!N&&R.passiveWorkPolicy().allows(N.platform,"observation-stream",x)},androidClientFactory:(x)=>k.getInstance(x,v),iosClientFactory:(x)=>Qc(x,Rt)}).catch((x)=>{e.warn(`[Daemon] Error pushing initial observation frame: ${x}`)}),B.length===0)e.info("[Daemon] No devices in pool to connect")}),d.setOnScreenshotCadenceChanged((C)=>{let T=R.devicePool().getAllDevices().filter((B)=>C===null||B.id===C);for(let B of T)if(B.platform==="android"){if(!R.passiveWorkPolicy().allows("android","observation-stream",B.id)){wt("android",B.id,"screenshot cadence");continue}k.getExistingInstance(B.id)?.refreshObservationStreamScreenshotCadence()}else if(B.platform==="ios"){if(!R.passiveWorkPolicy().allows("ios","observation-stream",B.id)){wt("ios",B.id,"screenshot cadence");continue}_.getExistingInstance(B.id)?.refreshObservationStreamScreenshotCadence()}}),d.setOnHierarchyCadenceChanged((C)=>{let T=R.devicePool().getAllDevices().filter((B)=>C===null||B.id===C);for(let B of T)if(B.platform==="android"){if(!R.passiveWorkPolicy().allows("android","observation-stream",B.id)){wt("android",B.id,"hierarchy cadence");continue}k.getExistingInstance(B.id)?.refreshObservationStreamHierarchyCadence()}else if(B.platform==="ios"){if(!R.passiveWorkPolicy().allows("ios","observation-stream",B.id)){wt("ios",B.id,"hierarchy cadence");continue}let O=_.getExistingInstance(B.id);if(!O)continue;let x=d.getHierarchyIntervalMsForDevice(B.id);O.ensureConnected().then((N)=>{if(N)O.refreshObservationStreamHierarchyCadence(x)}).catch((N)=>{e.warn(`[Daemon] Failed to refresh iOS hierarchy cadence for ${B.id}: ${N}`)})}}),d.setOnStorageSubscriptionRequested((C)=>R.applyStorageSubscriptionRequest(C)),d.setOnObservationRequested(async({deviceId:C,sessionUuid:T,signal:B})=>{let O=bn("observationStream",{allowObserverSessions:!0}),x=C?[R.devicePool().getDevice(C)].filter((H)=>H!==null):R.devicePool().getAllDevices().filter((H)=>dr(H.platform));if(x.length===0)throw Error(C?`Device ${C} is not available`:"No devices are available");if(B.aborted)throw Error("Observation request was aborted");let N=R.timer().now();return Kc(x,PA(N,(H)=>Yc({sessionManager:R.sessionManager(),devicePool:R.devicePool()},H,T)),{timer:R.timer(),signal:B,assertDeviceActionable:(H)=>{R.devicePool().assertDeviceActionable(H.id,"to observe"),O.authorize({sessionUuid:T,deviceId:H.id,admitViewer:!0})}})},mr+Lc)}class _d{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")ge.getExistingInstance(d)?.rearmAfterDeviceReappearance().catch((C)=>{e.warn(`[Daemon] Failed to rearm iOS CtrlProxy for ${d}: ${r(C)}`)});if(c.platform==="android")k.noteDeviceOnline(d);this.host.services.deviceSessionRegistry().onDeviceConnected({deviceId:c.id,platform:c.platform,incarnation:c.incarnation})}getDeviceSessionRoutingTargets(){return{deviceDataStream:Rt(),performancePush:zC(),failuresPush:Rz(),telemetryPush:Ow()}}configureDeviceDataStreamServer(){this.setupDeviceSessionRouting(),this.host.setupDeviceDataStreamCallback()}setupDeviceSessionRouting(){let d=ste(this.host.services.deviceSessionRegistry(),this.host.services.devicePool()),{deviceDataStream:c,performancePush:R,failuresPush:C,telemetryPush:T}=this.host.getDeviceSessionRoutingTargets();if(this.host.lifecycle.setDeviceDataStreamServer(c),c?.setDeviceSessionResolver(d),R?.setDeviceSessionResolver(d),C?.setDeviceSessionResolver(d),T?.setDeviceSessionResolver(d),c)this.host.services.deviceSessionRegistry().setLifecycleListener({onSessionStarted:(B)=>c.pushDeviceSessionStarted(B),onSessionEnded:(B,O)=>c.pushDeviceSessionEnded(B,O)})}getInitialFrameCoordinator(d){let c=this.initialFrameCoordinators.get(d);if(!c)c=new Od(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()??Rt();if(!d){e.warn("[Daemon] Observation stream server not available for callback setup");return}Kh(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 Xc({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 Nd{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,C)=>{if(!(R instanceof Pe))return!1;let T=this.gap(c,this.readClock(),R.timeoutMs,R.startupMs??0),B=[d.lateMs,d.sleptMs,T.lateMs,T.sleptMs].some((O)=>O>dH);if(B)e.warn(`Database health probe timeout inconclusive: tick lateness=${d.lateMs}ms, probe overrun=${T.lateMs}ms, tick host sleep=${d.sleptMs}ms, probe host sleep=${T.sleptMs}ms, timeout=${R.timeoutMs}ms; strike count stays at ${C}`);return B}}readClock(){return{wall:this.timer.now(),monotonic:this.timer.monotonicNow?.()??this.timer.now()}}gap(d,c,R,C=0){return lH({wallElapsedMs:Math.max(0,c.wall-d.wall-C),monotonicElapsedMs:Math.max(0,c.monotonic-d.monotonic-C),scheduledMs:R,monotonicIncludesHostSleep:this.timer.monotonicIncludesHostSleep,maxCredibleStallMs:BP})}}var $d=30000,CA=3,Gh=2*$d,Ld=10;function Vh(d){let c=new Nd(d.timer,$d),R=0,C="unknown",T=0,B=(V)=>{if(C!==V)R=0;C=V,R++},O=()=>{R=0,C="unknown"},x=()=>{let V=d.httpServer();if(!V)return e.warn("Health check failed: HTTP server not initialized"),B("http"),!1;if(!V.listening)return e.warn("Health check failed: HTTP server not listening"),B("http"),!1;if(!d.socketServerListening())return e.warn("Health check failed: Socket server not listening"),B("socket"),!1;if(!d.observationStreamHealthy()&&!PW("observation-stream"))return e.warn("Health check failed: Observation stream socket unavailable"),B("socket"),!1;return!0},N=(V,Y)=>{if(!(V instanceof Pe)||!(Y||(d.hostIoStalled?.()??!1)))return!1;if(T>=Ld){if(T===Ld)T++,e.error(`Host I/O stall excused ${Ld} consecutive database probe timeouts; counting further timeouts toward recovery`);return!1}return T++,e.warn(`Database health probe timeout inconclusive: host I/O stalled, timeout=${V.timeoutMs}ms; strike count stays at ${R}`),!0},H=async(V)=>{let Y=c.beginProbe(V),J=d.hostIoStalled?.()??!1;try{await d.databaseHealthProbe().check(),d.onDatabaseFailureChanged(void 0),O(),T=0,e.debug("Health check passed")}catch(X){if(Y(X,R))return!1;if(N(X,J))return!1;d.onDatabaseFailureChanged(r(X)),e.warn(`Health check failed: Database probe failed: ${X}`),B("database")}return!0},q=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)}},G=async()=>{if(!PW("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(!PW("observation-stream")&&d.observationStreamHealthy())await q()},W=async()=>{let V=c.tick();try{if(x()){let Y=await H(V);if(await G(),!Y)return}if(R>=CA)e.error(`Health check failed ${R} times, attempting recovery...`),await d.recover(C),O()}catch(Y){e.warn(`Health check error: ${Y}`),B("unknown")}};return new il(d.timer,$d,W)}var Jh={"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 TA=5000,MA=jM,EA=20000;function jh(d,c){return Ym(d,c)}class Hd{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:C=i,...T}={}){this.sessions=d;this.reap=R;this.timer=C,this.checkIntervalMs=T.checkIntervalMs??mC(),this.graceMs=T.graceMs??jh(g.SESSION_HEARTBEAT_INITIAL_GRACE_MS.name,g.SESSION_HEARTBEAT_INITIAL_GRACE_MS.legacyName)??EA,this.preFirstHeartbeatGraceMs=T.preFirstHeartbeatGraceMs??zb(),this.defaultHeartbeatTimeoutMs=T.heartbeatTimeoutMs??jh(g.SESSION_HEARTBEAT_TIMEOUT_MS.name,g.SESSION_HEARTBEAT_TIMEOUT_MS.legacyName)??Ya(),this.stallThresholdMs=T.stallThresholdMs??dH,this.forceStuckRelease=T.forceStuckRelease,this.maxCredibleStallMs=T.maxCredibleStallMs??BP,this.bunVersionOverride=T.bunVersion,this.executionVeto=new nI(c,C,fy,()=>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:TA,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=lH({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=OY(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 C=R.lateMs>this.stallThresholdMs?R.lateMs:0,T=R.sleptMs>this.stallThresholdMs?R.sleptMs:0;if(C===0&&T===0)return;let B=this.lastScanSettledAt??d;this.lastScanSettledAt=d-this.checkIntervalMs,this.lastScanSettledMonotonic=c-this.checkIntervalMs;let O=this.sessions.forgiveDaemonStall?.(d,C,T,B)??0;e.warn(`Heartbeat monitor tick fired ${C}ms late after the host slept ${T}ms; ${O} 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),C=c.ownership==="awaiting-owner"?this.rehydrationOwnerStaleReason(c,R):this.staleReason(c,R);if(!C){this.executionVeto.forget(c);continue}if(this.isVetoedByActiveExecution(c,C))continue;e.warn(`Session ${c.sessionId} ${Jh[C]}, cancelling (reason=${C})`+(C==="heartbeat-timeout"?`; last heartbeat age=${R-(this.sessions.judgedLeaseHeartbeat?.(c)??py(c))}ms, heartbeat timeout=${c.heartbeatTimeoutMs??this.defaultHeartbeatTimeoutMs}ms`:""));try{d.push(this.trackReap(c.sessionId,this.reap(c.sessionId,C)))}catch(T){e.warn(`Failed to reap stale session ${c.sessionId}`,T),d.push(Promise.reject(T))}}return d}trackReap(d,c){let R=c.catch((O)=>{throw e.warn(`Failed to reap stale session ${d}`,O),O}),C=R.then(()=>{return},()=>{return});this.reapsInFlight.set(d,C);let T=this.reapStartedAt.get(d),B=T?.sourceRelease&&this.sessions.isReleaseInProgress?.(d,T.at)===!0?{...T}:{at:this.now(),reported:!1};return this.reapStartedAt.set(d,B),C.then(()=>{if(this.reapsInFlight.get(d)===C)this.reapsInFlight.delete(d);if(this.reapStartedAt.get(d)===B)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((C)=>[C.session,C.startedAtMs]));let c=[d,this.sessions.getIdleReleasesInProgress?.(),this.sessions.getTerminalReleasesInProgress?.()].flatMap((C)=>C??[]),R=new Map(c.map((C)=>[C.sessionId,C.startedAtMs]));for(let[C,T]of this.reapStartedAt)if(T.sourceRelease&&R.get(C)!==T.at&&this.sessions.isReleaseInProgress?.(C,T.at)!==!0)this.reapStartedAt.delete(C);for(let[C,T]of R)if(!this.reapStartedAt.has(C))this.reapStartedAt.set(C,{at:T,reported:!1,sourceRelease:!0})}reportIfStuck(d){let c=this.reapStartedAt.get(d);if(!c||c.reported)return;let R=this.now(),C=R-c.at;if(R<(this.sessions.getReleaseStuckAtMs?.(d)??c.at+MA))return;if(c.reported=!0,!this.forceStuckRelease){e.warn(`Session ${d} release has not settled after ${C}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 ${C}ms; forcing its device back to the pool while the session stays fenced (#10963).`),this.forceStuckRelease(d).catch((T)=>{e.warn(`Forcing the stuck release of session ${d} failed: ${r(T)}`,T)})}isVetoedByActiveExecution(d,c){let R=this.executionVeto.judge(d);if(R.kind!=="expired")return R.kind==="kept";return e.warn(`Session ${d.sessionId} (${Jh[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>If(d)?"cli-idle-timeout":void 0;return this.heartbeatLeaseStaleReason(d,c)}heartbeatLeaseStaleReason(d,c){let R=d.heartbeatTimeoutMs??this.defaultHeartbeatTimeoutMs,C=py(d),T=this.sessions.judgedLeaseHeartbeat?.(d)??C;if(!d.hasReceivedHeartbeat&&T===C){if(d.heartbeatTimeoutSource==="default")return c-T>this.preFirstHeartbeatGraceMs?"missing-first-heartbeat":void 0;if(c-d.createdAt<this.graceMs)return}return rH(c,T,R,my(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,C=d.awaitingOwnerSince??c;return c-C>R+is?"rehydration-owner-timeout":void 0}}var BA=15000;class qd{port;idleMs;timer;lastBusyAt=new Map;interval;constructor(d,c,R=i,C=Math.min(Math.max(1,Math.floor(c/4)),BA)){this.port=d;this.idleMs=c;this.timer=R;this.interval=new il(R,C,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 T of[...this.lastBusyAt.keys()])if(!c.has(T))this.lastBusyAt.delete(T);let R=[...c].filter((T)=>this.isIdle(T,d)),C=[];for(let T of R){if(!this.isIdle(T,this.timer.now()))continue;try{e.info(`[CTRL_PROXY] Releasing idle CtrlProxy forwarding lease for ${T} (no session or tool activity for ${this.idleMs}ms)`),this.lastBusyAt.delete(T),await this.port.release(T),C.push(T)}catch(B){e.warn(`[CTRL_PROXY] Failed to release idle forwarding lease for ${T}: ${r(B)}`,B)}}return C}isIdle(d,c){let R=this.port.activity(d);if(gX(R))return this.lastBusyAt.set(d,c),!1;let C=this.lastBusyAt.get(d);if(C===void 0)return this.lastBusyAt.set(d,c),!1;let T=R.idleForMs??Number.POSITIVE_INFINITY;return Math.min(c-C,T)>=this.idleMs}}var OA=900000,xA=30000,_A=1;function Yh(d=process.env){return wu(g.PRIVATE_DAEMON_ORPHAN_IDLE_MS,d)??OA}var FA=g.DAEMON_LAUNCHER_PID.name;function Xh(d,c=process.env){let R=c[FA]?.trim()??"",C=rb(R);return C!==void 0&&C>1?C:d}var NA=g.HARNESS_PRIVATE_DAEMON.name;function Qh(d,c,R=process.env){let C=R[NA]?.trim();if(C==="1"||C==="0")return C==="1";return zh(R,[g.DAEMON_SOCKET_PATH.name,g.DAEMON_SOCKET_PATH.legacyName])!==""&&d!==c&&zh(R,[g.AUX_SOCKET_DIR.name])!==""}function zh(d,c){return c.map((R)=>d[R]?.trim()??"").find((R)=>R!=="")??""}class Ud{orphanIdleSince=null;lastClientActivityCount=null;handle=null;shutdownRequested=!1;launcherToken;port;idleMs;timer;checkIntervalMs;launcherGeneration;constructor(d,c,R=i,{checkIntervalMs:C=Math.min(xA,c),launcherGeneration:T=Nt}={}){this.port=d,this.idleMs=c,this.timer=R,this.checkIntervalMs=C,this.launcherGeneration=T}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===_A)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,C=this.timer.now();if(!R)return this.orphanIdleSince=null,!1;if(this.orphanIdleSince??=C,C-this.orphanIdleSince<this.idleMs)return!1;this.shutdownRequested=!0,this.stop();let T=`private daemon's parent exited and it has had no clients or sessions for ${Math.round((C-this.orphanIdleSince)/1000)}s`;return e.warn(`[Daemon] Shutting down orphaned private daemon: ${T}`),this.port.shutdown(T),!0}}var Zh=86400000,eg=7*Zh,tg=90*Zh,ig=50000,ng=500000,rg=5000,LA=20,og=21600000,sg=1e4,Kd=2147483647;function ag(d){return{screenshotsCleared:0,nodeObservationsDeleted:0,edgeObservationsDeleted:0,suggestionObservationsDeleted:0,buildKeysDeleted:0,edgeTraversalsDeleted:0,prunedAt:d}}function tr(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 tr(Ym(d.name,d.legacyName),c)}function Gd(d={}){let c=(R,C,T,B=Number.MAX_SAFE_INTEGER)=>tr(R,B)??lg(C,B)??T;return{screenshotTtlMs:c(d.screenshotTtlMs,g.NAV_RETENTION_SCREENSHOT_TTL_MS,eg),structureTtlMs:c(d.structureTtlMs,g.NAV_RETENTION_STRUCTURE_TTL_MS,tg),perAppMaxObservations:c(d.perAppMaxObservations,g.NAV_RETENTION_PER_APP_MAX_OBSERVATIONS,ig),globalMaxObservations:c(d.globalMaxObservations,g.NAV_RETENTION_GLOBAL_MAX_OBSERVATIONS,ng),evictionChunkSize:Math.min(c(d.evictionChunkSize,g.NAV_RETENTION_EVICTION_CHUNK_SIZE,rg),sg),maxEdgeTraversalsPerTransition:tr(d.maxEdgeTraversalsPerTransition)??LA}}function Wd(d){return tr(d,Kd)??lg(g.NAV_RETENTION_INTERVAL_MS,Kd)??og}async function ir(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((T)=>({id:T.id,appId:T.app_id}))}async function Vd(d,c,R){let C=c??await ir(d,R);if(C.length===0)return[];let T=await HA(d,R),B=new Map;for(let O of C){let x=T.get(O.id)??Number.NEGATIVE_INFINITY;if($A(B.get(O.appId),O.id,x))B.set(O.appId,{id:O.id,seen:x})}return Array.from(B.values(),(O)=>O.id)}function $A(d,c,R){if(d===void 0)return!0;return R>d.seen||R===d.seen&&c>d.id}function Mi(d,c){if(d.length!==c.length)return!1;let R=new Set(c);return d.every((C)=>R.has(C))}async function HA(d,c){let R=d.selectFrom("navigation_node_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((H)=>["observation.build_key_id",H.fn.max("observation.last_seen_at").as("max_seen")]),C=d.selectFrom("navigation_edge_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((H)=>["observation.build_key_id",H.fn.max("observation.last_seen_at").as("max_seen")]),T=d.selectFrom("navigation_suggestion_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((H)=>["observation.build_key_id",H.fn.max("observation.last_seen_at").as("max_seen")]);if(c&&c.length>0)R=R.where("buildKey.app_id","in",c),C=C.where("buildKey.app_id","in",c),T=T.where("buildKey.app_id","in",c);let B=await R.groupBy("observation.build_key_id").execute(),O=await C.groupBy("observation.build_key_id").execute(),x=await T.groupBy("observation.build_key_id").execute(),N=new Map;for(let H of[...B,...O,...x]){let q=Number(H.max_seen??0),G=N.get(H.build_key_id);if(G===void 0||q>G)N.set(H.build_key_id,q)}return N}async function Jd(d,c){if(c.length===0)return new Map;let R=Array.from(new Set(c));return qA(d,R)}async function qA(d,c){let R=await d.selectFrom("navigation_node_observations").select((O)=>["build_key_id",O.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),C=await d.selectFrom("navigation_edge_observations").select((O)=>["build_key_id",O.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),T=await d.selectFrom("navigation_suggestion_observations").select((O)=>["build_key_id",O.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),B=new Map;for(let O of[...R,...C,...T]){let x=Number(O.max_seen??0),N=B.get(O.build_key_id);if(N===void 0||x>N)B.set(O.build_key_id,x)}return B}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((T)=>T.node_id)}async function nr(d,c){return c===null?UA(d):KA(d,c)}async function UA(d){let c=await d.selectNoFrom(m`(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 KA(d,c){let R=await d.selectNoFrom(m`(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,C){let T=await mg(d,c,R,C).execute(),B=await fg(d,c,R,C).execute(),O=await GA(d,c,R,C).execute(),x=[...T.map((H)=>({kind:"node",id:H.id,buildKeyId:H.build_key_id,lastSeenAt:H.last_seen_at})),...B.map((H)=>({kind:"edge",id:H.id,buildKeyId:H.build_key_id,lastSeenAt:H.last_seen_at})),...O.map((H)=>({kind:"suggestion",id:H.id,buildKeyId:H.build_key_id,lastSeenAt:H.last_seen_at}))],N={node:0,edge:1,suggestion:2};return x.sort((H,q)=>H.lastSeenAt-q.lastSeenAt||N[H.kind]-N[q.kind]||H.id-q.id),x.slice(0,C)}function mg(d,c,R,C){let T=d.selectFrom("navigation_node_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)T=T.where("build_key_id","in",(B)=>B.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(R.length>0)T=T.where((B)=>B.or([B("build_key_id","not in",R),B("last_seen_at","<>",B.selectFrom("navigation_node_observations as t").select((O)=>O.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_node_observations.build_key_id"))]));return T.orderBy("last_seen_at","asc").orderBy("id","asc").limit(C)}function fg(d,c,R,C){let T=d.selectFrom("navigation_edge_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)T=T.where("build_key_id","in",(B)=>B.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(R.length>0)T=T.where((B)=>B.or([B("build_key_id","not in",R),B("last_seen_at","<>",B.selectFrom("navigation_edge_observations as t").select((O)=>O.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_edge_observations.build_key_id"))]));return T.orderBy("last_seen_at","asc").orderBy("id","asc").limit(C)}function GA(d,c,R,C){let T=d.selectFrom("navigation_suggestion_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)T=T.where("build_key_id","in",(B)=>B.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(R.length>0)T=T.where((B)=>B.or([B("build_key_id","not in",R),B("last_seen_at","<>",B.selectFrom("navigation_suggestion_observations as t").select((O)=>O.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_suggestion_observations.build_key_id"))]));return T.orderBy("last_seen_at","asc").orderBy("id","asc").limit(C)}var WA=()=>new Promise((d)=>setImmediate(d)),VA=3;class zd{db;config;removeScreenshotFile;logger;yieldBetweenBatches;resolveProtectedBuildKeyIds;constructor(d,c={},R={}){this.db=d;this.config=Gd(c),this.removeScreenshotFile=R.removeScreenshotFile,this.logger=R.logger??e,this.yieldBetweenBatches=R.yieldBetweenBatches??WA,this.resolveProtectedBuildKeyIds=R.resolveProtectedBuildKeyIds??Vd}async prune(d){let c=ag(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>=VA)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 C=await this.resolveProtectedBuildKeyIds(this.db),T=!Mi(C,d);return{ids:C,retry:T&&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,C=this.config.evictionChunkSize,T=await this.resolveProtectedBuildKeyIds(this.db),B=0;for(;;){let O=await this.db.transaction().execute(async(N)=>{let H=N.selectFrom("navigation_nodes").select(["id","app_id","screenshot_path"]).where("screenshot_path","is not",null).where("last_seen_at","<",R);if(T.length>0)H=H.where("id","not in",(ee)=>ee.selectFrom("navigation_node_observations").select("node_id").where("build_key_id","in",T));let q=await H.limit(C).execute();if(q.length===0)return null;let G=Array.from(new Set(q.map((ee)=>ee.app_id))),W=await this.resolveProtectedBuildKeyIds(N,void 0,G),V=await ug(N,q.map((ee)=>ee.id),W),Y=new Set(V),J=q.filter((ee)=>!Y.has(ee.id)),X=W.some((ee)=>!T.includes(ee));if(J.length===0)return{clearedCount:0,clearedPaths:[],isFullBatch:q.length===C,activeBuildChanged:X};let Z=J.map((ee)=>ee.id);await N.updateTable("navigation_nodes").set({screenshot_path:null}).where("id","in",Z).execute();let re=[];for(let ee of J)if(ee.screenshot_path!==null)re.push(ee.screenshot_path);return{clearedCount:Z.length,clearedPaths:re,isFullBatch:q.length===C,activeBuildChanged:X}});if(O===null){let N=await this.revalidateEmptyProtection(T,"screenshots",++B);if(T=N.ids,N.retry)continue;break}if(c.screenshotsCleared+=O.clearedCount,O.clearedCount>0)B=0;if(await this.removeFiles(O.clearedPaths),O.activeBuildChanged)T=await this.resolveProtectedBuildKeyIds(this.db);let x=O.clearedCount===0&&O.activeBuildChanged;if(x&&await this.retryAfterProtectionChange("screenshots",++B))continue;if(x)break;if(!O.isFullBatch||O.clearedCount===0)break;await this.yieldBetweenBatches()}}async pruneExcessEdgeTraversals(d){let c=this.config.maxEdgeTraversalsPerTransition,R=this.config.evictionChunkSize,C=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((T)=>T.fn.countAll(),">",c).execute();for(let T of C){for(;;){let B=await this.db.transaction().execute((x)=>x.deleteFrom("navigation_edges").where("id","in",(N)=>N.selectFrom("navigation_edges as e").select("e.id").where("e.app_id","=",T.app_id).where("e.from_screen","=",T.from_screen).where("e.to_screen","=",T.to_screen).where(m`e.tool_name is ${T.tool_name}`).where(m`e.tool_args is ${T.tool_args}`).where(m`not exists (select 1 from test_edge_coverage c where c.edge_id = e.id)`).orderBy("e.id","desc").limit(R).offset(c)).executeTakeFirst()),O=Number(B.numDeletedRows??0);if(d.edgeTraversalsDeleted+=O,O<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,C=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let T=await this.db.transaction().execute(async(O)=>{let x=O.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(C.length>0)x=x.where("observation.build_key_id","not in",C);let N=await x.limit(this.config.evictionChunkSize).execute();if(N.length===0)return null;let H=Array.from(new Set(N.map((J)=>J.app_id))),q=await this.resolveProtectedBuildKeyIds(O,void 0,H),G=new Set(q),W=N.filter((J)=>!G.has(J.build_key_id)).map((J)=>J.id),V=q.some((J)=>!C.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:N.length===this.config.evictionChunkSize,protectionChanged:V};let Y=await O.deleteFrom("navigation_node_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(Y.numDeletedRows??0),isFullBatch:N.length===this.config.evictionChunkSize,protectionChanged:V}});if(T===null){let O=await this.revalidateEmptyProtection(C,"node TTL",++R);if(C=O.ids,O.retry)continue;return c}if(c+=T.deletedCount,T.deletedCount>0)R=0;C=await this.refreshChangedProtection(C,T.protectionChanged);let B=T.protectionChanged&&T.deletedCount===0;if(B&&await this.retryAfterProtectionChange("node TTL",++R))continue;if(B)return c;if(!T.isFullBatch&&!T.protectionChanged||T.deletedCount===0)return c;await this.yieldBetweenBatches()}}async pruneEdgeObservationsByTtl(d){let c=0,R=0,C=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let T=await this.db.transaction().execute(async(O)=>{let x=O.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(C.length>0)x=x.where("observation.build_key_id","not in",C);let N=await x.limit(this.config.evictionChunkSize).execute();if(N.length===0)return null;let H=Array.from(new Set(N.map((J)=>J.app_id))),q=await this.resolveProtectedBuildKeyIds(O,void 0,H),G=new Set(q),W=N.filter((J)=>!G.has(J.build_key_id)).map((J)=>J.id),V=q.some((J)=>!C.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:N.length===this.config.evictionChunkSize,protectionChanged:V};let Y=await O.deleteFrom("navigation_edge_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(Y.numDeletedRows??0),isFullBatch:N.length===this.config.evictionChunkSize,protectionChanged:V}});if(T===null){let O=await this.revalidateEmptyProtection(C,"edge TTL",++R);if(C=O.ids,O.retry)continue;return c}if(c+=T.deletedCount,T.deletedCount>0)R=0;C=await this.refreshChangedProtection(C,T.protectionChanged);let B=T.protectionChanged&&T.deletedCount===0;if(B&&await this.retryAfterProtectionChange("edge TTL",++R))continue;if(B)return c;if(!T.isFullBatch&&!T.protectionChanged||T.deletedCount===0)return c;await this.yieldBetweenBatches()}}async pruneSuggestionObservationsByTtl(d){let c=0,R=0,C=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let T=await this.db.transaction().execute(async(O)=>{let x=O.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(C.length>0)x=x.where("observation.build_key_id","not in",C);let N=await x.limit(this.config.evictionChunkSize).execute();if(N.length===0)return null;let H=Array.from(new Set(N.map((J)=>J.app_id))),q=await this.resolveProtectedBuildKeyIds(O,void 0,H),G=new Set(q),W=N.filter((J)=>!G.has(J.build_key_id)).map((J)=>J.id),V=q.some((J)=>!C.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:N.length===this.config.evictionChunkSize,protectionChanged:V};let Y=await O.deleteFrom("navigation_suggestion_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(Y.numDeletedRows??0),isFullBatch:N.length===this.config.evictionChunkSize,protectionChanged:V}});if(T===null){let O=await this.revalidateEmptyProtection(C,"suggestion TTL",++R);if(C=O.ids,O.retry)continue;return c}if(c+=T.deletedCount,T.deletedCount>0)R=0;C=await this.refreshChangedProtection(C,T.protectionChanged);let B=T.protectionChanged&&T.deletedCount===0;if(B&&await this.retryAfterProtectionChange("suggestion TTL",++R))continue;if(B)return c;if(!T.isFullBatch&&!T.protectionChanged||T.deletedCount===0)return c;await this.yieldBetweenBatches()}}async enforceCaps(d){let c=await ir(this.db),R=Array.from(new Set(c.map((B)=>B.appId)));for(let B of R){let x=await nr(this.db,B)-this.config.perAppMaxObservations;if(x>0)await this.evictOldest(B,x,this.config.perAppMaxObservations,d);await this.yieldBetweenBatches()}let T=await nr(this.db,null)-this.config.globalMaxObservations;if(T>0)await this.evictOldest(null,T,this.config.globalMaxObservations,d)}async evictOldest(d,c,R,C){let T=c,B=0,O=!1,x=d===null?void 0:[d],N=await this.resolveProtectedBuildKeyIds(this.db,void 0,x);while(T>0){if(O){if(T=Math.max(0,await nr(this.db,d)-R),O=!1,T===0)return}let H=Math.min(T,this.config.evictionChunkSize),q=await this.db.transaction().execute(async(G)=>{let W=await pg(G,d,N,H);if(W.length===0){let oe=await this.resolveProtectedBuildKeyIds(G,void 0,x);return{evictedCount:0,protectionChanged:!Mi(oe,N)}}let V=await this.resolveProtectedBuildKeyIds(G,void 0,x);if(!Mi(V,N))return{evictedCount:0,protectionChanged:!0};let Y=await Jd(G,W.map((oe)=>oe.buildKeyId)),J=new Set(V),X=W.filter((oe)=>!J.has(oe.buildKeyId)||oe.lastSeenAt<(Y.get(oe.buildKeyId)??Number.NEGATIVE_INFINITY));if(X.length===0)return{evictedCount:0,protectionChanged:!1};let Z=X.filter((oe)=>oe.kind==="node").map((oe)=>oe.id),re=X.filter((oe)=>oe.kind==="edge").map((oe)=>oe.id),ee=X.filter((oe)=>oe.kind==="suggestion").map((oe)=>oe.id);if(Z.length>0){let oe=await G.deleteFrom("navigation_node_observations").where("id","in",Z).executeTakeFirst();C.nodeObservationsDeleted+=Number(oe.numDeletedRows??0)}if(re.length>0){let oe=await G.deleteFrom("navigation_edge_observations").where("id","in",re).executeTakeFirst();C.edgeObservationsDeleted+=Number(oe.numDeletedRows??0)}if(ee.length>0){let oe=await G.deleteFrom("navigation_suggestion_observations").where("id","in",ee).executeTakeFirst();C.suggestionObservationsDeleted+=Number(oe.numDeletedRows??0)}return{evictedCount:X.length,protectionChanged:!1}});if(q.evictedCount===0){if(q.protectionChanged)N=await this.resolveProtectedBuildKeyIds(this.db,void 0,x);if(q.protectionChanged&&await this.retryAfterProtectionChange("cap eviction",++B)){O=!0;continue}return}if(B=0,T-=q.evictedCount,T>0)await this.yieldBetweenBatches(),O=!0}}async pruneOrphanBuildKeys(d){let c=this.config.evictionChunkSize,R=async(B)=>{let O=await ir(B),x=await this.resolveProtectedBuildKeyIds(B,O),N=new Map(O.map((q)=>[q.id,q.appId])),H=new Map(x.map((q)=>[N.get(q),q]));return{ids:x,byApp:H}},C=await R(this.db),T=0;for(;;){let B=await this.db.transaction().execute(async(x)=>{let N=x.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(C.ids.length>0)N=N.where("id","not in",C.ids);let H=await N.limit(c).execute();if(H.length===0)return{deleted:0,protectionChanged:!1};if(H.some((X)=>!C.byApp.has(X.app_id)))return{deleted:0,protectionChanged:!0,currentProtection:await R(x)};let q=Array.from(new Set(H.map((X)=>C.byApp.get(X.app_id)).filter((X)=>X!==void 0))),G=await x.selectFrom("navigation_build_keys").select("id").where("id","in",q).execute(),W=new Set(G.map((X)=>X.id));if(q.some((X)=>!W.has(X)))return{deleted:0,protectionChanged:!0};let V=Array.from(new Set(H.filter((X)=>X.id>(C.byApp.get(X.app_id)??0)).map((X)=>C.byApp.get(X.app_id)).filter((X)=>X!==void 0))),Y=await Jd(x,V);if(V.some((X)=>!Y.has(X)))return{deleted:0,protectionChanged:!0};let J=await x.deleteFrom("navigation_build_keys").where("id","in",H.map((X)=>X.id)).executeTakeFirst();return{deleted:Number(J.numDeletedRows??0),protectionChanged:!1}});if(d.buildKeysDeleted+=B.deleted,B.deleted>0)T=0;let O=B.protectionChanged;if(O||B.deleted===0){let x=B.currentProtection??await R(this.db);O||=!Mi(x.ids,C.ids),C=x}if(O&&await this.retryAfterProtectionChange("orphan sweep",++T))continue;if(O)return;if(B.deleted<c)return;await this.yieldBetweenBatches()}}}class Yd{retention;timer;timerHandle=null;running=!1;intervalMs;lastSummary=null;constructor(d,c=i,R){this.retention=d;this.timer=c;this.intervalMs=Wd(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 Wt().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 Xd{host;constructor(d){this.host=d}startHealthCheckTimer(){this.host.setHealthCheck(Vh({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?.()??(()=>BY(Gh))})),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 Hd(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)=>G1(this.host.services.sessionManager(),this.host.services.devicePool(),d)})),this.host.lifecycle.heartbeatMonitor().start()}startNavigationRetentionMonitor(){let d=new ni,c=new zd(ke(),{},{removeScreenshotFile:(R)=>d.unlink(R)});this.host.lifecycle.setNavigationRetentionMonitor(new Yd(c,this.host.services.timer())),this.host.lifecycle.navigationRetentionMonitor().start()}startForwardLeaseIdleReleaser(){let d=J1((c)=>this.host.services.sessionManager().getSessionForDevice(c));this.host.lifecycle.setForwardLeaseIdleReleaser(new qd({heldDeviceIds:()=>k.getForwardLeaseHeldDeviceIds(),activity:(c)=>$M(d,c),release:(c)=>k.releaseIdleForwardLease(c)},lL(),this.host.services.timer())),this.host.lifecycle.forwardLeaseIdleReleaser().start()}startPrivateDaemonOrphanWatchdog(){if(process.platform==="win32"||!Qh(Ct,iL))return;let d=Xh(EV);this.host.lifecycle.setOrphanWatchdog(new Ud({parentPid:()=>process.ppid,launcherPid:()=>d,launcherIsExplicit:()=>d!==EV,isProcessRunning:(c)=>nt(c),clientCount:()=>(this.host.lifecycle.socketServer()?.getClientConnectionCount()??0)+ite()+this.host.services.httpIngress().openRequestCount,clientActivityCount:()=>(this.host.lifecycle.socketServer()?.getAcceptedClientConnectionCount()??0)+ote()+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"))}},Yh(),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 Ii(Ct,void 0,void 0,sr.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:vr,sockets:st(),dbPath:up(),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 Ei{sessions;plans;executions;constructor(d,c=M,R=j){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((C)=>C.assignedDevice===d).map((C)=>C.sessionId));return this.plans.getActivePlanExecutions().filter((C)=>{if(!C.sessionUuid)return c===void 0&&C.deviceId===d;let T=[C.sessionUuid,...C.labelSessionUuids??[]];return(c===void 0||this.ownerSession(C.sessionUuid)===this.ownerSession(c))&&T.some((B)=>R.has(B))})}ownerSession(d){return IL(d,this.sessions)}}var gg=15000,vg=Wg,hg=vg-2,JA=60000;function jA(d,c){return c!==void 0&&(d.transitionalSimulators?.length??0)>0}function zA(d,c){if(d!=="either")return{};let R=lB(c.map((C)=>C.platform));return{includeWatchOs:!0,...R.length>0?{includeAppleSimulatorPlatforms:R}:{}}}async function yg(d,c,{isPlanDevice:R=()=>!1,platform:C="either",bypassAndroidDeviceListCache:T=!1,heldDevices:B=[],iosDeviceListMaxAgeMs:O}){let x=[...d.getAllDevices().map((J)=>({platform:J.platform,id:J.id})),...B.map((J)=>({platform:J.platform,id:J.assignedDevice}))],N={bypassAndroidDeviceListCache:T,skipAndroidProfileEnrichment:!0,...zA(C,x),skipPhysicalIosDiscovery:!x.some((J)=>fo(J.platform,J.id)==="ios-physical")},H=async(J)=>{let X=await c.getBootedDevicesDetailed(C,J);return X.devices=await YA(d,X.devices),X},q=await H({...N,...O===void 0?{}:{iosDeviceListMaxAgeMs:O}}),G=jA(q,O),W=new Set(q.devices.map((J)=>J.deviceId)),V=x.filter((J)=>!R(J.id)&&!W.has(J.id));if(G||V.some((J)=>pi(q,J.platform,J.id)&&(J.platform==="ios"||!T)))q=await H({...N,bypassAndroidDeviceListCache:T||V.some((J)=>J.platform==="android"),bypassIosDeviceListCache:G||V.some((J)=>fo(J.platform,J.id)==="ios-simulator"),bypassPhysicalIosDeviceListCache:V.some((J)=>fo(J.platform,J.id)==="ios-physical")});let Y=q.devices.filter((J)=>!R(J.deviceId));if(Y.length>0||x.some((J)=>!R(J.id)))await d.reconcileDiscoveryObservation(Y,"disconnect-monitor",{settleMembership:!0});return q}async function YA(d,c){let R=d.mapAndroidDiscovery(c),C=new Set(R.map((N)=>N.deviceId)),T=d.getAllDevices().filter((N)=>N.platform==="android"),B=new Set(T.map((N)=>N.id));if(!R.some((N)=>N.platform==="android"&&!B.has(N.deviceId)&&Ho(N.deviceId)))return R;if(!T.some((N)=>!C.has(N.id)&&[N.id,...d.getAndroidTransportAliases(N.id)].some(Ho)))return R;return await d.normalizeAndroidDiscovery(c,!1,()=>!0,!1)}function Sg(d,c){return new Map([...c].flatMap((R)=>d.getAndroidTransportAliases(R).map((C)=>[C,R])))}async function bg(d,c,R){let C=[...R],T=Sg(d,C),B=await c.getAndroidOfflineDeviceIds(new Set([...C,...T.keys()]));return new Set([...B].map((O)=>T.get(O)??O))}function XA(d,c,R){return new Set([...d].filter((C)=>!c.has(C)&&R.get(C)==="android"))}async function wg(d,c,R,{candidateDeviceIds:C,bootedDeviceIds:T,candidatePlatforms:B}){if(R)return{};let O=XA(C,T,B),x=Sg(d,O);try{let N=O.size>0?await c.getAndroidListedDeviceStates(new Set([...O,...x.keys()])):new Map,H=[...N].map(([G,W])=>[x.get(G)??G,W]),q=new Map;for(let[G,W]of N){let V=x.get(G)??G;if(W==="offline"&&O.has(V)){let Y=q.get(V)??new Set;Y.add(G),q.set(V,Y)}}return{offlineTransportIds:q,listedNonDeviceIds:new Set(H.map(([G])=>G)),offlineDeviceIds:new Set(H.filter(([,G])=>G==="offline").map(([G])=>G)),transitionalAdbDeviceIds:new Set(H.filter(([,G])=>GU(G)).map(([G])=>G))}}catch(N){if(!(N instanceof ik))throw N;return e.warn(`[DisconnectMonitor] Retaining offline recovery attempts: ${r(N)}`),{}}}function Rg(d,c,R){return FJ(R.transitionalAdbDeviceIds,zg({transitional:c.transitionalSimulators,discovered:c.devices,devicePool:d}).map(({device:C})=>C.deviceId))}function Dg(d,c,R){let C=new Set,T=new Map,B=NJ(R);for(let O of R)C.add(O.deviceId),T.set(O.deviceId,O.platform);for(let O of d.getAllDevices())C.add(O.id),T.set(O.id,O.platform),B.set(O.id,O.incarnation);for(let O of c.getAllSessions())if(C.add(O.assignedDevice),!T.has(O.assignedDevice))T.set(O.assignedDevice,O.platform);return{candidateDeviceIds:C,candidatePlatforms:T,candidateIncarnations:B}}function kg(d,c,R){let C=d.length>0,T=new Map(d.map((B)=>[B.id,B]));if(C){e.warn("[DisconnectMonitor] All AutoMobile-owned Android emulators disappeared together; treating this as an ADB server reset and recovering by AVD name");for(let B of d)c.set(B.id,[])}for(let B of R)if(c.has(B.deviceId))c.get(B.deviceId).push(B.recordingId);return T}function Ag(d,c,R,C){for(let{deviceId:T,misses:B,budgetExhausted:O}of c.missed){let x=R.has(T),N=x?Math.min(B,hg):B;if(x)d.set(T,N);let q=`[DisconnectMonitor] Device ${T} not in booted list (${O?"budget exhausted":"absent"}, miss ${N}/${vg}, booted=${C.size})`;if(x&&B>hg)e.debug(q);else e.info(q)}for(let{deviceId:T,transitionalForMs:B}of c.transitional)e.info(`[DisconnectMonitor] Device ${T} listed in a transitional state for ${Math.round(B/1000)}s (budget ${PK/1000}s); keeping session`)}async function Ig(d,c,R){let{timer:C,stoppingRecordings:T}=d;if(T.has(c))return!1;T.add(c);let B=QA(c,R).finally(()=>T.delete(c)),O=Error("recording stop still running");try{return await l(B,{timer:C,timeoutMs:JA,label:"Stop recording after device disconnect",timeoutError:()=>O})}catch(x){if(x!==O)throw x;return e.warn(`[Daemon] Recording ${c} is still finishing after device ${R} disconnected; releasing the device without waiting`),!0}}async function QA(d,c){try{return await CU(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 ZA(d,c)}}async function ZA(d,c){try{return await El(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 ic(d,c){return d!==null&&d!==void 0&&(!Sr(d)||!!D(d))||c}var eI=120000;function tI(d,c){if(c===void 0)return;return{signature:c,unchanged:d?.signature===c?d.unchanged+1:0}}function iI(d,c,R=eI){return te({initialDelayMs:d,maxDelayMs:R}).delayForAttempt(c+1)}function rI(d,c,R){return JSON.stringify([[...d].sort(),[...c].sort(),[...R].sort()])}function oI(d,c,R,C){if(R===void 0||c-R>=C)return"either";let T=d.filter(dr),B=T[0];return B&&T.every((O)=>O===B)?B:"either"}class nc{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<iI(this.cadence.idleIntervalMs,this.idleState?.unchanged??0,this.cadence.maxIdleIntervalMs))return!1;return this.lastSweepAt=c,!0}selectPlatform(d,c,R){let C=this.watching&&!R?oI(d,c,this.lastEitherSweepAt,this.cadence.idleIntervalMs):"either";if(C==="either")this.lastEitherSweepAt=c;return C}recordSuccess(d){if(!this.watching)this.idleState=tI(this.idleState,d)}recordFailure(){this.idleState=void 0,this.lastEitherSweepAt=void 0}}function Pg(d,c,R,{bootedDeviceIds:C,pooledDeviceIds:T}){if(d.size===0||c!==0||![...R].every((B)=>C.has(B)))return;return rI(C,T,d)}function rr(d,c,R,C){let T=C.filter((B)=>B.platform==="android"&&B.avdName!==void 0&&B.androidImage!==void 0&&B.id.startsWith("emulator-"));if(!c.has("android")||T.length<2||!T.every((B)=>!d.has(B.id))||!T.some((B)=>R.has(B.id)))return[];return T}function oc(d,c,R,C){return rr(d,c,R,C).length>0}function Cg(d,c,R){let C=d.services.devicePool().getDevice(c),T=C?.assignmentCount,B=D(C)??d.services.sessionManager().getSessionForDevice(c),O=B?d.services.sessionManager().getSession(B):null,x=d.forceDisconnectedDeviceGenerations().get(c),N=R.get(c);return{pooledDeviceAtDisconnect:C,assignmentCountAtDisconnect:T,sessionIdAtDisconnect:B,sessionAtDisconnect:O,forceGenerationAtDisconnect:x,adbServerResetTarget:N}}function Tg(d,c,{pooledDeviceAtDisconnect:R,assignmentCountAtDisconnect:C,sessionIdAtDisconnect:T,sessionAtDisconnect:B}){if(R){if(d.services.devicePool().getDevice(c)!==R||R.assignmentCount!==C)return!1}else if(d.services.devicePool().getDevice(c))return!1;if(!T)return d.services.sessionManager().getSessionForDevice(c)===null;return d.services.sessionManager().getSessionForDevice(c)===T&&d.services.sessionManager().getSession(T)===B}var sI=5000,dI=30000;class sc{host;constructor(d){this.host=d}hasPlanExecution(d,c){return new Ei(this.host.services.sessionManager()).hasPlanExecution(d,c)}async tryRecoverCapturedDisconnectTarget(d){let{deviceId:c,incidentId:R,pooledDevice:C,sessionId:T,session:B,forceGeneration:O,preparation:x}=d;if(!x){if(T&&await this.host.services.devicePool().waitForSessionPreservingRecovery(T,R))return this.host.retireAdbServerResetDisconnectState(c,O),!0;if(T&&this.host.services.devicePool().isSessionRecoveryInFlight(T))return await this.host.services.devicePool().finishEmulatorLossIncident(R,"not-attempted"),this.host.retireAdbServerResetDisconnectState(c,O),!0}if(!C||!T||!B)return!1;if(this.host.services.devicePool().finishSessionPreservingRecoveryPreparation(x),await this.host.services.devicePool().recoverSessionBoundDeviceAfterLoss(c,R,C)==="not-attempted")return!1;return this.host.retireAdbServerResetDisconnectState(c,O),!0}async recordAndTryRecoverCapturedDisconnect(d,c){let{pooledDeviceAtDisconnect:R,assignmentCountAtDisconnect:C,sessionIdAtDisconnect:T,sessionAtDisconnect:B,forceGenerationAtDisconnect:O}=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 x=this.host.services.devicePool().prepareSessionPreservingRecovery(d,R??void 0);try{let N=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,O)||!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:R,assignmentCountAtDisconnect:C,sessionIdAtDisconnect:T,sessionAtDisconnect:B}))return await this.host.services.devicePool().finishEmulatorLossIncident(N,"not-attempted"),{incidentId:N,handled:!0};let q=await this.tryRecoverCapturedDisconnectTarget({deviceId:d,incidentId:N,pooledDevice:R,sessionId:T,session:B,forceGeneration:O,preparation:x});return{incidentId:N,handled:q}}finally{this.host.services.devicePool().finishSessionPreservingRecoveryPreparation(x)}}startDeviceDisconnectMonitor(d=new oi,c=this.host.listActiveVideoRecordings,R=SL,C={activeIntervalMs:sI,idleIntervalMs:dI}){if(this.host.lifecycle.deviceDisconnectMonitor())return;let T=this.createPlanDeviceLossCheck(d,(O)=>this.discoverAndReconcile(d,{platform:O,bypassAndroidDeviceListCache:!0}),R),B=new nc(C,this.host.services.timer().now());this.host.lifecycle.setDeviceDisconnectMonitor(new il(this.host.services.timer(),C.activeIntervalMs,async()=>{let O={adbServerResetCohort:[],selectPlatform:(x,N)=>B.selectPlatform(x,this.host.services.timer().now(),N)};try{await this.checkDisconnects(d,c,R,{checkPlanDeviceLoss:T,sweep:O}),B.recordSuccess(O.idleSignature)}catch(x){B.recordFailure(),e.warn(`[Daemon] Device disconnect monitor failed: ${x}`)}finally{if(O.adbServerResetCohort.length>0)await this.host.services.devicePool().releaseAdbServerResetCohortReservations(O.adbServerResetCohort)}},{shouldRun:async()=>{let O=this.host.services.devicePool(),x=this.host.services.sessionManager().getAllSessions().length>0||O.getAllDevices().some(({id:N})=>{let H=O.getDevice(N);return ic(H,O.isDeviceLeasedForAndroidStartup(N))})||M.isPlanExecutionActive()||(await c()).length>0;return B.shouldRun(x,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){Ag(this.host.lifecycle.deviceDisconnectMisses(),...d)}collectDisconnectCandidates(d){return Dg(this.host.services.devicePool(),this.host.services.sessionManager(),d)}createPlanDeviceLossCheck(d,c,R=SL){let C=new KU({timer:this.host.services.timer(),isTransportRestarting:(T)=>R.isRestarting(T),getDevice:(T)=>this.host.services.devicePool().getDevice(T),getPlanSessionUuid:(T)=>rt(T,this.host.services.sessionManager())??T,hasPlanExecution:(T,B)=>this.hasPlanExecution(T,B),getPlanExecutionIds:(T,B)=>new Ei(this.host.services.sessionManager()).getPlanExecutionIds(T,B),isStartupLeased:(T)=>this.host.services.devicePool().isDeviceLeasedForAndroidStartup(T),isShutdownReserved:(T)=>this.host.services.devicePool().isShutdownReservationHeld(T),discover:c,getOfflineDeviceIds:(T)=>bg(this.host.services.devicePool(),d,T),isAdbReset:(T,B)=>oc(T,B.succeededPlatforms,new Set(this.host.services.devicePool().getAllDevices().filter((O)=>!T.has(O.id)).map((O)=>O.id)),this.host.services.devicePool().getAllDevices()),recordLoss:(T)=>this.host.services.devicePool().recordEmulatorLossIncident(T,this.host.forceDisconnectedDeviceIds().has(T)?"adb-transport-failure":"device-discovery-miss",void 0,"absent"),finishLoss:(T)=>this.host.services.devicePool().finishEmulatorLossIncident(T,"not-attempted"),cancelPlan:(T,B,O)=>new Ei(this.host.services.sessionManager()).cancelPlanExecutions(T,B,O)});return async(T,B)=>{await C.check(T.missed.map(({deviceId:O})=>O),B),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(BJ(this.host.offlineRecoveryAttemptedDeviceIds(),d,c,{attemptedIncarnations:this.host.offlineRecoveryAttemptedIncarnations(),candidateIncarnations:R}));let C=new Set([...c??[]].filter((O)=>!this.hasPlanExecution(O)&&this.host.services.devicePool().isDeviceLeasedForAndroidStartup(O))),T=$J(c??new Set,d,this.host.offlineRecoveryAttemptedDeviceIds(),new Set([...C,...[...c??[]].filter((O)=>this.hasPlanExecution(O))])),B=C.size>0?[]:T;return this.host.setOfflineRecoveryAttemptedDeviceIds(new Set([...this.host.offlineRecoveryAttemptedDeviceIds(),...B])),this.host.setOfflineRecoveryAttemptedIncarnations(new Map([...R].filter(([O])=>this.host.offlineRecoveryAttemptedDeviceIds().has(O)))),{dispatchTargets:B,offlineRecoveryTargets:T}}async recoverOfflineCandidates(d,c,R,C){if([...R].every((x)=>this.hasPlanExecution(x)))return!1;let T=c.offlineDeviceIds&&new Set([...c.offlineDeviceIds,...[...this.host.offlineRecoveryAttemptedDeviceIds()].filter((x)=>this.hasPlanExecution(x))]),{dispatchTargets:B}=this.prepareOfflineRecovery(R,T,C);if(B.length===0)return!1;e.warn(`[DisconnectMonitor] In-session device(s) ADB-offline (${B.join(", ")}); attempting bounded 'adb -s <serial> reconnect' recovery before miss-counting`);let O=B.flatMap((x)=>{let N=c.offlineTransportIds?.get(x);return N?.size?[...N]:[x]});return await d.recoverAndroidOfflineDevices(O),B.filter((x)=>!O.includes(x)).forEach((x)=>yw(x,"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 C=this.captureDisconnectCleanup(d,R),{pooledDeviceAtDisconnect:T,forceGenerationAtDisconnect:B,adbServerResetTarget:O}=C;if(!O&&await this.host.shouldSkipStaleDisconnectCleanup(T,d,B))return;let x=!0;vc().stopMonitoring(d);for(let N of c)if(!await this.host.stopRecordingAfterDeviceDisconnect(N,d))x=!1;if(!O&&await this.host.shouldSkipStaleDisconnectCleanup(T,d,B))return;if(O){if(await this.tryRecoverProcessWideAdbServerResetDevice(d,O,B))return}return this.finishDisconnectedDeviceCleanup(d,C,x)}async finishDisconnectedDeviceCleanup(d,c,R){let{pooledDeviceAtDisconnect:C,assignmentCountAtDisconnect:T,sessionIdAtDisconnect:B,sessionAtDisconnect:O,forceGenerationAtDisconnect:x}=c,{incidentId:N,handled:H}=await this.host.recordAndTryRecoverCapturedDisconnect(d,{pooledDeviceAtDisconnect:C,assignmentCountAtDisconnect:T??0,sessionIdAtDisconnect:B,sessionAtDisconnect:O,forceGenerationAtDisconnect:x});if(H)return;if(!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:C,assignmentCountAtDisconnect:T,sessionIdAtDisconnect:B,sessionAtDisconnect:O})){await this.host.services.devicePool().finishEmulatorLossIncident(N,"not-attempted");return}if(B&&O)e.warn(`[DisconnectMonitor] Device ${d} confirmed disconnected \u2014 cancelling session ${B}`),await this.host.cancelAndReleaseSession(B,xn(d,N),{expectedSession:O});if(!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:C,assignmentCountAtDisconnect:T})){await this.host.services.devicePool().finishEmulatorLossIncident(N,"not-attempted");return}if(await this.host.services.devicePool().removeDisconnectedDevice(d,!0,N,C??void 0),this.host.services.devicePool().getDevice(d))R=!1;else this.host.lifecycle.socketServer()?.evictDeviceInputCache(d);if(R)this.confirmDisconnectedDeviceCleanup(d,x)}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(C){return e.warn(`[DisconnectMonitor] ADB-reset recovery failed for ${d}; continuing cohort cleanup: ${C}`),!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 Ig({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 C=await this.host.services.devicePool().isCurrentDisconnectedDevice(d);if(C==="current")return!1;if(C==="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(wee((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:C,sweep:T}){this.startDeferredSessionRecoverySweep();let B=await c(),O=B.map(({deviceId:ae,platform:cr})=>({assignedDevice:ae,platform:cr})),x=this.host.services.devicePool().getAllDevices(),N=this.host.services.sessionManager().getAllSessions(),H=[...x.map(({id:ae})=>ae),...N.flatMap(({assignedDevice:ae})=>ae===void 0?[]:[ae]),...B.map(({deviceId:ae})=>ae)].some((ae)=>this.hasPlanExecution(ae)),q=T.selectPlatform([...x.filter((ae)=>ic(ae,this.host.services.devicePool().isDeviceLeasedForAndroidStartup(ae.id))).map((ae)=>ae.platform),...N.map((ae)=>ae.platform),...B.map((ae)=>ae.platform)],H),G=await this.discoverAndReconcile(d,{iosDeviceListMaxAgeMs:gg,platform:q,heldDevices:O}),W=G.succeededPlatforms,V=new Set(G.devices.map((ae)=>ae.deviceId)),Y=new Map,{candidateDeviceIds:J,candidatePlatforms:X,candidateIncarnations:Z}=this.collectDisconnectCandidates(B),re=new Set([...J].filter((ae)=>this.hasPlanExecution(ae))),ee=new Set([...J].filter((ae)=>!re.has(ae))),oe=q==="ios"?{}:await wg(this.host.services.devicePool(),d,!1,{candidateDeviceIds:ee,bootedDeviceIds:V,candidatePlatforms:X});if(await this.recoverOfflineCandidates(d,oe,J,Z))G=await this.discoverAndReconcile(d,{heldDevices:O,platform:q,bypassAndroidDeviceListCache:!0}),W=G.succeededPlatforms,V=new Set(G.devices.map((ae)=>ae.deviceId));let fe=UJ({deviceDisconnectMisses:this.host.lifecycle.deviceDisconnectMisses(),confirmedDisconnectedDeviceIds:this.host.confirmedDisconnectedDeviceIds(),bootedDeviceIds:V,candidateDeviceIds:J,succeededPlatforms:W,succeededSources:G.succeededSources,candidatePlatforms:X,candidateIncarnations:Z,deviceDisconnectMissIncarnations:this.host.deviceDisconnectMissIncarnations(),forceDisconnectedDeviceIds:this.host.forceDisconnectedDeviceIds(),transitionalDeviceIds:Rg(this.host.services.devicePool(),G,oe),offlineEpisodes:this.host.offlineEpisodes(),nowMs:this.host.services.timer().monotonicNow?.()??this.host.services.timer().now(),immediateDisconnectDeviceIds:LJ(J,X,V,{listedNonDeviceIds:oe.listedNonDeviceIds,transportRestarts:R})});if(fe.skippedAllDiscoveryFailed){e.warn(`[DisconnectMonitor] No platform discovery succeeded but ${J.size} tracked \u2014 skipping miss count`);return}re=new Set([...re,...[...J].filter((ae)=>this.hasPlanExecution(ae))]),this.logDisconnectMisses(fe,re,V),await C(fe,V);for(let ae of fe.disconnected.filter((cr)=>!re.has(cr)))Y.set(ae,[]);T.idleSignature=Pg(G.succeededPlatforms,this.host.lifecycle.deviceDisconnectMisses().size,J,{bootedDeviceIds:V,pooledDeviceIds:this.host.services.devicePool().getAllDevices().map((ae)=>ae.id)}),await this.cleanupDisconnects(V,W,Y,{activeRecordings:B,sweep:T})}async cleanupDisconnects(d,c,R,{activeRecordings:C,sweep:T}){let B=rr(d,c,this.host.forceDisconnectedDeviceIds(),this.host.services.devicePool().getAllDevices()),O=B.some((q)=>this.hasPlanExecution(q.id));if(O)for(let q of B)R.delete(q.id);let x=O?[]:B,N=x.length>0?await this.host.services.devicePool().detachAdbServerResetCohort(x):{devices:[],deferred:!1};if(N.deferred){e.info("[DisconnectMonitor] Deferring process-wide ADB reset recovery until matching Android startup completes");return}T.adbServerResetCohort=N.devices;let H=kg(T.adbServerResetCohort,R,C);for(let[q,G]of R)if(!this.hasPlanExecution(q))await this.host.cleanupDisconnectedDevice(q,G,H)}}async function Eg(d){let c=new pa(gb),R=await j.cancelToolExecutions("provisionDevice",c);if(R===0)return;if(!await j.waitForToolExecutionsToEnd("provisionDevice",d))e.warn(`Timed out after ${d}ms persisting ${R} interrupted provisionDevice operation(s) before daemon shutdown`)}async function ac(d){if(!await Wt().drain(d))e.warn(`Timed out after ${d}ms draining in-flight DB writes; closing database anyway`)}async function Bg(d){if(!await j3(d))e.warn(`Timed out after ${d}ms awaiting in-flight startup migration; closing database anyway`)}function xg(d){return(c)=>{if(c.type==="uncaughtException"){d.error(`[daemon] uncaughtException in background task; keeping daemon alive: ${wp(c.error)}`,c.error);return}d.error(`[daemon] unhandledRejection in background task; keeping daemon alive: ${wp(c.reason)}`,c.reason)}}function se(d,c,R){return S6(b6,d,c,R)}var lI=1000,fI=2000,_g=1000,hI=3000,gI=5000;class dc{host;shutdownHandlersRegistered=!1;shutdownSessionReleasesDrained=!0;shutdownSessionIds=[];constructor(d){this.host=d}setupShutdownHandlers(){if(this.shutdownHandlersRegistered)return;this.shutdownHandlersRegistered=!0,yN(),QX(),rS(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"),QV(this.host.getDaemonFileCleanupOptions())}),vN(xg(e))}async stop(){this.host.lifecycle.setShutdownInProgress(!0),e.info("Stopping daemon..."),await CI([...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([s6(),Eg($l(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",()=>i2()),se("health check timer","the database health probe",async()=>{await this.host.stopHealthCheckTimer(),await this.host.services.databaseHealthProbe().dispose?.()}),se("location routes","nothing (synchronous)",()=>oD.stopAll()),se("shutdown monitors","the heartbeat and disconnect monitors and deferred recovery sweeps",(c)=>this.drainShutdownMonitors(d.navigationRetentionMonitor,d.heartbeatMonitor,d.deviceDisconnectMonitor,$l(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",()=>c2()),se("device gesture recording socket server","its connections closing",()=>u2()),se("device snapshot socket server","its connections closing",()=>f2()),se("appearance socket server","its connections closing",()=>y2()),se("performance stream socket server","its connections closing",()=>th()),se("performance push socket server","its connections closing",()=>xte()),se("device data stream socket server","its connections closing",()=>xW()),se("failures stream socket server","its connections closing",()=>oh()),se("failures push socket server","its connections closing",()=>Sre()),se("telemetry push socket server","its connections closing",()=>dte()),se("WebRTC stream socket server","WebRTC stream teardown (encoder stop, adb forward removal)",()=>S2()),se("video stream socket server","capture source stop (encoder stop, adb forward removal)",()=>kh()),se("iOS simulator capture helper pool","simulator capture helper processes exiting",()=>sO.shutdown()),se("native helper registry","tracked helper processes exiting",async(d)=>{await yT().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 u5({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",()=>R2()),se("performance monitor","an in-flight performance sample",()=>J5()),se("active HTTP sessions","streamable HTTP transports closing",()=>CI([...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=w6({closeDatabase:()=>G3({forShutdown:!0}),refusedAccessCount:()=>K3(),drainWrites:(c)=>ac(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",(c)=>this.releaseActiveSessionsForShutdown($l(c,uv))),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($l(c,fI))}),se("CtrlProxy forwarding leases","adb forward removal",(c)=>this.releaseForwardLeases($l(c,hI))),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)=>ac($l(c,lI))),se("in-flight migrations","a cold-start migration still running",(c)=>Bg($l(c,gI))),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 k.releaseForwardLeasesForShutdown(this.host.services.timer(),d)}clearHttpSessionRegistry(){this.host.services.httpIngress().clearSessions()}async drainShutdownMonitors(d,c,R,C){d?.stop(),GY();let[T,B]=await Promise.all([c?c.stop().then(()=>!0):!0,R?R.stop():!0]);if(!T)e.warn("Session heartbeat monitor did not settle before daemon shutdown");if(!B)e.warn("Device disconnect monitor did not settle before daemon shutdown");let O=Symbol("recovery sweep drain timeout"),x=!0;try{await l(Promise.allSettled(this.host.lifecycle.deferredSessionRecoverySweeps()),{timer:this.host.services.timer(),timeoutMs:C,label:"Recovery sweep drain",timeoutError:()=>O})}catch(N){if(N!==O)throw N;x=!1}if(!x)e.warn(`Timed out after ${C}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(O)=>{await this.host.cancelAndReleaseSession(O,"daemon-shutdown",{allowExpired:!0})}),C=(O)=>{for(let[x,N]of O.entries())if(N.status==="rejected")e.warn(`[Daemon] Failed to release session ${c[x]??"unknown"} during shutdown: ${N.reason}`)},T=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`),T.then(C);return}C(await T)}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),hi.emit(R,"daemon-shutdown")}}get testHooks(){return{markShutdownInProgress:()=>{this.host.lifecycle.setShutdownInProgress(!0)},quiesceProvisioningIngress:()=>this.quiesceProvisioningIngress()}}}function vI(d,c,R){let C=`${new Date(R).toISOString()} [ERROR] [Daemon] exiting with code ${d}: database health check failed repeatedly`;return c===void 0?C:`${C}; last failure: ${c.replace(/[\r\n]/g," ")}`}async function Fg(d,c,R){try{R.writeEmergency(vI(d,c,R.now()))}catch(C){}try{R.writeExitRecord()}catch(C){e.warn(`Failed to record database-health exit: ${r(C)}`,C)}R.cleanupDaemonFiles();try{await R.closeLogger()}finally{R.exit(d)}}class cc{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 Lg(d){return(c,R)=>Fg(c,R,{now:()=>d.timer().now(),writeEmergency:(C)=>Wi(C),writeExitRecord:()=>d.selfExitRecorder().record("database-health"),cleanupDaemonFiles:()=>{QV(d.getDaemonFileCleanupOptions())},closeLogger:()=>e.closeAfterFlush(),exit:(C)=>process.exit(C)})}function $g(d){return new cc({getServer:Rt,stopServer:xW,startServer:async()=>{await d.startAuxiliarySocket("observation-stream",()=>_W(d.timer()))},configureCallbacks:()=>d.configureDeviceDataStreamServer()})}function Hg(d){return new MG(d,void 0,(c)=>{NH(c).catch((R)=>{e.warn(`[Appearance] Failed to drop config of observer ${c}`,R)}),Iv.emit(c)})}function Ug(d){let c=H6(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 yI}from"http2";import{Http2ServerRequest as lc}from"http2";import{Readable as Kg}from"stream";import OI from"crypto";var vt=class extends Error{constructor(d,c){super(d,c);this.name="RequestError"}},bI=(d)=>{if(d instanceof vt)return d;return new vt(d.message,{cause:d})},RI=global.Request,Bi=class extends RI{constructor(d,c){if(typeof d==="object"&&jt in d)d=d[jt]();if(typeof c?.body?.getReader<"u")c.duplex??="half";super(d,c)}},DI=(d)=>{let c=[],R=d.rawHeaders;for(let C=0;C<R.length;C+=2){let{[C]:T,[C+1]:B}=R;if(T.charCodeAt(0)!==58)c.push([T,B])}return new Headers(c)},Yg=Symbol("wrapBodyStream"),kI=(d,c,R,C,T)=>{let B={method:d,headers:R,signal:T.signal};if(d==="TRACE"){B.method="GET";let O=new Bi(c,B);return Object.defineProperty(O,"method",{get(){return"TRACE"}}),O}if(!(d==="GET"||d==="HEAD"))if("rawBody"in C&&C.rawBody instanceof Buffer)B.body=new ReadableStream({start(O){O.enqueue(C.rawBody),O.close()}});else if(C[Yg]){let O;B.body=new ReadableStream({async pull(x){try{O||=Kg.toWeb(C).getReader();let{done:N,value:H}=await O.read();if(N)x.close();else x.enqueue(H)}catch(N){x.error(N)}}})}else B.body=Kg.toWeb(C);return new Bi(c,B)},jt=Symbol("getRequestCache"),Xg=Symbol("requestCache"),or=Symbol("incomingKey"),ar=Symbol("urlKey"),II=Symbol("headersKey"),Vt=Symbol("abortControllerKey"),PI=Symbol("getAbortController"),Oi={get method(){return this[or].method||"GET"},get url(){return this[ar]},get headers(){return this[II]||=DI(this[or])},[PI](){return this[jt](),this[Vt]},[jt](){return this[Vt]||=new AbortController,this[Xg]||=kI(this.method,this[ar],this.headers,this[or],this[Vt])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach((d)=>{Object.defineProperty(Oi,d,{get(){return this[jt]()[d]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach((d)=>{Object.defineProperty(Oi,d,{value:function(){return this[jt]()[d]()}})});Object.defineProperty(Oi,Symbol.for("nodejs.util.inspect.custom"),{value:function(d,c,R){let C={method:this.method,url:this.url,headers:this.headers,nativeRequest:this[Xg]};return`Request (lightweight) ${R(C,{...c,depth:d==null?null:d-1})}`}});Object.setPrototypeOf(Oi,Bi.prototype);var TI=(d,c)=>{let R=Object.create(Oi);R[or]=d;let C=d.url||"";if(C[0]!=="/"&&(C.startsWith("http://")||C.startsWith("https://"))){if(d instanceof lc)throw new vt("Absolute URL for :path is not allowed in HTTP/2");try{let x=new URL(C);R[ar]=x.href}catch(x){throw new vt("Invalid absolute URL",{cause:x})}return R}let T=(d instanceof lc?d.authority:d.headers.host)||c;if(!T)throw new vt("Missing host header");let B;if(d instanceof lc){if(B=d.scheme,!(B==="http"||B==="https"))throw new vt("Unsupported scheme")}else B=d.socket&&d.socket.encrypted?"https":"http";let O=new URL(`${B}://${T}${C}`);if(O.hostname.length!==T.length&&O.hostname!==T.replace(/:\d+$/,""))throw new vt("Invalid host header");return R[ar]=O.href,R},pc=Symbol("responseCache"),Gt=Symbol("getResponseCache"),yt=Symbol("cache"),hc=global.Response,zt=class d{#t;#e;[Gt](){return delete this[yt],this[pc]||=new hc(this.#t,this.#e)}constructor(c,R){let C;if(this.#t=c,R instanceof d){let T=R[pc];if(T){this.#e=T,this[Gt]();return}else this.#e=R.#e,C=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,C||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[Gt]().headers}get status(){return this[yt]?.[0]??this[Gt]().status}get ok(){let c=this.status;return c>=200&&c<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach((d)=>{Object.defineProperty(zt.prototype,d,{get(){return this[Gt]()[d]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach((d)=>{Object.defineProperty(zt.prototype,d,{value:function(){return this[Gt]()[d]()}})});Object.defineProperty(zt.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(d,c,R){let C={status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[pc]};return`Response (lightweight) ${R(C,{...c,depth:d==null?null:d-1})}`}});Object.setPrototypeOf(zt,hc);Object.setPrototypeOf(zt.prototype,hc.prototype);async function MI(d){return Promise.race([d,Promise.resolve().then(()=>Promise.resolve(void 0))])}function Qg(d,c,R){let C=(x)=>{d.cancel(x).catch(()=>{})};return c.on("close",C),c.on("error",C),(R??d.read()).then(O,T),d.closed.finally(()=>{c.off("close",C),c.off("error",C)});function T(x){if(x)c.destroy(x)}function B(){d.read().then(O,T)}function O({done:x,value:N}){try{if(x)c.end();else if(!c.write(N))c.once("drain",B);else return d.read().then(O,T)}catch(H){T(H)}}}function EI(d,c){if(d.locked)throw TypeError("ReadableStream is locked.");else if(c.destroyed)return;return Qg(d.getReader(),c)}var mc=(d)=>{let c={};if(!(d instanceof Headers))d=new Headers(d??void 0);let R=[];for(let[C,T]of d)if(C==="set-cookie")R.push(T);else c[C]=T;if(R.length>0)c["set-cookie"]=R;return c["content-type"]??="text/plain; charset=UTF-8",c},BI="x-hono-already-sent";if(typeof global.crypto>"u")global.crypto=OI;var yc=Symbol("outgoingEnded"),Jg=Symbol("incomingDraining"),xI=500,_I=67108864,uc=(d)=>{let c=d;if(d.destroyed||c[Jg])return;if(c[Jg]=!0,d instanceof jg){try{d.stream?.close?.(yI.NGHTTP2_NO_ERROR)}catch{}return}let R=0,C=()=>{clearTimeout(B),d.off("data",O),d.off("end",C),d.off("error",C)},T=()=>{C();let x=d.socket;if(x&&!x.destroyed)x.destroySoon()},B=setTimeout(T,xI);B.unref?.();let O=(x)=>{if(R+=x.length,R>_I)T()};d.on("data",O),d.on("end",C),d.on("error",C),d.resume()},FI=()=>new Response(null,{status:400}),Zg=(d)=>new Response(null,{status:d instanceof Error&&(d.name==="TimeoutError"||d.constructor.name==="TimeoutError")?504:500}),fc=(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)}},ev=(d)=>{if("flushHeaders"in d&&d.writable)d.flushHeaders()},nv=async(d,c)=>{let[R,C,T]=d[yt],B=!1;if(!T)T={"content-type":"text/plain; charset=UTF-8"};else if(T instanceof Headers)B=T.has("content-length"),T=mc(T);else if(Array.isArray(T)){let O=new Headers(T);B=O.has("content-length"),T=mc(O)}else for(let O in T)if(O.length===14&&O.toLowerCase()==="content-length"){B=!0;break}if(!B){if(typeof C==="string")T["Content-Length"]=Buffer.byteLength(C);else if(C instanceof Uint8Array)T["Content-Length"]=C.byteLength;else if(C instanceof Blob)T["Content-Length"]=C.size}if(c.writeHead(R,T),typeof C==="string"||C instanceof Uint8Array)c.end(C);else if(C instanceof Blob)c.end(new Uint8Array(await C.arrayBuffer()));else ev(c),await EI(C,c)?.catch((O)=>fc(O,c));c[yc]?.()},NI=(d)=>typeof d.then==="function",LI=async(d,c,R={})=>{if(NI(d))if(R.errorHandler)try{d=await d}catch(T){let B=await R.errorHandler(T);if(!B)return;d=B}else d=await d.catch(Zg);if(yt in d)return nv(d,c);let C=mc(d.headers);if(d.body){let T=d.body.getReader(),B=[],O=!1,x=void 0;if(C["transfer-encoding"]!=="chunked"){let N=2;for(let H=0;H<N;H++){x||=T.read();let q=await MI(x).catch((G)=>{console.error(G),O=!0});if(!q){if(H===1){await new Promise((G)=>setTimeout(G)),N=3;continue}break}if(x=void 0,q.value)B.push(q.value);if(q.done){O=!0;break}}if(O&&!("content-length"in C))C["content-length"]=B.reduce((H,q)=>H+q.length,0)}if(c.writeHead(d.status,C),B.forEach((N)=>{c.write(N)}),O)c.end();else{if(B.length===0)ev(c);await Qg(T,c,x)}}else if(C[BI]);else c.writeHead(d.status,C),c.end();c[yc]?.()},Sc=(d,c={})=>{let R=c.autoCleanupIncoming??!0;if(c.overrideGlobalObjects!==!1&&global.Request!==Bi)Object.defineProperty(global,"Request",{value:Bi}),Object.defineProperty(global,"Response",{value:zt});return async(C,T)=>{let B,O;try{O=TI(C,c.hostname);let x=!R||C.method==="GET"||C.method==="HEAD";if(!x){if(C[Yg]=!0,C.on("end",()=>{x=!0}),C instanceof jg)T[yc]=()=>{if(!x)setTimeout(()=>{if(!x)setTimeout(()=>{uc(C)})})};T.on("finish",()=>{if(!x)uc(C)})}if(T.on("close",()=>{if(O[Vt]){if(C.errored)O[Vt].abort(C.errored.toString());else if(!T.writableFinished)O[Vt].abort("Client connection prematurely closed.")}if(!x)setTimeout(()=>{if(!x)setTimeout(()=>{uc(C)})})}),B=d(O,{incoming:C,outgoing:T}),yt in B)return nv(B,T)}catch(x){if(!B)if(c.errorHandler){if(B=await c.errorHandler(O?x:bI(x)),!B)return}else if(!O)B=FI();else B=Zg(x);else return fc(x,T)}try{return await LI(B,T,c)}catch(x){return fc(x,T)}}};var rv=class{_webStandardTransport;_requestListener;_requestContext=new WeakMap;constructor(d={}){this._webStandardTransport=new x6(d),this._requestListener=Sc(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 C=d.auth;await Sc(async(T)=>this._webStandardTransport.handleRequest(T,{authInfo:C,parsedBody:R}),{overrideGlobalObjects:!1})(d,c)}closeSSEStream(d){this._webStandardTransport.closeSSEStream(d)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}};var $I=f({sessionId:y().min(1),livenessOwnerToken:hr().optional()});function sv(d){let c;try{c=JSON.parse(d)}catch(C){return e.debug(`Invalid heartbeat JSON: ${C}`),{ok:!1,response:{status:400,body:{error:"Invalid JSON"}}}}let R=$I.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 HI(d){return typeof d==="string"&&d.trim()?d:void 0}async function dv(d,c,R,C){let T=HI(C),B=d.getSession(R)??d.getReleasingSession?.(R)??null;if(!B||$i(d,R,B)){let x=await Z1(d,c,R,T);if(x.kind==="observer")return ov;return{status:404,body:{error:`Session not found: ${R}`,...Jf(x.recorded.releaseReason,x.recorded.idleTimeoutMs)}}}if(T?d.hasLivenessOwnership(R,T)||d.claimUnownedLivenessOwnership(R,T):!X1(B))d.recordHeartbeat(R);return ov}import{AsyncLocalStorage as KI}from"async_hooks";var qI={updates:zS,lists:kr,log:e,maxUrisPerStream:256,maxUriMemberships:4096},UI=s({method:I("subscriptions/listen"),params:s({notifications:s({resourceSubscriptions:b(n()).optional()})})});class bc{bus;uriReferences=new Map;memberships=0;warnedLimit=!1;unsubscribeUpdates;unsubscribeLists;deps;constructor(d,c={}){this.bus=d;this.deps={...qI,...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=UI.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 T of R)this.uriReferences.set(T,(this.uriReferences.get(T)??0)+1);this.memberships+=R.size;let C=!1;return()=>{if(!C)C=!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 GI=JSON.stringify({jsonrpc:"2.0",error:{code:-32000,message:"Method not allowed."},id:null}),WI=JSON.stringify({error:"Daemon is shutting down"});function xi(d){return(Array.isArray(d)?d:[d]).filter((R)=>!!R&&typeof R==="object"&&!Array.isArray(R))}function lv(d){return typeof d==="string"||typeof d==="number"}function Fi(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return;return Object.entries(d).find(([R])=>R===c)?.[1]}function VI(d){for(let c of xi(d)){let R=Fi(Fi(c.params,"arguments"),fC);if(typeof R==="string"&&R.length>0)return R}return}function fv(d){return`\x00${typeof d}:${String(d)}`}function mv(d,c){return`${d}${fv(c)}`}function JI(d,c){let R=new Headers;for(let[C,T]of Object.entries(d.headers)){let B=Array.isArray(T)?T:T===void 0?[]:[T];for(let O of B)R.append(C,O)}return new Request(new URL(nw,"http://localhost"),{method:"POST",headers:R,signal:c})}async function jI(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 C of d.body){if(c.destroyed||c.writableEnded)break;c.write(R.decode(C,{stream:!0}))}if(!c.destroyed&&!c.writableEnded)c.end(R.decode())}var zI="2026-07-28",YI=1024;function XI(d,c){let C=c?.params?._meta?.[Zo];return[d,C].some((T)=>typeof T==="string"&&T>=zI)}class wc{deps;inFlight=new Map;byCancelKey=new Map;accepting=!0;modernBus;modernEvents;modernListenStreams=0;modernScope=new KI;root=fa("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,C){if(d.method!=="POST"){c.writeHead(405,{"Content-Type":"application/json",Allow:"POST"}),c.end(GI);return}let T=x$(d.headers);if(await this.cancelNotifiedRequests(T,R),!this.accepting){c.writeHead(503,{"Content-Type":"application/json"}),c.end(WI);return}let B={requestScopeId:this.deps.idGenerator.next(),requestMcpSessionId:T??VI(R)};if(this.isModernRequest(d,R)){await this.handleModern(d,c,R,{scope:B,headerSessionKey:T,sendJsonRpcError:C});return}let O;try{O=this.deps.createServer(d,B)}catch(G){e.error("Failed to create MCP server:",G),C("Server error",G);return}let x=this.deps.createTransport(),N=this.track(B,T,R,{server:O,transport:x}),H=d.socket??void 0,q=()=>{H?.off("close",q),N.close().catch((G)=>{e.warn(`Stateless MCP request close failed: ${r(G)}`,G)})};c.once("close",q),c.once("finish",q),H?.once("close",q);try{await O.connect(x)}catch(G){e.error("MCP server connect failed:",G),C("Server error",G),await N.close();return}await this.dispatch(d,c,x,{parsedBody:R,sendJsonRpcError:C})}isModernRequest(d,c){if(!(this.deps.modern?.enabled()??$e(g.MCP_MODERN_ERA)))return!1;let R=(B)=>{let O=d.headers[B];return typeof O==="string"?O:void 0},C=R("mcp-protocol-version"),T=(this.deps.modern?.classify??j0)({httpMethod:d.method??"POST",protocolVersionHeader:C,mcpMethodHeader:R("mcp-method"),mcpNameHeader:R("mcp-name"),body:c});return T.kind==="modern"||T.kind==="reject"&&XI(C,c)}createModernHandler(d){return(this.deps.modern?.createHandler??LZ)((c)=>{let R=this.modernScope.getStore(),{req:C,scope:T}=R??{};if(!R||!C||!T)throw new t("Modern MCP request scope is missing");R.req=void 0,R.scope=void 0;let B=this.deps.createServer(C,{...T,era:c.era});if(!(B instanceof mh))throw new t("Modern MCP serving requires an SDK McpServer");return B},{legacy:"reject",responseMode:"sse",keepAliveMs:0,bus:d})}async handleModern(d,c,R,{scope:C,headerSessionKey:T,sendJsonRpcError:B}){let O=this.getModernBus(),x=this.openListenSlot(R,c);if(!x)return;let N=new AbortController,H;try{H=this.createModernHandler(O)}catch(J){throw x.release(),J}let q=this.track(C,T,R,{server:H,transport:{close:async()=>{N.abort(),x.release()}}}),G=d.socket??void 0,W=()=>{G?.off("close",W),q.close().catch((J)=>{e.warn(`Modern MCP request close failed: ${r(J)}`,J)})};c.once("close",W),c.once("finish",W),G?.once("close",W);let V=this.startKeepalive(c),Y=xi(R).map((J)=>Fi(J.params,"_meta")).find((J)=>J!==void 0);try{let J=await this.root.run(()=>this.modernScope.run({req:d,scope:C},()=>mm(gm(Y),()=>H.fetch(JI(d,N.signal),{parsedBody:R}))));await jI(J,c)}catch(J){e.error("Modern MCP HTTP request handling failed:",J),B("Server error",J)}finally{V(),G?.off("close",W),await q.close()}}openListenSlot(d,c){if(!xi(d).some((T)=>T.method==="subscriptions/listen"))return{release:()=>{}};let C=this.modernListenStreams<(this.deps.modern?.maxListenStreams??YI)?this.modernEvents?.track(d):void 0;if(!C)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:()=>{C(),this.modernListenStreams--}}}getModernBus(){if(!this.modernBus){let d=this.deps.modern?.createEventBus?.()??new G0((c)=>e.warn(`Modern MCP event listener failed: ${r(c)}`,c));this.modernBus=d,this.modernEvents=new bc(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:C,transport:T}){let{requestScopeId:B}=d,O=xi(R).map((H)=>H.id).filter(lv).map((H)=>mv(c??"",H)),x,N={requestScopeId:B,keyless:d.requestMcpSessionId===void 0,cancelKeys:O,close:(H)=>(x??=this.closeRequest(N,C,T,H),x)};this.inFlight.set(B,N);for(let H of O)this.byCancelKey.set(H,[...this.byCancelKey.get(H)??[],B]);return N}async closeRequest(d,c,R,C){try{let T=await this.deps.cancelScopeExecutions(d.requestScopeId,C??this.deps.closeReason());if(T>0)e.info(`Stateless MCP request ${d.requestScopeId} closed (cancelled ${T} executions)`)}finally{this.untrack(d);let T=await Promise.allSettled([R.close(),c.close()]);for(let B of T)if(B.status==="rejected")e.warn(`Stateless MCP request ${d.requestScopeId} teardown failed: ${wp(B.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((C)=>C!==d.requestScopeId);if(R.length===0)this.byCancelKey.delete(c);else this.byCancelKey.set(c,R)}this.releaseModernEventsIfIdle()}async cancelNotifiedRequests(d,c){let R=xi(c).filter((C)=>C.method==="notifications/cancelled");await Promise.all(R.map(async(C)=>{let T=Fi(C.params,"requestId");if(!lv(T))return;let B=this.cancelledScopeId(d,T),O=B===void 0?void 0:this.inFlight.get(B);if(!O){e.debug(`notifications/cancelled for unknown request ${String(T)}`);return}let x=Fi(C.params,"reason");await O.close(typeof x==="string"?x:"notifications/cancelled")}))}cancelledScopeId(d,c){if(d!==void 0)return this.byCancelKey.get(mv(d,c))?.at(-1);let R=fv(c),C=Array.from(this.byCancelKey.entries()).filter(([T])=>T.endsWith(R)).flatMap(([,T])=>T);if(C.length>1)e.warn(`Ignoring header-less notifications/cancelled for ambiguous request id ${String(c)}: ${C.length} in-flight requests share it`);return C.length===1?C[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,C=()=>{if(!R)R=!0,this.deps.timer.clearInterval(c)};return d.once("close",C),d.once("finish",C),C}async dispatch(d,c,R,{parsedBody:C,sendJsonRpcError:T}){let B=this.startKeepalive(c);try{await R.handleRequest(d,c,C)}catch(O){e.error("Streamable HTTP request handling failed:",O),T("Server error",O)}finally{B()}}}var QI=60000,ZI=268435456,hv=30000,eP=1,tP=30000;class Rc{deps;httpServer=null;httpServerClosePromise=null;shutdownIngressAbort=new AbortController;httpAllowedHosts=[];mcpHttpTransportFactory=(d)=>new rv({enableDnsRebindingProtection:!0,allowedHosts:d});mcpRequestServerFactory=(d,c)=>this.deps.createRequestMcpServer(d,c);mcpHttpEndpoint=new wc({timer:{setInterval:(d,c)=>this.deps.timer().setInterval(d,c),clearInterval:(d)=>this.deps.timer().clearInterval(d)},idGenerator:{next:()=>this.deps.idGenerator().next()},keepaliveIntervalMs:tP,createTransport:()=>this.mcpHttpTransportFactory(this.httpAllowedHosts),createServer:(d,c)=>this.mcpRequestServerFactory(d,c),cancelScopeExecutions:(d,c)=>j.cancelSessionExecutions(d,c),forgetScopeBindings:(d)=>Wk(d),closeReason:()=>this.deps.isShutdownInProgress()?new pa(gb):"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 C=[`127.0.0.1:${c}`,`localhost:${c}`,`[::1]:${c}`];this.httpAllowedHosts=C,R.requestTimeout=0,R.headersTimeout=0,R.timeout=0;let T=(B,O)=>this.handleHttpRequest(B,O,C);return R.on("request",(B,O)=>{T(B,O).catch((x)=>{if(e.warn(`HTTP request callback failed: ${r(x)}`,x),!O.headersSent)O.writeHead(500,{"Content-Type":"application/json"});O.end()})}),new Promise((B,O)=>{R.listen(c,d,()=>{e.info(`automobile:${d}:${c}${nw}`),B()}),R.on("error",(x)=>{if(this.deps.strictPort()&&x.code==="EADDRINUSE"){O(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: ${x}`),O(x)})})}closeListener(){let d=this.httpServer;if(!d)return Promise.resolve();return this.httpServerClosePromise??=new Promise((c,R)=>{d.close((C)=>{if(C){R(C);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 T=d.rawHeaders.length-2;T>=0;T-=2)if(d.rawHeaders[T]?.toLowerCase()==="authorization")d.rawHeaders.splice(T,2);let C=this.deps.httpToken().value;if(!C||!dl(R,C))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 C=new URL(d.url,`http://${d.headers.host}`);if(C.pathname===o5)return this.handleHeartbeatHttpRequest(d,c);if(C.pathname===nw)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 C=sv(R.body);if(!C.ok){c.writeHead(C.response.status,{"Content-Type":"application/json"}),c.end(JSON.stringify(C.response.body));return}let T=await dv(this.deps.sessionManager(),this.deps.observerSessionRegistry(),C.sessionId,C.livenessOwnerToken);c.writeHead(T.status,{"Content-Type":"application/json"}),c.end(JSON.stringify(T.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:hv,signal:R,label:"HTTP MCP startup admission",timeoutError:()=>c}),!0}catch(C){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(C===c)return e.warn(`HTTP MCP request refused: daemon still starting after ${hv}ms`),d.writeHead(503,{"Content-Type":"application/json","Retry-After":String(eP)}),d.end(JSON.stringify({error:"Daemon is still starting"})),!1;return e.warn(`HTTP MCP request refused: daemon startup failed: ${r(C)}`),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 T=await this.readHttpBody(d);if(!T.ok){this.respondToBodyReadFailure(c,T);return}try{R=JSON.parse(T.body)}catch(B){e.debug(`Invalid MCP JSON: ${B}`),c.writeHead(400,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Invalid JSON"}));return}}let C=(T,B)=>this.sendHttpJsonRpcError(c,R,T,B);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,C)}sendHttpJsonRpcError(d,c,R,C){if(d.headersSent)return;let T=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:T,error:{code:-32603,message:R,data:C instanceof Error?C.message:void 0}}))}readHttpBody(d){let c=this.deps.timer();return new Promise((R)=>{let C=[],T=0,B=!1,O=(V)=>{if(B)return;B=!0,c.clearTimeout(W),d.off("data",x),d.off("end",N),d.off("error",H),d.off("aborted",q),d.off("close",G),R(V)},x=(V)=>{let Y=Buffer.isBuffer(V)?V:Buffer.from(V);if(T+=Y.length,T>ZI){O({ok:!1,status:413,error:"Request body too large"}),d.destroy();return}C.push(Y)},N=()=>O({ok:!0,body:Buffer.concat(C).toString("utf8")}),H=(V)=>{e.warn("HTTP request body read failed",V),O({ok:!1,status:400,error:"Request body read failed"})},q=()=>O({ok:!1,status:400,error:"Request aborted"}),G=()=>O({ok:!1,status:400,error:"Request closed"}),W=c.setTimeout(()=>{O({ok:!1,status:408,error:"Request body timed out"}),d.destroy()},QI);d.on("data",x),d.on("end",N),d.on("error",H),d.on("aborted",q),d.on("close",G)})}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 Rc({...d,createRequestMcpServer:(c,R)=>Pn(this.statelessMcpServerBase(),An({headers:c.headers}),R)}),this.mcpDispatcher=Cn({base:()=>this.statelessMcpServerBase(),idGenerator:{next:()=>d.idGenerator().next()},closeReason:()=>d.isShutdownInProgress()?new pa(gb):ga})}statelessMcpServerBase(){return{deviceReadiness:this.host.deviceReadiness(),iosDependencies:this.host.iosDoctorDependencies,debug:this.host.debug(),acceptanceDiscoveryCapability:this.host.acceptanceDiscoveryCapability()}}}async function vv(d,c){let R=new Map,C=new Map,T=new Map,B=!1,O=nP(R,c),x=(q,G)=>{let W=c.getDeviceIncarnation(q),V=new Set(c.ownedCaptureIds()),Y=(R.get(q)??[]).filter((J)=>J.captureTeardown&&(!G||!V.has(J.recordingId))&&yv(J,W));if(Y.length===0||W!==void 0&&T.get(q)===W)return;if(W===void 0&&Y.some((J)=>J.captureTeardown?.kind!=="ios-host-recorder")){e.warn(`[RecordingTeardownRedrive] Device ${q} has no pool incarnation; retaining capture descriptors until the device is pooled`);return}for(let J of Y)J.hookDriven||=G;if(T.set(q,W),d.getSessionForDevice(q)!==null){if(C.set(q,{records:Y,hookDriven:G}),!B)rP(d,C,c),B=!0}else if(W===void 0)d.registerPendingDeviceCleanup(q,bv(d,q,Y,{deps:c,hookDriven:G}),Tl);else Sv(d,q,Y,{deps:c,hookDriven:G})};c.onDeviceIncarnationAssigned?.((q)=>x(q,!0)),c.onDeviceProcessStarted?.(async(q)=>{if(O.list(q).length===0)return;try{await l(()=>O.stop(q,void 0,{mode:"background"}),{timer:c.timer,timeoutMs:Tl,label:`Process-start orphan recorder teardown on ${q}`})}catch(G){e.warn(`[RecordingTeardownRedrive] Process-start teardown unconfirmed on ${q}`,G)}});let N;try{N=await c.recordingRepository.listRecordings({hasCaptureTeardown:!0,excludeLiveDaemonSessionIds:c.liveDaemonSessionIds})}catch(q){return e.warn("[RecordingTeardownRedrive] Could not read unconfirmed capture teardowns; continuing startup",q),!1}let H=new Set(c.ownedCaptureIds());for(let q of N){if(!q.captureTeardown||H.has(q.recordingId))continue;let G=R.get(q.deviceId)??[];G.push({...q}),R.set(q.deviceId,G)}for(let q of R.keys())x(q,!1);return c.onStartupOrphans?.(O),!0}function nP(d,c){let R=(T)=>(d.get(T)??[]).filter((B)=>B.captureTeardown&&!c.ownedCaptureIds().includes(B.recordingId)&&yv(B,c.getDeviceIncarnation(T))),C=(T)=>({recordingId:T.recordingId,deviceId:T.deviceId,ownerSessionUuid:T.ownerSessionUuid});return{list:(T)=>R(T).map(C),find:(T)=>{for(let B of d.keys()){let O=R(B).find((x)=>x.recordingId===T);if(O)return C(O)}return},stop:async(T,B,O)=>{let x=R(T).filter((N)=>!B||N.recordingId===B);try{await kc(T,x,c,{waitForExpiry:!1,mode:O?.mode??"user"})}finally{let N=new Set(x.map((H)=>H.withdrawRetry));for(let H of N)if(H&&!(d.get(T)??[]).some((q)=>q.withdrawRetry===H&&q.captureTeardown))H()}}}}function yv(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 Sv(d,c,R,{deps:C,hookDriven:T=!1}){if(R=R.filter((x)=>x.captureTeardown),R.length===0)return;let B=R.map((x)=>{let N=Pc(x);return Number.isFinite(N)?Math.max(0,N-C.now()):0}),O=d.markDeviceNeedsRecorderTeardown(c,()=>kc(c,R,C,{waitForExpiry:!0,hookDriven:T}),Math.max(Tl,...B.map((x)=>x+Tl)));for(let x of R)x.withdrawRetry=O,x.firstMarkedIncarnation??=C.getDeviceIncarnation(c)}function rP(d,c,R){let C=(T,B=!1)=>{let O=c.get(T);if(!O)return;let{hookDriven:x}=O,{records:N}=O;if(c.delete(T),B){if(oP(N.filter((H)=>H.captureTeardown?.kind!=="ios-host-recorder"),R),N=N.filter((H)=>H.captureTeardown?.kind==="ios-host-recorder"),N.length===0)return}d.registerPendingDeviceCleanup(T,bv(d,T,N,{deps:R,hookDriven:x}),Tl)};d.onSessionRelease((T,B,O,x)=>{if(!x?.upgradeOnly)C(B,x?.deviceIdentityReplaced)}),d.onSessionDeviceUnbound((T,B,O)=>C(B,O?.deviceIdentityReplaced))}async function oP(d,c){for(let R of d)try{await c.recordingRepository.updateRecording(R.recordingId,{captureTeardown:void 0}),R.captureTeardown=void 0}catch(C){e.warn(`[RecordingTeardownRedrive] Could not clear replaced-device descriptor for ${R.recordingId}`,C)}}async function bv(d,c,R,{deps:C,hookDriven:T}){try{await l(()=>kc(c,R,C,{waitForExpiry:!1,hookDriven:T}),{timer:C.timer,timeoutMs:Tl,label:`Released orphan recorder teardown on ${c}`})}catch(B){e.warn(`[RecordingTeardownRedrive] Release-time teardown unconfirmed on ${c}`,B),Sv(d,c,R,{deps:C,hookDriven:T})}}async function kc(d,c,R,{waitForExpiry:C,hookDriven:T=!1,mode:B="background"}){let O=[],x=[];for(let N of c){if(!N.captureTeardown||R.ownedCaptureIds().includes(N.recordingId))continue;try{await sP(N,R,C,{hookDriven:T,mode:B})}catch(H){e.warn(`[RecordingTeardownRedrive] Teardown unconfirmed for ${N.recordingId} on ${d}`,H),O.push(N.recordingId),x.push(H)}}if(O.length>0)throw new((x.every((H)=>H instanceof $c))?$c:t)(`Orphan recorder teardown on ${d} is unconfirmed for ${O.join(", ")}. Recover the device if retries fail.`,{cause:x[0]})}async function sP(d,c,R,{hookDriven:C,mode:T}){if(!R&&!Ac(d.captureTeardown)&&d.captureTeardown)await gv(d,c,!1,T);if(d.confirmation)return d.confirmation;let B=(async()=>{if((C||d.hookDriven)&&!await aP(d,c))return;let O=d.captureTeardown;if(!O||c.ownedCaptureIds().includes(d.recordingId))return;if(await gv(d,c,R,T),d.captureTeardown!==O)return;await c.recordingRepository.updateRecording(d.recordingId,{captureTeardown:void 0}),d.captureTeardown=void 0})();d.confirmation=B;try{await B}finally{if(d.confirmation===B)d.confirmation=void 0}}async function aP(d,c){if(c.ownedCaptureIds().includes(d.recordingId))return!1;if((await c.recordingRepository.listRecordings({hasCaptureTeardown:!0,excludeLiveDaemonSessionIds:c.liveDaemonSessionIds,deviceId:d.deviceId})).some((C)=>C.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)+Ai*1000+aH}async function gv(d,c,R,C){let T=d.captureTeardown;if(T.kind==="ios-host-recorder"){await c.forceStopOrphanedCapture(void 0,T,{mode:C});return}if(T.devicePid===void 0){let O=Pc(d);if(!Number.isFinite(O)||!R&&c.now()<O)throw new t(`Orphan recorder ${d.recordingId} on ${d.deviceId} has no pid and its screenrecord hard limit has not elapsed.`);if(c.now()<O)await c.timer.sleep(O-c.now());return}let B=c.getDevice(d.deviceId);if(!B)throw new $c(`Cannot find device ${d.deviceId} to confirm orphan recorder teardown.`);await c.forceStopOrphanedCapture(B,T)}var Yt={initializeRecordingTeardownRedriveState:(...d)=>HO(...d),listActiveVideoRecordings:(...d)=>Ka(...d),redriveUnconfirmedCaptureTeardowns:(...d)=>vv(...d),setStartupOrphanCaptures:(...d)=>uJ(...d),setVideoRecordingManagerDependencies:(...d)=>pJ(...d)};async function Rv(d,c){let R=d.services.sessionManager().getSession(c);if(d.lifecycle.shutdownInProgress()||!R||!d.services.sessionManager().isLiveManagedExecutionSession(c))return;let C=R.assignedDevice;if(Xn([{id:C,platform:R.platform}],d.services.passiveWorkPolicy()).length===0||d.services.sessionManager().getSessionForDevice(C)!==c)return;await Zn([C],{timer:d.services.timer(),perDeviceTimeoutMs:5000,pendingPrefetch:()=>et.pendingPrefetch(),isShuttingDown:()=>d.lifecycle.shutdownInProgress(),verifyIosDevice:async(B,O)=>{if(!d.lifecycle.shutdownInProgress()&&d.services.sessionManager().isLiveManagedExecutionSession(c)&&d.services.sessionManager().getSession(c)?.assignedDevice===B&&d.services.sessionManager().getSessionForDevice(B)===c&&d.lifecycle.managedExecutionReowner()?.ownershipState(c)===void 0)await d.services.iosDeviceVerifier()().verifyIosDevice(B,O)}})}function Cc(d){return{getSession:(c)=>d().getSession(c),getPersistedSession:(c)=>d().getSession(c)}}class Dv{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=ln({coreDeviceProbe:Wv()});exitRecordFileSystem=DP;startHost;selfExitRecorder=new AG({write:(d)=>this.startHost.writeExitRecord(d),now:()=>this.timer.now(),buildId:()=>No().buildId,options:()=>({...Yo(this.options),port:this.listen.port}),canRecord:()=>this.runtime.enteredDaemonProcess&&(this.runtime.socketBindCommitted||!this.incumbentOwnerGuard.hasLiveForeignOwner())});startupCompletion=pl();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 Rr;observerSessionRegistry;sessionManager;devicePool;deviceSessionRegistry;daemonSessionId;installedAppsRepository;deviceSessionRepository;timer;sessionBrokerConfigPath=E(g.SESSION_BROKER_CONFIG)?dP(E(g.SESSION_BROKER_CONFIG)):void 0;processIdentity;passiveWorkPolicy;idGenerator;database;observationStreamHealth;navigationGraphBridge=new wr({server:()=>this.runtime.deviceDataStreamServer,sessionIds:()=>this.sessionManager.getAllSessions().map((d)=>d.sessionId),defaultManager:()=>me.getInstance(),managerForSession:(d)=>me.getInstanceForSession(d)});deviceStateChangeNotifier;options;acceptanceDiscoveryCapability=E(g.ACCEPTANCE_DISCOVERY_CAPABILITY);shutdownState=new Dr;runtime=new Pr;daemonState;constructor(d={},c={}){let R=this.createDaemonCoreServices(),C=this.createDaemonIdentityState(),T=this.createDaemonLifecycleState();this.broker=this.createDaemonBroker(R,C,T),this.startup=this.createDaemonStartup(R,C,T),this.identity=this.createDaemonIdentity(R,C),this.streams=this.createDaemonStreams(R,T),this.maintenance=this.createDaemonMaintenance(R,C,T),this.shutdown=this.createDaemonShutdown(R,T);let{timer:B,deviceSessionRepository:O,idGenerator:x,databaseInitializer:N,startupFailureTracker:H,databaseHealthProbe:q,recoveryPolicyEnvironment:G,managedAdbServerShutdown:W,toolSelectionProfileProvenanceLoader:V,processBirthTime:Y,processGenerationToken:J,incumbentOwnerGuard:X,installedAppsRepository:Z,recoverFromDatabaseHealthFailure:re,...ee}=ul(c);this.deviceReadiness=ee.deviceReadiness,this.daemonState=ee.daemonState,this.httpToken=new Br(ee.httpTokenStore,c.idGenerator,ee.httpToken),this.injected={httpServerFactory:ee.httpServerFactory,liveDaemonSessionIdProvider:ee.liveDaemonSessionIdProvider,avdManagerFactory:ee.avdManagerFactory,iosDeviceVerifier:ee.iosDeviceVerifier,bindingExclusionFactory:ee.bindingExclusionFactory,foreignCtrlProxyForwardEvidence:ee.foreignCtrlProxyForwardEvidence,stopManagedAdbServer:W,hostIoStalled:ee.hostIoStalled},hb(),this.startupCompletion.promise.then(()=>{this.httpIngress.markStartupCompleted()},(fe)=>{e.debug(`Daemon startup completion rejected: ${r(fe)}`)}),this.options={...d},this.listen={port:d.port||Vc,host:d.host||"127.0.0.1",strictPort:d.strictPort??!1,debug:d.debug||!1},P7(this.listen.port),this.idGenerator=x,this.daemonSessionId=this.idGenerator.next(),this.timer=B,this.deviceStateChangeNotifier=jc({timer:B,invalidate:kE,notify:MJ}),this.processIdentity={generationStartedAt:this.timer.now(),processStartedAt:Y(),processGenerationToken:J(),liveAcceptanceStartupSecret:K1()},this.incumbentOwnerGuard=X,this.passiveWorkPolicy=new gr(Jc(process.env,kG),(fe)=>this.sessionManager.getAllSessions().some((ae)=>ae.assignedDevice===fe)),this.database={databaseInitializer:N,toolSelectionProfileProvenanceLoader:V,databaseHealthProbe:q,startupFailureTracker:H,recoverFromDatabaseHealthFailure:re??Lg({timer:()=>this.timer,selfExitRecorder:()=>this.selfExitRecorder,getDaemonFileCleanupOptions:()=>this.identity.getDaemonFileCleanupOptions()})},this.observationStreamHealth=$g({timer:()=>this.timer,startAuxiliarySocket:(...fe)=>this.identity.startAuxiliarySocket(...fe),configureDeviceDataStreamServer:()=>this.streams.configureDeviceDataStreamServer()}),this.deviceSessionRepository=O,this.sessionManager=new aI(this.timer,this.deviceSessionRepository,{sessionDeviceReboundEmitter:uH}),this.sessionManager.attachDaemonSessionId(this.daemonSessionId),this.sessionManager.attachLiveDaemonSessionIds(()=>this.incumbentOwnerGuard.withLiveIncumbent(this.injected.liveDaemonSessionIdProvider.collectLiveDaemonSessionIds())),this.observerSessionRegistry=Hg(this.timer),this.sessions.configureSessionLifecycleCallbacks(),this.installedAppsRepository=Z??new ps;let oe=Ug(G);this.deviceSessionRegistry=new XF(this.timer,this.idGenerator),this.devicePool=this.sessions.createDevicePool(oe.policy,G),j.setAutolockSessionResolver({autolockSessionForMcpSession:(fe)=>this.devicePool.captureAutolockSessionForMcpSession(fe)}),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 Tg({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&&Wc(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 C=this;return new ta({readPersistedSession:Cc(()=>this.deviceSessionRepository).getSession,warmConfirmedManagedExecution:(T)=>Rv({services:d,lifecycle:R},T),services:d,identity:c,lifecycle:R,bindingRegistry:()=>C.runtime.bindingRegistry,deviceClaimMirrors:()=>C.runtime.deviceClaimMirrors,setBindingRegistry:(T)=>{C.runtime.bindingRegistry=T},brokerDeviceAcquisition:()=>C.runtime.brokerDeviceAcquisition,setBrokerDeviceAcquisition:(T)=>C.runtime.brokerDeviceAcquisition=T,openBindingRegistry:(...T)=>this.openBindingRegistry(...T),cancelAndReleaseSession:(...T)=>this.cancelAndReleaseSession(...T)})}createDaemonSessions(d,c,R){let C=this;return new da({services:d,identity:c,lifecycle:R,bindingExclusionFactory:()=>C.injected.bindingExclusionFactory,startBackgroundRegistryUpgrade:()=>this.broker.startBackgroundRegistryUpgrade(),bindingRegistry:()=>C.runtime.bindingRegistry,deviceClaimMirrors:()=>C.runtime.deviceClaimMirrors,foreignCtrlProxyForwardEvidence:()=>C.injected.foreignCtrlProxyForwardEvidence,deviceStateChangeNotifier:()=>C.deviceStateChangeNotifier,observerSessionRegistry:()=>C.observerSessionRegistry,cancelAndReleaseSession:(...T)=>this.cancelAndReleaseSession(...T),onDeviceReadyForSessionRegistry:(...T)=>this.streams.onDeviceReadyForSessionRegistry(...T),reownRehydratedManagedExecutions:(...T)=>this.broker.reownRehydratedManagedExecutions(...T)})}createDaemonStartup(d,c,R){let C=this,T=new Td({initializeRecordingTeardownRedriveState:()=>Yt.initializeRecordingTeardownRedriveState(),redriveUnconfirmedCaptureTeardowns:(...B)=>Yt.redriveUnconfirmedCaptureTeardowns(...B),setStartupOrphanCaptures:(...B)=>Yt.setStartupOrphanCaptures(...B),setVideoRecordingManagerDependencies:(...B)=>Yt.setVideoRecordingManagerDependencies(...B),enterDaemonProcess:(...B)=>this.enterDaemonProcess(...B),prepareHttpToken:()=>this.httpToken.prepare(),publishHttpToken:()=>this.httpToken.publish(),startHttpIngress:()=>this.startup.startHttpIngress(),bindControlSocket:(...B)=>this.bindControlSocket(...B),startServicesAfterSocketBind:(...B)=>this.startServicesAfterSocketBind(...B),startMaintenanceMonitors:(...B)=>this.startMaintenanceMonitors(...B),readPersistedSession:Cc(()=>this.deviceSessionRepository).getPersistedSession,start:(...B)=>this.start(...B),services:d,identity:c,lifecycle:R,startHost:()=>C.startHost,setStartHost:(B)=>C.startHost=B,enteredDaemonProcess:()=>C.runtime.enteredDaemonProcess,setEnteredDaemonProcess:(B)=>C.runtime.enteredDaemonProcess=B,resolveStartupCompletion:()=>C.startupCompletion.resolve,rejectStartupCompletion:()=>C.startupCompletion.reject,exitRecordFileSystem:()=>C.exitRecordFileSystem,strictPort:()=>C.listen.strictPort,host:()=>C.listen.host,startupFailureTracker:()=>C.database.startupFailureTracker,avdManagerFactory:()=>C.injected.avdManagerFactory,databaseInitializer:()=>C.database.databaseInitializer,toolSelectionProfileProvenanceLoader:()=>C.database.toolSelectionProfileProvenanceLoader,liveDaemonSessionIdProvider:()=>C.injected.liveDaemonSessionIdProvider,startOn:(...B)=>this.startOn(...B),startThroughSocketBind:(...B)=>this.startThroughSocketBind(...B),startAfterSocketBind:(...B)=>this.startAfterSocketBind(...B),stopAfterFailedStartup:(...B)=>this.stopAfterFailedStartup(...B),stop:(...B)=>this.stop(...B),writeEarlyOwnerRecord:(...B)=>this.writeEarlyOwnerRecord(...B),setupShutdownHandlers:(...B)=>this.setupShutdownHandlers(...B),subscribeToolCallEndActivity:(...B)=>this.subscribeToolCallEndActivity(...B),initializeDatabase:(...B)=>this.initializeDatabase(...B),openBindingRegistry:(...B)=>this.openBindingRegistry(...B),initializeDevicePoolWithTimeout:(...B)=>this.initializeDevicePoolWithTimeout(...B),reownRehydratedManagedExecutions:(...B)=>this.broker.reownRehydratedManagedExecutions(...B),installSessionBroker:(...B)=>this.broker.installSessionBroker(...B),startBackgroundRegistryUpgrade:()=>this.broker.startBackgroundRegistryUpgrade(),initializeIosServices:(...B)=>this.initializeIosServices(...B),restoreIncumbentOwnerRecord:(...B)=>this.identity.restoreIncumbentOwnerRecord(...B),republishIdentity:(...B)=>this.identity.republishIdentity(...B),recordControlSocketIdentity:()=>this.identity.recordControlSocketIdentity(),startAuxiliarySocket:(...B)=>this.startAuxiliarySocket(...B),configureDeviceDataStreamServer:(...B)=>this.streams.configureDeviceDataStreamServer(...B),setupDeviceSessionRouting:(...B)=>this.streams.setupDeviceSessionRouting(...B),getAppearanceSyncTargets:(...B)=>this.sessions.getAppearanceSyncTargets(...B),startAdbMissingDeviceListener:(...B)=>this.startAdbMissingDeviceListener(...B),startDeviceDisconnectMonitor:(...B)=>this.startDeviceDisconnectMonitor(...B),writePidFile:(...B)=>this.writePidFile(...B),startHealthCheckTimer:(...B)=>this.maintenance.startHealthCheckTimer(...B),startNavigationRetentionMonitor:(...B)=>this.maintenance.startNavigationRetentionMonitor(...B),startForwardLeaseIdleReleaser:(...B)=>this.maintenance.startForwardLeaseIdleReleaser(...B),startPrivateDaemonOrphanWatchdog:(...B)=>this.maintenance.startPrivateDaemonOrphanWatchdog(...B),startHeartbeatMonitor:(...B)=>this.startHeartbeatMonitor(...B),initializeDevicePool:(...B)=>this.initializeDevicePool(...B)});return this.startHost=T.processStartHost(),T}createDaemonIdentity(d,c){return new Md({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 _d({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 Xd({services:d,identityState:c,identity:this.identity,lifecycle:R,healthCheck:()=>this.runtime.healthCheck,setHealthCheck:(C)=>this.runtime.healthCheck=C,observationStreamHealth:()=>this.observationStreamHealth,setObservationStreamHealth:(C)=>this.observationStreamHealth=C,lastDatabaseHealthFailure:()=>this.runtime.lastDatabaseHealthFailure,setLastDatabaseHealthFailure:(C)=>this.runtime.lastDatabaseHealthFailure=C,recoverFromDatabaseHealthFailure:()=>this.database.recoverFromDatabaseHealthFailure,hostIoStalled:()=>this.injected.hostIoStalled,attemptRecovery:(...C)=>this.attemptRecovery(...C),sessionExecutionProbe:(...C)=>this.sessions.sessionExecutionProbe(...C),cancelAndReleaseSession:(...C)=>this.cancelAndReleaseSession(...C),republishIdentity:(...C)=>this.identity.republishIdentity(...C),configureDeviceDataStreamServer:(...C)=>this.streams.configureDeviceDataStreamServer(...C)})}createDaemonDisconnect(d,c){let R=this;return new sc({listActiveVideoRecordings:(...C)=>Yt.listActiveVideoRecordings(...C),captureDisconnectCleanup:(C,T)=>Cg({services:d,forceDisconnectedDeviceGenerations:()=>R.deviceLoss.forceDisconnectedGenerations},C,T),stoppingRecordings:()=>this.stoppingRecordings,retireAdbServerResetDisconnectState:(...C)=>this.retireAdbServerResetDisconnectState(...C),cleanupDisconnectedDevice:(...C)=>this.cleanupDisconnectedDevice(...C),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:(C)=>R.deviceLoss.offlineRecoveryAttemptedIds=C,offlineRecoveryAttemptedIncarnations:()=>R.deviceLoss.offlineRecoveryAttemptedIncarnations,setOfflineRecoveryAttemptedIncarnations:(C)=>R.deviceLoss.offlineRecoveryAttemptedIncarnations=C,forceDisconnectedDeviceGenerations:()=>R.deviceLoss.forceDisconnectedGenerations,shouldSkipStaleDisconnectCleanup:(...C)=>this.shouldSkipStaleDisconnectCleanup(...C),isCapturedDisconnectTargetCurrent:(...C)=>this.isCapturedDisconnectTargetCurrent(...C),trackDeferredSessionRecoverySweep:(...C)=>this.trackDeferredSessionRecoverySweep(...C),stopRecordingAfterDeviceDisconnect:(...C)=>this.stopRecordingAfterDeviceDisconnect(...C),recordAndTryRecoverCapturedDisconnect:(...C)=>this.recordAndTryRecoverCapturedDisconnect(...C),cancelAndReleaseSession:(...C)=>this.cancelAndReleaseSession(...C)})}createDaemonShutdown(d,c){let R=this;return new dc({services:d,lifecycle:c,stopManagedAdbServer:()=>R.injected.stopManagedAdbServer,removeHttpToken:()=>this.httpToken.remove(),stop:(...C)=>this.stop(...C),getDaemonFileCleanupOptions:(...C)=>this.identity.getDaemonFileCleanupOptions(...C),closeManagedExecutionRelease:(...C)=>this.broker.closeManagedExecutionRelease(...C),stopHealthCheckTimer:(...C)=>this.maintenance.stopHealthCheckTimer(...C),stopSessionTimers:(...C)=>this.stopSessionTimers(...C),cleanupDaemonFilesForShutdown:(...C)=>this.cleanupDaemonFilesForShutdown(...C),cancelAndReleaseSession:(...C)=>this.cancelAndReleaseSession(...C)})}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 Qne(d={}){let c=new Dv(d,{foreignCtrlProxyForwardEvidence:PL()});wf().setDeviceReadiness(c.getDeviceReadiness()),await c.start()}export{Qne as startDaemon};
53
+
54
+ //# debugId=BCA4B935327F391E64756E2164756E21