@kaeawc/auto-mobile 0.0.91 → 0.0.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-info.json +12 -12
- package/dist/schemas/README.md +16 -0
- package/dist/schemas/prototype-icon-names.json +302 -0
- package/dist/schemas/test-plan.schema.json +370 -52
- package/dist/src/chunk-00167wan.js +55 -0
- package/dist/src/chunk-0jrrsnc9.js +6 -0
- package/dist/src/chunk-0n6swkwg.js +5 -0
- package/dist/src/chunk-0qsy1qsx.js +57 -0
- package/dist/src/chunk-11m8wj8j.js +237 -0
- package/dist/src/chunk-1p7xf5kb.js +5 -0
- package/dist/src/chunk-23p5f095.js +4 -0
- package/dist/src/chunk-26k317v5.js +5 -0
- package/dist/src/chunk-284ptqa4.js +7 -0
- package/dist/src/chunk-28re4xrg.js +4 -0
- package/dist/src/chunk-2f9rkmhx.js +5 -0
- package/dist/src/chunk-2fxdh48t.js +4 -0
- package/dist/src/chunk-2tbdrbt6.js +4 -0
- package/dist/src/chunk-2tqzq5qh.js +971 -0
- package/dist/src/chunk-32gvv9b4.js +21 -0
- package/dist/src/chunk-3f3t1x97.js +8 -0
- package/dist/src/chunk-3fspkbc7.js +4 -0
- package/dist/src/chunk-3qwrzxh0.js +11 -0
- package/dist/src/chunk-3sy6ahhz.js +26 -0
- package/dist/src/chunk-3vg455e6.js +4 -0
- package/dist/src/chunk-3xkpk44w.js +5 -0
- package/dist/src/chunk-3y6eykz9.js +4 -0
- package/dist/src/chunk-49bsqdx3.js +4 -0
- package/dist/src/chunk-4hw3665t.js +42 -0
- package/dist/src/chunk-58wzr3mt.js +5 -0
- package/dist/src/chunk-5d2hft6c.js +5 -0
- package/dist/src/chunk-5s645vr4.js +4 -0
- package/dist/src/chunk-5snsn9cf.js +4 -0
- package/dist/src/chunk-5tm9mn47.js +54 -0
- package/dist/src/chunk-5zc77a5t.js +4 -0
- package/dist/src/chunk-64j0majr.js +19 -0
- package/dist/src/chunk-65y8v4td.js +17 -0
- package/dist/src/chunk-6awz7vhq.js +5 -0
- package/dist/src/chunk-6bznss4t.js +8 -0
- package/dist/src/chunk-6ep7f5ge.js +4 -0
- package/dist/src/chunk-6pg7bqck.js +4 -0
- package/dist/src/chunk-6wt9rgjf.js +5 -0
- package/dist/src/chunk-6xmss8er.js +8 -0
- package/dist/src/chunk-710rxz9y.js +5 -0
- package/dist/src/chunk-7cs2da62.js +5 -0
- package/dist/src/chunk-7g103b54.js +4 -0
- package/dist/src/chunk-7j5vj4pa.js +4 -0
- package/dist/src/chunk-7rz9898k.js +5 -0
- package/dist/src/chunk-7tw8x05v.js +4 -0
- package/dist/src/chunk-7zy586cb.js +4 -0
- package/dist/src/chunk-8037tzzj.js +5 -0
- package/dist/src/chunk-84nanf8s.js +5 -0
- package/dist/src/chunk-8g1922rp.js +10 -0
- package/dist/src/chunk-8gvwcv2p.js +4 -0
- package/dist/src/chunk-8ph29g99.js +4 -0
- package/dist/src/chunk-8thrmfat.js +4 -0
- package/dist/src/chunk-8zgzzs7k.js +78 -0
- package/dist/src/chunk-97b1zmaq.js +4 -0
- package/dist/src/chunk-9fth9ayh.js +4 -0
- package/dist/src/chunk-9j6anhjr.js +4 -0
- package/dist/src/chunk-aabchzxk.js +9 -0
- package/dist/src/chunk-ayp07wbb.js +4 -0
- package/dist/src/chunk-bfjwqk8q.js +4 -0
- package/dist/src/chunk-bfw6125s.js +5 -0
- package/dist/src/chunk-bnhscm2n.js +4 -0
- package/dist/src/chunk-bxmsax22.js +5 -0
- package/dist/src/chunk-c1vs4g1n.js +4 -0
- package/dist/src/chunk-ct3e7yng.js +4 -0
- package/dist/src/chunk-cyy71ggq.js +5 -0
- package/dist/src/chunk-ddzkz92z.js +4 -0
- package/dist/src/chunk-dgrbdpb7.js +9 -0
- package/dist/src/chunk-drdz8hee.js +5 -0
- package/dist/src/chunk-e98dqnc9.js +145 -0
- package/dist/src/chunk-eersndy7.js +5 -0
- package/dist/src/chunk-eggq53ks.js +4 -0
- package/dist/src/chunk-f2dya7cs.js +4 -0
- package/dist/src/chunk-fbakd6cw.js +4 -0
- package/dist/src/chunk-fgb98zjj.js +5 -0
- package/dist/src/chunk-fmpad823.js +5 -0
- package/dist/src/chunk-g04bwyj3.js +4 -0
- package/dist/src/chunk-g0xr8zw0.js +4 -0
- package/dist/src/chunk-g3rjs80x.js +4 -0
- package/dist/src/chunk-g78rtrfv.js +4 -0
- package/dist/src/chunk-g7tmjbkt.js +5 -0
- package/dist/src/chunk-gabgv3y5.js +4 -0
- package/dist/src/chunk-gmr45m8f.js +4 -0
- package/dist/src/chunk-gsyfebqj.js +4 -0
- package/dist/src/chunk-h5rpn9wr.js +247 -0
- package/dist/src/chunk-hb1x7v55.js +4 -0
- package/dist/src/chunk-hrfytkxh.js +168 -0
- package/dist/src/chunk-j4yjzbak.js +4 -0
- package/dist/src/chunk-jd6a5v6p.js +5 -0
- package/dist/src/chunk-jh6vhqzx.js +5 -0
- package/dist/src/chunk-kn5spq15.js +4 -0
- package/dist/src/chunk-m94qs0f0.js +4 -0
- package/dist/src/chunk-mjrps0ac.js +7 -0
- package/dist/src/chunk-n03dmn5q.js +5 -0
- package/dist/src/chunk-n72qhwd9.js +4 -0
- package/dist/src/chunk-ndt1ccxm.js +71 -0
- package/dist/src/chunk-nr6y0n4y.js +5 -0
- package/dist/src/chunk-pcsen2vs.js +4 -0
- package/dist/src/chunk-ppfr0b8h.js +4 -0
- package/dist/src/chunk-q10bdnat.js +4 -0
- package/dist/src/chunk-q9xmq595.js +4 -0
- package/dist/src/chunk-qcxzr2my.js +5 -0
- package/dist/src/chunk-qf6nynk6.js +7 -0
- package/dist/src/chunk-qyqypn28.js +5 -0
- package/dist/src/chunk-r2epb56s.js +4 -0
- package/dist/src/chunk-r5bxavdx.js +311 -0
- package/dist/src/chunk-r6z1eztj.js +18 -0
- package/dist/src/chunk-r7bpkgff.js +4 -0
- package/dist/src/chunk-r8jf3d92.js +4 -0
- package/dist/src/chunk-rbpdk7m0.js +5 -0
- package/dist/src/chunk-rc0dbypm.js +4 -0
- package/dist/src/chunk-rhcty4ms.js +4 -0
- package/dist/src/chunk-rpvckv3p.js +4 -0
- package/dist/src/chunk-rqc9ap3x.js +4 -0
- package/dist/src/chunk-rvvy1bte.js +7 -0
- package/dist/src/chunk-ry0mz41y.js +4 -0
- package/dist/src/chunk-s3jc6cwp.js +5 -0
- package/dist/src/chunk-sfv61xjb.js +6 -0
- package/dist/src/chunk-t6bfvfkg.js +4 -0
- package/dist/src/chunk-t6c8akcm.js +5 -0
- package/dist/src/chunk-t7w8rctc.js +4 -0
- package/dist/src/chunk-thbh3jew.js +5 -0
- package/dist/src/chunk-v2wd4n3e.js +5 -0
- package/dist/src/chunk-v6pya0dm.js +5 -0
- package/dist/src/chunk-vy3bwm1d.js +17 -0
- package/dist/src/chunk-w3vs79ex.js +27 -0
- package/dist/src/chunk-w4zga19f.js +4 -0
- package/dist/src/chunk-w5b2jwk3.js +14 -0
- package/dist/src/chunk-w7hkv422.js +5 -0
- package/dist/src/chunk-waqwcjyn.js +4 -0
- package/dist/src/chunk-wbh8spm5.js +20 -0
- package/dist/src/chunk-wyrkw6hw.js +5 -0
- package/dist/src/chunk-xa73x2cx.js +5 -0
- package/dist/src/chunk-xgan0qqp.js +4 -0
- package/dist/src/chunk-y2vs6jwg.js +4 -0
- package/dist/src/chunk-yattm52s.js +4 -0
- package/dist/src/chunk-yb97j25b.js +6 -0
- package/dist/src/chunk-ybbtagbt.js +5 -0
- package/dist/src/chunk-ycaj2sgf.js +9 -0
- package/dist/src/chunk-yf7ympyz.js +325 -0
- package/dist/src/chunk-yjawdzk8.js +4 -0
- package/dist/src/chunk-z637nqg8.js +11 -0
- package/dist/src/chunk-zgja5f3p.js +6 -0
- package/dist/src/chunk-zs1sghs9.js +4 -0
- package/dist/src/daemon/processEntry.js +4 -0
- package/dist/src/index.js +4 -2843
- package/dist/src/runtime/bunRuntimeGuard.js +4 -0
- package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -3
- package/ios/CameraPosterInjection/Injection/CameraPosterInjection.m +466 -0
- package/package.json +7 -6
- package/schemas/README.md +16 -0
- package/schemas/prototype-icon-names.json +302 -0
- package/schemas/test-plan.schema.json +370 -52
- package/node_modules/@borewit/text-codec/README.md +0 -87
- package/node_modules/@jimp/diff/node_modules/pixelmatch/README.md +0 -110
- package/node_modules/@jimp/diff/node_modules/pixelmatch/node_modules/pngjs/README.md +0 -433
- package/node_modules/@jimp/file-ops/dist/browser/index.js +0 -8
- package/node_modules/@jimp/js-png/README.md +0 -35
- package/node_modules/@jimp/js-png/src/__image_snapshots__/index-node-test-ts-png-should-use-png-options-1-snap.png +0 -0
- package/node_modules/@jimp/js-png/src/output.png +0 -0
- package/node_modules/@jimp/js-png/vitest.config.browser.mjs +0 -3
- package/node_modules/@jimp/plugin-resize/README.md +0 -12
- package/node_modules/@jimp/plugin-resize/vitest.config.browser.mjs +0 -3
- package/node_modules/@tokenizer/inflate/README.md +0 -114
- package/node_modules/@tokenizer/token/README.md +0 -19
- package/node_modules/await-to-js/README.md +0 -82
- package/node_modules/debug/README.md +0 -481
- package/node_modules/exif-parser/README.md +0 -83
- package/node_modules/file-type/readme.md +0 -667
- package/node_modules/ieee754/README.md +0 -51
- package/node_modules/mime/README.md +0 -178
- package/node_modules/ms/readme.md +0 -59
- package/node_modules/parse-bmfont-xml/README.md +0 -74
- package/node_modules/parse-bmfont-xml/lib/browser.js +0 -85
- package/node_modules/parse-bmfont-xml/node_modules/xml2js/README.md +0 -507
- package/node_modules/pngjs/README.md +0 -287
- package/node_modules/sax/README.md +0 -228
- package/node_modules/strtok3/README.md +0 -795
- package/node_modules/tinycolor2/README.md +0 -492
- package/node_modules/tinycolor2/cjs/test.js +0 -2191
- package/node_modules/tinycolor2/cjs/test_template.js +0 -26
- package/node_modules/tinycolor2/deno_asserts@0.168.0.mjs +0 -807
- package/node_modules/tinycolor2/esm/test.js +0 -2189
- package/node_modules/tinycolor2/esm/test_template.js +0 -24
- package/node_modules/tinycolor2/tinycolor.js +0 -1191
- package/node_modules/token-types/README.md +0 -160
- package/node_modules/uint8array-extras/readme.md +0 -318
- package/node_modules/xml-parse-from-string/README.md +0 -35
- package/node_modules/xmlbuilder/README.md +0 -86
- package/node_modules/zod/README.md +0 -208
- package/node_modules/zod/v4/locales/ar.d.cts +0 -4
- package/node_modules/zod/v4/locales/ar.d.ts +0 -4
- package/node_modules/zod/v4/locales/az.d.cts +0 -4
- package/node_modules/zod/v4/locales/az.d.ts +0 -4
- package/node_modules/zod/v4/locales/be.d.cts +0 -4
- package/node_modules/zod/v4/locales/be.d.ts +0 -4
- package/node_modules/zod/v4/locales/ca.d.cts +0 -4
- package/node_modules/zod/v4/locales/ca.d.ts +0 -4
- package/node_modules/zod/v4/locales/cs.d.cts +0 -4
- package/node_modules/zod/v4/locales/cs.d.ts +0 -4
- package/node_modules/zod/v4/locales/de.d.cts +0 -4
- package/node_modules/zod/v4/locales/de.d.ts +0 -4
- package/node_modules/zod/v4/locales/en.d.cts +0 -5
- package/node_modules/zod/v4/locales/en.d.ts +0 -5
- package/node_modules/zod/v4/locales/eo.d.cts +0 -5
- package/node_modules/zod/v4/locales/eo.d.ts +0 -5
- package/node_modules/zod/v4/locales/es.d.cts +0 -4
- package/node_modules/zod/v4/locales/es.d.ts +0 -4
- package/node_modules/zod/v4/locales/fa.d.cts +0 -4
- package/node_modules/zod/v4/locales/fa.d.ts +0 -4
- package/node_modules/zod/v4/locales/fi.d.cts +0 -4
- package/node_modules/zod/v4/locales/fi.d.ts +0 -4
- package/node_modules/zod/v4/locales/fr-CA.d.cts +0 -4
- package/node_modules/zod/v4/locales/fr-CA.d.ts +0 -4
- package/node_modules/zod/v4/locales/fr.d.cts +0 -4
- package/node_modules/zod/v4/locales/fr.d.ts +0 -4
- package/node_modules/zod/v4/locales/he.d.cts +0 -4
- package/node_modules/zod/v4/locales/he.d.ts +0 -4
- package/node_modules/zod/v4/locales/hu.d.cts +0 -4
- package/node_modules/zod/v4/locales/hu.d.ts +0 -4
- package/node_modules/zod/v4/locales/id.d.cts +0 -4
- package/node_modules/zod/v4/locales/id.d.ts +0 -4
- package/node_modules/zod/v4/locales/index.d.cts +0 -39
- package/node_modules/zod/v4/locales/index.d.ts +0 -39
- package/node_modules/zod/v4/locales/it.d.cts +0 -4
- package/node_modules/zod/v4/locales/it.d.ts +0 -4
- package/node_modules/zod/v4/locales/ja.d.cts +0 -4
- package/node_modules/zod/v4/locales/ja.d.ts +0 -4
- package/node_modules/zod/v4/locales/kh.d.cts +0 -4
- package/node_modules/zod/v4/locales/kh.d.ts +0 -4
- package/node_modules/zod/v4/locales/ko.d.cts +0 -4
- package/node_modules/zod/v4/locales/ko.d.ts +0 -4
- package/node_modules/zod/v4/locales/mk.d.cts +0 -4
- package/node_modules/zod/v4/locales/mk.d.ts +0 -4
- package/node_modules/zod/v4/locales/ms.d.cts +0 -4
- package/node_modules/zod/v4/locales/ms.d.ts +0 -4
- package/node_modules/zod/v4/locales/nl.d.cts +0 -4
- package/node_modules/zod/v4/locales/nl.d.ts +0 -4
- package/node_modules/zod/v4/locales/no.d.cts +0 -4
- package/node_modules/zod/v4/locales/no.d.ts +0 -4
- package/node_modules/zod/v4/locales/ota.d.cts +0 -4
- package/node_modules/zod/v4/locales/ota.d.ts +0 -4
- package/node_modules/zod/v4/locales/pl.d.cts +0 -4
- package/node_modules/zod/v4/locales/pl.d.ts +0 -4
- package/node_modules/zod/v4/locales/ps.d.cts +0 -4
- package/node_modules/zod/v4/locales/ps.d.ts +0 -4
- package/node_modules/zod/v4/locales/pt.d.cts +0 -4
- package/node_modules/zod/v4/locales/pt.d.ts +0 -4
- package/node_modules/zod/v4/locales/ru.d.cts +0 -4
- package/node_modules/zod/v4/locales/ru.d.ts +0 -4
- package/node_modules/zod/v4/locales/sl.d.cts +0 -4
- package/node_modules/zod/v4/locales/sl.d.ts +0 -4
- package/node_modules/zod/v4/locales/sv.d.cts +0 -4
- package/node_modules/zod/v4/locales/sv.d.ts +0 -4
- package/node_modules/zod/v4/locales/ta.d.cts +0 -4
- package/node_modules/zod/v4/locales/ta.d.ts +0 -4
- package/node_modules/zod/v4/locales/th.d.cts +0 -4
- package/node_modules/zod/v4/locales/th.d.ts +0 -4
- package/node_modules/zod/v4/locales/tr.d.cts +0 -5
- package/node_modules/zod/v4/locales/tr.d.ts +0 -5
- package/node_modules/zod/v4/locales/ua.d.cts +0 -4
- package/node_modules/zod/v4/locales/ua.d.ts +0 -4
- package/node_modules/zod/v4/locales/ur.d.cts +0 -4
- package/node_modules/zod/v4/locales/ur.d.ts +0 -4
- package/node_modules/zod/v4/locales/vi.d.cts +0 -4
- package/node_modules/zod/v4/locales/vi.d.ts +0 -4
- package/node_modules/zod/v4/locales/zh-CN.d.cts +0 -4
- package/node_modules/zod/v4/locales/zh-CN.d.ts +0 -4
- package/node_modules/zod/v4/locales/zh-TW.d.cts +0 -4
- package/node_modules/zod/v4/locales/zh-TW.d.ts +0 -4
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{mae,Fr,hJ,i,BO,Ub,$O,gU,hae,$p,Q,No,Zi,bae,Ll,If,cr,Uu,l,at,wJ,e}from"./chunk-z637nqg8.js";import{f,Y,I,Be,Hu}from"./chunk-58wzr3mt.js";import{Xn,yo,DN,Ny,vS,rq,nq,Fy,Ly,By,MI,Sr,LN,oc,wS,sc,cq,Qf,gA,lq,uq,zN,pq,BI}from"./chunk-0jrrsnc9.js";import"./chunk-5d2hft6c.js";import{Ns,KL,xv,_w,JL,no,R,nre,ti,xw,zW,Br,ze,en,tn,Dr,cre,lre,rd,ls,QC,cg,nd,cp,eD,dg,Ov,Dw,Mv,iB,Lt,br,lg,Sre,Mw,L3,Rre,Pre,dp,zo,$m,qT,VT,lp,vu,Are,zT,Lv,us,$w,Ere,ri,ll,ul,Ire,lB,pg,qw,iz,Bt,mB,dz,lz,xre,Bv,pz,Eo,U3,je,H,Je,me,on,mz,re,GT,fB,wn,V3,Lre,mt,rt,ce,Ko,vz,fl,Fn,Gw,SB,Fs,v,$a,hs,Wm,zre,vg,Jw,dD,Ua,Ve,xo,uD,Qw,wz,yp,L,Tz,kz,mD,Ez,fD,Gm,Sg,Go,AB,b,Yo,ut,Gt,cd,sn,De,Ym,oR,Gv,sR,Oz,We,ji,le,bs,gl,cn,yl,vne,bne,Fz,cY,IB,Pn,st,_B,wD,Pu,CB,Lz,Zv,Xm,Ki,Rp,Ic,An,dR,Ap,uk,zn,Au,OB,Rne,Pne,lR,qa,Ane,uR,Tne,kne,Ene,pR,fe,TD,tb,NB,Si,fR,uY,Et,xne,qz,Vz,Tn,o,dn,kp,mY,fY,zz,hY,N,CD,Wne,zne,jne,xc,xY,CY,ws,of,Tk,it,Ik,ye,DR,hd,iie,Ur,fa,En,Dk,Ok,oi,Rs,_u,NR,ha,FR,u$,si,_t,vb,Lg,y$,Bg,Bk,jD,mie,fie,zR,S$,xp,kl,uf,YD,Hk,JD,XD,Vk,Wk,Rb,_$,x$,tO,XR,Uj,Nie,Fie,Lie,O,Tb,wr,x,Vs,E}from"./chunk-r5bxavdx.js";import{FJ,BJ}from"./chunk-drdz8hee.js";import{B,po,m,wd,_r,k9,bf,Ht,Sf,Cb,zs,Fi,ki,Ja,Yt,_e,I9,_9,x9,C9,Dp}from"./chunk-yf7ympyz.js";import{mo,y,T,gr,j,g,Fe,Ct,Xr,A,oE,n,a,h,sP,S,s,Ie,Nae,p,_,Op}from"./chunk-4hw3665t.js";import{fu,NC,Rw,p3,Er,sr,ol,Ue,Om,xe,td,aa}from"./chunk-0qsy1qsx.js";import{Zr,mi,yA,$I,rr,fi,Ql,$o,ac,om,gq,is,qy,YN,S7,w7,R7,P7,cc,eh,bA,zd,yq,Uc,jd,qI,Js,m4,Mn,A7,VI,T7,PS,Un,ka,Uo,TS,I7,_7,bq,WI,v4,wq,_i,eu,kS,Nn,ES,lc,e0,kq,Eq,IS,th,R4,_S,t0,wA,rh,T4,uc,k4,zy,nh,s0,CS,Cq,Dt,a0,c0,z7,DS,d0,E4,$e,XI,ZI,pc,OS,Dq,Oq,Mq,Nq,t_,Fq,tQ,Lq,bo,hi,tu,g0,Hc,Rt,D4,ah,sQ,mc,$4,_0,U4,H4,Xd,q4,c_}from"./chunk-hrfytkxh.js";import{fc,nu,Zu,pm,mm,q0,wh,V0,zS,W0,UA,z0}from"./chunk-0n6swkwg.js";import"./chunk-3xkpk44w.js";import{L0,JQ,XQ,BA,$0,vh}from"./chunk-2f9rkmhx.js";import"./chunk-00167wan.js";import"./chunk-7rz9898k.js";import"./chunk-ycaj2sgf.js";import{uX,N1,$M,fy}from"./chunk-6xmss8er.js";import"./chunk-g7tmjbkt.js";import{Lf,CM,Ul,X8,MM,Z8,C1,ql,rX,nX,nc,NP,oX,D1}from"./chunk-w3vs79ex.js";import"./chunk-v2wd4n3e.js";import"./chunk-yb97j25b.js";import{zb,Dn,zJ,nG,CE,lM,jJ,KJ,rc,GJ,Df,YJ,IP,uM,JJ,pM,LU,BU,sy,_P,$U,jb,Pa,r8,xP,ME,$l,n8,NE,UU,oG,sG,i8,HU,jU,hM,FE,u8,hn,g1,y1,b1,S1,w1,HE,R1,P1,Zb,qE,my,T1,Qb,z8,kG}from"./chunk-11m8wj8j.js";import{Ho,Zq,Y4,CQ,x0,C0,J4,DQ,Xs,Xu,Cr,X4,MQ,tV,O0,e5,BQ,$Q,UQ,HQ,ru,G}from"./chunk-64j0majr.js";import{ss,pV,mV,fV,ge,aee,wF,gee,Fh,PF}from"./chunk-e98dqnc9.js";import{UH,HH,qH,VH,WH,zH,jH,KH,lA,e7,z6,ns,K6,t7,GH,G6,r7}from"./chunk-dgrbdpb7.js";import{SU}from"./chunk-xa73x2cx.js";import{PK}from"./chunk-cyy71ggq.js";import{SE,EJ,IJ,_J,xJ,CJ,oy,AU,TU,kU,wE,EU,RE,tM,IU,zK,_U}from"./chunk-sfv61xjb.js";import{n7,EI,uA,PN,xs,YH,em,AN,pA,TN,o7,IN,JH,s7,_N,a7,Q6,e4,xN,c7,XH,t4,ZH,QH,CN}from"./chunk-65y8v4td.js";import"./chunk-jh6vhqzx.js";import{W1,z1,oI,PX,hy,VM,G1,AX,JG,Y1,TX,kX,EX,IX,_X,qf,gy,Ud,J1,KM,S6,dH,by,pI,Kf,vH,dZ,lZ,bH,uZ,mI,rN,SH,aS,pZ,A6,mZ,fZ,hZ,GP,XP,k6,PH,iN,Zp,Ks,go}from"./chunk-h5rpn9wr.js";import"./chunk-6awz7vhq.js";import{b5,AF}from"./chunk-84nanf8s.js";import{jl,M6,mS,wN,cA,fS,hS,W6,JZ,qd,XZ,ZZ}from"./chunk-3qwrzxh0.js";import{$K,UK,qK}from"./chunk-1p7xf5kb.js";import{PI,x6}from"./chunk-w5b2jwk3.js";import{xU}from"./chunk-jd6a5v6p.js";import"./chunk-3f3t1x97.js";import"./chunk-vy3bwm1d.js";import"./chunk-thbh3jew.js";import"./chunk-7tw8x05v.js";import{Ev}from"./chunk-zgja5f3p.js";import"./chunk-aabchzxk.js";import{$1}from"./chunk-qf6nynk6.js";import"./chunk-bfw6125s.js";import"./chunk-ybbtagbt.js";import{vV}from"./chunk-s3jc6cwp.js";import{eM,PU}from"./chunk-710rxz9y.js";import{AK,TK,kK}from"./chunk-nr6y0n4y.js";import{EK,IK,_K}from"./chunk-wyrkw6hw.js";import{xK,CK,DK}from"./chunk-eersndy7.js";import{OK,MK,NK}from"./chunk-bxmsax22.js";import{wU,jO,KO,YO,FK,LK,BK}from"./chunk-8037tzzj.js";import{Md,Nd,Is,_f,iy,JO,tc,Wp,XO,ZO,TJ,kJ,WK,QO}from"./chunk-t6c8akcm.js";import{UW}from"./chunk-n03dmn5q.js";import{RK}from"./chunk-7cs2da62.js";import{V4,Jq,lm}from"./chunk-26k317v5.js";import{gn,Ci,jc}from"./chunk-284ptqa4.js";import"./chunk-w7hkv422.js";import"./chunk-qyqypn28.js";import"./chunk-fgb98zjj.js";import{Sn}from"./chunk-rvvy1bte.js";import"./chunk-v6pya0dm.js";import{Vp,r,t,u}from"./chunk-rbpdk7m0.js";var Mc={async push(d,c){let w=x.getExistingInstance(d),D=$a(d)?null:E.getExistingInstance(d);if(!D&&!w)throw new t(`No live CtrlProxy client to clear network state on ${d}`);if(D?.syncNetworkStateToDevice()===!1)throw new t(`Android network state was not delivered to ${d}`);await w?.syncNetworkStateFromHost(c)}};async function Ec(d,c,w,D){let k=new AbortController,P=w.now()+Sr,C=w.setTimeout(()=>k.abort(Error("Network cleanup deadline expired")),Sr);C.unref?.();try{await l(()=>Je(()=>d.push(c,{deadlineMs:P,abortSignal:k.signal})),{timer:w,signal:k.signal,label:"push cleared network state"})}catch(M){e.warn(`[networkState] Failed to push cleared network state to ${c}: ${r(M)}`,M);try{D?.(M)}catch(F){e.warn("[networkState] Failed to mark uncleared network state",F)}}finally{w.clearTimeout(C)}}function Bc(d,c={}){let w=c.pusher??Mc,D=(k,P,C)=>{if(!(c.state?.()??cn.getInstance()).clearDeviceOwnedBySession(P,k))return;if(C?.deviceIdentityReplaced){e.debug(`[networkState] Cleanup for session ${k} on replaced serial ${P}: skipped cleared-state device push`);return}let F=c.gapMarkerFor?.(k);d.registerPendingDeviceCleanup(P,Ec(w,P,c.timer??i,(q)=>{F?.(`network mock rules and simulation may remain on ${P}: ${r(q)}`)}),{name:"push cleared network state",leftover:"the released session's network mock rules and error simulation"})};d.onSessionRelease((k,P,C,M)=>{D(k,P,M)}),d.onSessionDeviceUnbound(D)}function Oc(d,c={}){let w=c.pusher??Mc;return(D)=>{if(!(c.state?.()??cn.getInstance()).clearSessionlessDeviceState(D))return;hS(d,D,Ec(w,D,c.timer??i),{timer:c.timer??i,capMs:Sr,label:"push cleared network state"})}}class xi extends Error{}var hv=25000,dt=new Map;function gv(d,c=St){let w=(dt.get(d)??[]).filter((D)=>qe(c,D.sessionId,d,D.recordingIds).length>0);if(w.length>0)dt.set(d,w);else dt.delete(d);return w}var vv={android:120000,ios:120000},yv=/^[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}$/i;function Sv(d){return vv[yv.test(d)?"ios":"android"]}var St={abandonRecordingsOnReplacedDevice:wv,hasRecordingsToStop:(d,c)=>NP().length>0||_P.hasSegmentedVideoRecordingsForOwner(d,c)||N1(d,c),stopSegmentedRecordings:_P.stopSegmentedVideoRecordingsForOwner,captureSegmentedRecordingIdsForOwner:_P.captureSegmentedRecordingIdsForOwner,listActiveVideoRecordings:(d)=>nc({deviceId:d}),stopVideoRecording:async(d)=>{await C1(d)},isDeviceGestureRecordingOwnedBy:N1,ownedDeviceGestureRecordingId:$M,activeRecordingIdsForOwner:(d,c)=>{let w=$M(d,c);return[...D1(d,c),..._P.segmentedVideoRecordingHandlesForOwner(d,c),...w===void 0?[]:[w]]},retainedCaptureIdsForOwner:(d,c)=>{let w=$M(d,c);return[...D1(d,c),...w===void 0?[]:[w]]},stopDeviceGestureRecording:async(d)=>{await fy(d)},timer:i,finalizeCapMs:Sv,markVideoRecordingIncomplete:nX,teardownRetryBackoff:Q({initialDelayMs:1000,multiplier:2,maxDelayMs:8000}),teardownRetryBudgetMs:hv,markDeviceNeedsRecorderRecovery:(d)=>{let c=dt.get(d.deviceId)??[];c.push(d),dt.set(d.deviceId,c)}};function _c(d,c=St){return(w)=>{St.markDeviceNeedsRecorderRecovery(w),d.markDeviceNeedsRecorderTeardown(w.deviceId,()=>bv(w.deviceId,c),Ul,"release-give-ups")}}async function bv(d,c){let w=dt.get(d)??[];for(let k of w){let P=qe(c,k.sessionId,d,k.recordingIds);await fr(c,P,c.ownedDeviceGestureRecordingId(k.sessionId,d))}let D=gv(d,c).flatMap((k)=>qe(c,k.sessionId,d,k.recordingIds));if(D.length>0)throw new t(`Recorder teardown on device ${d} is still unconfirmed for ${D.join(", ")}. Recover the device if retries fail.`);dt.delete(d)}async function wv(d,c){let w=D1(d,c),D=$M(d,c);await Promise.all([Ni(()=>_P.finalizeSegmentedVideoRecordingsForOwnerOnReplacedDevice(d,c)),...w.map((k)=>Ni(()=>rX(k))),...D===void 0?[]:[Ni(()=>fy(D,void 0,void 0,{hostOnly:!0}))]])}async function Ni(d){try{await d()}catch(c){e.warn(`[RecordingSessionCleanup] Host-only recording cleanup failed: ${r(c)}`,c)}}var pr=new Map;function Fc(d){let c=pr.get(d)??[];return pr.delete(d),c}class mr extends Error{}async function zt(d,c){try{await c()}catch(w){e.warn(`[recording] Failed to ${d}: ${r(w)}`,w)}}async function Rv(d,c,w,{state:D,deviceGestureRecordingId:k}){let{stopping:P}=D,C=()=>{if(D.capExpired)return;let M=new Set(d.activeRecordingIdsForOwner(c,w));for(let F of P)if(!M.has(F))P.delete(F)};if(await zt(`finalize segmented recordings of released session ${c??"(owner-less)"}`,()=>d.stopSegmentedRecordings(c,w)),C(),await zt(`stop video recordings of released session ${c??"(owner-less)"} on ${w}`,async()=>{let M=await d.listActiveVideoRecordings(w);for(let{recordingId:F,ownerSessionUuid:q}of M){if(q!==c||D.capExpired&&!P.has(F))continue;if(!D.capExpired)P.add(F),D.owned.add(F);await zt(`stop video recording ${F} of released session ${c??"(owner-less)"}`,async()=>{if(await d.stopVideoRecording(F),!D.capExpired)P.delete(F);e.info(`[recording] Stopped recording ${F} on ${w}: owning session ${c??"(owner-less)"} was released`)})}}),k!==void 0&&d.isDeviceGestureRecordingOwnedBy(c,w))await zt(`stop device gesture recording of released session ${c??"(owner-less)"} on ${w}`,async()=>{await d.stopDeviceGestureRecording(k),C(),e.info(`[recording] Device gesture recording on ${w} stopped: owning session ${c??"(owner-less)"} was released; its plan stays fetchable by the owner`)})}async function Dv(d,c,w,D){let k=new Set(d.activeRecordingIdsForOwner(c,w)),P={stopping:new Set(k),owned:k,capExpired:!1},C=d.captureSegmentedRecordingIdsForOwner?.(c,w),M=[],F=d.ownedDeviceGestureRecordingId(c,w),q=d.finalizeCapMs(w),U=c??"(owner-less)";try{await l(Rv(d,c,w,{state:P,deviceGestureRecordingId:F}),{timer:d.timer,timeoutMs:q,label:`finalize recordings of released session ${U}`,timeoutError:()=>new mr,onTimeout:()=>{P.capExpired=!0;let W=C?.()??[];for(let z of W)P.stopping.add(z),k.add(z);let V=new Set([...d.activeRecordingIdsForOwner(c,w),...W]);M=[...new Set([...[...P.stopping].filter((z)=>V.has(z)),...qe(d,c,w,[...k])])]}})}catch(W){if(W instanceof mr)e.warn(`[recording] Finalizing recordings of released session ${U} on ${w} exceeded ${q}ms; force-stopping ${M.join(", ")||"none"} and marking incomplete`);else e.warn(`[recording] Finalizing recordings of released session ${U} on ${w} failed: ${r(W)}`,W)}if(!P.capExpired){let W=[...new Set([...k,...C?.()??[]])];if(M=qe(d,c,w,W),M.length===0)return;e.warn(`[recording] Finalizing recordings of released session ${U} on ${w} left retained captures; force-stopping ${M.join(", ")} and marking incomplete`)}if(await fr(d,M,F),qe(d,c,w,M).length===0)return;let K=Pv(d,{sessionId:c,deviceId:w,recordingIds:M,deviceGestureRecordingId:F,attempts:0});D(K,d.teardownRetryBudgetMs),await K}function qe(d,c,w,D){let k=new Set(d.retainedCaptureIdsForOwner(c,w));return D.filter((P)=>k.has(P))}async function fr(d,c,w,D){await Promise.all(c.map((k)=>zt(`force-stop recording ${k}`,()=>l(()=>k===w?d.stopDeviceGestureRecording(k):d.markVideoRecordingIncomplete(k),{timer:d.timer,timeoutMs:Ul,signal:D,label:`force-stop recording ${k}`}))))}async function kv(d,c,w){let D;try{await l(()=>new Promise((k)=>{D=d.timer.setTimeout(k,d.teardownRetryBackoff.delayForAttempt(c))}),{timer:d.timer,signal:w,label:"recording teardown retry backoff"})}finally{if(D!==void 0)d.timer.clearTimeout(D)}}async function Av(d,c,w){let D=()=>qe(d,c.sessionId,c.deviceId,c.recordingIds);while(!w.aborted&&D().length>0){if(await kv(d,c.attempts+1,w),w.aborted)return;let k=D();if(k.length===0)return;c.attempts+=1,await fr(d,k,c.deviceGestureRecordingId,w)}}async function Pv(d,c){let w=new AbortController;try{await l(()=>Av(d,c,w.signal),{timer:d.timer,timeoutMs:d.teardownRetryBudgetMs,label:`retry recording teardown on ${c.deviceId}`,timeoutError:()=>new xi,onTimeout:()=>w.abort()})}catch(D){if(!(D instanceof xi))e.warn(`[recording] Teardown retry failed on ${c.deviceId}: ${r(D)}`,D);let k=qe(d,c.sessionId,c.deviceId,c.recordingIds);if(k.length>0){let P={deviceId:c.deviceId,sessionId:c.sessionId,recordingIds:k,attempts:c.attempts,budgetMs:d.teardownRetryBudgetMs};e.warn(`[recording] Teardown gave up on device ${P.deviceId}, released session ${P.sessionId??"(owner-less)"}: recordings ${k.join(", ")}; ${P.attempts} attempts, ${P.budgetMs}ms budget; device needs recorder recovery`),d.markDeviceNeedsRecorderRecovery(P);return}}finally{w.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 Iv={timer:i,adoptVideoRecordings:oX,adoptSegmentedRecordings:_P.adoptOwnerlessSegmentedVideoRecordings,adoptDeviceGestureRecording:uX};function Cv(d,c){return d.finalizeCapMs(c)+Ul}function Nc(d,c=Iv){return(w,D)=>{if(d.getSessionForDevice(w)!==D)return;c.adoptSegmentedRecordings(w,D),c.adoptDeviceGestureRecording(w,D);let k=c.adoptVideoRecordings(w,D);if(!k)return;hS(d,w,k,{timer:c.timer,capMs:Ul,label:`persist adopted recording ownership for session ${D}`})}}function Lc(d,c=St){let w=(D,k,P)=>{if(P?.deviceIdentityReplaced){Ni(()=>c.abandonRecordingsOnReplacedDevice(D,k));return}if(!c.hasRecordingsToStop(D,k))return;d.registerPendingDeviceCleanup(k,Dv(c,D,k,(C,M)=>d.registerPendingDeviceCleanup(k,C,M)),Cv(c,k))};d.onSessionRelease((D,k,P,C)=>{if(!C?.upgradeOnly){let M=[...new Set(c.activeRecordingIdsForOwner(D,k))];if(M.length>0)pr.set(D,M);w(D,k,C)}}),d.onSessionDeviceUnbound(w)}var hr=TD,$c=3000;function qc(d){return async(c,w)=>{if(d.viewerRead&&await d.viewerRead.applies(c))return d.viewerRead.observe(c,w);let D=c.platform==="android"?await d.readAndroidDeviceClockMs(c,w):d.hostRequestStartMs;return w.throwIfAborted(),d.observe(c,{minTimestamp:D,signal:w})}}function Tv(d,c,w){return{observationId:po("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:w}}function Li(d,c,w,D){return{deviceId:w,observation:Tv(d,c,D)}}async function Kc(d,c,w){let{timer:D,signal:k,assertDeviceActionable:P}=w,C=w.idGenerator??B,M=w.perDeviceTimeoutMs??hr;return(await Promise.allSettled(d.map(async(q)=>{if(k.aborted)return Li(D,C,q.id,`Observation request was aborted for device ${q.id}`);try{P?.(q)}catch(V){let z=r(V);return e.warn(`[Daemon] Skipped observation for ${q.id}: ${z}`),Li(D,C,q.id,z)}let U=new AbortController,K=Error(`Observation request timed out after ${M}ms for device ${q.id}`),W=AbortSignal.any([k,U.signal]);try{let V=await l(c(q,W),{timer:D,timeoutMs:M,label:"Observation request",timeoutError:()=>K,onTimeout:()=>U.abort()});return{deviceId:q.id,observation:V}}catch(V){let z=r(V);return e.warn(`[Daemon] Failed to observe ${q.id}: ${z}`),Li(D,C,q.id,z)}}))).map((q,U)=>{if(q.status==="fulfilled")return q.value;let K=d[U],W=r(q.reason);return e.warn(`[Daemon] Observation task for ${K.id} rejected unexpectedly: ${W}`),Li(D,C,K.id,W)})}function Ae(d){return()=>{throw Error(`DaemonSocketServer.${d} was called on a test double that did not define it`)}}function Gc(d){return{start:Ae("start"),close:Ae("close"),quiesce:Ae("quiesce"),isListening:Ae("isListening"),evictDeviceInputCache:Ae("evictDeviceInputCache"),getClientConnectionCount:Ae("getClientConnectionCount"),getAcceptedClientConnectionCount:Ae("getAcceptedClientConnectionCount"),drainSessionReleaseNotifications:Ae("drainSessionReleaseNotifications"),liftSessionlessStrokesOn:Ae("liftSessionlessStrokesOn"),liftStrokesHeldByOn:Ae("liftStrokesHeldByOn"),...d}}function vr(d){return new Set((d??"").split(",").map((c)=>c.trim()).filter(Boolean))}function Wc(d,c){return{androidAppearanceSyncDevices:vr(I(f.ANDROID_APPEARANCE_SYNC_DEVICES,d)),androidObservationStreamDevices:vr(I(f.ANDROID_OBSERVATION_STREAM_DEVICES,d)),iosWarmupDevices:vr(I(f.IOS_WARMUP_DEVICES,d)),appearanceSyncEnabled:Lq(I(f.APPEARANCE_SYNC,d)),iosPassiveWorkEnabled:d[c]===void 0}}class yr{settings;isOwned;constructor(d,c){this.settings=d;this.isOwned=c}allows(d,c,w){if(d==="watchos")return!1;if(d==="android"){if(c==="appearance-sync"&&!this.settings.appearanceSyncEnabled)return!1;if(c==="startup-warmup")return!1;let D=c==="appearance-sync"?this.settings.androidAppearanceSyncDevices:this.settings.androidObservationStreamDevices;return this.isOwned(w)||D.has(w)}if(c==="appearance-sync"||!this.settings.iosPassiveWorkEnabled)return!1;return this.isOwned(w)||this.settings.iosWarmupDevices.has(w)}isAppearanceSyncEnabled(){return this.settings.appearanceSyncEnabled}isIosPassiveWorkEnabled(){return this.settings.iosPassiveWorkEnabled}}import{resolve as RI}from"path";var _v=100;function Vc(d){let{timer:c,invalidate:w,notify:D,debounceMs:k=_v}=d,P,C=!1;return Object.assign((F)=>{if(w(),P||C)return;P=c.setTimeout(()=>{P=void 0,D().catch((q)=>{e.warn(`[DeviceStateChangeNotifier] Resource notification failed: ${r(q)}`)})},k)},{dispose:()=>{if(C=!0,P)c.clearTimeout(P),P=void 0}})}function Rr(d){return{appId:d.appId,nodes:d.nodes.map((c)=>({id:c.id,screenName:c.screenName,visitCount:c.visitCount,screenshotPath:c.screenshotPath})),edges:d.edges.map((c)=>({id:c.id,from:c.from,to:c.to,toolName:c.toolName,traversalCount:c.traversalCount})),currentScreen:d.currentScreen}}function Jc(d){return async(c)=>{try{let w=c?await d.exportGraphSummaryForApp(c):await d.exportGraphSummary();return Rr(w)}catch(w){throw e.warn(`[Daemon] Failed to export navigation graph on request: ${w}`),u(w,"Failed to export navigation graph on request")}}}var Fv="to watch stored values";class kr{deps;listenerManagers=new WeakSet;seededStreamManagers=new WeakMap;constructor(d){this.deps=d}listen(d){if(!d)return;this.attach(this.deps.defaultManager());for(let c of this.deps.sessionIds())this.attach(this.deps.managerForSession(c));d.setOnNavigationGraphRequested(Jc({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 w=this.seededStreamManagers.get(c)??new WeakSet;w.add(d),this.seededStreamManagers.set(c,w);for(let D of d.getBuildContexts())if(D.deviceId!==pR)c.pushBuildContextUpdate(D.deviceId,D.appId,{packageId:D.appId,versionCode:D.versionCode,...D.versionKey===void 0?{}:{versionKey:D.versionKey},contentHash:D.contentHash})}if(this.listenerManagers.has(d))return;this.listenerManagers.add(d),d.setBuildContextUpdateListener(({appId:w,deviceId:D,buildContext:k})=>{if(!this.listenerManagers.has(d)||D===pR)return;this.deps.server()?.pushBuildContextUpdate(D,w,k===null?null:{packageId:w,versionCode:k.versionCode,...k.versionKey===void 0?{}:{versionKey:k.versionKey},contentHash:k.contentHash})}),d.setGraphUpdateListener(async()=>{e.info("[Daemon] Navigation graph listener triggered, exporting summary...");try{let w=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=${w.appId}, nodes=${w.nodes.length}, edges=${w.edges.length}`);let D=Rr(w),k=d.getDeviceIdForApp(w.appId);this.deps.server()?.pushNavigationGraphUpdate(D,k),e.info(`[Daemon] Pushed navigation graph update: ${w.nodes.length} nodes, ${w.edges.length} edges`)}catch(w){e.warn(`[Daemon] Failed to push navigation graph update: ${w}`)}})}}function bt(d,c,w){if(!cr(d)){e.info(`[Daemon] Skipping observation-stream ${w} for ${d} device ${c}: watchOS devices have no observation stream`);return}let D=d==="android"?f.ANDROID_OBSERVATION_STREAM_DEVICES.name:f.IOS_WARMUP_DEVICES.name;e.info(`[Daemon] Skipping observation-stream ${w} for ${d} device ${c}: passive-work policy filtered it; set ${D} to opt in`)}function Nv(d,c,w){let D=d.sessionManager.getSessionForDevice(c)??O(d.devicePool.getDevice(c));if(!D)return!1;let k=(P)=>st(P,d.sessionManager);return k(D)!==k(w?.trim()||void 0)}async function zc(d,c,w){let D=c.id;if(Nv(d,D,w))return!0;if(d.sessionManager.getSessionForDevice(D)??O(c))return!1;let k=c.platform,P=w?.trim()||void 0;try{return await Zv({action:"observe",deviceId:D,platform:k,requesterSessionUuid:P,sessionManager:d.sessionManager,gate:d.devicePool}),await Xm({deviceId:D,platform:k,gate:d.devicePool}),!1}catch(C){if(C instanceof mi||C instanceof Gt)e.debug(`[Daemon] observation of ${D} is read-only: ${r(C)}`);else e.warn(`[Daemon] ownership of ${D} unreadable; observation is read-only: ${r(C)}`,C);return!0}}async function Yc(d,{deviceId:c,sessionUuid:w,packageName:D,fileName:k,subscribe:P}){let C=d.devicePool.getAllDevices().filter((q)=>c===null||q.id===c),M=[],F=An("observationStream",{allowObserverSessions:!0});for(let q of C){if(q.platform!=="android")continue;try{F.authorize({sessionUuid:w,deviceId:q.id,admitViewer:!0})}catch(K){M.push(r(K));continue}if(P)try{d.devicePool.assertDeviceActionable(q.id,Fv)}catch(K){M.push(r(K));continue}let U=E.getExistingInstance(q.id);if(!U)continue;if(P)await U.subscribeStorage(D,k);else await U.unsubscribeStorage(`${D}:${k}`)}if(M.length>0)throw new t(M.join("; "))}function Xc(d,c){let w=x.getInstance(d);return{ensureConnected:async()=>{let D=await w.ensureConnected(),k=c();if(D&&k)w.refreshObservationStreamHierarchyCadence(k.getHierarchyIntervalMsForDevice(d.deviceId));return D},getLatestHierarchy:(...D)=>w.getLatestHierarchy(...D),requestHierarchySyncWithoutObservationStreamPush:async(...D)=>{let k=await w.requestHierarchySyncWithoutObservationStreamPush(...D);return k?{hierarchy:k.hierarchy,...k.frameContext===void 0?{}:{frameContext:k.frameContext}}:null},convertToViewHierarchyResult:(D)=>w.convertToViewHierarchyResult(D),recordInitialObservationStreamHierarchy:(D,k)=>w.recordInitialObservationStreamHierarchy(D,k),requestScreenshotWithoutObservationStreamPush:(...D)=>w.requestScreenshotWithoutObservationStreamPush(...D)}}class Ar{misses;missIncarnations;confirmedDisconnectedIds;forceDisconnectedIds;forceDisconnectedGenerations;offlineRecoveryAttemptedIds;offlineRecoveryAttemptedIncarnations;offlineEpisodes;constructor(d={}){this.misses=d.misses??new VM,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 Pr{inProgress=!1;releaseNotifications=null;fallbackReleaseNotifications=null}class Ir{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 Tr{deviceClaimMirrors=new Ir;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 $v,randomBytes as Hv,timingSafeEqual as qv}from"crypto";import{closeSync as Qc,constants as Zc,fchmodSync as Uv,fstatSync as Kv,lstatSync as Mr,readdirSync as Wv,linkSync as Vv,mkdtempSync as Jv,rmdirSync as jv,mkdirSync as zv,openSync as el,readFileSync as Yv,renameSync as tl,rmSync as Xv,unlinkSync as Qv,writeFileSync as ey}from"fs";import{basename as ty,join as ny,dirname as il}from"path";var ry=60000;function nl(d){return d?d.next():Hv(32).toString("base64url")}class Or{path;idGen;publishedToken;removalFiles;platform;renameFile;sleep;now;constructor(d=cg("token"),c=B,w={}){this.path=d;this.idGen=c;this.removalFiles=w.removalFiles??{createDirectory:Jv,list:Wv,inspect:(D)=>Mr(D,{throwIfNoEntry:!1}),move:(D,k)=>{this.assertTarget(D),tl(D,k)},read:(D)=>this.readAt(D),restore:Vv,remove:Qv,removeDirectory:jv},this.platform=w.platform??process.platform,this.now=w.now??Date.now,this.renameFile=w.renameFile??tl,this.sleep=w.sleep??((D)=>{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,D)})}assertTarget(d=this.path){let c=Mr(d,{throwIfNoEntry:!1});if(c&&(!c.isFile()||c.isSymbolicLink()))throw Error("Unsafe daemon HTTP token file")}observeDestination(){let d=Mr(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(),w=Q({initialDelayMs:10,maxDelayMs:100});for(let D=1;;D++){if(this.assertTarget(),D>1&&this.observeDestination()!==c)throw new t("Daemon HTTP token file changed while publication was retrying; another daemon may own it");try{this.renameFile(d,this.path);return}catch(k){let P=k instanceof Error&&"code"in k?k.code:void 0;if(this.platform!=="win32"||D>=5||P!=="EPERM"&&P!=="EBUSY"&&P!=="EACCES")throw u(k,"Unable to persist daemon HTTP token");e.debug("Retrying daemon HTTP token publication after a sharing violation"),this.sleep(w.delayForAttempt(D))}}}write(d){let c=`${this.path}.${this.idGen.next()}.tmp`,w=!1;try{zv(il(this.path),{recursive:!0,mode:448}),this.assertTarget();let D=el(c,"wx",384);w=!0;try{if(process.platform!=="win32")Uv(D,384);ey(D,d,"utf8")}finally{Qc(D)}this.publish(c),w=!1,this.publishedToken=d.trim(),this.sweepRemovalDirectories()}catch(D){throw e.warn("Unable to persist daemon HTTP token"),u(D,"Unable to persist daemon HTTP token")}finally{if(w)try{Xv(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=el(d,Zc.O_RDONLY|(process.platform==="win32"?0:Zc.O_NOFOLLOW));let w=Kv(c);if(!w.isFile()||process.platform!=="win32"&&(w.uid!==process.getuid?.()||(w.mode&4095)!==384)){e.debug("Daemon HTTP token file permissions unavailable");return}return Yv(c,"utf8").trim()||void 0}catch{e.debug("Daemon HTTP token file unavailable");return}finally{if(c!==void 0)try{Qc(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()-ry&&(this.platform==="win32"||d.uid===process.getuid?.()&&(d.mode&4095)===448)}sweepRemovalDirectories(){let d=this.removalFiles;try{let c=il(this.path),w=`${ty(this.path)}.remove-`;for(let D of d.list(c)){if(!D.startsWith(w)||!/^[A-Za-z0-9]{6}$/.test(D.slice(w.length)))continue;let k=ny(c,D),P=d.inspect(k);if(this.isStaleRemovalDirectory(P))this.cleanClaim(k)}}catch{e.debug("Daemon HTTP token stale claim cleanup unavailable")}}remove(){let d=this.publishedToken;if(this.publishedToken=void 0,!d)return;let c=this.removalFiles,w;try{w=c.createDirectory(`${this.path}.remove-`);let D=`${w}/token`;if(c.move(this.path,D),!sl(c.read(D)??"",d)){let k=c.inspect(D);if(k?.isFile()&&!k.isSymbolicLink())c.restore(D,this.path)}}catch{e.debug("Daemon HTTP token file removal unavailable")}finally{if(w)this.cleanClaim(w)}}}function rl(d,c){let w=d?.slice(0,7).toLowerCase()==="bearer "?d.slice(7):"";return sl(w,c)}function sl(d,c){let w=(k)=>$v("sha256").update(k).digest();return qv(w(d),w(c))&&d.length>0&&c.length>0}import{createServer as py}from"http";class Pe extends Error{timeoutMs;phase;startupMs;constructor(d,c="query",w){super(`Database health probe timed out after ${d}ms`);this.timeoutMs=d;this.phase=c;this.startupMs=w;this.name="DatabaseHealthProbeTimeoutError"}}class $i extends Pe{constructor(d){super(d,"init",0);this.name="DatabaseHealthProbeInitTimeoutError",this.message=`Database health probe worker did not become ready within ${d}ms`}}import{Worker as ay}from"worker_threads";var dy=1000,cy=1e4,ly=50,uy=`
|
|
3
|
+
const { parentPort, workerData } = require("node:worker_threads");
|
|
4
|
+
const { Database } = require("bun:sqlite");
|
|
5
|
+
const db = new Database(workerData.dbPath, { readonly: true, create: false });
|
|
6
|
+
db.exec("PRAGMA busy_timeout = " + Number(workerData.sqliteBusyTimeoutMs) + ";");
|
|
7
|
+
parentPort.on("message", (request) => {
|
|
8
|
+
try {
|
|
9
|
+
db.query("SELECT 1 as ok").get();
|
|
10
|
+
parentPort.postMessage({ id: request.id, ok: true });
|
|
11
|
+
} catch (error) {
|
|
12
|
+
parentPort.postMessage({
|
|
13
|
+
id: request.id,
|
|
14
|
+
ok: false,
|
|
15
|
+
message: error instanceof Error ? error.message : String(error),
|
|
16
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
parentPort.postMessage({ type: "ready" });
|
|
21
|
+
`;class xr{timer;getMigrationsError;executeSelectOne;getDatabasePath;timeoutMs;initTimeoutMs;sqliteBusyTimeoutMs;workerFactory;worker=null;workerRequestId=0;pendingRequest=null;constructor(d={}){this.timer=d.timer??i,this.getMigrationsError=d.getMigrationsError??I9,this.getDatabasePath=d.getDatabasePath??Dp,this.timeoutMs=d.timeoutMs??dy,this.initTimeoutMs=d.initTimeoutMs??cy,this.sqliteBusyTimeoutMs=d.sqliteBusyTimeoutMs??ly,this.workerFactory=d.workerFactory??((c,w)=>new ay(c,{eval:!0,workerData:w})),this.executeSelectOne=d.executeSelectOne}async check(){let d=this.getMigrationsError();if(d)throw d;let c=this.timer.monotonicNow?.()??this.timer.now(),w=this.executeSelectOne?void 0:this.getWorker(),D=0;if(w&&!w.ready)await l(w.readiness,{timer:this.timer,timeoutMs:this.initTimeoutMs,unref:!0,label:"Database health probe worker initialization",timeoutError:()=>new $i(this.initTimeoutMs),onTimeout:()=>{e.warn(`Database health probe worker init timed out after ${this.timer.now()-w.startedAt}ms (init budget ${this.initTimeoutMs}ms)`),this.abandonPendingWorkerRequest(w,new $i(this.initTimeoutMs))}}),D=Math.max(0,(this.timer.monotonicNow?.()??this.timer.now())-c);await l(()=>this.executeSelectOne?.()??this.executeSelectOneInWorker(w),{timer:this.timer,timeoutMs:this.timeoutMs,unref:!0,label:"Database health probe",timeoutError:()=>new Pe(this.timeoutMs,"query",D),onTimeout:()=>{if(w)this.abandonPendingWorkerRequest(w,new Pe(this.timeoutMs,"query",D))}})}async dispose(){let d=this.worker;this.worker=null;let c=Error("Database health probe disposed");if(d?.rejectReady(c),this.pendingRequest){let w=this.pendingRequest;this.pendingRequest=null,w.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((w)=>{e.debug("Abandoned database health probe worker termination failed",w)})}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((w,D)=>{this.pendingRequest={resolve:w,reject:D},d.worker.postMessage({id:c})})}getWorker(){if(this.worker)return this.worker;let d=this.timer.now(),c=this.workerFactory(uy,{dbPath:this.getDatabasePath(),sqliteBusyTimeoutMs:this.sqliteBusyTimeoutMs}),w,D,k=new Promise((C,M)=>{w=C,D=M}),P={worker:c,readiness:k,ready:!1,startedAt:d,resolveReady:w,rejectReady:D};return this.worker=P,c.on("message",(C)=>{if(this.worker!==P)return;if("type"in C){if(!P.ready)P.ready=!0,P.resolveReady(),e.debug(`Database health probe worker ready after ${this.timer.now()-P.startedAt}ms`);return}if(!this.pendingRequest||C.id!==this.workerRequestId)return;let M=this.pendingRequest;if(this.pendingRequest=null,C.ok){M.resolve();return}let F=Error(C.message??"Database health probe failed");if(C.stack)F.stack=C.stack;M.reject(F)}),c.on("error",(C)=>{this.rejectWorker(P,C)}),c.on("exit",(C)=>{this.rejectWorker(P,Error(`Database health probe worker exited with code ${C}`))}),P}rejectWorker(d,c){if(this.worker!==d)return;this.worker=null,d.rejectReady(c),this.pendingRequest?.reject(c),this.pendingRequest=null}}function vy(){return Date.now()-Math.max(0,process.uptime()*1000)}function yy(d,c){return{deviceSessionRepository:d.deviceSessionRepository??new vS({timer:c}),idGenerator:d.idGenerator??B,databaseInitializer:d.databaseInitializer??new SU,startupFailureTracker:d.startupFailureTracker??new eM,databaseHealthProbe:d.databaseHealthProbe??new xr({timer:c})}}function Sy(d){return{recoveryPolicyEnvironment:d.recoveryPolicyEnvironment??process.env,processBirthTime:d.processBirthTime??vy,processGenerationToken:d.processGenerationToken??bf,liveDaemonSessionIdProvider:d.liveDaemonSessionIdProvider??new U3,incumbentOwnerGuard:d.incumbentOwnerGuard??new G6}}function wy(d){let c=d.deviceReadiness??Hc.createInstance();return{managedAdbServerShutdown:d.managedAdbServerShutdown??PK,toolSelectionProfileProvenanceLoader:d.toolSelectionProfileProvenanceLoader??IU,httpToken:d.httpToken??"",httpTokenStore:d.httpTokenStore??new Or,httpServerFactory:d.httpServerFactory??(()=>py()),avdManagerFactory:d.avdManagerFactory??(()=>new sy),deviceReadiness:c,iosDeviceVerifier:d.iosDeviceVerifier??(()=>c),bindingExclusionFactory:d.bindingExclusionFactory??wA,daemonState:d.daemonState??nre}}function al(d){let c=d.timer??i;return{...d,timer:c,...yy(d,c),...Sy(d),...wy(d)}}class Nr{store;idGenerator;token;published=!1;constructor(d,c,w=""){this.store=d;this.idGenerator=c;this.token=w}get isPublished(){return this.published}get value(){return this.token}prepare(){this.published=!1,this.token=nl(this.idGenerator)}publish(){if(!this.token)throw new t("Daemon HTTP token is not configured");this.store.write(this.token),this.published=!0}remove(){if(this.published)this.store.remove(),this.published=!1;this.token=""}}function dl(){let d,c;return{promise:new Promise((D,k)=>{d=D,c=k}),resolve:d,reject:c}}var wt=25,kt=1000,At=5000,pl=R4,cl=new WeakMap;class Me{closing=new AbortController;backoff;shared;options;constructor(d){this.options={...d,initialDelayMs:d.initialDelayMs??wt,maxDelayMs:d.maxDelayMs??kt,maxBlockedWaitMs:d.maxBlockedWaitMs??At},this.backoff=d.backoff??Q(this.options);let c=cl.get(d.timer);if(!c)c={quietUntilMs:0,queue:[]},cl.set(d.timer,c);this.shared=c}close(){this.closing.abort()}delay(d){try{let c=this.backoff.delayForAttempt(d);if(!Number.isFinite(c))throw Error(`Registry retry backoff delay must be finite, got ${c}`);return Math.min(Math.max(c,this.options.initialDelayMs),this.options.maxDelayMs)}catch(c){if(!this.closing.signal.aborted)e.debug(`[Bindings] Registry retry backoff failed; using the cap: ${r(c)}`,c);return this.options.maxDelayMs}}async wait(d,c,w){let D,k,P=this.signal(c),C=()=>{if(D!==void 0)this.options.timer.clearTimeout(D)};P.addEventListener("abort",C,{once:!0});try{await l(()=>new Promise((M)=>{if(k=M,w?.addEventListener("abort",k,{once:!0}),w?.aborted)M();else D=this.options.timer.setTimeout(M,d)}),{timer:this.options.timer,signal:P,label:"Registry retry wait"})}finally{if(P.removeEventListener("abort",C),k)w?.removeEventListener("abort",k);if(D!==void 0)this.options.timer.clearTimeout(D)}}async run(d,c,w,D){let k=this.signal(w);k.throwIfAborted();let P=Promise.withResolvers(),C={resolve:P.resolve,reject:P.reject,expedited:D,started:!1},M=()=>this.schedule(),F=()=>{if(P.reject(k.reason),this.removeQueued(C),this.shared.active===C&&!C.started)this.shared.active=void 0;this.schedule()};k.addEventListener("abort",F,{once:!0}),D?.addEventListener("abort",M,{once:!0}),this.shared.queue.push(C);let q,U=!0;try{this.schedule(),await P.promise,k.throwIfAborted(),C.started=!0,q=this.options.timer.now();let K=await l(d,{timer:this.options.timer,signal:k,label:"Registry retry operation"});return U=!c(K),K}finally{if(k.removeEventListener("abort",F),D?.removeEventListener("abort",M),U&&q!==void 0)this.extendQuietPeriod(q);if(this.removeQueued(C),this.shared.active===C)this.shared.active=void 0;this.schedule()}}removeQueued(d){let c=this.shared.queue.indexOf(d);if(c!==-1)this.shared.queue.splice(c,1)}schedule(){let d=this.shared,c=this.options.timer,w=(P)=>P.expedited?.aborted||c.now()>=d.quietUntilMs,D=d.active?void 0:d.queue.find(w),k=!d.active&&!D&&d.queue.length>0;try{this.updateQuietTimer(k)}catch(P){e.warn(`[Bindings] Registry retry quiet timer failed: ${r(P)}`,P);for(let C of[...d.queue])if(!w(C))this.removeQueued(C),C.reject(P)}if(D)this.removeQueued(D),d.active=D,D.resolve()}updateQuietTimer(d){let c=this.shared,w=this.options.timer;if(!d||c.wakeAtMs!==c.quietUntilMs){if(c.quietTimer!==void 0){let D=c.quietTimer;c.quietTimer=void 0,c.wakeAtMs=void 0,w.clearTimeout(D)}}if(d&&c.quietTimer===void 0){let D=w.setTimeout(()=>{if(c.quietTimer!==D)return;c.quietTimer=void 0,c.wakeAtMs=void 0,this.schedule()},c.quietUntilMs-w.now());c.quietTimer=D,c.wakeAtMs=c.quietUntilMs}}noteBlocked(d){this.extendQuietPeriod(d)}extendQuietPeriod(d){if(this.closing.signal.aborted)return;let c=this.options.timer.now();this.shared.quietUntilMs=Math.max(this.shared.quietUntilMs,c+Math.min(Math.max(0,c-d),this.options.maxBlockedWaitMs)),this.schedule()}signal(d){return d?AbortSignal.any([this.closing.signal,d]):this.closing.signal}}var ml=500,Ee=700,hl=250,vl=300000,Sl=30000,Lr=Q({initialDelayMs:250,maxDelayMs:5000}),bl=256,wl="managed-execution-release",$r=wt,Hr=kt,qr=At,Rl=5000;function Kr(){return{marked:[],owed:[],stamped:new Set,stampWarned:!1}}function Se(d){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex}}function Hi(d,c){return{scopeKey:d.scopeKey,bindingIndex:d.bindingIndex,role:d.role,platform:d.platform,generation:d.generation,stableDeviceId:d.stableDeviceId,deviceName:d.deviceName,state:d.state,execOwnerReleased:c}}function qi(d,c){let w=(D)=>d.getSession(D)?.assignedDevice??d.getReleasingSession(D)?.assignedDevice??d.getTerminalReleaseSnapshot(D)?.deviceId??null;return{isSessionLive:(D)=>d.hasSession(D)||d.getReleasingSession(D)!==null,deviceOf:w,getKeepAwakeRestoreReport:(D)=>d.getKeepAwakeRestoreReport?.(D),releaseSession:async(D)=>{let k=w(D);return await xs({manager:d,pool:c},k,D,{release:async()=>(k=await d.releaseSession(D),k)}),k},forceStuckRelease:async(D)=>{let k=!1;return await YH({forceStuckRelease:(P)=>{let C=d.forceStuckRelease(P);return k=C!==void 0,C}},c,D),k},hasDeviceCleanupInProgress:(D)=>d.hasDeviceCleanupInProgress(D)}}async function Al(d,c,w,D){let k;try{k=await Ry(d,c,w)}catch(C){let M=await Dl(d,c,w);if(M===null)throw C;let F=Se(w);return d.warn(`[BrokerExecutionRelease] Marking binding ${F.scopeKey}/${F.bindingIndex} settling failed after the mark was written; going on from the written mark: ${r(C)}`,C),M}if(!("refused"in k))return k;let P=await Dl(d,c,w);if(P===null)D.push({...Se(w),error:`could not mark settling: ${k.refused}`});return P}async function Ry(d,c,w){let D=await Dy(d,c,w);if(D!=="unjournaled")return D;let k=Se(w),P=await c.updateBindingState(k,{generation:w.generation,stableDeviceId:w.stableDeviceId},"settling",{settler:d.settlerIdentity()});if(P.kind!=="updated")return{refused:P.kind};return{key:k,execOwner:P.assignment.execOwner,generation:P.assignment.generation,stableDeviceId:P.assignment.stableDeviceId}}async function Dl(d,c,w){let D=Se(w),k=d.settlerIdentity(),P=await c.getAssignment(D);if(P===null||P.state!=="settling"||P.settler===null||!Uc(P.settler,k)||P.stableDeviceId!==w.stableDeviceId||P.generation!==w.generation+1)return null;let C={key:D,execOwner:P.execOwner,generation:P.generation,stableDeviceId:P.stableDeviceId},M=d.options.journal;if(!M)return C;let F=(await c.listOpenBindingJournal(D)).find((q)=>q.kind==="release"&&Uc(q.owner,k));if(!F)return C;return M.inFlight.add(F.id),{...C,journalEntryId:F.id}}async function Dy(d,c,w){let D=d.options.journal;if(!D)return"unjournaled";let k=Se(w),P=d.settlerIdentity(),C=await c.openBindingJournal(k,{kind:"release",phase:"intent",owner:P,target:{oldStableId:w.stableDeviceId,oldName:w.deviceName,newName:null,newStableId:null,requestedSpec:w.requestedSpec,resolvedSpec:w.resolvedSpec,specFingerprint:w.specFingerprint},assignment:{kind:"state",expected:{generation:w.generation,stableDeviceId:w.stableDeviceId},state:"settling",options:{settler:P}}});if(C.kind==="opened")return D.inFlight.add(C.entry.id),{key:k,execOwner:C.assignment.execOwner,generation:C.assignment.generation,stableDeviceId:C.assignment.stableDeviceId,journalEntryId:C.entry.id};if(C.kind==="journal_open")return"unjournaled";return{refused:C.kind}}class Gr{ctx;inFlight=new Set;constructor(d){this.ctx=d}async clearLeftover(d,c,w){if(w===null)return!0;if(this.ctx.isExecOwnerLive(w))return!1;try{await d.releaseExecution(c,w.sessionUuid)}catch(D){this.ctx.warn(`[BrokerExecutionRelease] Retrying the owner clear of binding ${c.scopeKey}/${c.bindingIndex} for ended session ${w.sessionUuid} failed; the binding still returns to ready and the clear is retried: ${r(D)}`,D),this.ctx.track(this.retry(d,c,w.sessionUuid))}return!0}async retry(d,c,w){let D=`${c.scopeKey}/${c.bindingIndex}/${w}`;if(this.ctx.isClosed()||this.inFlight.has(D))return;this.inFlight.add(D);let{timer:k}=this.ctx,P=k.now()+this.ctx.settlementCapMs;try{for(;;){if(await k.sleep(this.ctx.settlementPollMs),this.ctx.isClosed())return;let C=await this.ctx.retrier.run(`Clearing the owner of binding ${c.scopeKey}/${c.bindingIndex} for ended session ${w}`,P,()=>this.clearEndedOnce(d,c,w));if(!C.done||C.value==="done"||k.now()+this.ctx.settlementPollMs>P)return}}finally{this.inFlight.delete(D)}}async clearEndedOnce(d,c,w){let D=(await d.getAssignment(c))?.execOwner??null;if(D===null||D.sessionUuid!==w||this.ctx.isClosed())return"done";if(this.ctx.isSessionLive(w)||this.ctx.isExecOwnerLive(D))return"owner_live";return await d.releaseExecution(c,w),"done"}}class Wr{ctx;constructor(d){this.ctx=d}async run(d,c,w,{stopWhen:D,schedule:k}={}){if(k?.fastRecovery)return this.runRecovery(d,w);let{timer:P}=this.ctx,C=!1,M=await this.ctx.registryRetry.execute(w,{maxAttempts:Number.MAX_SAFE_INTEGER,signal:this.ctx.closing,shouldRetry:()=>!(D?.()??!1),delays:(F)=>P.now()>=c?this.ctx.settlementSlowPollMs:this.ctx.backoff.delayForAttempt(F),onRetry:(F,q,U)=>{if(q===1)this.ctx.warn(`[BrokerExecutionRelease] ${d} failed; retrying in ${U}ms: ${F.message}`,F);if(P.now()>=c&&!C)C=!0,this.ctx.warn(`[BrokerExecutionRelease] ${d} has kept failing past the ${this.ctx.settlementCapMs}ms settlement cap; it is retried every ${this.ctx.settlementSlowPollMs}ms until the registry recovers. a daemon restart (its settled-binding recovery) also recovers the binding: `+F.message,F)},expectedFailure:{reason:"the drain reports why it stopped retrying a registry step"}});if(M.success)return{done:!0,value:M.value};if(!this.ctx.isClosed())this.ctx.warn(`[BrokerExecutionRelease] ${d} failed and is no longer needed, so it is not retried: ${r(M.error)}`,M.error);return{done:!1}}async runRecovery(d,c){let w=this.ctx.timer.now(),D=0,k=!1,P;while(!this.ctx.isClosed()){D++;try{let C=await this.ctx.recoveryPacing.run(async()=>{let M=!1;try{return await l(()=>(P??=c(),P),{timer:this.ctx.timer,timeoutMs:this.ctx.recoveryTurnBudgetMs,signal:this.ctx.closing,label:d,onTimeout:()=>{M=!0}})}finally{if(!M)P=void 0}},()=>!0);if(this.ctx.isClosed())return{done:!1};if(D>1)e.info(`[BrokerExecutionRelease] ${d} resolved after ${this.ctx.timer.now()-w} ms (${D} attempts)`);return{done:!0,value:C}}catch(C){if(this.ctx.isClosed())return{done:!1};if(e.debug(`[BrokerExecutionRelease] ${d} failed: ${r(C)}`,C),!k&&this.ctx.timer.now()-w>this.ctx.recoveryWarnAfterMs)k=!0,this.ctx.warn(`[BrokerExecutionRelease] ${d} still failing after ${this.ctx.timer.now()-w} ms (${D} attempts): ${r(C)}`,C)}try{await this.ctx.recoveryPacing.wait(this.ctx.recoveryPacing.delay(D))}catch(C){if(!this.ctx.isClosed())e.debug(`[BrokerExecutionRelease] Recovery retry wait cancelled: ${r(C)}`,C);return{done:!1}}}return{done:!1}}}class Vr{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??lc,this.drainBudgetMs=d.drainBudgetMs??ml,this.releaseBudgetMs=d.releaseBudgetMs??Ee,this.settlementPollMs=d.settlementPollMs??hl,this.settlementCapMs=d.settlementCapMs??vl,this.settlementSlowPollMs=d.settlementSlowPollMs??Sl,this.recoveryPacing=new Me({timer:d.timer,initialDelayMs:$r,maxDelayMs:Hr,maxBlockedWaitMs:qr}),this.ownerHolds=d.ownerHolds??e0,this.retrier=new Wr({timer:d.timer,registryRetry:new wn(d.timer),recoveryPacing:this.recoveryPacing,backoff:d.registryRetryBackoff??Lr,closing:this.closing.signal,isClosed:()=>this.closed,warn:(c,w)=>this.warn(c,w),settlementCapMs:this.settlementCapMs,settlementSlowPollMs:this.settlementSlowPollMs,recoveryTurnBudgetMs:Ee,recoveryWarnAfterMs:Rl}),this.ownerClearer=new Gr({timer:d.timer,retrier:this.retrier,isExecOwnerLive:this.isExecOwnerLive,isSessionLive:(c)=>this.options.sessions.isSessionLive(c),isClosed:()=>this.closed,warn:(c,w)=>this.warn(c,w),track:(c)=>this.track(c),settlementCapMs:this.settlementCapMs,settlementPollMs:this.settlementPollMs})}releaseExecution(d){let c=this.driven.get(d);if(c)return c;let w=this.drainAndRelease(d).finally(()=>{this.driven.delete(d)});return this.driven.set(d,w),w}onSessionReleased(d,c){if(c?.upgradeOnly||d.livenessPolicy!==Xn||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,w=await this.options.registry(),D=await w.findExecutionAssignments(d),k=c.isSessionLive(d);if(D.length===0&&!k)return this.reportReleased(w,d);this.rememberBindings(d,D);let P=c.deviceOf(d),C=this.holdOwner(d,P);try{return await this.drainHeldBindings(w,d,D,{live:k,device:P})}finally{C()}}async drainHeldBindings(d,c,w,{live:D,device:k}){let{cancellationRequested:P,drained:C}=await this.cancelAndDrain(c),M=[],F=Kr();if(!C)await this.markSettling(d,c,w,{failures:M,marks:F});let q=D?await this.releaseSessionWithinBudget(c,k):{releasedDevice:k,releaseSettled:!0,releaseForced:!1},{releasedDevice:U,releaseForced:K}=q,W=C&&q.releaseSettled&&this.isSettled(c,U);if(!W&&C)await this.markSettling(d,c,w,{failures:M,marks:F});let V=await this.releaseOwnership(d,c,w,{failures:M,owed:F.owed});if(F.marked.length>0)this.track(this.settleLater(d,c,U,F.marked));if(F.owed.length>0){let z=this.holdOwner(c,U);this.track(this.settleOwedMarks(d,c,U,{first:F,releaseHold:z}))}return{...this.keepAwakeRestoreResult(c),...await IN(c),...await _N(c),sessionId:c,outcome:W?"reusable_for_this_binding":"cleanup_pending",settlement:W?"confirmed":"settling",alreadyReleased:!D,cancellationRequested:P,releaseForced:K,device:U,bindings:V,bindingFailures:M}}async cancelAndDrain(d){let{work:c}=this.options,w=await c.cancelDeviceSessionExecutions(d,wl);if(w===0&&!c.hasActiveDeviceSessionExecutions(d))return{cancellationRequested:w,drained:!0};let D=await c.waitForDeviceSessionExecutionsToEnd(d,this.drainBudgetMs);return{cancellationRequested:w,drained:D}}async reportReleased(d,c){let w=this.recentBindings.get(c)??[],D=(await Promise.all(w.map((P)=>d.getAssignment(P)))).filter((P)=>P!==null),k=this.options.work.hasActiveDeviceSessionExecutions(c)||D.some((P)=>P.state==="settling");return{...this.keepAwakeRestoreResult(c),...await IN(c),...await _N(c),sessionId:c,outcome:k?"cleanup_pending":"reusable_for_this_binding",settlement:k?"settling":"confirmed",alreadyReleased:!0,cancellationRequested:0,releaseForced:!1,device:null,bindings:D.map((P)=>Hi(P,!1)),bindingFailures:[]}}async releaseSessionWithinBudget(d,c){let{sessions:w,timer:D}=this.options,k=w.releaseSession(d);try{return{releasedDevice:await l(k,{timer:D,timeoutMs:this.releaseBudgetMs,unref:!0,label:`Managed execution release of session ${d}`})??c,releaseSettled:!0,releaseForced:!1}}catch(C){if(this.options.ownership?.isReleaseHeld(d))return e.debug(`[BrokerExecutionRelease] Session ${d} release awaits ownership; settlement continues within its hold cap`,C),{releasedDevice:c,releaseSettled:!1,releaseForced:!1};this.warn(`[BrokerExecutionRelease] Session ${d} release did not finish within ${this.releaseBudgetMs}ms; forcing it into the stuck-release quarantine: `+r(C),C)}let P=!1;try{P=await w.forceStuckRelease(d)}catch(C){this.warn(`[BrokerExecutionRelease] Forcing the stuck release of ${d} failed: `+r(C),C)}return{releasedDevice:c,releaseSettled:!1,releaseForced:P}}isSettled(d,c){return!this.options.work.hasActiveDeviceSessionExecutions(d)&&(c===null||!this.options.sessions.hasDeviceCleanupInProgress(c))}async releaseBindingsAfterExternalRelease(d,c){let w=this.holdOwner(d,c);try{let D=await this.retrier.run(`Finding the bindings of released session ${d}`,this.options.timer.now()+this.settlementCapMs,async()=>{if(this.isSettled(d,c))w();let q=await this.options.registry();return{registry:q,held:await q.findExecutionAssignments(d)}});if(!D.done||D.value.held.length===0)return;let{registry:k,held:P}=D.value;this.rememberBindings(d,P);let C=[],M=Kr();if(!this.isSettled(d,c))await this.markSettling(k,d,P,{failures:C,marks:M});await this.releaseOwnership(k,d,P,{failures:C,owed:M.owed});for(let q of C)this.warn(`[BrokerExecutionRelease] Binding ${q.scopeKey}/${q.bindingIndex} bookkeeping after the release of ${d} failed: ${q.error}`);let F=M.owed.length>0?this.holdOwner(d,c):void 0;w(),await Promise.all([M.marked.length>0?this.settleLater(k,d,c,M.marked):void 0,F?this.settleOwedMarks(k,d,c,{first:M,releaseHold:F}):void 0])}finally{w()}}async markSettling(d,c,w,{failures:D,marks:k}){await this.stampOwners(d,c,w,k),(await Promise.allSettled(w.map((C)=>this.markBinding(d,C,D)))).forEach((C,M)=>{if(C.status==="rejected")D.push({...Se(w[M]),error:`could not mark settling: ${r(C.reason)}; the binding keeps its owner record and the mark is retried`}),k.owed.push(w[M]);else if(C.value){if(k.marked.push(C.value),C.value.execOwner?.sessionUuid===c)this.options.ownership?.confirmOwnership(c)}})}async stampOwners(d,c,w,D){let k=this.settlerIdentity();(await Promise.allSettled(w.map(async(C)=>{let M=C.execOwner;if(D.stamped.has(C)||M===null||M.sessionUuid!==c||Uc(M,k))return M?.sessionUuid===c&&Uc(M,k);let F=await d.claimExecution(Se(C),{generation:C.generation,stableDeviceId:C.stableDeviceId},{...k,sessionUuid:c},{supersedesSessionUuid:c});if(F.kind==="binding_in_use")this.options.ownership?.loseOwnership?.(c);return F.kind==="claimed"}))).forEach((C,M)=>{if(C.status==="fulfilled"){if(D.stamped.add(w[M]),C.value)this.options.ownership?.confirmOwnership(c)}else if(!D.stampWarned){D.stampWarned=!0;let F=Se(w[M]);this.warn(`[BrokerExecutionRelease] Binding ${F.scopeKey}/${F.bindingIndex} of released session ${c} still names another daemon as its owner and could not be re-stamped; it is retried with the settling mark: ${r(C.reason)}`,C.reason)}})}async markBinding(d,c,w){return Al({warn:this.warn.bind(this),settlerIdentity:this.settlerIdentity.bind(this),options:this.options},d,c,w)}async settleOwedMarks(d,c,w,{first:D,releaseHold:k}){let P=[...D.owed],C={...D,marked:[],owed:[...P]},M=()=>this.isSettled(c,w);try{if(await this.retrier.run(`Marking the bindings of released session ${c} settling`,this.options.timer.now()+this.settlementCapMs,async()=>{if(M())return;let q=[],U=C.owed;if(C.owed=[],await this.markSettling(d,c,U,{failures:q,marks:C}),C.owed.length>0)throw Error(q.map((K)=>K.error).join("; "));for(let K of q)this.warn(`[BrokerExecutionRelease] Binding ${K.scopeKey}/${K.bindingIndex} of released session ${c}: ${K.error}`)},{stopWhen:M}),this.closed)return;let F=[];await this.releaseOwnership(d,c,P,{failures:F,owed:[]});for(let q of F)this.warn(`[BrokerExecutionRelease] Clearing the owner of binding ${q.scopeKey}/${q.bindingIndex} for released session ${c} failed; the dead record pins nothing in this daemon (#11339) and the clear is retried: ${q.error}`)}finally{k()}if(C.marked.length>0)await this.settleLater(d,c,w,C.marked)}async releaseOwnership(d,c,w,{failures:D,owed:k}){return(await Promise.allSettled(w.map(async(C)=>k.includes(C)?{released:!1,assignment:C}:d.releaseExecution(Se(C),c)))).flatMap((C,M)=>{if(C.status==="rejected")return D.push({...Se(w[M]),error:r(C.reason)}),this.track(this.ownerClearer.retry(d,Se(w[M]),c)),[Hi(w[M],!1)];let F=C.value.assignment??w[M];return[Hi(F,C.value.released)]})}async settleLater(d,c,w,D){let{timer:k}=this.options,P=k.now()+this.settlementCapMs,C=!1;while(!this.isSettled(c,w)){if(this.closed)return;if(!C&&k.now()>=P)C=!0,this.warn(`[BrokerExecutionRelease] Work of released session ${c} did not settle within ${this.settlementCapMs}ms; its bindings stay settling and are re-checked every ${this.settlementSlowPollMs}ms until the work settles (#11336)`);await k.sleep(C?this.settlementSlowPollMs:this.settlementPollMs)}await this.restoreOnceUnowned(d,D,P)}async restoreOnceUnowned(d,c,w){let D=(await Promise.all(c.map((P)=>this.restoreBindingOnceUnowned(d,P,w)))).filter((P)=>P!==null);if(D.length===0)return;let k=D.map((P)=>`${P.key.scopeKey}/${P.key.bindingIndex}`).join(", ");this.warn(`[BrokerExecutionRelease] A live execution still holds the owner record of settled binding(s) ${k} past the ${this.settlementCapMs}ms settlement cap; they stay settling. Once that execution ends, a daemon restart (its settled-binding recovery) returns them to ready (#11545)`)}async restoreBindingOnceUnowned(d,c,w){let{timer:D}=this.options;for(;;){if(await this.restoreReady(d,c,w)==="done"||this.closed)return null;if(D.now()>=w)return c;await D.sleep(this.settlementPollMs)}}async restoreReady(d,c,w){let D=await this.retrier.run(`Returning settled binding ${c.key.scopeKey}/${c.key.bindingIndex} to ready`,w,()=>this.restoreReadyOnce(d,c));return D.done?D.value:"done"}async restoreReadyOnce(d,c){let w=await d.getAssignment(c.key);if(!(w!==null&&w.state==="settling"&&w.generation===c.generation&&w.stableDeviceId===c.stableDeviceId))return await this.closeSupersededEntry(d,c,w),"done";if(!await this.ownerClearer.clearLeftover(d,c.key,w.execOwner))return"owner_live";let k=await this.restoreBindingState(d,c);if(k.kind!=="updated"&&k.kind!=="advanced")this.warn(`[BrokerExecutionRelease] Binding ${c.key.scopeKey}/${c.key.bindingIndex} settled but could not return to ready: ${k.kind}`);return"done"}async restoreBindingState(d,c){let w={generation:c.generation,stableDeviceId:c.stableDeviceId},D=this.options.journal;if(!D||c.journalEntryId===void 0)return d.updateBindingState(c.key,w,"ready");let k=await d.advanceBindingJournal(c.journalEntryId,{owner:this.settlerIdentity(),expectedPhase:"intent",phase:"committed",assignment:{kind:"state",expected:w,state:"ready"}});return D.inFlight.delete(c.journalEntryId),k}async closeSupersededEntry(d,c,w){let D=this.options.journal,k=w?.execOwner??null;if(!D||c.journalEntryId===void 0||k&&this.isExecOwnerLive(k))return;let P=!w||w.generation!==c.generation||w.stableDeviceId!==c.stableDeviceId;await d.advanceBindingJournal(c.journalEntryId,{owner:this.settlerIdentity(),expectedPhase:"intent",phase:P?"rolled_back":"committed"}),D.inFlight.delete(c.journalEntryId)}holdOwner(d,c){let w=this.ownerHoldCounts.get(d)??0;if(this.ownerHoldCounts.set(d,w+1),w===0)this.ownerHolds.add(d);let D=!1;return()=>{if(D||this.closed&&!this.isSettled(d,c))return;D=!0;let k=(this.ownerHoldCounts.get(d)??1)-1;if(k>0){this.ownerHoldCounts.set(d,k);return}this.ownerHoldCounts.delete(d),this.ownerHolds.delete(d)}}settlerIdentity(){return this.settler??=this.options.settler??{daemonId:`pid-${process.pid}`,...Eq()},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>bl){let w=this.recentBindings.keys().next().value;if(w!==void 0)this.recentBindings.delete(w)}}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((w)=>{this.warn(`[BrokerExecutionRelease] Background binding release failed: ${r(w)}`,w)}).finally(()=>{this.background.delete(c)});this.background.add(c)}}function Pl(d,c=`${IS()}.session-broker.lock`){return{acquire:()=>{if(!Fi(c,{pid:d.pid,ownerToken:d.daemonId,ownerGeneration:Ht}))throw new t("Another provider owns session-broker execution on this host; stop it before starting a replacement")},release:()=>ki(c,d.pid,d.daemonId)}}import{createHash as ky}from"crypto";function Pt(d,c){let w=ky("sha256").update(JSON.stringify(c)).digest("hex").slice(0,16);return`${d}:sha256:${w}`}var Jr="android-sdk-installed-catalog",Ay="android-native-catalog-v1";function Il(d){let c=new Set,w=new Set;for(let D of d){if(c.has(D))w.add(D);c.add(D)}return w}function Py(d,c,w,D){let k=c.profileArchetypes[d.id];return{profileId:d.id,...k===void 0?{}:{archetype:k},metadataState:w==="stale"||D||d.id.length===0?"stale":"current"}}function Iy(d){if(d<=1)return"major";return d===2?"minor":"patch"}function Cy(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 Ty(d,c,w){return d==="stale"||c||!w?"stale":"current"}function My(d){let c=zW(d);if(c===void 0)return{versionPrecision:"major"};let w=Uo(c);if(!w.ok)return{versionPrecision:"major"};return{osVersion:w.value.value,versionPrecision:Iy(w.value.precision)}}function Ey(d,c,w){let D=tn(d.packageName),k=Ty(c,w,Cy(d,D)),P=D?.apiLevel??d.apiLevel;return{systemImagePackage:d.packageName,...My(P),apiLevel:P,abi:D?.abi??d.abi,flavor:D?.tag??d.tag,installed:!0,metadataState:k}}function Cl(d,c,w,D={}){let k=D.metadataState??"current",P=Il(d.map((U)=>U.id)),C=Il(c.map((U)=>U.packageName)),M=d.map((U)=>Py(U,w,k,P.has(U.id))).sort((U,K)=>U.profileId.localeCompare(K.profileId)),F=c.map((U)=>Ey(U,k,C.has(U.packageName))).sort((U,K)=>U.systemImagePackage.localeCompare(K.systemImagePackage)),q=Pt(Jr,{adapterVersion:Ay,policy:Object.entries(w.profileArchetypes).sort(([U],[K])=>U.localeCompare(K)),profiles:M,releases:F});return{platform:"android",provenance:{source:Jr,revision:q,state:"ready"},profiles:M,releases:F,hostAbis:OS(D.hostArchitecture??process.arch)}}async function Oy(d,c){let[w,D]=await Promise.allSettled([d.listDevices(c),d.listInstalledSystemImages(void 0,c)]);if(w.status==="rejected")throw w.reason;if(D.status==="rejected")throw D.reason;if(w.value.length===0)throw Error("Android emulator profile catalog returned no profiles.");return[w.value,D.value]}async function jr(d,c,w={}){try{let[D,k]=await Oy(d,w.signal);return Cl(D,k,c,w)}catch(D){if(w.signal?.aborted)throw D;let k=`Unable to read the installed Android emulator catalog: ${r(D)}`;return(w.logger??e).warn(k,D),{platform:"android",provenance:{source:Jr,revision:"unavailable",state:"unavailable",message:k},profiles:[],releases:[]}}}var zr="simctl-installed-catalog",xy="simctl-fields-v1";function _y(d){if(d.family==="duo")return"duo";return d.family==="ipad"?"tablet":"phone"}function Tl(d){if(d===void 0)return;let[c,w]=d.split("."),D=w?.replace(/0+$/,"");return D?`${Number(c)}.${D}`:String(Number(c))}function $y(d,c){if(d===void 0)return{modelType:c,conflict:!1};if(d.family!==c.family||d.variant!==c.variant)return{modelType:d,conflict:!0};if(d.family!=="ipad"||c.family!=="ipad")return{modelType:d,conflict:!1};let w=Tl(d.sizeInches),D=Tl(c.sizeInches);if(w!==void 0&&D!==void 0&&w!==D)return{modelType:d,conflict:!0};return{modelType:w===void 0?c:d,conflict:!1}}function Hy(d){if(/^iPhone (?:\d+ )?Pro Max$/.test(d))return{family:"iphone",variant:"pro-max"};if(/^iPhone (?:\d+ )?Pro$/.test(d))return{family:"iphone",variant:"pro"};if(/^iPhone (?:\d+ )?Air$/.test(d))return{family:"iphone",variant:"air"};return/^iPhone (?:\d+(?:s|c)?(?: Plus| mini|e)?|SE \(\d+(?:st|nd|rd|th) generation\)|X|X\u0280|XR|Xs|XS|Xs Max|XS Max)$/.test(d)?{family:"iphone",variant:"standard"}:void 0}function Uy(d){return/(?:^|[\s(])(\d+(?:\.\d+)?)-inch(?:[\s)]|$)/.exec(d)?.[1]}function Ky(d){let c=Uy(d),w=(D)=>c===void 0?D:{...D,sizeInches:c};if(/^iPad Pro(?:\s|\()/.test(d))return w({family:"ipad",variant:"pro"});if(/^iPad Air(?:\s|\()/.test(d))return w({family:"ipad",variant:"air"});if(/^iPad mini(?:\s|\()/.test(d))return w({family:"ipad",variant:"mini"});if(/^iPad(?:\s+\(|\s+\d|$)/.test(d))return w({family:"ipad",variant:"standard"});return}function Gy(d){if(hs(d.identifier)||d.productFamily==="Duo"||d.name==="iPhone Duo")return{archetype:"duo",modelType:{family:"duo",variant:"duo"},conflict:!1};if(d.productFamily==="iPhone"){let c=Hy(d.name);return{archetype:"phone",...c===void 0?{}:{modelType:c},conflict:!1}}if(d.productFamily==="iPad"){let c=Ky(d.name);return{archetype:"tablet",...c===void 0?{}:{modelType:c},conflict:!1}}return{conflict:!1}}function Wy(d,c){let w=Gy(d),D=c.filter((M)=>M.simulatorDeviceTypeIdentifier===d.identifier);if(D.length>1)return{...w,conflict:!0};let k=D[0];if(!k)return w;let P=_y(k.modelType);if(w.archetype!==void 0&&w.archetype!==P)return{...w,conflict:!0};let C=$y(w.modelType,k.modelType);return{archetype:w.archetype??P,modelType:C.modelType,...C.conflict||k.aliases===void 0?{}:{aliases:k.aliases},conflict:C.conflict}}function Vy(d){if(d===void 0)return;let c=[...new Set(d.filter((w)=>w.length>0))].sort();return c.length===0?void 0:c}function Jy(d,c,w,{classificationConflict:D,malformedBounds:k}){let P=d.identifier.length>0&&d.name.length>0&&d.productFamily.length>0;return c==="stale"||w||D||k||!P?"stale":"current"}function jy(d,c,w,D){let k=Wy(d,c),P=ZI(d),C=XI(d)&&P===void 0,M=Jy(d,w,D,{classificationConflict:k.conflict,malformedBounds:C}),F=Vy(k.aliases);return{simulatorDeviceTypeIdentifier:d.identifier,...d.modelIdentifier?{modelIdentifier:d.modelIdentifier}:{},name:d.name,productFamily:d.productFamily,...F===void 0?{}:{aliases:F},...k.archetype===void 0?{}:{archetype:k.archetype},...k.modelType===void 0?{}:{modelType:k.modelType},metadataState:M,...P===void 0?{}:{minOsVersion:P.minVersion,maxOsVersion:P.maxVersion}}}function Yy(d){return d.platform==="iOS"||d.identifier.startsWith("com.apple.CoreSimulator.SimRuntime.iOS-")||d.name.startsWith("iOS ")}function Xy(d,c,w){let D=Uo(d.version);return{runtimeId:d.identifier,...D.ok?{osVersion:D.value.value}:{},installed:d.isAvailable===!0,metadataState:c==="stale"||w||!d.identifier||!D.ok||d.isAvailable===void 0?"stale":"current"}}function Ml(d){let c=new Set,w=new Set;for(let D of d){if(c.has(D))w.add(D);c.add(D)}return w}function El(d,c,w={}){let D=w.metadataState??"current",k=w.classifications??[],P=Ml(d.map((K)=>K.identifier)),C=c.filter(Yy),M=Ml(C.map((K)=>K.identifier)),F=d.map((K)=>jy(K,k,D,P.has(K.identifier))).sort((K,W)=>K.simulatorDeviceTypeIdentifier.localeCompare(W.simulatorDeviceTypeIdentifier)),q=C.map((K)=>Xy(K,D,M.has(K.identifier))).sort((K,W)=>K.runtimeId.localeCompare(W.runtimeId)),U=Pt(zr,{classificationVersion:xy,classifications:[...k].sort((K,W)=>K.simulatorDeviceTypeIdentifier.localeCompare(W.simulatorDeviceTypeIdentifier)),models:F,releases:q});return{platform:"ios",provenance:{source:zr,revision:U,state:"ready"},models:F,releases:q}}async function Qy(d,c){let w=(P)=>P.then((C)=>()=>C,(C)=>()=>{throw C}),[D,k]=await Promise.all([w(d.getDeviceTypesChecked(c)),w(d.getRuntimesChecked(void 0,c))]);return[D(),k()]}async function Yr(d,c={}){try{let[w,D]=await Qy(d,c.signal);return El(w,D,c)}catch(w){if(c.signal?.aborted)throw w;let D=`Unable to read the installed iOS simulator catalog: ${r(w)}`;return(c.logger??e).warn(D,w),{platform:"ios",provenance:{source:zr,revision:"unavailable",state:"unavailable",message:D},models:[],releases:[]}}}var Ui="simctl-watch-catalog";function Bl(d){let c=d.runtimes.map((D)=>{let k=D.version.trim()||wz(D.identifier);return{runtime:D.identifier,...k?{osVersion:k}:{},installed:D.isAvailable===!0}}).sort((D,k)=>D.runtime.localeCompare(k.runtime)),w=d.deviceTypes.map((D)=>({deviceType:D.identifier,name:D.name})).sort((D,k)=>D.deviceType.localeCompare(k.deviceType));return{platform:"watchos",provenance:{source:Ui,revision:Pt(Ui,{runtimes:c,deviceTypes:w}),state:"ready"},runtimes:c,deviceTypes:w}}async function Qr(d,c={}){if(!d)return{platform:"watchos",provenance:{source:Ui,revision:"not-installed",state:"not-installed",message:"Apple Watch simulators exist only on macOS hosts with Xcode's simctl."},runtimes:[],deviceTypes:[]};try{return Bl(await d.readCatalog(c.signal))}catch(w){if(c.signal?.aborted)throw w;let D=`Unable to read the Apple Watch simulator catalog: ${r(w)}`;return(c.logger??e).warn(D,w),{platform:"watchos",provenance:{source:Ui,revision:"unavailable",state:"unavailable",message:D},runtimes:[],deviceTypes:[]}}}function Ol(d){let c=new L(null),w=process.platform==="darwin"?new ha(c):void 0;return(D,k)=>{if(D==="watchos")return Qr(w,{signal:k});if(D==="ios")return Yr(c,{signal:k,classifications:d.iosClassifications});return jr({listDevices:(P)=>NR(void 0,P),listInstalledSystemImages:(P,C)=>_u(P,void 0,C)},{profileArchetypes:d.androidProfileArchetypes},{signal:k})}}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 w=c.value.filter(Sg).map(({command:D})=>Gm(D).avdName);if(w.includes(void 0))throw new t("Cannot identify a running emulator's AVD; stop it or restore process discovery before retrying cleanup");return w.some((D)=>D?.toLowerCase()===d.toLowerCase())}findLiveEmulatorSerial(d){return Jq(d,async()=>{let c=await this.listDevicesChecked();if(c.some((w)=>!w.name||fa(w.name,w.deviceId)))throw new t("Cannot identify a discovered emulator's AVD; retry cleanup after emulator discovery recovers");return c})}}function Zy(d,c){let w=new oi;return{registry:d,resolver:new Br,filesystem:a7,liveness:new eo(new nh(new re,{timer:c,procFs:zy}),()=>w.getBootedDevicesChecked(!0))}}function to(d,c,w){return d??Zy(c?.avdSnapshotCleanupRegistry(),w)}var Xt=180;class io{adb;hinge;timer;constructor(d,c=new pM,w=i){this.adb=d;this.hinge=c;this.timer=w}async restore(d,c){try{if(c.throwIfAborted(),!d.deviceId.startsWith("emulator-"))throw new t("Fold posture baseline reset requires an Android emulator");let w=this.adb.create(d),D={signal:c,assertCurrent:()=>c.throwIfAborted()};if(await _$(w,"opened",void 0,{supportsRearDisplay:!0,operation:D}))throw new t("Emulator refused unfolded posture; cannot prove opened baseline");let P=await this.hinge.setHingeAngle(w,Xt,{signal:c});if(!P.ok)throw new t(`Cannot restore hinge angle to ${Xt}: ${P.reason}`);let C=await this.hinge.getHingeAngle(w,{signal:c});if(!C.ok||C.degrees!==Xt)throw new t(`Hinge angle read-back did not confirm ${Xt} degrees`);let M=await tO(w,D);await x$(w,"opened",{states:M},{timer:this.timer,observe:()=>{throw new t("The device exposes no committed posture state to read back")},operation:D}),c.throwIfAborted()}catch(w){throw new t(`Cannot restore Android device '${d.deviceId}' to opened posture (${Xt} degrees): ${r(w)}`,{cause:w})}}}class ro{reasons=new Map;mark(d,c){if(!this.reasons.has(d))this.reasons.set(d,c)}reasonFor(d){return this.reasons.get(d)}clear(d){this.reasons.delete(d)}}function xl(d,c){let w=d.restartReservationExclusions(c.platform,{});if(c.platform==="android"?w.names.has(c.name):w.ids.has(c.deviceId??""))return"restart recovery reservation";let D=d.getAllDevices().find((k)=>k.platform===c.platform&&(c.platform==="android"?(k.avdName??k.name)===c.name:k.id===c.deviceId));if(!D)return;if(!wr(D))return`pooled runtime is ${Tb(D)}`;if(O(D)!==null)return"a session holds the runtime";if(d.isUnderShutdownReservation(D.id))return"shutdown reservation";return d.isDeviceLeasedForAndroidStartup(D.id)?"android startup lease":void 0}function he(d){return d.platform==="android"?d.name:d.deviceId}var eS=["android","ios","watchos"],_l=["assigned_active","assigned_idle","deleting","preparing","orphaned"],oo=10,tS={assigned_active:"committed: in use by a session",assigned_idle:"committed: assigned to a binding",free:"free",deleting:"committed: being deleted",deletion_stuck:"committed: deletion stuck",preparing:"committed: being prepared",orphaned:"orphaned"};function iS(d){if(d.kind!=="orphaned")return tS[d.kind];return d.orphanState==="transitioning"?"orphaned: booting or shutting down":"orphaned: running"}function nS(d){let{limit:c,usage:w,charged:D,chargedOmitted:k,retained:P,evictionFailures:C}=d;return{limit:c,usage:w,charged:D,...k?{chargedOmitted:k}:{},retained:P,evictionFailures:C}}function Hl(d){let c=nS(d);return{message:rS(c),budget:c}}function rS(d){let c=`Managed-binding total-resource budget is exhausted (${d.usage.total} charged, limit ${d.limit}).`;if(d.charged.length===0)return c;let w=d.charged.map((k)=>`${k.name??k.stableDeviceId} (${k.platform}, ${iS(k)})`).join("; "),D=d.chargedOmitted??0;return`${c} Charged devices: ${w}${D>0?`; and ${D} more`:""}.`}function oS(d){let c={active:"assigned_active",assignedIdle:"assigned_idle",deleting:"deleting",preparing:"preparing",orphaned:"orphaned"};return d.map((w)=>({platform:w.platform,stableDeviceId:w.stableDeviceId,kind:c[w.category],...w.name?{name:w.name}:{},...w.orphanState?{orphanState:w.orphanState}:{}})).sort((w,D)=>_l.indexOf(w.kind)-_l.indexOf(D.kind)||w.platform.localeCompare(D.platform)||w.stableDeviceId.localeCompare(D.stableDeviceId))}function Oe(d,c){return JSON.stringify([d,c])}function sS(d,c){return c.find((w)=>Js(w)===d.platform&&qI(w)===d.stableDeviceId)}function dS(d,c){if(d.scopeState===null)return"preparing";if(c.has(Oe(d.platform,d.stableDeviceId)))return"deleting";return d.execSessionUuid!==null?"active":"assignedIdle"}function cS(d,c,w){return[{category:dS(d,c),platform:d.platform,stableDeviceId:d.stableDeviceId,journal:sS(d,w)}]}function Fl(d,c){let w=qI(c)??c.target.newName??c.target.oldStableId??c.target.oldName;if(!w)return;d.push({category:"preparing",platform:Js(c),stableDeviceId:w,journal:c})}function lS(d){let{charges:c,seen:w}=Kl(d);return gS(d,c,w),c}function Kl(d){let c=d.openJournal.filter((C)=>bA(C.phase)),w=new Set(c.filter((C)=>C.kind==="replace"&&["intent","deleting"].includes(C.phase)&&C.target.oldStableId!==null).map((C)=>Oe(C.platform,C.target.oldStableId))),D=new Map(d.managed.filter((C)=>!c.some((M)=>M.kind==="create"&&C.holder==="session_broker"&&C.scopeState!==null&&M.scopeKey===C.scopeKey&&M.bindingIndex===C.bindingIndex&&qI(M)!==C.stableDeviceId)).map((C)=>[Oe(C.platform,C.stableDeviceId),C])),k=new Set(D.keys()),P=[...D.values()].flatMap((C)=>cS(C,w,c));for(let C of c){if(C.kind==="release")continue;let M=qI(C);if(M!==null){let F=Oe(Js(C),M);if(!k.has(F))Fl(P,C),k.add(F)}else if(!SS(C,D))Fl(P,C)}return{charges:P,seen:k}}function uS(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 pS(d){return m4(d.platform)}function Gl(d,c){let w=new Set(c),D=[];for(let k of d.inventory??[]){let P=he(k);if(!pS(k)||!P||!cc(k.name))continue;let C=Oe(k.platform,P);if(!(d.managed.some((F)=>Oe(F.platform,F.stableDeviceId)===C)||d.openJournal.some((F)=>F.platform===k.platform&&[F.target.oldStableId,F.target.oldName].some((q)=>q===P||q===k.name)||Js(F)===k.platform&&[F.target.newStableId,F.target.newName].some((q)=>q===P||q===k.name)))&&!w.has(C)&&!k.name.startsWith(P7))D.push(k),w.add(C)}return D}function gS(d,c,w){for(let D of Gl(d,w)){let k=uS(D),P=he(D);if(k===null||!P)continue;c.push({category:"orphaned",platform:D.platform,stableDeviceId:P,name:D.name,orphanState:k}),w.add(Oe(D.platform,P))}}function yS(d){return Gl(d,Kl(d).seen).filter((c)=>c.isRunning!==!0&&c.isRunningStateKnown===!1)}function SS(d,c){return d.target.oldStableId!==null&&c.has(Oe(d.platform,d.target.oldStableId))}function bS(d){let c={total:d.length,active:0,assignedIdle:0,preparing:0,deleting:0,orphaned:0};for(let w of d)c[w.category]+=1;return c}async function RS(d,c,w,D){let k=Oe(c.platform,he(c)??c.name),P=D.get(k);if(P)return P;let C=d.probeRunning?d.probeRunning(c,{signal:w}).catch((M)=>(w?.throwIfAborted(),e.debug(`[Bindings] running-state probe of ${c.name} failed: ${M}`),!1)):Promise.resolve(!1);return D.set(k,C),C}async function AS(d,c,w,D){let k=yS(c),P=new Set((await Promise.all(k.map(async(C)=>await RS(d,C,w,D)?C:null))).filter((C)=>C!==null));return(c.inventory??[]).map((C)=>P.has(C)?{...C,isRunning:!0,isRunningStateKnown:!0}:C)}async function MS(d,c,w,{timer:D,probes:k}){Gi(w,D);let P=await d.snapshotBindingResources(),C=[];for(let q of eS){Gi(w,D);let U=await c.list(q,{signal:w.signal});if(!U.complete&&U.toolchain==="not_installed")continue;if(!U.complete)throw new t(`${q} inventory is incomplete; total-resource usage is unknown.`);C.push(...U.devices)}Gi(w,D);let M=await AS(c,{...P,inventory:C},w.signal,k),F=lS({...P,inventory:M});return{charges:F,charged:oS(F)}}function Gi(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 Nl(d,c){let w=d.filter((k)=>k.category!=="preparing"||k.journal?.kind!=="create"||k.journal.id<=c),D=w.some((k)=>k.category==="preparing"&&k.journal?.id===c);return w.length+(D?0:1)}class so{deps;timer;constructor(d){this.deps=d;this.timer=d.timer??i}async admitCreation(d){let c=this.deps.policy.limit();if(c===null)return{kind:"admitted",enforced:!1};if(!Number.isSafeInteger(c)||c<0)throw new t("Managed-binding total-resource limit must be a nonnegative safe integer or null; correct the budget policy.");try{Gi(d,this.timer);let w=async()=>this.admitFromRegistry(await this.deps.registry(),c,d);return d.deadlineMs===void 0?await w():await l(w,{timer:this.timer,timeoutMs:Math.max(0,d.deadlineMs-this.timer.now()),signal:d.signal,label:"Managed-binding resource admission"})}catch(w){return d.signal?.throwIfAborted(),e.warn(`[Bindings] Resource admission could not read capacity: ${r(w)}`,w),{kind:"unknown",message:r(w)}}}async admitFromRegistry(d,c,w){let D=new Map,k=()=>MS(d,this.deps.inventory,w,{timer:this.timer,probes:D}),P=await k();if(Nl(P.charges,w.journalEntryId)>c)P=await k();let C=bS(P.charges);return Nl(P.charges,w.journalEntryId)<=c?{kind:"admitted",enforced:!0,limit:c,usage:C,evicted:[]}:{kind:"exhausted",limit:c,usage:C,charged:P.charged.slice(0,oo),...P.charged.length>oo?{chargedOmitted:P.charged.length-oo}:{},retained:[],evictionFailures:[]}}}var 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 ao{timer;deletion;constructor(d,c=i8){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 w=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(IP(w))return{kind:"failed",...xS(w),evidence:w};return{kind:"absent",evidence:w}}}function xS(d){let c=d.content[0]?.text;if(c===void 0)return{message:"deleteDevice failed"};try{let w=JSON.parse(c);if(w&&typeof w==="object"){let D="error"in w&&typeof w.error==="string"?w.error:c,k="failure"in w?FS(w.failure):void 0;if(k)return{message:D,notAttempted:{reason:k}};if(NS("failure"in w?w.failure:void 0))return{message:D,escalationExhausted:!0};return{message:D}}}catch(w){e.debug(`[Bindings] Unparsed deleteDevice failure text: ${r(w)}`)}return{message:c}}function FS(d){if(!d||typeof d!=="object"||!("phase"in d)||d.phase!=="precondition"||!("code"in d))return;return BS.find((c)=>c===d.code)}function NS(d){return!!d&&typeof d==="object"&&"code"in d&&d.code===sG}class Ke extends Error{reason;constructor(d){super("Journal drive cancelled");this.reason=d}}function ue(d){if(d?.aborted)throw new Ke(d.reason)}function co(d,c,w){return d.devices.find((D)=>D.platform===c&&he(D)===w)}var lo=1000,Wi=3,uo=6,Vi=500;class fo{registry;stages;constructor(d,c){this.registry=d;this.stages=c}async checkDeviceFree(d,c,w){let D=await this.stages.listInventory(d,d.platform,w);if(!D)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let k=co(D,d.platform,c);if(!k)return D.complete?{kind:"free"}:{kind:"blocked",reason:"discovery_incomplete",message:`Device '${c}' was not listed and discovery was incomplete.`};let P=await this.stages.describeClaim(d,k,w);if(P.kind==="free")return{kind:"free"};return{kind:"blocked",reason:P.kind==="held"?"device_busy":"discovery_incomplete",message:`Device '${c}' is not free: ${P.reason}`}}async locateForDeletion(d,c,w,D){if(D)return{kind:"present",device:D};let k=await this.stages.listInventory(d,d.platform,w);if(!k)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let P=co(k,d.platform,c);if(!P)return k.complete?{kind:"absent"}:{kind:"blocked",reason:"discovery_incomplete",message:`Device '${c}' was not listed and discovery was incomplete.`};let C=await this.stages.describeClaim(d,P,w);if(C.kind!=="free")return{kind:"blocked",reason:C.kind==="held"?"device_busy":"discovery_incomplete",message:`Device '${c}' cannot be deleted: ${C.reason}`};let M=await this.registry.findDeviceHolder(d.platform,c);if(ue(w),M?.kind!=="binding"||M.assignment.scopeKey!==d.scopeKey||M.assignment.bindingIndex!==d.bindingIndex||!jd(M.assignment,d.binding))return{kind:"blocked",reason:"reconcile_in_progress",message:`Device '${c}' is no longer this binding's device.`};return{kind:"present",device:P}}async locateCreated(d,c){let{newStableId:w,newName:D}=d.target;if(!w&&!D)return{kind:"absent"};let k=Js(d),P=await this.stages.listInventory(d,k,c);if(!P)return{kind:"blocked",reason:"discovery_incomplete",message:"Device discovery failed."};let C=P.devices.filter((F)=>F.platform===k&&(w?he(F)===w:F.name===D));if(C.length===0)return P.complete?{kind:"absent"}:{kind:"blocked",reason:"discovery_incomplete",message:`Created device '${w??D}' was not listed and discovery was incomplete.`};let M=C.length===1?he(C[0]):void 0;if(!M)return{kind:"blocked",reason:"discovery_incomplete",message:`Created device '${D}' is ambiguous (${C.length} listed).`};return{kind:"present",device:C[0],stableId:M}}}class Qt{ids=new Set;removals=new Map;operations=new WeakMap;warned=new Set;hasRemoval(d,c){return(this.removals.get(JSON.stringify([d,c]))?.size??0)>0}hasRemovalForPass(d,c,w){let D=this.removals.get(JSON.stringify([d,c]));for(let k of D??[])if(k.overdueAtMs!==void 0&&w-k.overdueAtMs>=lo)k.abandoned=!0;return this.removalBlocked(d,c)}removalBlocked(d,c){let w=JSON.stringify([d,c]),D=this.removals.get(w);if(!D)return!1;if([...D].filter((P)=>P.abandoned).length>=Wi){if(!this.warned.has(w))this.warned.add(w),e.warn(`[BindingJournal] Removal of '${c}' reached the pending abandoned delete bound.`);return!0}return[...D].some((P)=>!P.abandoned)}markRemovalOverdue(d,c){let w=this.operations.get(d);if(w&&w.overdueAtMs===void 0)w.overdueAtMs=c}trackRemoval(d,c,w){let D=JSON.stringify([d,c]),k=this.removals.get(D)??new Set,P={abandoned:!1};k.add(P),this.removals.set(D,k);let C=Promise.resolve().then(w).finally(()=>{if(P.abandoned)e.debug(`[BindingJournal] Abandoned removal of '${c}' settled late.`);if(k.delete(P),this.operations.delete(C),k.size===0)this.removals.delete(D);if([...k].filter((M)=>M.abandoned).length<Wi)this.warned.delete(D)});return this.operations.set(C,P),C}add(d){this.ids.add(d)}delete(d){this.ids.delete(d)}has(d){return this.ids.has(d)}}function Wl(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 Vl(d){return{stableDeviceId:null,deviceName:null,requestedSpec:d,resolvedSpec:null,specFingerprint:null,state:"provisioning"}}function ho(d){return{entryId:d.entry.id,kind:d.entry.kind,phase:d.entry.phase,outcome:d.kind,...d.kind==="blocked"?{reason:d.reason}:{}}}var LS={android:I7,ios:_7,watchos:bq};function Jl(d){let c=LS[Js(d)].safeParse(d.target.requestedSpec);return c.success?c.data:void 0}class vo{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 w=await this.tryRemovalFlag(d,new AbortController().signal,!0);if(w)return w.kind==="advanced"?w.entry:d;if(c.deadlineMs!==void 0&&this.deps.timer.now()>=c.deadlineMs)return e.warn(`[BindingJournal] Removal flag for entry ${d.id} missed its deadline.`),d;let D=new AbortController,k=c.signal?AbortSignal.any([c.signal,D.signal]):D.signal;try{return await l(()=>this.retryRemovalFlag(d,k),{timer:this.deps.timer,timeoutMs:c.deadlineMs===void 0?void 0:Math.max(0,c.deadlineMs-this.deps.timer.now()),signal:k,label:`removal flag for entry ${d.id}`,onTimeout:()=>D.abort()})}catch(P){if(!k.aborted)throw P;return e.warn(`[BindingJournal] Removal flag for entry ${d.id} interrupted: ${r(P)}`,P),d}}async retryRemovalFlag(d,c){for(let w=2;w<=uo;w++){c.throwIfAborted(),await this.deps.pacing.wait(this.deps.pacing.delay(w-1),c);let D=await this.tryRemovalFlag(d,c);if(D)return D.kind==="advanced"?D.entry:d}return e.warn(`[BindingJournal] Removal flag for entry ${d.id} exhausted registry retries.`),d}async tryRemovalFlag(d,c,w=!1){let D=this.deps.timer.now(),k=Error(`Removal flag for entry ${d.id} exceeded its write budget.`);try{let P=()=>this.deps.advance(d,{expectedPhase:d.phase,phase:d.phase,target:{removalRequested:!0,...d.target.newStableId?{newStableId:d.target.newStableId}:{}}},c),C=await(w?l(P,{timer:this.deps.timer,timeoutMs:Vi,timeoutError:()=>k,label:`first removal flag write for entry ${d.id}`}):this.deps.pacing.run(P,(M)=>M.kind==="advanced",c));if(C.kind==="advanced"||C.kind==="journal_conflict")this.clear(d.id);return C}catch(P){if(P===k)return e.warn(`[BindingJournal] ${r(P)}`,P),{kind:"removal_flag_timed_out"};if(Ja(P)!=="retryable")throw e.warn(`[BindingJournal] Removal flag failed: ${r(P)}`,P),P;if(w)this.deps.pacing.noteBlocked(D);e.debug(`[BindingJournal] Removal flag deferred: ${r(P)}`,P);return}}}class Ge extends Error{}class So{deps;constructor(d){this.deps=d}async boundedStage(d,c,w){ue(c.cancel);let D=new AbortController,k=c.signal?AbortSignal.any([c.signal,D.signal]):D.signal,P=Error(`${c.label} timed out after ${c.timeoutMs}ms`);try{let C=await l(()=>d(k),{timer:this.deps.timer,timeoutMs:Math.max(0,c.timeoutMs),signal:c.signal,label:c.label,timeoutError:()=>P,onTimeout:()=>D.abort(P)});return ue(c.cancel),C}catch(C){if(c.cancel?.aborted)throw D.abort(c.cancel.reason),new Ke(c.cancel.reason);return e.warn(`[BindingJournal] ${c.label} failed: ${r(C)}`,C),w(c.signal?.aborted?Error(`${c.label} cancelled: ${r(C)}`):C)}}listInventory(d,c=d.platform,w){return this.boundedStage((D)=>this.deps.inventory.list(c,{signal:D}),{label:`discovery for entry ${d.id}`,timeoutMs:this.deps.budgets.discoveryMs,signal:w,cancel:w},()=>null)}describeClaim(d,c,w){return this.boundedStage(()=>this.deps.claims.describe(c),{label:`claim for entry ${d.id}`,timeoutMs:this.deps.budgets.claimMs,signal:w,cancel:w},(D)=>({kind:"unknown",reason:r(D)}))}async deleteDevice(d,c,w){let{inFlight:D}=this.deps;if(D.removalBlocked(d.platform,d.stableId))return{kind:"failed",message:`Removal of device '${d.stableId}' is still in flight.`};let k;try{let P=await this.boundedStage((C)=>(k=D.trackRemoval(d.platform,d.stableId,()=>this.deps.deleter.deleteAndVerifyAbsence({...d,signal:C})),k),{label:`deleting '${d.stableId}'`,timeoutMs:Math.max(0,Math.min(d.deadlineMs+this.deps.budgets.deleteGraceMs,w??1/0)-this.deps.timer.now()),signal:d.signal,cancel:c},(C)=>({kind:"failed",message:r(C)}));return{...P,nativeDeleteFailed:k!==void 0&&P.kind==="failed"&&!P.notAttempted}}finally{if(k)D.markRemovalOverdue(k,this.deps.timer.now())}}}function zl(d,c){return{target:{quarantinedAtMs:d},attempt:{error:c,nextAttemptAtMs:d+600000}}}function Yl(d,c,w){let D=c.lastError??"its emulator would not stop";return{advance:{attempt:{error:D,nextAttemptAtMs:d+600000}},message:`Device '${w}' is quarantined: ${D}`}}var Xl=120000,$S=30000,HS=1e4,qS=1e4,US=5000,KS=25,GS=1000,WS=5000,VS=6,JS=Q({initialDelayMs:1000,multiplier:2,maxDelayMs:60000});function Ce(d,c,w){return{kind:"blocked",entry:d,reason:c,message:w}}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 Qt,this.isOwnerLive=d.isOwnerLive??lc,this.isExecOwnerLive=d.isExecOwnerLive??lc,this.backoff=No(d.backoff??JS),this.budgets={discoveryMs:$S,claimMs:HS,matchMs:qS,deleteGraceMs:US,...d.stageBudgets},this.removalFlags=new vo({timer:d.timer,pacing:new Me({timer:d.timer,initialDelayMs:KS,maxDelayMs:GS,maxBlockedWaitMs:WS}),advance:(c,w,D)=>this.advanceStep(c,w,D)}),this.stages=new So({inventory:d.inventory,deleter:d.deleter,claims:d.claims,timer:d.timer,inFlight:this.inFlight,budgets:this.budgets}),this.locator=new fo(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(w){if(w instanceof Ke)throw e.debug("[BindingJournal] acquisition redrive cancelled"),w.reason;throw w}}async redriveBindingEntries(d,c){ue(c);let w=[],D=await this.deps.registry.listOpenBindingJournal(d);if(ue(c),D.length===0){let k=await this.adoptUnjournaledWork(d,c);D=k?[k]:[]}for(let k of D){let P=await this.driveEntry(k,c);if(P.kind==="skipped")return{kind:"blocked",reason:Wl(P.entry),message:`Binding ${d.bindingIndex} has unfinished ${P.entry.kind} work (${P.why}).`,entry:P.entry,redriven:w};if(w.push(ho(P)),P.kind==="blocked")return{kind:"blocked",reason:P.reason,message:P.message,entry:P.entry,redriven:w}}return{kind:"clear",redriven:w}}async runPass(d={}){let{signal:c}=d,w={settled:[],blocked:[],skipped:0};if(c?.aborted)return w;let D=await this.deps.registry.listOpenBindingJournal();for(let k of D){if(c?.aborted)break;try{let P=await this.driveEntry(k,c,{fromPass:!0});if(P.kind==="skipped")w.skipped+=1;else(P.kind==="settled"?w.settled:w.blocked).push(ho(P))}catch(P){if(P instanceof Ke){e.debug("[BindingJournal] pass cancelled");break}e.warn(`[BindingJournal] redrive of entry ${k.id} failed: ${r(P)}`,P),w.blocked.push({entryId:k.id,kind:k.kind,phase:k.phase,outcome:"blocked"})}}return w}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,w){ue(w);let D=d.target.oldStableId,k=await this.deps.registry.getAssignment(wo(d));if(ue(w),!D||!k||!jd(k,d.binding))return this.closeStep(d,"rolled_back",w);if(k.execOwner&&this.isExecOwnerLive(k.execOwner))return Ce(d,"binding_in_use",`Binding is held by ${k.execOwner.sessionUuid}.`);let P=this.pendingRemoval(d,d.platform,D,"step");if(P)return P;let C=await this.locator.locateForDeletion(d,D,w,c.device);if(C.kind==="blocked")return this.recordBlocked(d,C.reason,C.message,{signal:w});if(C.kind==="present"&&d.target.quarantinedAtMs!==void 0)return this.probeQuarantine(d,D,w);let M=C.kind==="present"?await this.stages.deleteDevice({platform:d.platform,stableId:D,name:d.target.oldName,deadlineMs:c.deadlineMs??this.deps.timer.now()+Xl,signal:c.signal},w):{kind:"absent",evidence:{listed:!1}};return ue(w),this.recordDeletion(d,D,M,w)}async probeQuarantine(d,c,w){let D=Yl(this.deps.timer.now(),d,c),k=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleting",...D.advance},w);return{kind:"blocked",entry:k.kind==="advanced"?k.entry:d,reason:"cleanup_quarantined",message:D.message}}async recordDeletion(d,c,w,D){if(w.kind==="failed"){let P=w.escalationExhausted===!0,C=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleting",assignment:{kind:"state",expected:d.binding,state:"cleanup_pending"},...P?zl(this.deps.timer.now(),w.message):{attempt:this.attemptAfter(d,w.message,this.entryRemovalInFlight(d))}},D);return{kind:"blocked",entry:C.kind==="advanced"?C.entry:d,reason:P?"cleanup_quarantined":"cleanup_pending",message:`Deleting device '${c}' failed: ${w.message}`,evidence:w.evidence}}let k=await this.advanceStep(d,{expectedPhase:"deleting",phase:"deleted",assignment:{kind:"commit",expected:d.binding,next:{...Vl(d.target.requestedSpec),platform:Js(d)}}},D);if(k.kind!=="advanced"||!k.assignment)return{kind:"blocked",entry:d,reason:"reconcile_in_progress",message:`Recording the deletion failed: ${k.kind}.`};return{kind:"deleted",entry:k.entry,assignment:k.assignment,evidence:w.evidence}}async settleCreation(d,c={adopt:!0}){return(d.target.newStableId?this.pendingRemoval(d,Js(d),d.target.newStableId):void 0)??this.creationStep(d,c)}async removalRegistryStage(d,c){let w=Math.min(Vi,c===void 0?1/0:Math.max(0,c-this.deps.timer.now()));return l(d,{timer:this.deps.timer,timeoutMs:w,label:"uncommitted cleanup registry stage",timeoutError:()=>new Ge("Removal deferred to journal redrive: registry stage timed out.")})}async creationStep(d,c,w){try{return await this.creationRegistryStep(d,c,w)}catch(D){if(!(D instanceof Ge))throw D;let k=c.adopt?`Settling created entry ${d.id} deferred to the next redrive: registry stage timed out`:"Creation cleanup deferred to journal redrive: registry stage timed out";return e.warn(`[BindingJournal] ${k}`,D),Ce(d,"reconcile_in_progress",k)}}async creationRegistryStep(d,c,w){ue(w);let D=await this.locator.locateCreated(d,w);if(D.kind==="absent")return this.removalRegistryStage(()=>this.closeStep(d,"rolled_back",w),c.deadlineMs);if(D.kind==="blocked")return this.removalBlocked(d,D.reason,D.message,{signal:w,deadlineMs:c.deadlineMs});let{device:k,stableId:P}=D,C=this.pendingRemoval(d,Js(d),P,"step");if(C)return C;let M=await this.removalRegistryStage(()=>this.deps.registry.findDeviceHolder(Js(d),P),c.deadlineMs);if(ue(w),M)return this.removalRegistryStage(()=>this.closeStep(d,"rolled_back",w),c.deadlineMs);let F=await this.removalRegistryStage(()=>this.deps.registry.getAssignment(wo(d)),c.deadlineMs);ue(w);let q=F!==null&&jd(F,d.binding),U=Jl(d);if(c.adopt&&!this.removalFlags.removalIntended(d)&&q&&U){let K=await this.stages.boundedStage(()=>this.deps.matcher.matches(k,U),{label:`configuration for entry ${d.id}`,timeoutMs:this.budgets.matchMs,signal:w,cancel:w},()=>"unknown");if(K==="unknown")return this.recordBlocked(d,"discovery_incomplete",`Configuration of '${P}' is unreadable.`,{signal:w});if(K==="match")return this.adoptCreated(d,k,P,w)}return this.removeCreated(d,k,P,{deadlineMs:c.deadlineMs,signal:w})}async close(d,c){return this.closeStep(d,c)}async closeStep(d,c,w){let D=await this.advanceStep(d,{expectedPhase:d.phase,phase:c},w);return this.removalFlags.clear(d.id),{kind:"settled",entry:D.kind==="advanced"?D.entry:d}}async advance(d,c){let w=await this.advanceStep(d,c);if(w.kind==="journal_conflict"||w.kind==="advanced"&&w.entry.target.removalRequested)this.removalFlags.clear(d.id);return w}async advanceStep(d,c,w){ue(w);let D=await this.deps.registry.advanceBindingJournal(d.id,{...c,owner:this.deps.owner});return ue(w),D}async driveEntry(d,c,w={}){if(ue(c),this.inFlight.has(d.id))return!w.fromPass&&this.pendingEntryRemoval(d)||{kind:"skipped",entry:d,why:"in progress in this process"};let D=await this.takeOwnership(d,c);if(D.kind==="skipped")return D;let k=D.entry,P=this.pendingEntryRemoval(k,w.fromPass);if(P)return P;if(k.attempts>0&&k.nextAttemptAtMs>this.deps.timer.now())return{kind:"skipped",entry:k,why:`retry due in ${k.nextAttemptAtMs-this.deps.timer.now()}ms`};this.inFlight.add(k.id);try{for(let C=0;C<VS;C+=1){ue(c);let M=await this.step(k,c);if(M.kind!=="next")return M;k=M.entry}return Ce(k,"reconcile_in_progress","Journal entry did not settle.")}finally{this.inFlight.delete(k.id)}}async takeOwnership(d,c){if(Uc(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 w=await this.deps.registry.claimBindingJournal(d.id,d.owner,this.deps.owner);if(ue(c),w.kind!=="claimed")return{kind:"skipped",entry:w.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:w.entry}}async step(d,c){if(d.kind==="release")return this.settleRelease(d,c);switch(d.phase){case"deleting":{let w=await this.deletionStep(d,{signal:c},c);return w.kind==="deleted"?{kind:"next",entry:w.entry}:w}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 w=await this.deps.registry.getAssignment(wo(d));if(ue(c),!w||!jd(w,d.binding))return this.closeStep(d,"rolled_back",c);if(w.state!=="settling")return this.closeStep(d,"committed",c);if(w.settler&&this.isOwnerLive(w.settler))return Ce(d,"binding_settling","The binding's settler is still watching its work.");if(w.execOwner&&this.isExecOwnerLive(w.execOwner))return Ce(d,"binding_in_use",`Binding is held by ${w.execOwner.sessionUuid}.`);let D=w.stableDeviceId;if(D){let P=await this.locator.checkDeviceFree(d,D,c);if(P.kind==="blocked")return this.recordBlocked(d,P.reason,P.message,{signal:c})}let k=await this.advanceStep(d,{expectedPhase:d.phase,phase:"committed",assignment:{kind:"state",expected:d.binding,state:"ready"}},c);if(k.kind!=="advanced")return Ce(d,"reconcile_in_progress",`Restoring the binding failed: ${k.kind}.`);return{kind:"settled",entry:k.entry}}async adoptCreated(d,c,w,D){if(this.removalFlags.removalIntended(d))return this.removeCreated(d,c,w,{signal:D});let k=await this.advanceStep(d,{expectedPhase:d.phase,phase:"committed",target:{newStableId:w,newName:c.name},assignment:{kind:"commit",expected:d.binding,next:{stableDeviceId:w,deviceName:c.name,requestedSpec:d.target.requestedSpec,resolvedSpec:d.target.resolvedSpec,specFingerprint:d.target.specFingerprint,state:"provisioning"}}},D);if(k.kind==="advanced")return{kind:"settled",entry:k.entry};if(k.kind==="journal_conflict")return Ce(d,"reconcile_in_progress","The journal entry changed during adoption.");return this.removeCreated(d,c,w,{signal:D})}async removeCreated(d,c,w,{deadlineMs:D,signal:k}={}){if(!d.target.removalRequested){this.markRemovalIntended(d);let F=await this.removalRegistryStage(()=>this.advanceStep(d,{expectedPhase:d.phase,phase:d.phase,target:{removalRequested:!0,newStableId:w}},k),D);if(F.kind==="advanced"||F.kind==="journal_conflict")this.removalFlags.clear(d.id);if(F.kind!=="advanced")return Ce(d,"reconcile_in_progress",`Recording removal of '${w}' failed: ${F.kind}.`);d=F.entry}let P=await this.stages.describeClaim(d,c,k);if(P.kind!=="free")return this.removalBlocked(d,P.kind==="held"?"device_busy":"discovery_incomplete",`Uncommitted device '${w}' cannot be removed: ${P.reason}`,{target:{newStableId:w},signal:k,deadlineMs:D});let C=await this.stages.deleteDevice({platform:Js(d),stableId:w,name:c.name,deadlineMs:D??this.deps.timer.now()+Xl,signal:k},k);if(C.kind==="failed")return this.removalBlocked(d,"cleanup_pending",`Removing uncommitted device '${w}' failed: ${C.message}`,{target:{newStableId:w},signal:k,deadlineMs:D});let M=await this.removalRegistryStage(()=>this.advanceStep(d,{expectedPhase:d.phase,phase:"rolled_back",target:{newStableId:w}},k),D);return this.removalFlags.clear(d.id),{kind:"settled",entry:M.kind==="advanced"?M.entry:d}}async adoptUnjournaledWork(d,c){let w=await this.deps.registry.getAssignment(d);if(ue(c),!w?.stableDeviceId||w.state!=="replacing"&&w.state!=="cleanup_pending"||w.execOwner&&this.isExecOwnerLive(w.execOwner))return null;let D=await this.deps.registry.openBindingJournal(d,{kind:"replace",phase:"deleting",owner:this.deps.owner,target:{oldStableId:w.stableDeviceId,oldName:w.deviceName,newName:null,newStableId:null,requestedSpec:w.requestedSpec,resolvedSpec:w.resolvedSpec,specFingerprint:w.specFingerprint},assignment:{kind:"state",expected:{generation:w.generation,stableDeviceId:w.stableDeviceId},state:w.state}});if(ue(c),D.kind==="opened")return e.warn(`[BindingJournal] binding ${d.bindingIndex} was left ${w.state} without a journal entry; redriving it as entry ${D.entry.id}`),D.entry;return D.kind==="journal_open"?D.entry:null}removalBlocked(d,c,w,{target:D,signal:k,deadlineMs:P}){return this.removalRegistryStage(()=>this.recordBlocked(d,c,w,{target:D,signal:k}),P)}async recordBlocked(d,c,w,{target:D,signal:k}={}){let P=D?.newStableId&&d.phase==="creating"?"created":d.phase,C=await this.advanceStep(d,{expectedPhase:d.phase,phase:P,...D?{target:D}:{},attempt:this.attemptAfter(d,w,this.entryRemovalInFlight(d))},k);return Ce(C.kind==="advanced"?C.entry:d,c,w)}entryRemovalInFlight(d){return this.inFlight.hasRemoval(d.platform,d.target.oldStableId??"")||this.inFlight.hasRemoval(Js(d),d.target.newStableId??"")}attemptAfter(d,c,w=!1){return{error:c,nextAttemptAtMs:this.deps.timer.now()+(w?0:this.backoff.delayForAttempt(d.attempts+1))}}pendingEntryRemoval(d,c=!1){let w=d.phase==="deleting",D=w?d.target.oldStableId:d.target.newStableId;return D?this.pendingRemoval(d,w?d.platform:Js(d),D,c?"pass":"caller"):void 0}pendingRemoval(d,c,w,D="caller"){if(!(D==="pass"?this.inFlight.hasRemovalForPass(c,w,this.deps.timer.now()):D==="caller"?this.inFlight.hasRemoval(c,w):this.inFlight.removalBlocked(c,w)))return;return Ce(d,"cleanup_pending",`Removal of device '${w}' is still in flight.`)}}import{createHash as jS}from"crypto";function Zl(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 iu(d,c,w){let D=bq.safeParse(c);if(!D.success)return{kind:"unsupported",code:"spec_unsupported",message:`A watchOS binding spec names exactly runtime and deviceType: ${oE(D.error)}`};if(!d)return{kind:"unsupported",code:"spec_unsupported",message:"Apple Watch simulators exist only on macOS hosts with Xcode's simctl."};let k;try{k=await d.readCatalog(w)}catch(C){return w?.throwIfAborted(),e.warn(`[Bindings] watch catalog unreadable: ${r(C)}`,C),{kind:"unresolved",message:`The Apple Watch simulator catalog could not be read: ${r(C)}`}}let P=D.data;try{oG(P,k)}catch(C){if(!(C instanceof t))throw C;let M=k.runtimes.find((q)=>q.identifier===P.runtime);return{kind:"unsupported",code:k.deviceTypes.some((q)=>q.identifier===P.deviceType)&&M&&!M.isAvailable?"runtime_incompatible":"spec_unsupported",message:C.message}}return{kind:"resolved",resolvedSpec:{runtime:P.runtime,deviceType:P.deviceType,displayCutout:"unknown"}}}var ou=1,du="pixel_8",YS={phone:du,tablet:"pixel_tablet",foldable:"pixel_fold",tv:Ll("tv"),watch:Ll("watch"),automotive:Ll("automotive"),"xr-headset":Ll("xr-headset"),"xr-glasses":Ll("xr-glasses")};function ko(d,c){let w=jS("sha256").update(Dr({version:ou,platform:d,resolvedSpec:c})).digest("hex");return{version:ou,hash:w}}function ei(d){let c={...d};return delete c.deviceFamily,c}function XS(d,c){if(c.deviceFamily===void 0)return;if(c.deviceType===void 0)return d==="android"?QS(c):void 0;let w=d==="ios"?Wm(c.deviceType):If({profileId:c.deviceType,systemImageTag:tn(c.runtime)?.tag});if(w===void 0||w==="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 w===c.deviceFamily?void 0:`deviceType '${c.deviceType}' is a ${w}; it conflicts with deviceFamily '${c.deviceFamily}'.`}function QS(d){let c=If({systemImageTag:tn(d.runtime)?.tag});return bae(c)?c===d.deviceFamily?void 0:`runtime '${d.runtime}' is a ${c} image; it conflicts with deviceFamily '${d.deviceFamily}'.`:void 0}function ZS(d,c){if(d!=="android"||c.deviceFamily===void 0||!("configuration"in c))return;return["screenWidth","screenHeight","screenDensity"].some((D)=>c.configuration?.[D]!==void 0)?"The family is classified from screen geometry, so it cannot be verified before creation when the geometry is overridden. Request deviceFamily without screen overrides, or an explicit deviceType without deviceFamily.":void 0}var su="com.apple.CoreSimulator.SimRuntime.";class Ji{iosRuntimeCatalog;androidDefaultDeviceType;androidDefaultDeviceTypesByFamily;androidImageCatalog;androidProfileCatalog;watchCatalog;constructor(d,c={}){this.iosRuntimeCatalog=d;this.androidDefaultDeviceType=c.androidDefaultDeviceType??du,this.androidDefaultDeviceTypesByFamily={...YS,phone:this.androidDefaultDeviceType,...c.androidDefaultDeviceTypesByFamily},this.androidImageCatalog=c.androidImageCatalog,this.androidProfileCatalog=c.androidProfileCatalog,this.watchCatalog=c.watchCatalog}async checkCreatable(d,c,w){if(d==="ios"||d==="watchos"){let k=await this.resolve(d,{runtime:c.runtime,deviceType:c.deviceType},w);return k.kind==="resolved"?{kind:"creatable"}:k}if(!this.androidProfileCatalog)return{kind:"creatable"};let D;try{D=await this.androidProfileCatalog.listProfileIds(w.signal)}catch(k){return e.warn(`[Bindings] Android profile catalog unreadable: ${r(k)}`,k),{kind:"unresolved",message:`The Android hardware profile catalog could not be read: ${r(k)}`}}if(D.includes(c.deviceType))return{kind:"creatable"};return{kind:"unsupported",code:"spec_unsupported",message:`Android hardware profile '${c.deviceType}' is not available on this host. List valid profile IDs with avdmanager list device.`}}async resolve(d,c,w){if(d==="watchos"){let q=await iu(this.watchCatalog,c,w.signal);return q.kind==="resolved"?{...q,fingerprint:ko(d,q.resolvedSpec)}:q}let D=this.catalogRead(w.signal),k=await this.findUnsupportedSpec(d,c,w.signal,D);if(k)return{kind:"unsupported",code:"spec_unsupported",message:k};let P=await this.resolveDeviceType(d,c,D);if(P.kind!=="resolved")return P.resolution;let C={...ei(c),deviceType:P.deviceType},M=Mq(d,C);if(M.kind!=="resolved")return{kind:"unsupported",code:"spec_unsupported",message:M.message};if(d==="ios"&&this.iosRuntimeCatalog&&c.deviceType!==void 0){let q=await this.findIosIncompatibility(C,D);if(q)return{kind:"unsupported",code:"runtime_incompatible",message:q}}let F={...C,displayCutout:M.displayCutout};return{kind:"resolved",resolvedSpec:F,fingerprint:ko(d,F)}}catalogRead(d){let c;return()=>{if(!c){let w=this.iosRuntimeCatalog;if(!w)throw new t("The simulator catalog is unavailable");c=w.getCatalogChecked?w.getCatalogChecked(d):Promise.all([w.getRuntimesChecked(void 0,d),w.getDeviceTypesChecked(d)]).then(([D,k])=>({runtimes:D,deviceTypes:k}))}return c}}async findUnsupportedSpec(d,c,w,D){let k=ZS(d,c)??XS(d,c);if(k!==void 0)return k;if(d==="android")return tn(c.runtime)?await this.findMissingAndroidImage(c.runtime,w):`Android runtime '${c.runtime}' is not a system-image identifier.`;return c.runtime.startsWith(su)?await this.findMissingIosCatalogEntry(c,D):`iOS runtime '${c.runtime}' is not a CoreSimulator runtime identifier (${su}...).`}async resolveDeviceType(d,c,w){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 D,k;try{({runtimes:D,deviceTypes:k}=await w())}catch(C){return e.warn(`[Bindings] iOS catalog unreadable; cannot choose a model: ${r(C)}`,C),{kind:"refused",resolution:{kind:"unresolved",message:`The simulator catalog could not be read to choose a model: ${r(C)}`}}}let P=cu(c.runtime,D,k,c.deviceFamily);return P?{kind:"resolved",deviceType:P}: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 w;try{w=await this.androidImageCatalog.listInstalledPackages(c)}catch(D){e.warn(`[Bindings] Android image check skipped: ${r(D)}`,D);return}if(w.includes(d))return;return`Android system image '${d}' is not installed. Install it with sdkmanager, or request an installed image (${w.join(", ")||"none installed"}).`}async findMissingIosCatalogEntry(d,c){if(!this.iosRuntimeCatalog)return;let w,D;try{({runtimes:w,deviceTypes:D}=await c())}catch(P){e.warn(`[Bindings] iOS catalog check skipped: ${r(P)}`,P);return}if(!w.some((P)=>P.identifier===d.runtime)){let P=w.map((C)=>C.identifier);return`iOS runtime '${d.runtime}' is not installed on this host. Install it with Xcode, or request an installed runtime (${P.join(", ")||"none installed"}).`}if(d.deviceType===void 0||D.some((P)=>P.identifier===d.deviceType))return;let k=D.filter((P)=>P.productFamily==="iPhone").map((P)=>P.identifier);return`iOS device type '${d.deviceType}' is not installed on this host. Request an installed device type (iPhone types: ${k.join(", ")||"none installed"}; all types: xcrun simctl list devicetypes).`}async findIosIncompatibility(d,c){let w,D;try{({runtimes:w,deviceTypes:D}=await c())}catch(C){e.warn(`[Bindings] iOS catalog check skipped: ${r(C)}`,C);return}let k=Nq(d,w,D);if(!k)return;let P=k.compatibleRuntimes.map((C)=>C.id).join(", ")||"none installed";return k.unavailable?`Runtime '${d.runtime}' is not available. Compatible installed runtimes: ${P}.`:`Device type '${d.deviceType}' does not support runtime '${d.runtime}'. Compatible installed runtimes: ${P}.`}}function Do(d,c){return{kind:"refused",resolution:{kind:"unsupported",code:d,message:c}}}function cu(d,c,w,D){let k=c.find((q)=>q.identifier===d);if(!k?.isAvailable)return;let P=w.filter((q)=>D===void 0?q.productFamily==="iPhone"&&!q.modelIdentifier?.startsWith("iPod")&&!hs(q.identifier):Wm(q.identifier)===D),C=(q)=>pc(q,k.version).status,M=P.filter((q)=>C(q)==="supported"),F=P.filter((q)=>C(q)==="unknown");return(M.toSorted(au).at(-1)??F.toSorted(au).at(-1))?.identifier}function au(d,c){let w=/^(iPhone|iPad)(\d+),(\d+)$/.exec(d.modelIdentifier??""),D=/^(iPhone|iPad)(\d+),(\d+)$/.exec(c.modelIdentifier??"");if(!w||!D)return Number(Boolean(w))-Number(Boolean(D));return Number(w[2])-Number(D[2])||Number(D[3])-Number(w[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 eb={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},ib={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 Ao(d,c,w){let D=w.toLowerCase().replace(/[^a-z0-9]/g,"").slice(0,8);if(D.length===0)throw Error(`Binding device name nonce '${w}' has no usable characters`);return`${R7}${Po(d)}${c}-${D}`}function Po(d){return`${d.scopeKey.slice(0,8)}-${d.bindingIndex}-g`}function ct(d){return`v${d.version}:${d.hash}`}function Z(d,c,w={}){return{code:d,retryable:w.retryable??eb[d],message:c,nextAction:ib[d],...w.provision?{provision:w.provision}:{},...w.capacity?{capacity:w.capacity}:{},...w.budget?{budget:w.budget}:{}}}function Io(d,c){switch(d.kind){case"scope_not_valid":return Z("scope_not_valid",`Binding scope is no longer valid (${c}).`);case"binding_missing":return Z("concurrent_modification",`Binding disappeared during ${c}.`);case"stale_binding":return Z("concurrent_modification",`Binding binding changed during ${c} (now generation ${d.current.generation}).`);case"device_assigned_elsewhere":return Z("concurrent_modification",`Device is already assigned to binding ${d.holder.bindingIndex} of another scope (${c}).`)}}function Ne(d,c){switch(d.kind){case"binding_in_use":return Z("binding_in_use",`Binding is held by live session ${d.owner.sessionUuid} (${c}).`);case"binding_not_ready":return Z("concurrent_modification",`Binding stopped being ready during ${c}.`);default:return Io(d,c)}}function zi(d){return d&&d.length>0?{externalDevices:[...d]}:{}}function It(d){if(d instanceof Un)return Z("capacity_exhausted",d.message,{capacity:{limit:d.limit,booted:d.booted,retryAfterMs:d.retryAfterMs,...zi(d.details.externalDevices),...d.details.heldDevices?.length?{heldDevices:[...d.details.heldDevices]}:{}}});if(d instanceof $e){if(d.code==="discovery_incomplete")return Z("discovery_incomplete",d.message);if(d.code==="runtime_incompatible")return Z("runtime_incompatible",d.message);let c=d.diagnostics.capacity;if(d.code==="capacity_exhausted"&&c)return Z("capacity_exhausted",d.message,{capacity:{limit:c.limit,booted:c.booted,retryAfterMs:d.diagnostics.retryAfterMs??0,...zi(c.externalDevices),...c.heldDevices?.length?{heldDevices:[...c.heldDevices]}:{}}});return Z("provision_failed",d.message,{retryable:d.retryable,provision:{code:d.code,retryable:d.retryable}})}return Z("provision_failed",r(d),{retryable:!1})}function Te(d){return{generation:d.generation,stableDeviceId:d.stableDeviceId}}function lu(d){let{createDeadlineMs:c,deadlineMs:w}=d.request;if(c===void 0||c>=w)return d;return{...d,request:{...d.request,deadlineMs:c}}}function nb(d){return d.isRunning||d.platform!=="android"&&d.state!==void 0&&k4.has(d.state)}class Co{deps;host;constructor(d,c){this.deps=d;this.host=c}async createAndCommit(d,c,w,{replacing:D,...k}={}){let{request:P}=d,C;if(D===void 0)try{if(this.host.checkBudget(P),await this.assertCreatable(d),!k.bootReservation)C=await this.assertBootCapacity(P)}catch(q){throw await this.removeNeverBoundBinding(d,c,"pre-provision refusal"),q}else if(this.host.checkBudget(P),!k.bootReservation)C=await this.assertBootCapacity(P);let M=Ao(P.key,c.generation+1,this.deps.idGenerator.next());d.evidence.createdName=M;let F=D?await this.advanceToCreating(d,D,M):await this.openCreateEntry(d,c,M);this.deps.journal.inFlight.add(F.id);try{if(D===void 0&&this.deps.resourceBudget)await this.admitFreshCreation(d,c,F);let q;try{let K=()=>this.deps.provisioner.provision({platform:P.platform,name:M,spec:{...ei(P.requestedSpec),deviceType:d.resolvedSpec.deviceType},mode:"create",deadlineMs:P.deadlineMs,signal:P.signal}),W=P.platform,V=()=>W==="watchos"?K():r8({platform:W,name:M,spec:{runtime:P.requestedSpec.runtime,deviceType:d.resolvedSpec.deviceType}},C,this.deps.timer,K);q=k.bootReservation?await k.bootReservation.run(V):await V()}catch(K){return await this.failedCreate(d,c,F,{fresh:D===void 0,error:K})}let U=this.host.isBindingReady(P.platform,q);return await this.host.readyOrReleaseOnBusy(q,async(K)=>{if(q.created&&!U)this.deps.journal.markRemovalIntended(F);if(F=await this.recordCreated(d,F,q.device,{release:K,removalRequested:q.created&&!U}),!U)return await this.discardUncommitted(d,q,F,{release:K,reason:Z("readiness_incomplete",`Device '${M}' did not reach ${wq(P.platform)}.`)});let W=await this.deps.journal.advance(F,{expectedPhase:"created",phase:"committed",assignment:{kind:"commit",expected:F.binding,next:{stableDeviceId:q.device.stableId,deviceName:q.device.name,requestedSpec:P.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ct(d.fingerprint),state:"ready"}}});if(W.kind==="journal_conflict")throw await this.host.releaseSession(q.sessionUuid),new ie(Z("concurrent_modification","The binding's journal entry was taken over."));if(W.kind!=="advanced")return await this.discardUncommitted(d,q,F,{release:K,reason:Ne(W,"create commit")});return this.noteJournal(d,W.entry),await this.host.claimAndReady(d,w,W.assignment,{provisioned:q})})}finally{this.deps.journal.inFlight.delete(F.id)}}async openCreateEntry(d,c,w){let{request:D}=d,k=await this.deps.registry.openBindingJournal(D.key,{kind:"create",phase:"creating",owner:this.deps.journal.owner,target:this.journalTarget(d,c,w),assignment:{kind:"state",expected:Te(c),state:"provisioning"}});if(k.kind==="journal_open")throw new ie(Z("reconcile_in_progress",`Binding ${D.key.bindingIndex} has unfinished work.`));if(k.kind!=="opened")throw new ie(Ne(k,"create"));return this.noteJournal(d,k.entry),k.entry}async advanceToCreating(d,c,w){let D=await this.deps.journal.advance(c,{expectedPhase:"deleted",phase:"creating",target:{newName:w}});if(D.kind!=="advanced")throw new ie(Z("concurrent_modification",`Replacement journal changed: ${D.kind}.`));return this.noteJournal(d,D.entry),D.entry}async failedCreate(d,c,w,{fresh:D,error:k}){let{request:P}=d;if(k instanceof $e&&k.retryable&&k.code==="timeout"&&k.diagnostics.retainedDevice&&k.diagnostics.retainedDevice.name===w.target.newName&&k.diagnostics.retainedDevice.platform==="ios"&&P.platform==="ios"&&!P.signal?.aborted){try{await this.recordCreated(d,w,k.diagnostics.retainedDevice)}catch(M){throw e.warn(`[Bindings] retaining created device failed: ${r(M)}`,M),new ie(It(k))}throw new ie({...It(k),retainedDevice:k.diagnostics.retainedDevice})}let C=await this.settleFailedCreate(d,w);if(D)await this.removeFailedUnboundBinding(d,c,C);throw new ie(It(k))}async recordCreated(d,c,w,{release:D,removalRequested:k=!1}={}){let P=await this.deps.journal.advance(c,{expectedPhase:"creating",phase:"created",target:{newStableId:w.stableId,newName:w.name,...k?{removalRequested:!0}:{}}}).catch(async(C)=>{throw e.warn(`[Bindings] recording created device failed: ${r(C)}`,C),await D?.(),C});if(P.kind!=="advanced")throw await D?.(),new ie(Z("concurrent_modification","The binding's journal entry was taken over."));return this.noteJournal(d,P.entry),P.entry}async admitFreshCreation(d,c,w){let D;try{D=await this.deps.resourceBudget.admitCreation({journalEntryId:w.id,deadlineMs:d.request.deadlineMs,signal:d.request.signal}),this.host.checkBudget(d.request)}catch(M){let F=await this.settleFailedCreate(d,w,!0);throw await this.removeFailedUnboundBinding(d,c,F),M}if(D.kind==="admitted")return;let k=await this.settleFailedCreate(d,w,!0);if(await this.removeFailedUnboundBinding(d,c,k),D.kind==="unknown")throw new ie(Z("discovery_incomplete",D.message));let{message:P,budget:C}=Hl(D);throw new ie(Z("binding_budget_exhausted",P,{budget:C}))}async removeFailedUnboundBinding(d,c,w){if(w?.phase!=="rolled_back")return;await this.removeNeverBoundBinding(d,c,`failed creation entry ${w.id}`)}async withEmptyBindingCleanup(d,c,w){try{return await w()}catch(D){throw await this.removeNeverBoundBinding(d,c,"empty-binding discovery refusal"),D}}async removeNeverBoundBinding(d,c,w){if(c.generation!==0||c.stableDeviceId!==null)return;try{await this.deps.registry.removeUnboundBinding(d.request.key,{generation:c.generation,stableDeviceId:null})}catch(D){e.warn(`[Bindings] removing never-bound binding after ${w} failed: ${r(D)}`,D)}}async settleFailedCreate(d,c,w=!1){try{if(w){let k=(await this.deps.journal.close(c,"rolled_back")).entry;return this.noteJournal(d,k),k}let D=await this.deps.journal.settleCreation(c,{adopt:!1,deadlineMs:d.request.deadlineMs});return this.noteJournal(d,D.entry),D.entry}catch(D){e.warn(`[Bindings] settling failed creation entry ${c.id} failed; redrive will retry: `+r(D),D)}}async discardUncommitted(d,c,w,{release:D,reason:k}){try{if(c.created)this.deps.journal.markRemovalIntended(w),w=await this.deps.journal.requestRemoval(w,{deadlineMs:d.request.deadlineMs,signal:d.request.signal})}finally{await D()}try{await this.cleanupUncommitted(d,c,w)}catch(P){if(P instanceof Ge)e.warn(`[Bindings] uncommitted cleanup deferred: ${r(P)}`,P),d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:P.message};else if(Ja(P)!=="retryable")throw e.warn(`[Bindings] uncommitted cleanup failed: ${r(P)}`,P),P;e.debug(`[Bindings] uncommitted cleanup deferred: ${r(P)}`)}throw new ie(k)}async cleanupUncommitted(d,c,w){if(!c.created){this.noteJournal(d,(await this.deps.journal.removalRegistryStage(()=>this.deps.journal.close(w,"rolled_back"),d.request.deadlineMs)).entry);return}if(this.noteJournal(d,w),!w.target.removalRequested){d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:"Removal deferred to journal redrive or its current driver."};return}let D=await this.deps.journal.removalRegistryStage(()=>this.deps.registry.findDeviceHolder(d.request.platform,c.device.stableId),d.request.deadlineMs);if(D){let C=D.kind==="binding"?`binding ${D.assignment.bindingIndex} of scope ${D.assignment.scopeKey}`:"the managed free pool";d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:!1,message:`kept: held by ${C}`},e.warn(`[Bindings] not discarding '${c.device.stableId}': it is held by ${C}`),this.noteJournal(d,(await this.deps.journal.removalRegistryStage(()=>this.deps.journal.close(w,"rolled_back"),d.request.deadlineMs)).entry);return}let k=await this.deps.journal.settleCreation(w,{adopt:!1,deadlineMs:d.request.deadlineMs});this.noteJournal(d,k.entry);let P=k.kind==="settled";if(d.evidence.uncommittedCleanup={stableId:c.device.stableId,removed:P,...k.kind==="blocked"?{message:k.message}:{}},!P)e.warn(`[Bindings] uncommitted device '${c.device.stableId}' was not removed: `+(k.kind==="blocked"?k.message:"unknown"))}async replaceOrphan(d,c,w){let{request:D}=d;await this.assertCreatable(d),this.host.checkBudget(D);let k=await this.reserveReplacement(D,c,w);try{this.host.checkBudget(D);let P={stableDeviceId:he(w),deviceName:w.name,requestedSpec:D.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ct(d.fingerprint),state:"replacing"},C=await this.deps.registry.openBindingJournal(D.key,{kind:"replace",phase:"deleting",owner:this.deps.journal.owner,target:{...this.journalTarget(d,c,null),oldStableId:P.stableDeviceId,oldName:w.name},assignment:{kind:"commit",expected:Te(c),next:P}});if(C.kind==="journal_open")throw new ie(Z("reconcile_in_progress",`Binding ${D.key.bindingIndex} has unfinished work.`));if(C.kind!=="opened")throw new ie(Ne(C,"reclaim"));return d.evidence.adoptedFrom="orphan",await this.finishReplacement(d,C.entry,w,k)}finally{k?.release()}}async replaceAssigned(d,c,w,D){let{request:k}=d;await this.assertCreatable(d),await this.assertReplaceable(k,c,w,D);let P=await this.reserveReplacement(k,c,w);try{return this.host.checkBudget(k),await this.replaceReserved(d,c,w,P)}finally{P?.release()}}async replaceReserved(d,c,w,D){let{request:k}=d,P=await this.deps.registry.openBindingJournal(k.key,{kind:"replace",phase:"deleting",owner:this.deps.journal.owner,target:this.journalTarget(d,c,null),assignment:{kind:"state",expected:Te(c),state:"replacing"}});if(P.kind==="journal_open")throw new ie(Z("reconcile_in_progress",`Binding ${k.key.bindingIndex} has unfinished work.`));if(P.kind!=="opened")throw new ie(Ne(P,"replace"));return await this.finishReplacement(d,P.entry,w,D)}async finishReplacement(d,c,w,D){let{request:k,evidence:P}=d,C=c.target.oldStableId;this.noteJournal(d,c),this.deps.journal.inFlight.add(c.id);let M,F;try{let q=await this.deps.journal.driveDeletion(c,{device:w,deadlineMs:k.deadlineMs,signal:k.signal});if(this.noteJournal(d,q.entry),q.kind!=="deleted"){if(q.kind==="blocked")throw P.deletion=q.evidence,new ie(Z(q.reason,q.message));throw new ie(Z("concurrent_modification",`Device '${C}' is no longer this binding's device.`))}P.deletion=q.evidence,P.deletedStableId=C,M=q.entry,F=q.assignment,D?.markReplacedDeviceGone()}finally{this.deps.journal.inFlight.delete(c.id)}return await this.createAndCommit(d,F,"replaced",{replacing:M,bootReservation:D})}journalTarget(d,c,w){return{oldStableId:c.stableDeviceId,oldName:c.deviceName,...c.platform!==d.request.platform?{newPlatform:d.request.platform}:{},newName:w,newStableId:null,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:ct(d.fingerprint)}}noteJournal(d,c){d.evidence.journal={entryId:c.id,kind:c.kind,phase:c.phase}}async assertReplaceable(d,c,w,D){let k=c.stableDeviceId;if(!D)throw new ie(Z("discovery_incomplete","Replacement requires complete device discovery."));let P=await this.deps.claims.describe(w);if(P.kind!=="free")throw new ie(Z(P.kind==="held"?"device_busy":"discovery_incomplete",`Device '${k}' cannot be replaced: ${P.reason}`));this.host.checkBudget(d);let C=await this.deps.registry.findDeviceHolder(c.platform,k);if(C?.kind!=="binding"||C.assignment.scopeKey!==d.key.scopeKey||C.assignment.bindingIndex!==d.key.bindingIndex||!yq(C.assignment,Te(c)))throw new ie(Z("concurrent_modification",`Device '${k}' is no longer this binding's device.`))}async reserveReplacement(d,c,w){if(!this.deps.capacity)return;let D=s0(c.platform)===s0(d.platform)&&nb(w);this.host.checkBudget(d);let k=await this.deps.capacity.reserve(d.platform,{replacingDeviceId:D?w.deviceId:void 0,resolveReplacingDeviceId:D&&!w.deviceId?(P)=>this.deps.inventory.runtimeDeviceId?.(w,P)??Promise.resolve(void 0):void 0,timeoutMs:Math.max(1,d.deadlineMs-this.deps.timer.now()),signal:d.signal});if(k.kind==="available")return k.reservation;throw this.assertCapacityCheck(d,k),new ie(Z("discovery_incomplete","Boot capacity reservation returned no admission."))}async assertCreatable(d){if(d.creatabilityChecked)return;let{request:c}=d,w=await this.deps.resolver.checkCreatable?.(c.platform,d.resolvedSpec,{signal:c.signal});if(this.host.checkBudget(c),w?.kind==="unsupported")throw new ie(Z(w.code,w.message));if(w?.kind==="unresolved")throw new ie(Z("discovery_incomplete",w.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(Z("discovery_incomplete",c.message));if(c.kind==="exhausted"&&c.booted>=c.limit)throw new ie(Z("capacity_exhausted",`${c.booted} ${d.platform} device(s) booted; limit is ${c.limit}.${T4(c)}`,{capacity:{limit:c.limit,booted:c.booted,retryAfterMs:c.retryAfterMs,...zi(c.externalDevices),...c.heldDevices?.length?{heldDevices:[...c.heldDevices]}:{}}}))}}function To(){return{daemonId:`pid-${process.pid}`,pid:process.pid,processGenerationToken:bf()??null}}function uu(d){return`${d.scopeKey}#${d.bindingIndex}`}class Yi{androidConfigReader;constructor(d){this.androidConfigReader=d}async matches(d,c){switch(d.platform){case"watchos":return Zl(d,c);case"android":return await this.matchesAndroid(d,c);case"ios":return rb(d,c);case"tvos":case"visionos":return"mismatch"}}async matchesAndroid(d,c){let w;try{w=await this.androidConfigReader.readConfig(d.name)}catch(k){return e.warn(`[Bindings] cannot read AVD config for '${d.name}': ${r(k)}`,k),"unknown"}if(!w)return"unknown";let D={...c,deviceType:c.deviceType??w.deviceName};if(!Dq(D,w))return"mismatch";return pu(c.deviceFamily,()=>If({systemImageTag:w.systemImagePackage?tn(w.systemImagePackage)?.tag:void 0,profileId:w.deviceName,width:w.screenWidth,height:w.screenHeight,density:w.screenDensity}))}}function rb(d,c){if(d.isAvailable===!1||d.runtime===void 0||c.deviceType!==void 0&&d.deviceType===void 0)return"unknown";let w={runtime:c.runtime,deviceType:c.deviceType??d.deviceType};return Oq(w,d)===void 0?pu(c.deviceFamily,()=>Wm(d.deviceType)):"mismatch"}function pu(d,c){if(d===void 0)return"match";let w=c();if(w===void 0||w==="unknown")return"unknown";return w===d?"match":"mismatch"}class Mo{deps;inFlight=new Map;isExecOwnerLive;idGenerator;reservations;creation;journal;constructor(d){this.deps=d;this.isExecOwnerLive=d.isExecOwnerLive??lc,this.idGenerator=d.idGenerator??B,this.reservations=d.reservations??e0,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??To(),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 Co({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:v4,releaseSession:(c)=>this.releaseSession(c),readyOrReleaseOnBusy:(c,w)=>this.readyOrReleaseOnBusy(c,w),claimAndReady:(c,w,D,{provisioned:k,reservation:P})=>this.claimAndReady(c,w,D,{provisioned:k,reservation:P})})}async reconcile(d){let c=uu(d.key),w=this.inFlight.get(c),D=!1,k=(w??Promise.resolve()).then(()=>{return},()=>{return}).then(()=>D?void 0:this.reconcileSerialized(d));this.inFlight.set(c,k);try{if(w){let P=await this.waitForQueue(w,d);if(P)return D=!0,{outcome:"failed",failure:P,assignment:await this.failedResultAssignment(d,void 0),evidence:{initial:null,inventoryComplete:null}}}return await k}finally{let P=()=>{if(this.inFlight.get(c)===k)this.inFlight.delete(c)};if(D)k.then(P,P);else P()}}async waitForQueue(d,c){try{await l(d.then(()=>{return},()=>{return}),{timer:this.deps.timer,timeoutMs:Math.max(0,c.deadlineMs-this.deps.timer.now()),...c.signal?{signal:c.signal}:{},label:"Waiting for the binding's in-flight reconcile"});return}catch(w){return e.debug(`[Bindings] queued reconcile stopped waiting: ${r(w)}`),c.signal?.aborted?Z("cancelled","Binding preparation was cancelled."):Z("timeout","Binding preparation deadline passed.")}}async failedResultAssignment(d,c){try{return await this.journal.removalRegistryStage(()=>this.deps.registry.getAssignment(d.key),c)}catch(w){if(w instanceof Ge||Ja(w)==="retryable")return e.warn(`[Bindings] failed result assignment unavailable: ${r(w)}`,w),null;throw w}}async reconcileSerialized(d){let c={initial:null,inventoryComplete:null};try{return await this.reconcileSteps(d,c)}catch(w){if(w instanceof ie||Ja(w)==="retryable")return{outcome:"failed",failure:w instanceof ie?w.failure:Z("discovery_incomplete",r(w)),assignment:await this.failedResultAssignment(d,d.deadlineMs),evidence:c};throw w}}async reconcileSteps(d,c){let{registry:w}=this.deps;this.checkBudget(d);let D=await this.deps.resolver.resolve(d.platform,d.requestedSpec,{signal:d.signal});if(D.kind==="unsupported")throw new ie(Z(D.code,D.message));if(D.kind==="unresolved")throw new ie(Z("discovery_incomplete",D.message));let k={request:d,resolvedSpec:D.resolvedSpec,fingerprint:D.fingerprint,evidence:c},P=await w.initBinding(d.key,{role:d.role,platform:d.platform,requestedSpec:d.requestedSpec});if(P.kind==="scope_not_valid")throw new ie(Z("scope_not_valid","Binding scope is not valid."));let C=await this.redriveUnfinished(d,P.assignment,c),M=await this.recoverIfSettled(d,C);if(c.initial={generation:M.generation,stableDeviceId:M.stableDeviceId,state:M.state},this.assertBindingAcceptsWork(d,M),M.platform!==d.platform)return await this.changePlatform(k,M);let F=async()=>{let W=await this.deps.inventory.list(d.platform,{signal:d.signal});return c.inventoryComplete=W.complete,this.checkBudget(d),W},q=M.stableDeviceId===null?await this.withEmptyBindingCleanup(k,M,F):await F();if(M.stableDeviceId===null)return await this.fillEmptyBinding(k,M,q);let U=q.devices.find((W)=>W.platform===d.platform&&he(W)===M.stableDeviceId);if(!U){if(!q.complete)throw new ie(Z("discovery_incomplete",`Assigned device '${M.stableDeviceId}' was not listed and discovery was incomplete.`));return c.assignedMissing=!0,await this.createAndCommit(k,M,"created")}let K=await this.deps.matcher.matches(U,d.requestedSpec);if(c.assignedMatch=K,K==="unknown")throw new ie(Z("discovery_incomplete",`Configuration of assigned device '${M.stableDeviceId}' could not be read.`));if(K==="match")return await this.reuseAssigned(k,M,U);return await this.replaceAssigned(k,M,U,q.complete)}async redriveUnfinished(d,c,w){let D=await this.journal.redriveBinding(d.key);if(D.redriven.length>0)w.redriven=D.redriven;if(D.kind==="blocked")throw new ie(Z(D.reason,D.message));if(D.redriven.length===0)return c;let k=await this.deps.registry.getAssignment(d.key);if(!k)throw new ie(Z("scope_not_valid","Binding disappeared during redrive."));return k}async recoverIfSettled(d,c){if(c.state!=="settling")return c;let w=(await this.deps.registry.recoverSettledBindings(d.key.scopeKey)).find((D)=>D.bindingIndex===d.key.bindingIndex);if(w)return w;throw new ie(Z("binding_settling",`Binding ${d.key.bindingIndex} is settling the released work of its previous execution.`))}assertBindingAcceptsWork(d,c){if(c.execOwner&&this.isExecOwnerLive(c.execOwner))throw new ie(Z("binding_in_use",`Binding ${d.key.bindingIndex} is held by live session ${c.execOwner.sessionUuid}.`));if(c.state==="cleanup_pending")throw new ie(Z("cleanup_pending",`Binding ${d.key.bindingIndex} still holds device '${c.stableDeviceId}' pending cleanup.`));if(c.state==="replacing")throw new ie(Z("reconcile_in_progress",`Binding ${d.key.bindingIndex} is mid-replacement of '${c.stableDeviceId}'.`))}async changePlatform(d,c){let{request:w,evidence:D}=d;if(c.stableDeviceId===null){let C=await this.withEmptyBindingCleanup(d,c,async()=>{let M=await this.deps.inventory.list(w.platform,{signal:w.signal});return D.inventoryComplete=M.complete,this.checkBudget(w),M});return await this.fillEmptyBinding(d,c,C)}let k=await this.deps.inventory.list(c.platform,{signal:w.signal});D.inventoryComplete=k.complete,this.checkBudget(w);let P=k.devices.find((C)=>C.platform===c.platform&&he(C)===c.stableDeviceId);if(!P){if(!k.complete)throw new ie(Z("discovery_incomplete",`Assigned device '${c.stableDeviceId}' was not listed and discovery was incomplete.`));D.assignedMissing=!0,await this.assertCreatable(d);let C=await this.emptyOnRequestedPlatform(d,c);return await this.createAndCommit(d,C,"created")}return D.assignedMatch="mismatch",await this.replaceAssigned(d,c,P,k.complete)}async emptyOnRequestedPlatform(d,c){let{request:w}=d,D=await this.deps.registry.commitBinding(w.key,Te(c),{platform:w.platform,stableDeviceId:null,deviceName:null,requestedSpec:w.requestedSpec,resolvedSpec:null,specFingerprint:null,state:"provisioning"});if(D.kind!=="committed")throw new ie(Io(D,"platform change"));return D.assignment}async reuseAssigned(d,c,w){this.assertNoLiveExecutionOn(d,w);let D=await this.reserveExecution(d,c);try{return await this.reuseReserved(d,c,w,D)}catch(k){if(D)await this.releaseReservation(d.request.key,D);throw k}finally{if(D)this.reservations.delete(D)}}async reuseReserved(d,c,w,D){d={...d,resolvedSpec:await this.existingSpec(w)};let k=await this.provisionExisting(d,w);return await this.readyOrReleaseOnBusy(k,async()=>{let P=Te(c),C=ct(d.fingerprint),F=c.state==="ready"&&c.specFingerprint===C&&Dr(c.requestedSpec)===Dr(d.request.requestedSpec)&&this.resolvedIdentityMatches(c.resolvedSpec,d.resolvedSpec)?await this.deps.registry.updateBindingState(d.request.key,P,"ready"):await this.deps.registry.commitBinding(d.request.key,P,{stableDeviceId:c.stableDeviceId,deviceName:k.device.name,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:C,state:"ready"});if(F.kind!=="updated"&&F.kind!=="committed")throw await this.releaseSession(k.sessionUuid),new ie(Ne(F,"reuse"));return await this.claimAndReady(d,"reused",F.assignment,{provisioned:k,reservation:D})})}resolvedIdentityMatches(d,c){if(d===null||typeof d!=="object")return!1;return["runtime","deviceType","displayCutout"].every((w)=>Reflect.get(d,w)===c[w])}async reserveExecution(d,c){let{owner:w,key:D}=d.request;if(!w||c.state!=="ready")return;let k=`reserve-${this.idGenerator.next()}`;this.reservations.add(k);try{let P=await this.deps.registry.claimExecution(D,Te(c),{...w,sessionUuid:k});if(P.kind!=="claimed")throw new ie(Ne(P,"reservation"))}catch(P){throw this.reservations.delete(k),P}return k}async releaseReservation(d,c){try{await this.deps.registry.releaseExecution(d,c)}catch(w){e.warn(`[Bindings] releasing reservation ${c} failed: ${r(w)}`,w)}}async fillEmptyBinding(d,c,w){let D=await this.withEmptyBindingCleanup(d,c,async()=>{if(!w.complete)throw new ie(Z("discovery_incomplete","Device discovery was incomplete for an empty binding."));let P=await this.findAdoptionCandidate(d,w.devices);if(c.platform!==d.request.platform)await this.assertCreatable(d);return P});if(c.platform!==d.request.platform)c=await this.emptyOnRequestedPlatform(d,c);let k=lu(d);if(D)return await this.creation.replaceOrphan(k,c,D);return await this.createAndCommit(k,c,"created")}async findAdoptionCandidate(d,c){let{request:w}=d,D=Po(w.key),k=w.priorDeviceHint?.stableId,P=c.filter((C)=>C.platform===w.platform).map((C)=>({device:C,stableId:he(C)})).filter((C)=>!!C.stableId).sort((C,M)=>Number(M.stableId===k)-Number(C.stableId===k)||C.stableId.localeCompare(M.stableId));for(let{device:C,stableId:M}of P){if(!cc(C.name)||!C.name.slice(C.name.indexOf("-")+1).startsWith(D))continue;if(await this.deps.registry.findDeviceHolder(w.platform,M)||this.sessionsOn(C).length>0||(await this.deps.claims.describe(C)).kind!=="free")continue;if(await this.deps.matcher.matches(C,w.requestedSpec)==="match")return C}return}async existingSpec(d){let c=await this.deps.provisioner.readExistingSpec(d);if(!c)throw new ie(Z("discovery_incomplete",`The configuration of device '${d.name}' could not be read.`));return c}async createAndCommit(d,c,w,{replacing:D,...k}={}){return this.creation.createAndCommit(d,c,w,{replacing:D,...k})}async withEmptyBindingCleanup(d,c,w){return this.creation.withEmptyBindingCleanup(d,c,w)}async replaceAssigned(d,c,w,D){return this.creation.replaceAssigned(d,c,w,D)}async assertCreatable(d){return this.creation.assertCreatable(d)}sessionsOn(d){return this.deps.claims.sessionsOn?.(d)??[]}async releaseStaleSessions(d,c){let w=this.sessionsOn(c);if(w.length===0)return new Set;this.assertNoLiveExecutionOn(d,c,w);try{await Promise.all(w.map((D)=>this.deps.provisioner.releaseSession(D)))}catch(D){throw e.warn(`[Bindings] releasing stale session(s) on '${c.name}' failed: ${r(D)}`,D),new ie(Z("stale_session",`An earlier execution's session on '${c.name}' could not be released: ${r(D)}`))}return d.evidence.releasedStaleSessions=w,new Set(w)}assertNoLiveExecutionOn(d,c,w=this.sessionsOn(c)){let D=w.find((k)=>this.deps.claims.isLiveExecution?.(k));if(D!==void 0)throw new ie(Z("binding_in_use",`Binding ${d.request.key.bindingIndex} is held by live session ${D} on '${c.name}'.`))}async provisionExisting(d,c){let{request:w}=d,D=await this.releaseStaleSessions(d,c),k;try{k=await this.deps.provisioner.provision({platform:w.platform,name:c.name,...w.platform!=="android"&&c.deviceId?{deviceId:c.deviceId}:{},spec:ei(w.requestedSpec),mode:"adopt",deadlineMs:w.deadlineMs,signal:w.signal})}catch(P){throw new ie(It(P))}if(D.has(k.sessionUuid))throw await this.releaseSession(k.sessionUuid),new ie(Z("stale_session",`Provisioning '${c.name}' returned earlier session ${k.sessionUuid}.`));if(!v4(w.platform,k))throw await this.releaseSession(k.sessionUuid),new ie(Z("readiness_incomplete",`Device '${c.name}' did not reach ${wq(w.platform)}.`));return k}async releaseSession(d){try{await this.deps.provisioner.releaseSession(d)}catch(c){e.warn(`[Bindings] releasing unpublished session ${d} failed: ${r(c)}`,c)}}checkBudget(d){if(d.signal?.aborted)throw new ie(Z("cancelled","Binding preparation was cancelled."));if(this.deps.timer.now()>=d.deadlineMs)throw new ie(Z("timeout","Binding preparation deadline passed."))}async claimAndReady(d,c,w,{provisioned:D,reservation:k}){let{owner:P,key:C}=d.request;if(!P)return this.ready(d,c,w,D);let M=await this.deps.registry.claimExecution(C,Te(w),{...P,sessionUuid:D.sessionUuid},k?{supersedesSessionUuid:k}:{});if(M.kind!=="claimed")throw await this.releaseSession(D.sessionUuid),new ie(Ne(M,"execution claim"));return this.ready(d,c,M.assignment,D)}async readyOrReleaseOnBusy(d,c){let w=!1,D=async()=>{if(!w)w=!0,await this.releaseSession(d.sessionUuid)};try{return await c(D)}catch(k){if(Ja(k)==="retryable"||k instanceof Zr)await D();throw k}}ready(d,c,w,D){return{outcome:"ready",disposition:c,assignment:w,device:D.device,sessionUuid:D.sessionUuid,requestedSpec:d.request.requestedSpec,resolvedSpec:d.resolvedSpec,specFingerprint:d.fingerprint,readiness:D.readiness,...D.lifecycle!==void 0?{lifecycle:D.lifecycle}:{},evidence:d.evidence}}}var ob={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,w){return{code:d,retryable:w,message:c,nextAction:ob[d]??"Retry."}}function sb(d,c){return c!==void 0&&c>0?{createDeadlineMs:d-c}:{}}var ab=5000;class Bo{deps;closed=!1;closeController=new AbortController;backOutSessionReleases=new WeakMap;backOutOwnerReads=new WeakMap;backOutOwnerClears=new WeakMap;pacing;backOutCleanups=new Map;background=new Set;warnedBackOutCleanups=new WeakSet;constructor(d){this.deps=d;this.pacing=new Me({timer:d.timer,backoff:d.backOutRetryBackoff})}close(){this.closed=!0,this.closeController.abort(),this.pacing.close()}async whenIdle(){while(this.background.size>0)await Promise.allSettled([...this.background])}pendingBackOutCleanups(){return[...this.backOutCleanups.values()].map(({cleanup:d})=>({...d,key:{...d.key},ageMs:this.deps.timer.now()-d.owedSinceMs}))}async acquire(d,c){let w={managedHostScope:d.managedHostScope,runnerNamespace:d.runnerNamespace,runnerIncarnation:d.runnerIncarnation},D=(U,K)=>({contractVersion:1,scope:{...w,scopeKey:U,...K?{revived:K}:{}}}),k;try{k=rq(d.idleTimeoutMs)}catch(U){return{...D(null),outcome:"failed",bindings:[],failure:Ye("binding_config_invalid",r(U),!1)}}let P=this.deps.timer.now()+(d.preparationTimeoutMs??xo),C,M;try{C=await this.deps.registry(),M=await this.admitScope(C,w)}catch(U){if(U instanceof Zr)return e.warn(`[Bindings] Registry schema unsupported: ${r(U)}`,U),{...D(null),outcome:"failed",bindings:[],failure:Ye(U.code,r(U),U.retryable)};if(Ja(U)!=="retryable"&&!(U instanceof is))throw U;return{...D(zd(w)),outcome:"failed",bindings:[],failure:Z("discovery_incomplete",r(U))}}if(M.kind==="failed")return{...D(zd(w)),outcome:"failed",bindings:[],failure:M.failure};let{bindings:F,failure:q}=await this.acquireBindings(C,M.scopeKey,d.requests,{deadlineMs:P,...sb(P,d.createRetryReserveMs),idleTimeoutMs:k,livenessOwnerToken:c.livenessOwnerToken,signal:c.signal});return{...D(M.scopeKey,M.revived),outcome:q?"failed":"ready",idleTimeoutMs:k,bindings:F,...q?{failure:q}:{}}}async acquireBindings(d,c,w,D){let k=[],P=[],C;for(let M of w){let F={scopeKey:c,bindingIndex:M.bindingIndex},q=await this.acquireBinding(d,F,M,D);if(k.push(q),q.failure){C=q.failure;break}P.push({key:F,sessionUuid:q.sessionUuid})}if(!C&&D.signal?.aborted)C=Ye("cancelled","The binding acquisition was cancelled.",!0);if(C){await Promise.all(P.map(({key:M,sessionUuid:F})=>this.backOut(d,M,F)));for(let M of k)if(!M.failure)M.sessionUuid=null}return{bindings:k,failure:C}}async admitScope(d,c){let w=await d.ensureScope(c);switch(w.kind){case"ready":return{kind:"ready",scopeKey:w.scope.scopeKey,revived:w.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 '${w.current.runnerIncarnation}' is still being retired.`,!0)}}}async acquireBinding(d,c,w,D){let k;try{k=await this.deps.reconcile(d,{key:c,role:w.role,platform:w.platform,requestedSpec:w.requestedSpec,...w.priorDeviceHint?{priorDeviceHint:w.priorDeviceHint}:{},deadlineMs:D.deadlineMs,...D.createDeadlineMs===void 0?{}:{createDeadlineMs:D.createDeadlineMs},signal:D.signal,owner:this.deps.owner()})}catch(M){if(!(M instanceof Zr))throw M;return{bindingIndex:w.bindingIndex,role:w.role,platform:w.platform,assignmentGeneration:null,device:null,sessionUuid:null,requestedSpec:w.requestedSpec,resolvedSpec:null,specFingerprint:null,disposition:null,readiness:null,lifecycle:null,failure:Ye(M.code,r(M),M.retryable)}}if(k.outcome==="failed")return{bindingIndex:w.bindingIndex,role:w.role,platform:w.platform,assignmentGeneration:k.assignment?.generation??null,device:null,sessionUuid:null,requestedSpec:w.requestedSpec,resolvedSpec:k.assignment?.resolvedSpec??null,specFingerprint:null,disposition:null,readiness:null,lifecycle:{evidence:k.evidence},failure:k.failure};let P={bindingIndex:w.bindingIndex,role:w.role,platform:w.platform,assignmentGeneration:k.assignment.generation,device:k.device,sessionUuid:k.sessionUuid,requestedSpec:k.requestedSpec,resolvedSpec:k.resolvedSpec,specFingerprint:k.specFingerprint,disposition:k.disposition,readiness:k.readiness,lifecycle:{...k.lifecycle!==void 0?{provision:k.lifecycle}:{},evidence:k.evidence}},C=await this.handOff(k.sessionUuid,D);if(C)return await this.backOut(d,c,k.sessionUuid),{...P,sessionUuid:null,failure:C};return P}async handOff(d,c){try{let w=await this.deps.sessions.claimLivenessOwnership(d,c.livenessOwnerToken);if(w!=="claimed")return Ye("liveness_owner_conflict",`Session ${d} could not be claimed for this execution (${w}).`,!0);await this.deps.sessions.adoptManagedExecutionLivenessPolicy(d,{idleTimeoutMs:c.idleTimeoutMs});return}catch(w){return e.warn(`[Bindings] Holding session ${d} on the ${Xn} policy failed: ${r(w)}`,w),Ye("execution_policy_failed",r(w),!0)}}async backOut(d,c,w){let D=this.deps.timer.now(),k={key:{...c},sessionUuid:w,attempts:0,owedSinceMs:this.deps.timer.now(),ageMs:0,ownerClearOwed:!1,sessionReleaseOwed:!1,lastError:""};try{await d.releaseExecution(c,w)}catch(P){if(k.owedSinceMs=this.deps.timer.now(),k.ownerClearOwed=!0,k.lastError=r(P),!this.closed)e.info(`[Bindings] Clearing binding ${c.scopeKey}/${c.bindingIndex}'s owner ${w} failed: ${k.lastError}; cleanup continues in the background`,P)}try{await this.deps.sessions.releaseSession(w)}catch(P){if(!k.ownerClearOwed)k.owedSinceMs=this.deps.timer.now();if(k.sessionReleaseOwed=!0,k.lastError=r(P),!this.closed)e.info(`[Bindings] Releasing backed-out session ${w} for binding ${c.scopeKey}/${c.bindingIndex} failed: ${k.lastError}; cleanup continues in the background`,P)}if(k.ownerClearOwed||k.sessionReleaseOwed)this.retainBackOutCleanup(d,k),this.pacing.noteBlocked(D)}retainBackOutCleanup(d,c){let w=JSON.stringify([c.key.scopeKey,c.key.bindingIndex,c.sessionUuid]);if(this.closed)return;let D=this.backOutCleanups.get(w);if(D){D.cleanup.ownerClearOwed||=c.ownerClearOwed,D.cleanup.sessionReleaseOwed||=c.sessionReleaseOwed,D.cleanup.lastError=c.lastError;return}this.backOutCleanups.set(w,{registry:d,cleanup:c}),this.startBackOutRetry(w,d,c)}startBackOutRetry(d,c,w){let D=this.retryBackOutCleanup(d,c,w).catch((k)=>{if(!this.closed)w.lastError=r(k),e.warn(`${this.backOutCleanupLabel(w)} retry stopped; no task remains: ${w.lastError}`,k)}).finally(()=>this.background.delete(D));this.background.add(D)}async retryBackOutCleanup(d,c,w){for(let D=1;!this.closed;D++){if(await this.pacing.wait(this.pacing.delay(D)),this.closed)return;if(await this.pacing.run(()=>(w.attempts=D,this.retryBackOutOnce(c,w)),(P)=>P)){if(this.backOutCleanups.delete(d),!this.closed)e.info(`${this.backOutCleanupLabel(w)} landed after ${this.deps.timer.now()-w.owedSinceMs} ms (${w.attempts} retries)`);return}if(this.closed)return}}async retryBackOutOnce(d,c){let w=this.deps.timer.now()+Ee;try{if(c.sessionReleaseOwed){if(await this.retryBackOutStep(c,this.backOutSessionReleases,()=>this.deps.sessions.releaseSession(c.sessionUuid),{step:"session release",deadlineMs:w}),this.closed)return!1;c.sessionReleaseOwed=!1}if(c.ownerClearOwed){if(await this.retryBackOutOwnerClear(d,c,w),this.closed)return!1;c.ownerClearOwed=!1}return!0}catch(D){if(!this.closed)c.lastError=r(D),this.logBackOutRetryFailure(c,D);return!1}}async retryBackOutStep(d,c,w,{step:D,deadlineMs:k}){let P=k-this.deps.timer.now();if(P<=0)throw Error(`${this.backOutCleanupLabel(d)} ${D} attempt deadline reached`);let C=await l(()=>{let M=c.get(d);if(!M)M=w().then(void 0,(F)=>{throw c.delete(d),F}),c.set(d,M);return M},{timer:this.deps.timer,timeoutMs:P,signal:this.closeController.signal,label:`${this.backOutCleanupLabel(d)} ${D}`});return c.delete(d),C}async retryBackOutOwnerClear(d,c,w){let D=()=>this.retryBackOutStep(c,this.backOutOwnerClears,()=>d.releaseExecution(c.key,c.sessionUuid),{step:"owner clear",deadlineMs:w});if(this.backOutOwnerClears.has(c)){await D();return}let k=()=>this.retryBackOutStep(c,this.backOutOwnerReads,()=>d.getAssignment(c.key),{step:"ownership read",deadlineMs:w});if(this.backOutOwnerReads.has(c))await k();let P=(await k())?.execOwner;if(!this.closed&&P&&this.isBackedOutOwner(P,c.sessionUuid))await D()}logBackOutRetryFailure(d,c){let w=`${this.backOutCleanupLabel(d)} retry failed: ${d.lastError}`;e.debug(w,c);let D=this.deps.timer.now()-d.owedSinceMs;if(D>ab&&!this.warnedBackOutCleanups.has(d))this.warnedBackOutCleanups.add(d),e.warn(`${this.backOutCleanupLabel(d)} owed for ${D} ms (${d.attempts} retries): ${d.lastError}; retries continue with waits capped at 5 s`,c)}isBackedOutOwner(d,c){let w=this.deps.owner(),D=d.processGenerationToken??void 0,k=w.processGenerationToken??void 0;return d.sessionUuid===c&&d.pid===w.pid&&(D===void 0||k===void 0||D===k)}backOutCleanupLabel(d){return`[Bindings] Back-out cleanup for binding ${d.key.scopeKey}/${d.key.bindingIndex} session ${d.sessionUuid}`}}class Oo{deviceManager;watches;constructor(d,c){this.deviceManager=d;this.watches=c}async listImages(d,c){if(d!=="watchos")return await this.deviceManager.listDeviceImages(d,c);if(!this.watches)throw new yp("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,w){try{let D=await this.deviceManager.getBootedDevicesDetailed?.(d.platform,{signal:c.signal,bypassAndroidDeviceListCache:!0,skipForeignEnrichment:!0});if(c.signal?.throwIfAborted(),!D?.succeededPlatforms.has(d.platform))return;return D.devices.find((k)=>!k.foreignOwned&&k.platform===d.platform&&k.name===d.name&&ce(k.deviceId))?.deviceId}catch(D){c.signal?.throwIfAborted(),e.warn(`[Bindings] cannot resolve ${w}: ${r(D)}`,D);return}}async list(d,c){try{return{complete:!0,devices:await this.listImages(d,c.signal)}}catch(w){if(c.signal?.throwIfAborted(),d==="android"&&w instanceof Dk||d!=="android"&&w instanceof yp)return e.debug(`[Bindings] ${d} toolchain not installed: ${r(w)}`),{complete:!1,devices:[],toolchain:"not_installed"};return e.warn(`[Bindings] ${d} device inventory failed: ${r(w)}`,w),{complete:!1,devices:[]}}}}class ii extends Error{}var db=2000,_o=uc+db;class Fo{timer;assertAvailable;reserveCapacity;constructor(d,c=(D,k)=>CS(D,{signal:k}),w=Cq){this.timer=d;this.assertAvailable=c;this.reserveCapacity=w}async reserve(d,c){let w=new AbortController,D=c.signal?AbortSignal.any([c.signal,w.signal]):w.signal,k=this.timer.now()+c.timeoutMs,P=()=>Math.max(0,k-this.timer.now()),C=(q)=>l(q,{timer:this.timer,timeoutMs:Math.min(P(),_o),signal:c.signal,label:`Reserving ${d} boot capacity`,onTimeout:()=>w.abort(),timeoutError:()=>new ii(`Timed out reserving ${d} boot capacity.`)}),M=!1,F;try{let q=c.resolveReplacingDeviceId,U=q?await C(()=>q({signal:D})):c.replacingDeviceId;D.throwIfAborted();let K=await C(async()=>{if(F=await this.reserveCapacity(d,{...c,replacingDeviceId:U,timeoutMs:Math.max(1,P()),signal:D}),D.aborted)F.release(),D.throwIfAborted();return F});return M=!0,{kind:"available",reservation:K}}catch(q){return this.refusal(d,q)}finally{if(!M)w.abort(),F?.release()}}async check(d,c){let w=Math.min(c.timeoutMs??_o,_o),D=new AbortController,k=c.signal?AbortSignal.any([c.signal,D.signal]):D.signal;try{return await l(()=>this.assertAvailable(d,k),{timer:this.timer,timeoutMs:w,signal:c.signal,label:`Checking ${d} boot capacity`,onTimeout:()=>D.abort(),timeoutError:()=>new ii(`Timed out after ${w}ms checking ${d} boot capacity.`)}),{kind:"available"}}catch(P){return this.refusal(d,P)}finally{D.abort()}}refusal(d,c){if(c instanceof Un){let{externalDevices:w,heldDevices:D,ownershipUnknown:k}=c.details;return{kind:"exhausted",limit:c.limit,booted:c.booted,retryAfterMs:c.retryAfterMs,...w&&w.length>0?{externalDevices:w}:{},...D&&D.length>0?{heldDevices:D}:{},...k?{ownershipUnknown:!0}:{}}}if(c instanceof ze||c instanceof is||c instanceof ii)return e.warn(`[Bindings] ${d} boot capacity is unknown: ${r(c)}`,c),{kind:"unknown",message:r(c)};throw c}}class Lo{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),w=c.find((D)=>O(D)!==null);if(w)return{kind:"held",reason:`session ${O(w)} holds ${w.id}`};if(d.isRunningStateKnown===!1&&c.length===0)return{kind:"unknown",reason:"its running state could not be determined"};if(d.platform==="android"&&this.hasUnresolvedSessionRuntime())return{kind:"unknown",reason:"a session holds an emulator whose AVD is unresolved"};for(let D of c)try{await this.pool.assertNotClaimedByForeignDaemon(D.id,d.platform)}catch(k){return{kind:"held",reason:r(k)}}return{kind:"free"}}sessionsOn(d){return this.runtimesOf(d).flatMap((c)=>O(c)?[O(c)]:[])}hasUnresolvedSessionRuntime(){return this.pool.getAllDevices().some((d)=>d.platform==="android"&&O(d)!==null&&!d.avdName&&d.name.startsWith("Unknown ("))}runtimesOf(d){let c=he(d);return this.pool.getAllDevices().filter((w)=>w.platform===d.platform&&(d.platform==="android"?(w.avdName??w.name)===c:w.id===c))}}function mu(d,c){let{runtime:w,deviceType:D}=d.spec;if(D===void 0)throw new $e("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:w,deviceType:D}},boot:!0,readiness:"none",timeoutMs:c}}function hu(d){if(d.isAvailable===!1||!d.runtime||!d.deviceType)return null;return{runtime:d.runtime,deviceType:d.deviceType,displayCutout:"unknown"}}function ni(d){let c=d??{};if(c.structuredContent&&typeof c.structuredContent==="object")return{isError:c.isError===!0,payload:c.structuredContent};let w=c.content?.find((k)=>typeof k.text==="string")?.text,D={};if(w!==void 0)try{let k=JSON.parse(w);D=k&&typeof k==="object"?k:{}}catch(k){e.debug(`[Bindings] tool response text is not JSON: ${r(k)}`),D={message:w}}return{isError:c.isError===!0,payload:D}}function we(d){return typeof d==="string"&&d.length>0?d:void 0}function qo(d){return typeof d==="number"&&Number.isFinite(d)?d:void 0}function gu(d){return Array.isArray(d)?d.filter((c)=>typeof c==="string"):[]}function yu(d){return d!==null&&typeof d==="object"&&!Array.isArray(d)}function cb(d){let c=d.lifecycle;if(!yu(c)||!yu(c.device))return{};let w=c.device,D=we(w.name),k=[we(w.stableId),we(w.runtimeDeviceId)].find((C)=>C!==void 0&&C!==D),P=c.state==="created_not_ready"&&c.phase==="readiness"&&w.platform==="ios"&&k&&D?{platform:"ios",stableId:k,name:D}:void 0;return P?{retainedDevice:P}:{}}function lb(d,c){let w=d.error??{},D=we(w.code)??"platform_command_failed",k=we(w.message)??we(d.message)??c,P=typeof w.retryable==="boolean"?w.retryable:void 0,C=qo(w.limit),M=qo(w.booted),F=qo(w.retryAfterMs),q=gu(w.externalDevices),U=gu(w.heldDevices);return new $e(D,k,P,{...cb(d),...F!==void 0?{retryAfterMs:F}:{},...C!==void 0&&M!==void 0?{capacity:{limit:C,booted:M,...q.length>0?{externalDevices:q}:{},...U.length>0?{heldDevices:U}:{}}}:{}})}function ub(d,c){let w=d.device??{},D=d.readiness??{},k=we(w.identity?.stableId);if(!k)throw new $e("platform_command_failed",`provisionDevice '${c}' returned no stable device identity.`);return{device:{stableId:k,transportId:we(w.runtime?.deviceId)??null,name:we(w.name)??c},created:d.created===!0,sessionUuid:we(d.sessionId)??"",readiness:{mode:we(D.mode)??"none",status:we(D.status)??"unknown"},lifecycle:pb(d)}}function pb(d){let c={lifecycleState:d.lifecycleState};for(let w of["lifecycle","resources","timing"])if(d[w]!==void 0)c[w]=d[w];return c}function mb(d,c){return Math.max(1,Math.min(c,Math.floor(d)))}class Wo{deps;constructor(d){this.deps=d}async readExistingSpec(d){if(d.platform==="watchos")return hu(d);if(d.platform==="ios"){if(d.isAvailable===!1||!d.runtime||!d.deviceType)return null;return{runtime:d.runtime,deviceType:d.deviceType,displayCutout:TS("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:TS("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=mb(d.deadlineMs-this.deps.timer.now(),Qw),w=d.platform,D=w==="watchos"?mu(d,c):{...await this.exactProvisionArgs({...d,platform:w},c)},k=await this.deps.invokeTool("provisionDevice",D,d.signal),{isError:P,payload:C}=ni(k);if(P)throw lb(C,`provisionDevice '${d.name}' failed`);return ub(C,d.name)}async exactProvisionArgs(d,c){let w={...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:w},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 w=(await this.deps.androidConfigReader.readConfig(d.name))?.deviceName;if(w)return w}else{let w=(await this.deps.deviceManager.listDeviceImages("ios",d.signal)).find((D)=>d.deviceId?D.deviceId===d.deviceId:D.name===d.name)?.deviceType;if(w)return w}throw new $e("discovery_incomplete",`The model of ${d.platform} device '${d.name}' could not be read.`)}}var fb=100,hb=5000;class Vo{journal;timer;intervalMs;stopped=!1;running;stopping;controller=new AbortController;cancelWait;constructor(d,c,w=hb){this.journal=d;this.timer=c;this.intervalMs=w}start(){if(!this.stopped)this.running??=this.loop()}stop(d=fb){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 gb={listInstalledPackages:async(d)=>(await _u(void 0,void 0,d)).map((c)=>c.packageName)},yb={listProfileIds:async(d)=>(await NR(void 0,d)).map((c)=>c.id)};function Sb(d={},c){let w=process.platform==="darwin"?new ha(new L(null)):void 0;return{deviceManager:d.deviceManager??(c?new si().withForeignAndroidSerialSource(c):new si),androidConfigReader:d.androidConfigReader??new Br,androidImageCatalog:d.androidImageCatalog??gb,androidProfileCatalog:d.androidProfileCatalog??yb,iosRuntimeCatalog:d.iosRuntimeCatalog??(process.platform==="darwin"?new L(null):void 0),watchInventory:d.watchInventory??w,watchCatalog:d.watchCatalog??w,checkBootCapacity:d.checkBootCapacity,reserveBootCapacity:d.reserveBootCapacity}}var ai=async(d,c,w)=>await Kf().callInternal(d,c,{signal:w});function Su(d){let c=(M)=>xl(d.pool,M),w=d.invokeTool??ai,D=new WeakMap,k=new WeakMap,P=(M)=>{let F=D.get(M);if(!F){let q=Sb(d.tooling,d.pool.foreignSerials?{foreignSerials:(J,X)=>d.pool.foreignSerials(J,X)}:void 0),{deviceManager:U,androidConfigReader:K}=q,W=new Oo(U,q.watchInventory),V=new Lo(d.pool,d.executions),z=d.resourceBudgetPolicy?new so({registry:async()=>M,policy:d.resourceBudgetPolicy,inventory:W,timer:d.timer}):void 0;F=new Mo({registry:M,inventory:W,...z?{resourceBudget:z}:{},isBusy:c,matcher:new Yi(K),resolver:new Ji(q.iosRuntimeCatalog,{androidImageCatalog:q.androidImageCatalog,androidProfileCatalog:q.androidProfileCatalog,watchCatalog:q.watchCatalog}),provisioner:d.tooling?.provisioner??new Wo({invokeTool:w,deviceManager:U,androidConfigReader:K,timer:d.timer,releaseSession:(J)=>d.sessions.releaseSession(J),discardAndroidSnapshotOnExit:d.discardAndroidSnapshotOnExit}),deleter:d.tooling?.deleter??new ao(d.timer),claims:V,...d.executions?{isExecOwnerLive:kq(lc,d.executions)}:{},capacity:new Fo(d.timer,q.checkBootCapacity,q.reserveBootCapacity),timer:d.timer,journal:{owner:d.journal.owner,inFlight:d.journal.inFlight}}),D.set(M,F)}return F};return{acquisition:new Bo({registry:d.registry,reconcile:(M,F)=>t0(F.key,()=>P(M).reconcile(F)),sessions:d.sessions,owner:d.owner,timer:d.timer}),startJournalRedrive:(M)=>{let F=k.get(M);if(!F)F=new Vo(P(M).journal,d.timer),k.set(M,F),F.start();return F},journalFor:(M)=>P(M).journal}}var Jo="watchos-keep-booted-unsupported: a watch session has no mutation journal, pool-entry app baseline or CtrlProxy health probe, so keep-booted cleaning cannot prove it clean",bu="watchos-minimal-unsupported: the session's installed watch apps are not journaled and the minimal appearance, content-size, pasteboard and Files-fixture steps have no watchOS equivalent; minimal mode never erases, so the watch is destroyed";class jo{dependencies;constructor(d){this.dependencies=d}async resetWithTiming(d,c,w,D={}){bb(d,c);let k=this.dependencies.policy;switch(k.mode){case"erase":return this.erase(d,c,w,{...D,mode:"erase"});case"keep-booted":if(k.fallback==="destroy")return e.info(`[SessionBroker] watch ${d.deviceId} keep-booted release destroys: ${Jo}`),{outcome:"pending",mode:"keep-booted",phases:{},fallbackReason:Jo};return this.erase(d,c,w,{...D,mode:"keep-booted",fallbackReason:Jo});case"minimal":return e.info(`[SessionBroker] watch ${d.deviceId} minimal release destroys: ${bu}`),{outcome:"pending",mode:"minimal",phases:{},fallbackReason:bu}}}async erase(d,c,w,{signal:D,runResetBoot:k,mode:P,fallbackReason:C}){let M={},F=async()=>{D?.throwIfAborted(),await w(),D?.throwIfAborted()};try{await F();let q=()=>this.reservedEraseAndBoot(d,c,F,{phases:M,signal:D});await(k?k(q):q()),await F()}catch(q){throw new _i(r(q),{outcome:"pending",mode:P,phases:M,fallbackReason:r(q)},{cause:q})}return P==="erase"?{outcome:"clean",mode:P,phases:M}:{outcome:"fallback:erase",mode:P,phases:M,...C?{fallbackReason:C}:{}}}async reservedEraseAndBoot(d,c,w,D){let k=await this.dependencies.reserveBoot?.({replacingDeviceId:d.deviceId,timeoutMs:Ve,reason:"reset",signal:D.signal}),P=()=>this.eraseAndBoot(d,c,w,D);try{await(k?k.run(P):P())}finally{k?.release()}}async eraseAndBoot(d,c,w,{phases:D,signal:k}){if((await this.expectedWatch(d,c,k,"start watch reset")).isRunning)await w(),await this.measure(D,"stop",()=>this.dependencies.stopDevice(d));let C=await this.expectedWatch(d,c,k,"erase watch");if(C.state!=="Shutdown")throw new t(`Cannot erase Apple Watch simulator '${d.deviceId}': it is ${C.state}, not Shutdown`);if(await w(),await this.measure(D,"erase",()=>this.dependencies.simctl.eraseSimulator(d.deviceId)),await w(),await this.measure(D,"boot",()=>this.dependencies.lifecycle.boot(C,{timeoutMs:Ve,signal:k})),!(await this.expectedWatch(d,c,k,"confirm erased watch")).isRunning)throw new t(`Apple Watch simulator '${d.deviceId}' did not report Booted after its erase`)}async expectedWatch(d,c,w,D){let k=await this.dependencies.lifecycle.findWatch({deviceId:d.deviceId},w);if(k.runtimeId!==c.runtime||k.deviceType!==c.deviceType)throw new t(`Cannot ${D}: Apple Watch simulator '${d.deviceId}' is ${k.deviceType??"an unknown device type"} on ${k.runtimeId??"an unknown runtime"}, not ${c.deviceType} on ${c.runtime}`);return k}async measure(d,c,w){let D=this.dependencies.timer.now();try{return await w()}finally{d[c]=this.dependencies.timer.now()-D}}}function bb(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 wb(d){let c=YN(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 Db(d,c=Go){let w=c.iosBootInstrumentation();return w.reserveBoot?w.reserveBoot(d):Promise.resolve({run:(D)=>D(),markReplacedDeviceGone:()=>{},release:()=>{}})}function wu(d,c){let w=wb(d);if(!w)return;let D=new L(null),k=new jo({policy:w,timer:c,simctl:D,lifecycle:new FR(D,new ha(D),{run:(P,C)=>Go.iosBootInstrumentation().run(P,C)}),reserveBoot:Db,stopDevice:async(P)=>{let C=ni(await ai("killDevice",{device:P},void 0));if(C.isError||C.payload.success===!1)throw new t("Provider watch shutdown did not confirm a clean teardown")}});return(P,C,M,F)=>k.resetWithTiming(P,C,M,F)}function Xe(d){if((d.platform==="android"?[d.resourceId,d.stableDeviceId,...d.bootId===null?[]:[d.bootId]]:[d.scopeKey,d.stableDeviceId]).some((w)=>typeof w!=="string"||!w.trim())||d.platform==="ios"&&(!Number.isSafeInteger(d.allocationIndex)||d.allocationIndex<0))throw new t("Mutation incarnation requires non-empty identities and a safe non-negative allocation index");return JSON.stringify(d.platform==="android"?[d.resourceId,d.stableDeviceId,d.bootId]:[d.scopeKey,d.allocationIndex,d.stableDeviceId])}function Xi(d){let{resource:c,stableDeviceId:w}=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:w,incarnation:Xe({platform:"ios",scopeKey:c.scopeKey,allocationIndex:c.allocationIndex,stableDeviceId:w})}:{sessionUuid:d.sessionUuid,deviceId:d.transportId??w,incarnation:Xe({platform:"android",resourceId:c.resourceId,stableDeviceId:w,bootId:d.bootId??null})}}class Xo{journal;scope;constructor(d,c){this.journal=d;eu(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:Nn("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),w=new Set(c.map((D)=>JSON.stringify([D.kind,D.key])));return d.filter((D)=>!w.has(JSON.stringify([D.kind,D.key])))}readBaseline(){return this.journal.getBaseline(this.scope)}async baselinePrior(d,c){let w=await this.journal.getBaseline(this.scope);if(!w?.completeKinds.includes(d)||w.unobservable.includes(d))return{state:"unobservable"};return w.observations.find((D)=>D.kind===d&&D.key===c)?.value??{state:"absent"}}}var Ru=Xr(()=>g({name:y(),durationMs:T().finite().nonnegative(),children:Du.optional()})),Du=Xr(()=>Fe([j(Ru),Ct(y(),Ru)])),kb=g({provision:g({timing:Du.nullable().optional()})});function ku(d){let c=kb.safeParse(d);if(!c.success||!c.data.provision.timing)return;let w={},D=(k)=>{for(let P of Object.values(k)){if(P.name==="provisionExactDevice")w.createMs=P.durationMs;if(P.name==="bootDevice")w.bootMs=P.durationMs;if(P.name==="ensureCtrlProxy iOS"||P.name==="ensureAccessibilityService")w.automationReadyMs=P.durationMs;if(P.children)D(P.children)}};return D(c.data.provision.timing),w}class Qo{dependencies;managesResetBootSlots=!0;androidDevices=new Map;scope;scopeKey;isExecOwnerLive;constructor(d){this.dependencies=d;this.scope={...d.scope},this.scopeKey=zd(this.scope),this.isExecOwnerLive=d.isExecOwnerLive??lc}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 w=Mn(d),D=this.requestedDevice(w),k=this.dependencies.timer??i,P=k.now()+(c.preparationTimeoutMs??xo),C=(W,V=0)=>{let z=this.bindingConfig(d,D,{...c,preparationTimeoutMs:Math.max(1,W)});return this.dependencies.brokerDeviceAcquisition.acquire(V>0?{...z,createRetryReserveMs:V}:z,{livenessOwnerToken:c.livenessOwnerToken,...c.signal?{signal:c.signal}:{}})},M=P-k.now(),F=w.platform==="ios"?Math.min(M/3,Ua):0,q=await C(M,F);if(this.canRetryReadiness(q,d,w)&&!this.preparationStopped(P,c.signal)){if(await this.waitForRetry(Math.min(P-k.now(),25),c.signal),!this.preparationStopped(P,c.signal))q=await C(P-k.now())}let U=await this.readySessionId(q,d,w);await this.captureBaselinesHoldingLease(d,q,w,{sessionId:U,signal:c.signal,deadlineMs:P,deviceProfileOptions:c});let K=q.bindings.find((W)=>W.bindingIndex===d.allocationIndex);return{sessionId:U,profile:await A7(w,K,this.dependencies.androidConfigReader),timing:ku(K?.lifecycle)}}async applyDeviceProfile(d,c,w,D){let k=D.deviceProfile;if(!k)return;let P=this.androidDevices.get(d.resourceId)?.device??Ab(c),M=await(this.dependencies.manufacturerProfileApplier??UU).apply(P,k,w,D.signal);if(M.status==="route_to_real_device")throw new t(M.message);e.info(`[SessionBroker] ${M.message}`)}async captureBaselinesHoldingLease(d,c,w,D){let{sessionId:k}=D,P=this.dependencies.leaseKeepalive?.hold({taskId:d.requestId,ownerKey:"session-broker",sessionUuid:k});try{if(await this.captureAndroidBaseline(d,c,w,D),w.platform==="ios"&&this.dependencies.captureIosBaseline)await this.capturePoolEntryBaseline(d,k,D);await this.applyDeviceProfile(d,c,k,D.deviceProfileOptions)}finally{P?.()}}async captureAndroidBaseline(d,c,w,D){let{sessionId:k}=D,P=this.dependencies.resetBaseline?.android;if(w.platform!=="android"||!P||!P.canCapture)return;this.androidDevices.delete(d.resourceId);try{let C=c.bindings[0],M=C?.device;if(!M?.transportId||typeof C?.assignmentGeneration!=="number")throw new t("Android reset baseline requires the acquired emulator serial");let F={platform:"android",name:M.name,deviceId:M.transportId};this.androidDevices.set(d.resourceId,{device:F,generation:C.assignmentGeneration,stableDeviceId:M.stableId});let q=await t0(this.key(d),()=>P.capture(d.resourceId,F,w,{sessionId:k,fresh:C.disposition==="created"||C.disposition==="replaced",signal:D.signal,timeoutMs:Math.max(0,D.deadlineMs-(this.dependencies.timer??i).now()),timer:this.dependencies.timer??i,stableDeviceId:M.stableId,assertOwned:async()=>{D.signal?.throwIfAborted();let U=await this.dependencies.registry.getAssignment(this.key(d));if(!U||!jd(U,{generation:C.assignmentGeneration,stableDeviceId:M.stableId})||U.state!=="ready"||U.deviceName!==F.name||U.execOwner?.sessionUuid!==k||U.settler!==null||await this.hasOpenJournal(this.key(d)))throw new t("Android baseline capture lost exclusive binding ownership")}}));if(q)this.bindSessionMutationRecorder(C,d,w,q.bootId)}catch(C){await this.handleAndroidBaselineCaptureFailure(d.resourceId,P,D,C)}}async handleAndroidBaselineCaptureFailure(d,c,w,D){if(await c.forget(d),this.androidDevices.delete(d),w.signal?.throwIfAborted(),this.preparationStopped(w.deadlineMs,w.signal))throw new t("Android reset baseline capture exceeded preparation deadline");e.warn(`Android reset baseline unavailable; device will be destroyed on release: ${r(D)}`,D)}async capturePoolEntryBaseline(d,c,w){let D=this.dependencies.timer??i,k=new AbortController,P=je(k.signal,w.signal)??k.signal,C;try{if(P.throwIfAborted(),this.preparationStopped(w.deadlineMs,P))throw new t("iOS reset baseline capture exceeded preparation deadline");let M=this.key(d),F=await this.dependencies.registry.getAssignment(M);if(!F?.stableDeviceId||F.execOwner?.sessionUuid!==c)throw new t("iOS baseline capture requires the acquired execution binding");let q=async()=>{if(P.throwIfAborted(),this.preparationStopped(w.deadlineMs,P))throw new t("iOS reset baseline capture exceeded preparation deadline");let U=await this.dependencies.registry.getAssignment(M);if(!U||!jd(U,F)||U.state!=="ready"||U.execOwner?.sessionUuid!==c||U.settler!==null||await this.hasOpenJournal(M))throw new t("iOS baseline capture lost execution binding ownership")};C=q,await l(()=>this.dependencies.captureIosBaseline({scope:{...this.mutationScope(d,F),sessionUuid:c},assertOwned:q,signal:P}),{timer:D,signal:P,timeoutMs:Math.max(0,w.deadlineMs-D.now()),label:"iOS pool-entry baseline capture",timeoutError:()=>new DOMException("iOS reset baseline capture exceeded preparation deadline","TimeoutError"),onTimeout:()=>k.abort(new DOMException("iOS baseline preparation deadline","TimeoutError"))}),await q()}catch(M){if(e.warn(`Skipping iOS pool-entry baseline; release erases if app baseline is unavailable: ${r(M)}`,M),w.signal?.throwIfAborted(),this.preparationStopped(w.deadlineMs,w.signal))throw u(M,"iOS reset baseline capture exceeded preparation deadline");if(!C)throw u(M,"Cannot capture iOS pool-entry baseline after ownership loss");await C()}}preparationStopped(d,c){return c?.aborted===!0||(this.dependencies.timer??i).now()>=d}canRetryReadiness(d,c,w){let D=d.bindings.find((C)=>C.bindingIndex===c.allocationIndex);if(!D?.failure)return!1;let k=D.failure,P=k.code==="readiness_incomplete"||k.code==="timeout"||k.code==="provision_failed"&&k.provision?.code==="timeout";return[w.platform==="ios",d.outcome==="failed",d.scope.scopeKey===this.scopeKey,d.bindings.length===1,D.sessionUuid===null,k.retryable,k.retainedDevice?.platform==="ios",P].every(Boolean)}async waitForRetry(d,c){let w=this.dependencies.timer??i,D;try{await l(()=>new Promise((k)=>{D=w.setTimeout(k,d)}),{timer:w,signal:c,label:"Managed device readiness retry"})}catch(k){throw new ka({code:c?.aborted?"cancelled":"session_preparation_failed",retryable:c?.aborted===!0,message:c?.aborted?"The binding acquisition was cancelled.":r(k)})}finally{if(D!==void 0)w.clearTimeout(D)}}async readySessionId(d,c,w){let D=d.bindings.find((q)=>q.bindingIndex===c.allocationIndex);if([d.outcome==="ready",d.scope.scopeKey===this.scopeKey,d.bindings.length===1].every(Boolean)&&this.isReadyBinding(D,w))return this.bindSessionMutationRecorder(D,c,w),D.sessionUuid;let P=D===void 0?null:D.sessionUuid;if(typeof P==="string"&&P.length>0)await this.dependencies.brokerExecutionRelease.releaseExecution(P);let{code:C,retryable:M,message:F}=d.failure??D?.failure??{code:"session_preparation_failed",retryable:!1,message:"Managed device preparation did not return an automation-ready session"};throw new ka({code:C,retryable:M,message:F})}bindSessionMutationRecorder(d,c,w,D=null){if(!this.dependencies.bindMutationRecorder||w.platform==="watchos")return;try{this.dependencies.bindMutationRecorder(Xi({platform:w.platform,sessionUuid:d.sessionUuid,resource:c,stableDeviceId:d.device.stableId,transportId:d.device.transportId,assignmentGeneration:d.assignmentGeneration,bootId:D}))}catch(k){e.warn("Failed to bind broker device mutation recorder; acquiring without recording",k)}}isReadyBinding(d,c){if(d===void 0||d.readiness===null)return!1;if(typeof d.sessionUuid!=="string"||d.sessionUuid.length===0)return!1;let w=c.platform==="watchos"?WI:{mode:"automation",status:"automation_ready"};return[d.platform===c.platform,d.failure===void 0,d.device!==null,d.readiness.mode===w.mode,d.readiness.status===w.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,w){this.assertResource(d,"resetting");let D=Mn(d),k=this.dependencies.resetBaseline?.ios,P=this.dependencies.resetBaseline?.android,C=this.dependencies.resetBaseline?.watch,M=this.dependencies.isCurrentReset;if(!M||!this.hasReset(D.platform))return"pending";let F=this.key(d),q=await this.dependencies.registry.getAssignment(F);if(!q?.stableDeviceId||!q.deviceName)throw new t("Reset requires a current bound native device");let U=q.deviceName,K={generation:q.generation,stableDeviceId:q.stableDeviceId},W=async()=>{if(c?.throwIfAborted(),!await M(d))throw new t("Clean reset no longer owns its durable resource revision");let z=await this.dependencies.registry.getAssignment(F);if(!(z&&jd(z,K)&&z.state==="ready"&&z.execOwner===null&&z.settler===null&&z.deviceName===U&&this.belongsToResource(z,D,this.requestedSpec(D)))||await this.hasOpenJournal(F))throw new t("Clean reset lost exclusive native binding ownership")};await W();let V=await t0(F,async()=>{if(D.platform==="watchos"&&C)return C({platform:"watchos",deviceId:K.stableDeviceId,name:U},D,W,{signal:c,runResetBoot:w});if(D.platform==="ios"&&k)return k({platform:"ios",deviceId:K.stableDeviceId,name:U},D,W,{signal:c,context:{resource:d,scope:this.mutationScope(d,q),runResetBoot:w}});if(!P||D.platform!=="android")throw new t("Android reset dispatch requires an Android reset implementation and profile");if(!P.canCapture)throw new t("Android reset is destruction-only: no androidResetMode reset strategy is configured");let z=this.androidResetTarget(d,q,U);return P.reset(d.resourceId,z,D,{assertOwned:W,signal:c})});return await W(),V}hasReset(d){let c=this.dependencies.resetBaseline;switch(d){case"ios":return c?.ios!==void 0;case"android":return c?.android!==void 0;case"watchos":return c?.watch!==void 0}}androidResetTarget(d,c,w){let D=this.androidDevices.get(d.resourceId);if(!D)throw new t("Android reset baseline was not captured at acquisition");let k=[];if(!this.sameReleasedBinding(c,D))k.push("generation");if(D.stableDeviceId!==c.stableDeviceId)k.push("stableDeviceId");if(D.device.name!==w)k.push("deviceName");if(c.stableDeviceId!==w)k.push("avdName");if(k.length>0)throw e.warn(`Android reset acquired transport identity mismatch: ${k.join(", ")}`,{resourceId:d.resourceId,fields:k,acquired:{generation:D.generation,stableDeviceId:D.stableDeviceId,deviceName:D.device.name},expected:{generation:c.generation,stableDeviceId:c.stableDeviceId,deviceName:w}}),new t(`Android reset lacks its original acquired transport identity (mismatched: ${k.join(", ")})`);return D.device}mutationScope(d,c){if(!c.stableDeviceId)throw new t("iOS mutation scope requires an exact bound device");return{deviceId:c.stableDeviceId,incarnation:Xe({platform:"ios",scopeKey:d.scopeKey,allocationIndex:d.allocationIndex,stableDeviceId:c.stableDeviceId})}}async destroy(d,c){c?.throwIfAborted(),this.assertResource(d,"destroying");let w=Mn(d);if(w.platform==="android")await this.dependencies.resetBaseline?.android?.forget(d.resourceId),this.androidDevices.delete(d.resourceId);let D=this.requestedSpec(w),k=this.key(d);if(await this.redriveOpenJournal(k,c)==="pending")return"pending";c?.throwIfAborted();let P=await this.destroyableAssignment(k,w,D);if(typeof P==="string")return P;c?.throwIfAborted();let C=await this.drainAssignment(k,P,w,D);return c?.throwIfAborted(),typeof C==="string"?C:this.deleteAssignment(k,C,c)}async destroyableAssignment(d,c,w){let D=await this.dependencies.registry.getAssignment(d);if(!D||D.stableDeviceId===null)return this.confirmNoBinding(d);return this.belongsToResource(D,c,w)?D:"pending"}async drainAssignment(d,c,w,D){if(!c.execOwner)return c;if(!Uc(c.execOwner,this.dependencies.bindingJournal.owner))return this.isExecOwnerLive(c.execOwner)?"pending":c;if(!(await this.release(c.execOwner.sessionUuid)).settled)return"pending";let P=await this.dependencies.registry.getAssignment(d);if(!P)return this.confirmNoBinding(d);return[this.sameReleasedBinding(P,c),P.state==="ready",P.settler===null,P.execOwner===null,this.belongsToResource(P,w,D)].every(Boolean)?P:"pending"}sameReleasedBinding(d,c){return jd(d,c)||jd(d,{...c,generation:c.generation+1})}async deleteAssignment(d,c,w){if(c.stableDeviceId===null)return this.confirmNoBinding(d);let D=c.stableDeviceId;w?.throwIfAborted();let k=await this.dependencies.registry.openBindingJournal(d,{kind:"replace",phase:"deleting",owner:this.dependencies.bindingJournal.owner,target:{oldStableId:D,oldName:c.deviceName,newName:null,newStableId:null,requestedSpec:c.requestedSpec,resolvedSpec:c.resolvedSpec,specFingerprint:c.specFingerprint},assignment:{kind:"state",expected:{generation:c.generation,stableDeviceId:D},state:"replacing"}});if(k.kind!=="opened"&&k.kind!=="journal_open")return"pending";w?.throwIfAborted();let P=await this.dependencies.bindingJournal.redriveBinding(d,{signal:w});if(w?.throwIfAborted(),P.kind==="blocked"||await this.hasOpenJournal(d))return"pending";let C=await this.dependencies.registry.getAssignment(d);return!C||C.stableDeviceId===null?"absent":"pending"}async confirmNoBinding(d){let c=await this.dependencies.registry.getAssignment(d);if(c!==null&&(c.stableDeviceId!==null||c.execOwner!==null||c.settler!==null))return"pending";return await this.hasOpenJournal(d)?"pending":"absent"}assertResource(d,c){if(!d.resourceId.trim())throw new t("A broker resource identity must be non-empty");if(!Number.isSafeInteger(d.allocationIndex)||d.allocationIndex<0||d.scopeKey!==this.scopeKey)throw new t("Broker resource does not belong to this provider-owned scope");if(d.state!==c)throw new t(`Broker resource '${d.resourceId}' must be ${c}, not ${d.state}`)}key(d){return{scopeKey:this.scopeKey,bindingIndex:d.allocationIndex}}bindingConfig(d,c,w){return{contractVersion:1,...this.scope,localBindingCapacity:1,requests:[{bindingIndex:d.allocationIndex,role:eh,...c}],...w.preparationTimeoutMs===void 0?{}:{preparationTimeoutMs:w.preparationTimeoutMs},...w.idleTimeoutMs===void 0?{}:{idleTimeoutMs:w.idleTimeoutMs},...w.executionOwnerPid===void 0?{}:{executionOwnerPid:w.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=tn(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,w){if(d.scopeKey!==this.scopeKey||d.role!==eh||d.platform!==c.platform)return!1;let D=d.requestedSpec;if(!D||typeof D!=="object")return!1;let k=D;return k.runtime===w.runtime&&k.deviceType===w.deviceType&&k.configuration?.memoryMb===("configuration"in w?w.configuration?.memoryMb:void 0)}async redriveOpenJournal(d,c){if(!await this.hasOpenJournal(d))return"clear";c?.throwIfAborted();let w=await this.dependencies.bindingJournal.redriveBinding(d,{signal:c});return c?.throwIfAborted(),w.kind==="clear"&&!await this.hasOpenJournal(d)?"clear":"pending"}async hasOpenJournal(d){return(await this.dependencies.registry.listOpenBindingJournal(d)).length>0}}function Ab(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 Tt(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 di(d,c,w,{state:D,action:k,timeoutMs:P,signal:C}){let M;try{M=P!==void 0?await d.readSimulatorTarget(c,P,C):await d.readSimulatorTarget(c)}catch(q){throw u(q,`Cannot ${k}: fresh iOS simulator inventory failed`)}if(!M||M.udid!==c)throw new t(`Cannot ${k}: fresh iOS simulator inventory did not prove one exact target '${c}'`);let F=dD(M.runtime,M.os_version);if(![M.isAvailable===!0,M.deviceTypeIdentifier===w.simulatorDeviceTypeIdentifier,M.runtime===w.runtimeId,KL(F,w.osVersion)===0,M.state===D].every(Boolean))throw new t(`Cannot ${k}: simulator '${c}' lacks authoritative ${D} identity, runtime, type, OS, or availability evidence`)}var Pb=60000;class Zo{dependencies;timer;deferredBoots=new Set;constructor(d,c=i){this.dependencies=d;this.timer=c}async reset(d,c,w,D){return await this.runReset(d,c,w,{phases:{},signal:D}),"clean"}async resetWithTiming(d,c,w,D){let k={};try{return await this.runReset(d,c,w,{phases:k,signal:D})}catch(P){throw new _i(r(P),{outcome:"pending",mode:"erase",phases:k,fallbackReason:r(P)},{cause:P})}}async runReset(d,c,w,{phases:D,signal:k}){let P=async()=>{k?.throwIfAborted(),await w(),k?.throwIfAborted()};Tt(d,c);let C=this.deferredBoots.delete(d.deviceId);await this.readExpectedTarget(d.deviceId,c,C?"Shutdown":"Booted","start reset"),await P();let M;try{M=await this.reserveResetBoot(d.deviceId,P,k)}catch(q){if(C)this.deferredBoots.add(d.deviceId);throw u(q,"Cannot reserve iOS reset boot slot")}let F=()=>this.eraseAndBoot(d,c,P,{phases:D,deferredBoot:C,signal:k});try{return await(M?M.run(F):F())}finally{M?.release()}}async reserveResetBoot(d,c,w){let D=this.timer.now(),k=D+Ve,P=Q({initialDelayMs:1000,maxDelayMs:8000}),C=0,M=0;for(;;){w?.throwIfAborted();let F=this.timer.now();try{return await this.dependencies.iosBootInstrumentation.reserveBoot?.({replacingDeviceId:d,timeoutMs:k-this.timer.now(),reason:"reset",signal:w})}catch(q){if(q instanceof Un){await this.waitResetCapacity({error:q,deviceId:d,startedAt:D,owned:c,delayMs:P.delayForAttempt(++M)}),k+=this.timer.now()-F;continue}let U=P.delayForAttempt(++C);if(!(q instanceof ze)||k-this.timer.now()<=U)throw u(q,"Cannot reserve iOS reset boot slot");if(await this.timer.sleep(U),await c(),this.timer.now()>=k)throw u(q,"Cannot reserve iOS reset boot slot")}}}async waitResetCapacity(d){let{error:c,deviceId:w,startedAt:D,owned:k,delayMs:P}=d,C=D+Pb;if(this.timer.now()+P>C||this.timer.now()>=C)throw new VI(w,this.timer.now()-D,c);if(await this.timer.sleep(P),await k(),this.timer.now()>=C)throw new VI(w,this.timer.now()-D,c)}async eraseAndBoot(d,c,w,{phases:D,deferredBoot:k,signal:P}){if(this.dependencies.iosBootInstrumentation.reserveBoot)await w();if(!k)await this.measureStep(d.deviceId,"stop",D,()=>this.dependencies.stopDevice(d));await this.readExpectedTarget(d.deviceId,c,"Shutdown","erase simulator"),await w(),await this.measureStep(d.deviceId,"erase",D,()=>this.dependencies.simctl.eraseSimulator(d.deviceId));let C=await this.measureStep(d.deviceId,"boot",D,()=>this.bootAdmitted(d.deviceId,c,w,P));if(C.platform!=="ios"||C.deviceId!==d.deviceId)throw new t(`iOS baseline reset booted a different target instead of simulator '${d.deviceId}'`);return await this.readExpectedTarget(d.deviceId,c,"Booted","confirm clean baseline"),await w(),{outcome:"clean",mode:"erase",phases:D}}async bootAdmitted(d,c,w,D){let k=!1;try{return await this.dependencies.iosBootInstrumentation.run({udid:d,runtime:c.runtimeId,timeoutMs:Ve,reason:"reset",signal:D},async()=>(k=!0,await w(),this.dependencies.simctl.bootSimulator(d)))}catch(P){if(P instanceof Un||!k&&P instanceof ze)this.deferredBoots.add(d);throw u(P,"Cannot boot erased iOS simulator")}}async measureStep(d,c,w,D){let k=this.timer.now(),P=!1;e.info(`[SessionBroker] iOS baseline reset ${c} started for ${d}`);try{let C=await D();return P=!0,C}finally{w[c]=this.timer.now()-k,e.info(`[SessionBroker] iOS baseline reset ${c} ${P?"completed":"failed"} for ${d} after ${this.timer.now()-k}ms`)}}async readExpectedTarget(d,c,w,D){await di(this.dependencies.simctl,d,c,{state:w,action:D})}}function nn(d){let c=d.kind==="installed-app"&&d.priorValue.state==="absent",w=d.kind==="clipboard"&&(d.priorValue.state==="absent"||d.priorValue.state==="present"&&(d.priorValue.value===""||d.priorValue.value===null));return c||w?{kind:d.kind,key:d.key,priorValue:d.priorValue,toolName:"baseline-diff"}:null}function es(d,c,w){let D=new Set(kS),k=[...c.dirty],P=[...d].sort((C,M)=>M.sequence-C.sequence).map((C)=>({source:"journal",mutation:C}));for(let C of c.changes.filter((M)=>!M.journaled)){let M=w.baselineRevert?.(C,c.changes)??nn(C);if(M){if(!P.some((F)=>F.mutation.kind===M.kind&&F.mutation.key===M.key))P.push({source:"baseline",mutation:M})}else k.push(`Unjournaled ${C.kind}:${C.key}`)}for(let C of P){if(C.mutation.priorValue.state==="unobservable"){k.push(`Unobservable prior value ${C.mutation.kind}:${C.mutation.key}`);continue}if(!D.has(C.mutation.kind)||!w.canRevert(C.mutation))k.push(`Unsupported ${C.mutation.kind}:${C.mutation.key}`)}return k.length>0?{status:"non_revertible",reasons:k}:{status:"revertible",steps:P}}class ts{dependencies;budgetTimeouts=new WeakSet;pending=new Map;eraseReasons=new Map;constructor(d){this.dependencies=d;if(!Number.isSafeInteger(d.maxUses)||d.maxUses<1)throw new t("iOS keep-booted reset maxUses must be a positive safe integer")}async resetWithTiming(d,c,w,{scope:D,...k}){let{reuseCount:P,signal:C,runResetBoot:M}=k;this.assertInput(d,c,D,P);let F={},q=async()=>{C?.throwIfAborted(),await w(),C?.throwIfAborted()};await q(),await this.assertSettled(D,q,C);let U=JSON.stringify([D.deviceId,D.incarnation,D.sessionUuid]),K=this.eraseReasons.get(U)??"maxUses reached";if(!this.eraseReasons.has(U)&&(P+1)%this.dependencies.maxUses!==0){let W={scope:D,signal:C??new AbortController().signal,assertOwned:async()=>{W.signal.throwIfAborted(),await q(),W.signal.throwIfAborted()},recordPhase:(J,X)=>{F[J]=(F[J]??0)+X}},V=(J,X)=>this.cleaningStep(W,C,J,{phases:F,operation:X}),z=await this.loadJournal(W,V,F);try{if(this.assertCompleteRecording(D.sessionUuid),await V("inventory",()=>di(this.dependencies.simctl,d.deviceId,c,{state:"Booted",action:"start keep-booted reset",signal:W.signal,timeoutMs:this.innerReadTimeoutMs()})),!W.baseline?.completeKinds.includes("installed-app"))throw new t("iOS reset requires a captured app baseline; erase required");let J=z.find(ES);if(J)throw new t(`iOS opaque journaled mutation (${J.toolName}) cannot be journal-reverted; erase required`);let X=await this.dependencies.journal.listStrayIncarnations(W.scope);if(X.length>0)throw new t(`iOS journaled mutations recorded under a different incarnation (${X.length}) cannot be journal-reverted; erase required`);await this.replayJournal(z,W,V),await V("sanitize",()=>this.dependencies.mutations.sanitize(W)),await q(),await this.checkHealth(d,c,W,{phases:F,signal:C})}catch(J){e.warn(`iOS keep-booted cleaning failed: ${r(J)}`,J),await q(),K=this.fallbackReason(J),e.warn(`iOS erase fallback: ${K}`,J),this.eraseReasons.set(U,K)}if(!this.eraseReasons.has(U))return await q(),await this.dependencies.journal.deleteSession(D),await q(),{outcome:"clean",mode:"keep-booted",phases:F}}return await q(),await this.assertSettled(D,q,C),this.nonCleanOutcome({device:d,profile:c,scope:D,assertOwned:q,phases:F,signal:C},K,M)}nonCleanOutcome(d,c,w){return this.dependencies.fallback==="destroy"?Promise.resolve(this.destroyFallback(d.phases,c)):this.eraseFallback(d,c,w)}destroyFallback(d,c){return{outcome:"pending",mode:"keep-booted",phases:d,fallbackReason:c}}async eraseFallback(d,c,w){let{device:D,profile:k,scope:P,assertOwned:C,phases:M,signal:F}=d;try{let q=()=>this.dependencies.erase.resetWithTiming(D,k,C,F),U=await(w?w(q):q());if(await C(),U.outcome!=="clean")throw new t("iOS erase fallback did not confirm a clean baseline");return await this.dependencies.journal.deleteSession(P),await C(),this.dependencies.recordingGaps?.clear(P.sessionUuid),this.eraseReasons.delete(JSON.stringify([P.deviceId,P.incarnation,P.sessionUuid])),{outcome:"fallback:erase",mode:"erase",phases:{...M,...U.phases},fallbackReason:c}}catch(q){throw e.warn(`iOS erase fallback failed: ${r(q)}`,q),new _i(r(q),{outcome:"pending",mode:"erase",phases:{...M,...q instanceof _i?q.reset.phases:{}},fallbackReason:`${c}; erase: ${r(q)}`},{cause:q instanceof _i?q.cause:q})}}async loadJournal(d,c,w){try{return await c("journal",async()=>(d.baseline=await this.dependencies.journal.getBaseline(d.scope)??void 0,this.dependencies.journal.list(d.scope)))}catch(D){throw new _i(r(D),{outcome:"pending",mode:"keep-booted",phases:w,fallbackReason:r(D)},{cause:D})}}async replayJournal(d,c,w){let D=[...d].sort((k,P)=>P.sequence-k.sequence).map((k)=>({entry:k,plan:es([k],{dirty:[],changes:[]},this.dependencies.mutations)}));for(let{entry:k,plan:P}of D)if(!["installed-app","app-group"].includes(k.kind)&&P.status==="non_revertible"&&!this.sanitizeCovers(k,c))throw new t(`iOS journaled mutation ${k.kind}:${k.key} (${k.toolName}) cannot be journal-reverted or sanitized; erase required`);for(let{entry:k,plan:P}of D){if(["installed-app","app-group"].includes(k.kind)){e.warn(`iOS reset handles ${k.kind}:${k.key} through app inventory cleaning`);continue}if(P.status==="non_revertible"){e.warn(`iOS reset skipped journal revert: ${P.reasons.join("; ")}`);continue}await w(`revert:${k.kind}:${k.key}`,()=>this.dependencies.mutations.revert(k,c))}}assertCompleteRecording(d){let c=this.dependencies.recordingGaps?.reasonFor(d);if(c!==void 0)throw new t(`iOS device mutation recording failed (${c}); journal is incomplete; erase required`)}sanitizeCovers(d,c){if(d.kind==="opaque")return!ES(d);if(d.kind==="preference")return PH(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,w,{phases:D,operation:k}){let P=kz({baseMs:this.dependencies.budgetMs??30000,ceilingMs:this.dependencies.budgetCeilingMs??120000},this.dependencies.hostLoad??Tz());try{return await this.cleaningAttempt(d,c,w,{phases:D,operation:k,first:P,timeoutMs:P.budgetMs})}catch(C){if(!this.isBudgetTimeout(C)||c?.aborted)throw C;return e.warn(`Retrying iOS reset ${w}: ${r(C)}`,C),await this.waitForAbandonedStep(d.scope.deviceId,mD(P),C,c),this.cleaningAttempt(d,c,w,{phases:D,operation:k,first:P,timeoutMs:mD(P)})}}async cleaningAttempt(d,c,w,{phases:D,operation:k,first:P,timeoutMs:C}){let M=new AbortController;d.signal=je(M.signal,c)??M.signal;let F=new DOMException(`iOS reset ${w} timed out after ${C}ms (${Ez(P)})`,"TimeoutError");return l(()=>this.measure(d.scope.deviceId,w,D,async()=>{await d.assertOwned();let q=await k();return await d.assertOwned(),q}),{timer:this.dependencies.timer,timeoutMs:C,signal:c,label:`iOS reset ${w}`,timeoutError:()=>F,onTimeout:()=>{this.budgetTimeouts.add(F),M.abort(F)}})}async waitForAbandonedStep(d,c,w,D){await l(Promise.allSettled([...this.pending.get(d)??[]]),{timer:this.dependencies.timer,timeoutMs:c,signal:D,label:"iOS reset abandoned step settlement",timeoutError:()=>w})}async checkHealth(d,c,w,{phases:D,signal:k}){let P=this.dependencies.timer.now();try{await this.cleaningStep(w,k,"health-probe",{phases:D,operation:async()=>{if(await di(this.dependencies.simctl,d.deviceId,c,{state:"Booted",action:"confirm keep-booted health",signal:w.signal,timeoutMs:this.innerReadTimeoutMs()}),await w.assertOwned(),!await this.dependencies.health.probe(d,w.signal))throw new t("iOS keep-booted automation server is unhealthy")}})}finally{D.health=(D.health??0)+this.dependencies.timer.now()-P}}async measure(d,c,w,D){let k=this.dependencies.timer.now(),P=Promise.resolve().then(D),C=this.pending.get(d)??new Set;this.pending.set(d,C),C.add(P);try{return await P}finally{if(C.delete(P),C.size===0)this.pending.delete(d);w[c]=(w[c]??0)+this.dependencies.timer.now()-k}}assertInput(d,c,w,D){if(Tt(d,c),eu(w,w.sessionUuid),d.deviceId!==w.deviceId||!Number.isSafeInteger(D)||D<0)throw new t("iOS keep-booted reset requires the exact mutation scope and durable use count")}async assertSettled(d,c,w){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:w??new AbortController().signal})}catch(D){throw new _i(r(D),{outcome:"pending",mode:"keep-booted",phases:{}},{cause:D})}}}var Ib="light",Mb="large",Eb={kind:"clipboard",key:"pasteboard",priorValue:{state:"present",value:""},toolName:"minimal-reset"},Bb=30000,Ob=1e4;class rs{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,w,{scope:D,reuseCount:k,signal:P}){if(Tt(d,c),eu(D,D.sessionUuid),d.deviceId!==D.deviceId||!Number.isSafeInteger(k)||k<0)throw new t("iOS minimal reset requires the exact mutation scope and durable use count");let C={},M=JSON.stringify([D.deviceId,D.incarnation,D.sessionUuid]),F=this.failures.get(M);if(F!==void 0)return this.pending(C,F);if((k+1)%this.dependencies.maxUses===0)return this.pending(C,"maxUses reached");try{await this.clean(D,w,C,P)}catch(q){if(P?.aborted)throw q;await w();let U=r(q);return e.warn(`iOS minimal cleaning failed; simulator will be destroyed: ${U}`,q),this.failures.set(M,U),this.pending(C,U)}return await w(),await this.dependencies.journal.deleteSession(D),await w(),this.dependencies.recordingGaps?.clear(D.sessionUuid),{outcome:"clean",mode:"minimal",phases:C}}pending(d,c){return{outcome:"pending",mode:"minimal",phases:d,fallbackReason:c}}async clean(d,c,w,D){let k=this.dependencies.recordingGaps?.reasonFor(d.sessionUuid);if(k!==void 0)throw new t(`iOS device mutation recording failed (${k}); the session's apps are unknown`);let P=[...await this.dependencies.journal.list(d)].sort((F,q)=>q.sequence-F.sequence),C=d.deviceId,M=(F,q)=>this.step({scope:d,assertOwned:c,phases:w,callerSignal:D},F,q);for(let F of P.filter((q)=>q.kind==="installed-app"))await M(`uninstall:${F.key}`,(q)=>this.dependencies.mutations.revert(F,q));if(P.some((F)=>F.kind==="shared-file"&&dZ(F.key)))await M("files-fixture",(F)=>this.simctl(["uninstall",C,qE],F));await M("keychain",(F)=>this.simctl(["keychain",C,"reset"],F)),await M("privacy",(F)=>this.simctl(["privacy",C,"reset","all"],F)),await M("appearance",(F)=>this.simctl(["ui",C,"appearance",Ib],F)),await M("content-size",(F)=>this.simctl(["ui",C,"content_size",Mb],F)),await M("pasteboard",(F)=>this.dependencies.mutations.revert(Eb,F))}async simctl(d,c){let w=await this.dependencies.simctl.executeCommandArgs(d,Ob,c.signal);if(w.error){if(d[0]==="uninstall"&&/\b(?:app|application)\b[^\n]*\bis not installed\b/i.test(`${w.error}
|
|
22
|
+
${w.stderr}`)){e.debug("iOS minimal reset Files fixture already absent",w.error);return}throw new t(`iOS minimal reset ${d[0]} failed: ${w.error}`)}}async step({scope:d,assertOwned:c,phases:w,callerSignal:D},k,P){let C=new AbortController,M=je(C.signal,D)??C.signal,F=this.dependencies.budgetMs??Bb,q={scope:d,signal:M,assertOwned:async()=>{M.throwIfAborted(),await c(),M.throwIfAborted()},recordPhase:(U,K)=>{w[U]=(w[U]??0)+K}};await l(async()=>{await q.assertOwned(),await P(q),await q.assertOwned()},{timer:this.dependencies.timer,timeoutMs:F,signal:D,label:`iOS minimal reset ${k}`,timeoutError:()=>new DOMException(`iOS minimal reset ${k} timed out after ${F}ms`,"TimeoutError"),onTimeout:()=>C.abort()})}}import{realpath as Gb,rm as Wb}from"fs/promises";import{homedir as Vb}from"os";import{posix as _b}from"path";function os(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 Iu(d,c){let w=S$;return["spawn",d,"notifyutil","-1",w,"-s",w,c?"1":"0","-g",w,"-p",w]}import{isDeepStrictEqual as xb}from"util";var cs=["media","shared-file","keyboard","accessibility"],ds={photos:{kind:"media",key:"dcim"},documents:{kind:"shared-file",key:"documents"},safariDocuments:{kind:"shared-file",key:"safari-documents"},keyboard:{kind:"keyboard",key:"defaults"},accessibility:{kind:"accessibility",key:"defaults"}};function Mu(d){return Object.keys(ds).map((c)=>({...ds[c],value:{state:"present",value:d[c]}}))}function Eu(d){return cs.every((c)=>d?.completeKinds.includes(c))}function ci(d,c){let{kind:w,key:D}=ds[c],k=d.observations.find((P)=>P.kind===w&&P.key===D);return k?.value.state==="present"?k.value.value:void 0}function as(d){return Array.isArray(d)?d.filter((c)=>typeof c==="string"):[]}function Cu(d){let c={};if(d!==null&&typeof d==="object"&&!Array.isArray(d)){for(let[w,D]of Object.entries(d))if(typeof D==="boolean"||typeof D==="number"||typeof D==="string")c[w]=D}return c}function Bu(d){return{photos:as(ci(d,"photos")),documents:as(ci(d,"documents")),safariDocuments:as(ci(d,"safariDocuments")),keyboard:Cu(ci(d,"keyboard")),accessibility:Cu(ci(d,"accessibility"))}}function rn(d,c){return d.filter((w)=>!c.includes(w))}function ps(d,c){let w=[],D=rn(c.photos,d.photos).length,k=rn(d.photos,c.photos).length;if(D>0)w.push(`iOS reset cannot revert ${D} added photo(s)`);if(k>0)w.push(`iOS reset cannot restore ${k} removed photo(s)`);let P=[];for(let[C,M,F,q]of[["documents","Documents",d.documents,c.documents],["safari-documents","Safari Documents",d.safariDocuments,c.safariDocuments]]){let U=rn(F,q).length;if(U>0)w.push(`iOS reset cannot restore ${U} removed ${M} file(s)`);let K=rn(q,F);if(K.length>0)P.push({area:C,names:K})}return{unrevertible:w,removals:P,keyboard:Tu(d.keyboard,c.keyboard),accessibility:Tu(d.accessibility,c.accessibility)}}function Tu(d,c){return[...new Set([...Object.keys(d),...Object.keys(c)])].sort().filter((w)=>!xb(d[w],c[w])).map((w)=>({key:w,prior:d[w]}))}function ms(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:S(n().min(1)).min(1),calendarSystem:n().min(1),"force-24-hour-time":h(),"force-12-hour-time":h()},Fb=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"},Nb={"app-group":"simctl lists app-owned group paths, not complete shared/orphan container contents.","keep-awake":"simctl cannot inventory the simulator's effective idle-timer assertions.",rotation:"simctl has no complete orientation readback and restoration API.","screen-reader":"simctl cannot read back effective VoiceOver state.",notification:"simctl cannot inventory or remove all delivered and pending notifications.",contact:"simctl cannot inventory and restore the complete Contacts store.",calendar:"simctl cannot inventory and restore the complete Calendar store.",clock:"simctl cannot observe all effective clock and automatic time-zone state.","network-condition":"simctl cannot inventory effective simulator and host network shaping.","biometric-enrollment":"simctl cannot read back complete biometric enrollment state.",profile:"simctl cannot inventory and restore all configuration profiles.",certificate:"simctl cannot inventory and restore complete certificate trust settings.","opened-url":"simctl cannot inventory persistent effects of arbitrary URL handlers.",preference:"simctl cannot inventory every app's arbitrary preferences and live caches.",account:"simctl cannot inventory and restore all provider and system accounts."},Ou={contentSize:"content-size",increaseContrast:"increase-contrast"},Lb={reduceMotion:"ReduceMotionEnabled",boldText:"EnhancedTextLegibilityEnabled"};function fs(d){return Object.hasOwn(Ou,d)?Ou[d]:d}function Fu(d){return Object.entries(Lb).find(([c])=>c===d)?.[1]}function $b(d,c,w){return["spawn",d,"defaults",w===void 0?"delete":"write","com.apple.Accessibility",c,...w===void 0?[]:["-bool",w==="1"?"YES":"NO"]]}function Nu(d){return Object.entries(an).find(([c])=>c===d)?.[1]}async function Hb(d){let c=await kp(d);if(!(c instanceof Map))throw new t("iOS global settings export is not a dictionary");let w=Fb.parse(Object.fromEntries(c));return Object.entries(an).map(([D,k])=>{let P=w[k];return{kind:"device-setting",key:D,value:P===void 0?{state:"absent"}:{state:"present",value:P}}})}function qb(d){let c=d.priorValue;if(c.state!=="present")return c.state==="absent"&&(Nu(d.key)!==void 0||Fu(d.key)!==void 0);let w=fs(d.key);return Object.entries(Le).find(([k])=>k===w)?.[1]?.safeParse(c.value).success??!1}var xu=["keychain","permission","location","status-bar","clipboard"];function Kb(d,c){let w=vH(d.key);return d.kind==="shared-file"&&w!==void 0&&c?.baseline?.completeKinds.includes("installed-app")===!0&&!c.baseline.observations.some((D)=>D.kind==="installed-app"&&D.key.toLowerCase()===w.toLowerCase())}class gs{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 qb(d);case"biometric-enrollment":return os(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(),PS(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 w=c.map((k)=>{let P=dn(k);if(!P)throw new t("iOS baseline app inventory contains an unidentified bundle");return{kind:"installed-app",key:P,value:{state:"present",value:Op().parse(k)}}}),D=["installed-app"];try{let k=await this.captureSettings(d);w.push(...k),D.push("device-setting")}catch(k){await this.inventoryFailure(k,d,"device-setting")}try{w.push(...Mu(await this.dependencies.residue.read(d.scope.deviceId,d.signal))),D.push(...cs)}catch(k){await this.inventoryFailure(k,d,"out-of-band residue")}return{observations:w,completeKinds:D,unobservable:kS.filter((k)=>(k in Nb)||!D.includes(k))}}async inventoryFailure(d,c,w){if(e.warn(`iOS ${w} inventory is unobservable: ${r(d)}`,d),c.signal.throwIfAborted(),await c.assertOwned(),PS(d)==="retryable")throw u(d,`iOS ${w} inventory is temporarily unavailable`)}async captureSettings(d){let c=d.scope.deviceId,w=Le.appearance.parse((await this.command(d,["ui",c,"appearance"])).stdout.trim()),D=Le["content-size"].parse((await this.command(d,["ui",c,"content_size"])).stdout.trim()),k=Le["increase-contrast"].parse((await this.command(d,["ui",c,"increase_contrast"])).stdout.trim()),P=await this.command(d,["spawn",c,"defaults","export","-g","-"]);return[...["appearance","nightMode"].map((C)=>({kind:"device-setting",key:C,value:{state:"present",value:w}})),{kind:"device-setting",key:"content-size",value:{state:"present",value:D}},{kind:"device-setting",key:"increase-contrast",value:{state:"present",value:k}},...await Hb(P.stdout)]}async revert(d,c){if(!this.canRevert(d))throw new t(`Unsupported iOS reset mutation ${d.kind}:${d.key}`);let w=c.scope.deviceId,D=d.priorValue.state==="present"?d.priorValue.value:void 0;switch(d.kind){case"installed-app":await this.terminate(d.key,c),await this.clearAppGroups(d.key,c),await this.command(c,["uninstall",w,d.key]);break;case"app-group":await this.terminate(d.key,c),await this.clearAppGroups(d.key,c);break;case"clipboard":{await c.assertOwned();let k=this.timer.now();try{await this.dependencies.pasteboard.write(w,typeof D==="string"?D:"",c.signal)}finally{c.recordPhase?.("simctl:pbcopy",this.timer.now()-k)}await c.assertOwned();break}case"biometric-enrollment":await this.revertBiometricEnrollment(d,c);break;default:await this.revertByCommand(d,c)}}async revertByCommand(d,c){let w=this.revertCommand(d,c.scope.deviceId);try{await this.command(c,w)}catch(D){if(w[0]!=="spawn"||w[3]!=="delete"||!mS(D))throw u(D,"iOS reset command failed");e.debug(`iOS reset preference already absent: ${r(D)}`),c.signal.throwIfAborted(),await c.assertOwned()}}async revertBiometricEnrollment(d,c){let w=os(d);if(w===void 0)throw new t("iOS cannot restore an unreadable biometric enrollment");let D=await this.command(c,Iu(c.scope.deviceId,w));if(zR(D.stdout)!==w)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 w=d.priorValue.state==="present"?d.priorValue.value:void 0,D=fs(d.key);if(["appearance","nightMode","content-size","increase-contrast"].includes(D))return["ui",c,D==="content-size"?"content_size":D==="increase-contrast"?"increase_contrast":"appearance",String(w)];let k=Fu(d.key);if(k)return $b(c,k,w);let P=Nu(d.key);if(!P)throw new t(`Unsupported iOS setting ${d.key}`);return["spawn",c,"defaults",w===void 0?"delete":"write",".GlobalPreferences",P,...w===void 0?[]:Array.isArray(w)?["-array",...w.map(String)]:typeof w==="boolean"?["-bool",String(w)]:["-string",String(w)]]}preferenceCommand(d,c){let w=d.priorValue.state==="present"?d.priorValue.value:void 0,[D,k]=d.key.split(":");return["spawn",c,"defaults",w===void 0?"delete":"write",D,k,...w===void 0?[]:[typeof w==="boolean"?"-bool":typeof w==="number"?Number.isInteger(w)?"-int":"-float":"-string",String(w)]]}sanitizeCovers(d,c){if(d.kind==="shared-file")return Kb(d,c);if(["installed-app","app-group",...xu,"certificate","media"].includes(d.kind))return!0;return d.kind==="device-setting"&&(["appearance","nightMode","content-size","increase-contrast"].includes(fs(d.key))||Object.hasOwn(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(),w=await this.dependencies.simctl.listAppsOrThrow(d.scope.deviceId,{signal:d.signal,timeoutMs:1e4}).finally(()=>d.recordPhase?.("app-inventory",this.timer.now()-c));await d.assertOwned();let D=new Set(d.baseline?.observations.filter((C)=>C.kind==="installed-app"&&C.value.state==="present").map((C)=>C.key)),k=w.filter((C)=>C.ApplicationType==="User").filter((C)=>{let M=dn(C);if(!M)throw new t("iOS reset app inventory contains an unidentified bundle");return!D.has(M)}),P=k.length>0?await this.appGroupCleanup(d):void 0;for(let C of k){let M=dn(C);await this.terminate(M,d),await this.clearAppGroups(M,d,P),await this.command(d,["uninstall",d.scope.deviceId,M])}for(let C of xu)await this.revert({kind:C,key:"device",priorValue:{state:"absent"},toolName:"baseline-reset"},d);await this.resetSurvivingPrivacyGrants(d),await this.assertNoUserTrustedCertificates(d),await this.restoreSettings(d),await this.sanitizeResidue(d)}async sanitizeResidue(d){if(await d.assertOwned(),!Eu(d.baseline)||!d.baseline)throw new t("iOS reset requires a residue baseline; erase required");let c=Bu(d.baseline),w=async(k)=>{let P=this.timer.now();try{let C=await this.dependencies.residue.read(d.scope.deviceId,d.signal);return await d.assertOwned(),C}finally{d.recordPhase?.(k,this.timer.now()-P)}},D=ps(c,await w("residue:inspect"));if(D.unrevertible.length>0)throw new t(`${D.unrevertible.join("; ")}; erase required`);if(ms(D))return;for(let{area:k,names:P}of D.removals)await d.assertOwned(),await this.dependencies.residue.removeEntries(d.scope.deviceId,k,P,d.signal);for(let[k,P]of[[mY,D.keyboard],[fY,D.accessibility]])for(let{key:C,prior:M}of P)await this.revert({kind:"preference",key:`${k}:${C}`,priorValue:M===void 0?{state:"absent"}:{state:"present",value:M},toolName:"baseline-reset"},d);if(!ms(ps(c,await w("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 w=await this.dependencies.trustStore.readUserTrustedCertificates(d.scope.deviceId,d.signal);if(await d.assertOwned(),d.signal.throwIfAborted(),w.length>0)throw new t(`iOS reset cannot remove ${w.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,w=async()=>{await d.assertOwned(),d.signal.throwIfAborted();let C=this.timer.now();try{return await this.dependencies.privacyGrants.readServiceRows(c,zre,d.signal)}catch(M){throw u(M,"iOS privacy grant verification failed")}finally{d.recordPhase?.("tcc:privacy-verify",this.timer.now()-C)}},D=await w();if(await d.assertOwned(),d.signal.throwIfAborted(),D.length===0)return;let k=[...new Set(D.map((C)=>C.client))].sort();e.warn(`iOS privacy grants survived global reset; resetting clients: ${k.join(", ")}`);for(let C of k)await this.command(d,["privacy",c,"reset","all",C]);let P=await w();if(await d.assertOwned(),d.signal.throwIfAborted(),P.length>0)throw new t("iOS privacy grants survived reset: "+P.map((C)=>`${C.service}:${C.client}`).join(", "))}async restoreSettings(d){let c={appearance:{state:"present",value:"light"},"content-size":{state:"present",value:"large"},"increase-contrast":{state:"present",value:"disabled"},...Object.fromEntries(Object.keys(an).map((w)=>[w,{state:"absent"}]))};for(let[w,D]of Object.entries(c)){let k=d.baseline?.observations.find((C)=>C.kind==="device-setting"&&C.key===w)??(w==="appearance"?d.baseline?.observations.find((C)=>C.kind==="device-setting"&&C.key==="nightMode"):void 0),P={kind:"device-setting",key:w,priorValue:k?.value??D,toolName:"baseline-reset"};if(!this.canRevert(P))e.warn(`iOS reset using simulator default for unsupported baseline setting ${w}`),P.priorValue=D;await this.revert(P,d)}}async command(d,c){let w=this.timer.now();try{d.signal.throwIfAborted(),await d.assertOwned();let D=await this.dependencies.simctl.executeCommandArgs(c,1e4,d.signal);if(D.error)throw new t(`iOS reset ${c[0]} failed: ${D.error}`);return await d.assertOwned(),d.signal.throwIfAborted(),D}finally{d.recordPhase?.(`simctl:${c[0]}`,this.timer.now()-w),d.recordPhase?.(`simctl:${c[0]}:${c.slice(2,c[0]==="spawn"?6:3).join(":")}`,this.timer.now()-w)}}async clearAppGroups(d,c,w){let D=await this.appGroups(d,c);if(Object.keys(D).length===0)return;let k=w??await this.appGroupCleanup(c);this.excludeSharedGroups(D,k);for(let P of Object.values(D)){if(await c.assertOwned(),k.removedPaths.has(P))continue;let{isAbsolute:C,normalize:M,sep:F}=_b,q=`${F}${c.scope.deviceId}${F}data${F}Containers${F}Shared${F}AppGroup${F}`;if(!C(P)||M(P)!==P||!P.includes(q)||P.slice(P.indexOf(q)+q.length).includes(F)||P.endsWith(F)||await this.dependencies.files.realpath(P)!==P)throw new t("iOS reset refused an unproven app-group container path");await c.assertOwned();let U=this.timer.now();try{await this.dependencies.files.remove(P),k.removedPaths.add(P)}finally{c.recordPhase?.("app-group-remove",this.timer.now()-U)}await c.assertOwned()}}async appGroupCleanup(d){let c={baselineIds:new Set,baselinePaths:new Set,removedPaths:new Set};for(let w of d.baseline?.observations.filter((D)=>D.kind==="installed-app"&&D.value.state==="present"&&D.value.value!==null&&typeof D.value.value==="object"&&!Array.isArray(D.value.value)&&D.value.value.ApplicationType==="User")??[]){let D=await this.appGroups(w.key,d);for(let[k,P]of Object.entries(D))c.baselineIds.add(k),c.baselinePaths.add(P)}return c}excludeSharedGroups(d,c){for(let[w,D]of Object.entries(d))if(w.startsWith("group.com.apple.")||c.baselineIds.has(w)||c.baselinePaths.has(D))e.warn(`iOS reset retained protected or baseline-shared app-group ${w}`),delete d[w]}async terminate(d,c){try{await this.command(c,["terminate",c.scope.deviceId,d])}catch(w){if(!of(r(w)))throw u(w,"iOS reset could not terminate app");e.debug(`iOS reset app already terminated: ${r(w)}`),await c.assertOwned()}}async appGroups(d,c){let w=await this.command(c,["get_app_container",c.scope.deviceId,d,"groups"]),D={};for(let k of w.stdout.split(`
|
|
23
|
+
`).filter((P)=>P.trim()!=="")){let P=k.split("\t");if(P.length!==2||!P[0]||!P[1]||Object.hasOwn(D,P[0]))throw new t("iOS reset received invalid app-group inventory");D[P[0]]=P[1]}return D}}function vs(d,c){let w=new Set,D=new Jw({timer:c});return new gs({simctl:d,privacyGrants:D,trustStore:D,residue:new hY({simctl:d,files:zz,deviceSetRoot:vg(Vb())}),files:{realpath:Gb,remove:(k)=>Wb(k,{recursive:!0,force:!1})},pasteboard:{assertSettled:(k)=>{if(w.has(k))throw u(new DOMException("iOS pasteboard child teardown remains unconfirmed","TimeoutError"),"Cannot redrive iOS reset")},write:async(k,P,C)=>{C.throwIfAborted();let M=await d.startCommandArgs(["pbcopy",k],{stdio:["pipe","ignore","pipe"]}),F=uk(M,[]);w.add(k),M.once("exit",()=>w.delete(k));let q=()=>{M.kill("SIGTERM")},U=(W)=>{q(),K=W},K;C.addEventListener("abort",q,{once:!0}),M.stdin?.on("error",U);try{if(C.aborted||!M.stdin)q();else M.stdin.end(P);if(await zn(M,F.exitPromise,{timer:c,signal:null,timeoutMs:1e4,forceKillTimeoutMs:1000}),C.throwIfAborted(),K||!M.stdin||F.exitState.exitCode!==0)throw new t("iOS reset could not restore the pasteboard",{cause:K})}catch(W){if(W instanceof Ap)throw u(new DOMException(r(W),"TimeoutError"),"iOS pasteboard teardown remains unconfirmed");throw u(W,"iOS reset pasteboard command failed")}finally{if([M.exitCode!==null,M.signalCode!==null,M.pid===void 0].some(Boolean))w.delete(k);C.removeEventListener("abort",q),M.stdin?.off("error",U)}}}},c)}function Lu(d){return{probe:async(c,w)=>{let D=ye.registry.peek(c.deviceId);if(!D)return!1;return new Ik(void 0,d,{deviceId:c.deviceId,useRemoteRunner:()=>!1,getHost:()=>"127.0.0.1"}).checkHealthEndpointOnPortForDevice(D.getServicePort(),c.deviceId,5000,{signal:w,requireDeviceId:!0})}}}async function ln(d,c,w){if(w.signal.throwIfAborted(),await w.assertOwned(),await d.getBaseline(w.scope))return;let D=await c.capture(w);if(await w.assertOwned(),w.signal.throwIfAborted(),D.completeKinds.length===0&&D.observations.length===0)throw new t("Device baseline capture returned no observable inventory");await d.captureBaseline(w.scope,D)}var $u=4,un=2000,ys=2000,Jb=Q({initialDelayMs:250,multiplier:2,maxDelayMs:2000});function lt(d,c,w=$u){return Math.min(d,Math.max(un,Math.floor(d/2**(w-c+2))))}function Ss(d){if(!(d instanceof Error)||d.name==="AbortError")return!1;return d instanceof mt||/timed out after \d+ms/.test(d.message)}function pn(d,c){let w=d.now(),D=c-w;return w+Math.min(D,Math.max(un,Math.floor(D/4)))}async function qu(d,c){await d.timer.sleep(Math.min(Jb.delayForAttempt(c),Math.max(0,d.deadlineMs-d.timer.now()))),d.signal?.throwIfAborted()}async function Mt(d,c){let w=c.attempts??$u;for(let D=1;;D++){c.signal?.throwIfAborted();let k=c.deadlineMs-c.timer.now();if(k<=0)throw new t(`${c.label} exceeded the reset budget`);let P=Math.min(k,Math.max(c.minAttemptMs??0,lt(k,D,w)));try{let C=await d(P);return c.signal?.throwIfAborted(),C}catch(C){if(c.signal?.throwIfAborted(),!Ss(C)||D>=w||c.timer.now()>=c.deadlineMs)throw C;e.warn(`${c.label} timed out; retrying (attempt ${D+1})`,C)}await qu(c,D)}}async function mn(d,c){for(let w=1;;w++){c.signal?.throwIfAborted();let D=c.deadlineMs-c.timer.now();if(D<=0)return!1;let k=await d(lt(D,Math.min(w,2)));if(c.signal?.throwIfAborted(),c.timer.now()>=c.deadlineMs)return!1;if(k)return!0;await qu(c,w)}}var Ds=600000,Ku=3;function Gu(d,c){return d.fullBaseline?!c.madeHostSideChanges():c.canReset()}function Yb(d){return Ss(d)}function Wu(d,c){let w=!0,D=!1,k=!1,P=d.onSessionExecutionEnded((C,M)=>{if(C.includes(c)&&M.admitted)w=!1,D||=XQ(M.toolName),k||=JQ(M.toolName)});return{canReset:()=>w,madeOpaquePersistentChanges:()=>D,madeHostSideChanges:()=>k,close:P}}class ks{dependencies;baselines=new Map;constructor(d){this.dependencies=d}get canCapture(){return this.dependencies.strategy!==void 0}async capture(d,c,w,D){let{sessionId:k}=D;if(this.closeBaseline(d),!this.dependencies.strategy)return;let P=this.dependencies.watchSession(k),C=D.timer??i,M=C.now()+(D.timeoutMs??2000),F=new AbortController,q=D.signal?AbortSignal.any([D.signal,F.signal]):F.signal,U=(W,V,z)=>{q.throwIfAborted();let J=M-C.now();if(J<=0)throw new t("Android reset baseline capture exceeded preparation deadline");return l(async()=>{await D.assertOwned?.(),q.throwIfAborted();let X=await W(z===void 0?Math.min(2000,J):Math.min(J,Math.max(2000,Math.floor(J/z))));return q.throwIfAborted(),await D.assertOwned?.(),X},{timer:C,timeoutMs:J,signal:q,label:V,timeoutError:()=>new t("Android reset baseline capture exceeded preparation deadline"),onTimeout:()=>F.abort(new t("Android reset baseline capture exceeded preparation deadline"))})},K=async(W,V,z=!1)=>{for(let J=1;;J++)try{let X=z?Ku-J+1:void 0;return await U(W,V,X)}catch(X){if(!(J<Ku&&!q.aborted&&M-C.now()>0&&Yb(X)))throw X;e.warn(`${V} timed out; retrying (attempt ${J+1})`)}};try{await K((J)=>this.assertTarget(c,w,q,{timeoutMs:J}),"Android reset baseline target verification",!0);let W=await K((J)=>this.packages(c,q,J),"Android reset baseline package inventory"),V=this.dependencies.strategy.handlesSessionMutations?await K((J)=>this.bootIdentity(c,q,J),"Android reset boot identity"):void 0,z=Xe({platform:"android",resourceId:d,stableDeviceId:D.stableDeviceId,bootId:V??null});if(this.dependencies.strategy.capture){if(this.dependencies.strategy.fullBaseline&&!D.assertOwned)throw new t("Android snapshot capture requires exclusive binding ownership");await this.dependencies.strategy.capture(c,{fresh:D.fresh,resourceId:d,sessionId:k,incarnation:z,signal:q,timeoutMs:Math.max(0,M-C.now()),assertOwned:async()=>{if(await D.assertOwned?.(),await this.assertTarget(c,w,q,{timeoutMs:Math.max(1,M-C.now()),allowPendingName:!0}),V)await this.assertBootIdentity(c,V,q);await D.assertOwned?.()}})}return this.baselines.set(d,{device:{...c},profile:{...w},packages:W,activity:P,sessionId:k,incarnation:z,stableDeviceId:D.stableDeviceId,bootId:V,timer:C}),{bootId:V??null}}catch(W){throw P.close(),await this.forget(d),u(W,"Cannot capture Android reset baseline")}}async forget(d,c=!0){if(this.closeBaseline(d),c)try{await this.dependencies.strategy?.forget?.(d)}catch(w){e.warn("Android reset baseline pruning failed; continuing teardown",w)}}closeBaseline(d){this.baselines.get(d)?.activity.close(),this.baselines.delete(d)}async reset(d,c,w,{assertOwned:D,signal:k}){let P={outcome:"pending",mode:"none",phases:{}},C=this.dependencies.timer??this.baselines.get(d)?.timer??i,M=this.dependencies.resetTimeoutMs??Ds;if(!Number.isSafeInteger(M)||M<=0)throw new t("Android reset timeout must be a positive integer in milliseconds");let F=C.now()+M,q=new AbortController,U=k?AbortSignal.any([k,q.signal]):q.signal,K=async()=>{U.throwIfAborted(),await D(),U.throwIfAborted()};try{return await l(()=>this.resetWithinDeadline(d,c,w,{assertOwned:K,signal:U,deadlineMs:F,timing:P,timer:C}),{timer:C,timeoutMs:M,signal:U,label:"Android baseline reset",onTimeout:()=>q.abort(new t("Android baseline reset deadline exceeded"))})}catch(W){if(q.abort(W),W instanceof _i)throw W;throw new _i(u(W,"Android baseline reset failed").message,{...P,outcome:"pending"},{cause:W})}finally{this.closeBaseline(d)}}async restoreFoldPosture(d,c,w,D){if(c.archetype==="foldable"){if(D.throwIfAborted(),await w(),!this.dependencies.postureReset)throw new t(`Cannot restore Android device '${d.deviceId}' to opened posture: posture reset is unavailable`);await this.dependencies.postureReset.restore(d,D),D.throwIfAborted(),await w()}}requireBaseline(d,c,w){let D=this.baselines.get(d);if(!D||D.device.deviceId!==c.deviceId||D.device.name!==c.name||D.profile.systemImagePackage!==w.systemImagePackage||D.profile.profileId!==w.profileId||D.profile.memoryMb!==w.memoryMb)throw new t("Android reset lacks the original session baseline");return D}async resetWithinDeadline(d,c,w,{assertOwned:D,signal:k,deadlineMs:P,timing:C,timer:M}){let F=this.dependencies.strategy;if(!F)throw await this.forget(d),new t("Android reset cannot prove restoration of unobservable state");let q=this.requireBaseline(d,c,w),U={deadlineMs:P,timer:M,assertOwned:D},K=async()=>{if(await D(),!F.handlesSessionMutations&&!Gu(F,q.activity))throw new t("Android session mutations cannot be restored by this reset");if(await this.assertTarget(c,w,k,{timeoutMs:Math.max(1,P-M.now()),requireBoot:!F.handlesSessionMutations,allowPendingName:!0,budget:U}),q.bootId)await this.assertBootIdentity(c,q.bootId,k,U);await D()};try{if(await K(),!F.fullBaseline&&!F.handlesSessionMutations)await this.assertPackagesMatch(c,q.packages,"Android reset detected untracked package inventory changes",{signal:k,budget:U});let W=(z)=>this.healthCheck(c,w,z?.signal??k,tw(U,z)),V=await F.reset(c,q.packages,F.fullBaseline?async()=>{if(await D(),!F.handlesSessionMutations&&!Gu(F,q.activity))throw new t("Android session mutations cannot be restored by this reset")}:K,{resourceId:d,sessionId:q.sessionId,incarnation:q.incarnation,opaquePersistentChanges:q.activity.madeOpaquePersistentChanges(),foldPostureRestored:w.archetype==="foldable"&&this.dependencies.postureReset!==void 0,signal:k,timeoutMs:P-M.now(),deadlineMs:P,assertOwned:D,assertBindingOwned:D,rebindIncarnation:async()=>{await D(),await this.assertTarget(c,w,k,{timeoutMs:Math.max(1,P-M.now()),allowPendingName:!0,budget:U});let z=await this.bootIdentity(c,k,void 0,U);return await D(),q.bootId=z,q.incarnation=Xe({platform:"android",resourceId:d,stableDeviceId:q.stableDeviceId,bootId:z??null}),q.incarnation},healthCheck:W,resetTiming:C});if(Object.assign(C,V),await K(),await this.restoreFoldPosture(c,w,D,k),await K(),!F.handlesSessionMutations)await this.assertPackagesMatch(c,q.packages,"Android reset did not restore the original package inventory",{signal:k,budget:U});return await W(),await K(),V??"clean"}finally{this.closeBaseline(d)}}async healthCheck(d,c,w,D){if(await D.assertOwned(),await this.assertTarget(d,c,w,{timeoutMs:Math.max(1,D.deadlineMs-D.timer.now()),allowPendingName:!0,budget:D}),await D.assertOwned(),await this.packages(d,w,void 0,D),await D.assertOwned(),!await this.checkCtrlProxy(d,D,w))throw new t("Android reset CtrlProxy health check failed");await D.assertOwned()}async assertTarget(d,c,w,{timeoutMs:D=2000,requireBoot:k=!0,allowPendingName:P=!1,budget:C}={}){let M=tn(c.systemImagePackage);if(![d.platform==="android",/^emulator-\d+$/.test(d.deviceId),d.name.trim().length>0,M?.apiLevel===c.apiLevel,M?.abi===c.abi,M?.tag===c.flavor].every(Boolean))throw new t("Android reset requires an exact emulator and system-image profile");let q=await this.readWithinBudget((U)=>this.dependencies.inventory({signal:w,timeoutMs:U,targetDeviceId:d.deviceId}),w,D,C);if(w?.throwIfAborted(),!ew(q,d,c,P))throw new t("Fresh Android inventory did not prove the exact online reset target");if(k)await this.assertBoot(d,w,iw(D,C),C)}async assertBoot(d,c,w=2000,D){let k=await this.readWithinBudget((P)=>this.dependencies.adb(d).executeCommand("shell getprop sys.boot_completed",{timeoutMs:P,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,w,D);if(k.stdout.trim()!=="1"||We(k.stdout,k.stderr))throw new t("Android reset target has not completed boot")}async bootIdentity(d,c,w=2000,D){c?.throwIfAborted();let k=await this.readWithinBudget((C)=>this.dependencies.adb(d).executeCommand("shell cat /proc/sys/kernel/random/boot_id",{signal:c,timeoutMs:C,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,w,D);c?.throwIfAborted();let P=k.stdout.trim();if(k.error||k.stderr.trim()||!/^[a-f\d]{8}-(?:[a-f\d]{4}-){3}[a-f\d]{12}$/i.test(P))throw new t("Android reset cannot read emulator boot identity");return P}async assertBootIdentity(d,c,w,D){if(await this.bootIdentity(d,w,void 0,D)!==c)throw new t("Android reset target changed emulator boot identity")}async checkCtrlProxy(d,c,w){let D=new AbortController,k=w?AbortSignal.any([w,D.signal]):D.signal,P=pn(c.timer,c.deadlineMs),C=()=>new t("Android reset CtrlProxy health check failed");return l(()=>mn(async(M)=>{await c.assertOwned();let F=await this.dependencies.ctrlProxyReady(d,{signal:k,timeoutMs:M,noRetry:!0});return await c.assertOwned(),F},{timer:c.timer,deadlineMs:P,signal:k,label:"Android reset CtrlProxy health check"}),{timer:c.timer,timeoutMs:Math.max(0,P-c.timer.now()),signal:w,label:"Android reset CtrlProxy health check",timeoutError:C,onTimeout:()=>D.abort(C())})}readWithinBudget(d,c,w,D){if(!D)return d(w);return Mt(async(k)=>{await D.assertOwned(),c?.throwIfAborted();let P=await d(k);return await D.assertOwned(),P},{timer:D.timer,deadlineMs:D.deadlineMs,signal:c,label:"Android reset adb"})}async assertPackagesMatch(d,c,w,{signal:D,budget:k}={}){let P=await this.packages(d,D,void 0,k);if(P.size!==c.size||[...c].some((C)=>!P.has(C)))throw new t(w)}async packages(d,c,w=2000,D){let k=await this.readWithinBudget((M)=>this.dependencies.adb(d).executeCommand("shell pm path android",{timeoutMs:M,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,w,D);if(c?.throwIfAborted(),!k.stdout.trim().startsWith("package:")||k.stderr.trim())throw new t("Android reset package manager is not responsive");let P=await this.readWithinBudget((M)=>this.dependencies.adb(d).executeCommand("shell pm list packages -3",{timeoutMs:M,signal:c,noRetry:!0,waitForProcessSettlementAfterAbort:!0}),c,w,D);if(c?.throwIfAborted(),P.stderr.trim()||We(P.stdout,P.stderr))throw new t("Android reset package manager is not responsive");let C=new Set;for(let M of P.stdout.split(`
|
|
24
|
+
`)){let F=M.trim();if(!F)continue;if(!/^package:[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/.test(F))throw new t("Android reset received an invalid package inventory");C.add(F.slice(8))}return C}}function Xb(d,c,w,D){return[d.platform==="android",d.deviceId===c.deviceId,D||d.name===c.name,d.isRunning===!0,d.isRunningStateKnown!==!1,D||d.runtimeId===w.systemImagePackage,D||d.deviceType===w.profileId,D||d.apiLevel===w.apiLevel].every(Boolean)}function ew(d,c,w,D){let k=d.filter((M)=>M.deviceId===c.deviceId||M.name===c.name),P=k[0];if(k.length!==1||!P)return!1;let C=D&&fa(P.name,c.deviceId);return Xb(P,c,w,C)}function tw(d,c){return{...d,deadlineMs:Math.min(d.deadlineMs,c?.deadlineMs??d.deadlineMs),assertOwned:c?.assertOwned??d.assertOwned}}function iw(d,c){return c?d:Math.min(2000,d)}import{isDeepStrictEqual as vn}from"util";import{createHash as Vu}from"crypto";var fn=["device-setting","account"],nw={"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"},rw=["global","secure","system"],As=["/sdcard/Download","/sdcard/DCIM","/sdcard/Pictures","/sdcard/Movies","/sdcard/Documents"],Ps="/sdcard/Download",Cs="download-entries";function Qe(d){return d.startsWith("/sdcard/")&&!d.split("/").slice(1).some((c)=>c==="."||c===".."||c==="")&&!/[\x00-\x1f\x7f\\]/.test(d)}async function Ju(d){let c=[],w=(P,C,M)=>{c.push({kind:P,key:C,value:M===null?{state:"absent"}:{state:"present",value:M}})},D=await Os(d);await cw(d,w,D),await ow(d,w,D),await sw(d,w),w("device-setting","locale",await d("shell getprop persist.sys.locale")),w("clock","timezone",await d("shell getprop persist.sys.timezone"));for(let[P,C]of Ms(await d("shell dumpsys account"),D))w("account",Ts(P),C);await aw(d,w);let k=kS.filter((P)=>!fn.some((C)=>C===P));return{completeKinds:[...fn],observations:c,unobservable:k,unobservableReasons:Object.fromEntries(k.map((P)=>[P,nw[P]??"No complete Android observation and restoration contract is available"]))}}function Ts(d){return`user:${d}`}function Ms(d,c){let w=d.split(/\r?\n/),D=new Map;for(let k of c){let P=w.findIndex((F)=>new RegExp(`^User UserInfo\\{${k}:[^\\n]*\\}:\\s*$`).test(F)),C=/^\s*Accounts: (\d+)\s*$/.exec(w[P+1]??"")?.[1];if(P<0||C===void 0)throw new t(`Android account inventory is unreadable for user ${k}`);let M=w.slice(P+2,P+2+Number(C)).map((F)=>F.trim());if(M.length!==Number(C)||M.some((F)=>!/^Account \{.+\}$/.test(F)))throw new t(`Android account inventory is malformed for user ${k}`);D.set(k,Es(M))}return D}function Es(d){return Vu("sha256").update(JSON.stringify([...d].sort())).digest("hex")}async function ow(d,c,w){for(let D of rw)for(let k of D==="global"?[0]:w){let P=await d(`shell settings --user ${k} list ${D}`);Bs(P,D,k,c)}}function Bs(d,c,w,D){let k=new Set;for(let P of d.split(`
|
|
25
|
+
`).filter(Boolean)){let C=P.indexOf("="),M=P.slice(0,C);if(C<1||!/^[A-Za-z0-9_]\S*$/.test(M)||k.has(M))throw new t(`Android baseline ${c} settings inventory is malformed`);k.add(M),D("device-setting",w===0?`${c}:${M}`:`${c}:user:${w}:${M}`,P.slice(C+1))}}async function sw(d,c){c("device-setting","display:density",ui(await d("shell wm density"),"density")),c("device-setting","display:size",ui(await d("shell wm size"),"size")),c("device-setting","display:night-mode",_s(await d("shell cmd uimode night")))}async function aw(d,c){let D=(await d("shell find /sdcard/ -mindepth 1 -maxdepth 1 -print")).split(`
|
|
26
|
+
`).filter(Boolean).sort();if(new Set(D).size!==D.length||D.some((k)=>!Qe(k)||k.slice(8).includes("/")))throw new t("Android baseline shared-storage root inventory is malformed");c("shared-file","roots",Vu("sha256").update(JSON.stringify(D)).digest("hex")),await dw(d,c);for(let k of As){let P=`if [ -d ${b(k)} ]; then find ${b(k)} -type f -exec sha256sum {} \\;; elif [ -e ${b(k)} ]; then exit 1; fi`,C=await d(`shell sh -c ${b(P)}`,30000);for(let M of C.split(`
|
|
27
|
+
`).filter(Boolean)){let F=/^([a-fA-F0-9]{64}) (.+)$/.exec(M),q=F?.[2];if(!F?.[1]||!q||!q.startsWith(`${k}/`)||!Qe(q))throw new t("Android baseline shared-file inventory is malformed");c("shared-file",q,F[1].toLowerCase())}}}async function dw(d,c){let w=Ps,D=`if [ -d ${b(w)} ]; then find ${b(w)} -mindepth 1 -maxdepth 1 -print; elif [ -e ${b(w)} ]; then exit 1; fi`,k=(await d(`shell sh -c ${b(D)}`)).split(`
|
|
28
|
+
`).filter(Boolean).sort();if(new Set(k).size!==k.length||k.some((P)=>!P.startsWith(`${w}/`)||!Qe(P)||P.slice(w.length+1).includes("/")))throw new t("Android baseline Downloads entry inventory is malformed");c("shared-file",Cs,JSON.stringify(k))}async function Os(d){let c=await d("shell pm list users"),w=vz(c).map((k)=>k.userId),D=c.split(`
|
|
29
|
+
`).filter((k)=>k.trim());if(D[0]?.trim()!=="Users:"||D.length!==w.length+1||!w.includes(0)||w.some((k)=>!Number.isSafeInteger(k))||new Set(w).size!==w.length||D.slice(1).some((k)=>!/^\s*UserInfo\{\d+:[^:]+:[a-fA-F0-9]+\}(?: running)?\s*$/.test(k)))throw new t("Android baseline user inventory is malformed");return w.sort((k,P)=>k-P)}function li(d){let c=d.split(`
|
|
30
|
+
`).filter((w)=>w.trim()).map((w)=>{let D=/^package:([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)$/.exec(w.trim());if(!D?.[1])throw new t("Android baseline package inventory is malformed");return D[1]});if(new Set(c).size!==c.length)throw new t("Android baseline package inventory has duplicates");return c.sort()}async function cw(d,c,w){let D=new Map;if(!new Set(li(await d("shell pm list packages -s -u"))).has("android"))throw new t("Android baseline system package inventory is incomplete");let P=new Set;for(let C of w){c("installed-app",`users:${C}`,!0);let M=li(await d(`shell pm list packages --user ${C}`)),F=li(await d(`shell pm list packages -3 --user ${C}`));if(!M.includes("android")||F.some((q)=>!M.includes(q)))throw new t("Android baseline package inventory is incomplete");D.set(C,M);for(let q of M)c("installed-app",`user:${C}:${q}`,!0);for(let q of F)P.add(q)}for(let C of[...P].sort())await lw(d,c,C,w.filter((M)=>D.get(M)?.includes(C)))}async function lw(d,c,w,D){let k=await d(`shell dumpsys package ${b(w)}`),P=new RegExp(`^\\s*Package \\[${w.replaceAll(".","\\.")}\\] \\([^\\n]+\\):\\s*$`,"m").exec(k),C=P?k.slice(P.index+P[0].length).split(/^\s*Package \[/m)[0]:"",M=/^\s*lastUpdateTime=(.+)$/m.exec(C)?.[1],F=/^\s*versionCode=(\d+)\b/m.exec(C)?.[1],q=/^\s*codePath=(.+)$/m.exec(C)?.[1];if(!M||!F||!q)throw new t(`Android baseline cannot read package identity for ${w}`);c("installed-app",`identity:${w}`,JSON.stringify([M,F,q]));for(let U of D){let K=gn(k,w,U);if(!K||!new RegExp(`^\\s*User ${U}:.*\\binstalled=true\\b`,"m").test(C))throw new t(`Android baseline cannot read permissions for ${w} user ${U}`);for(let[W,V]of K.runtimePermissions)c("permission",`runtime:${U}:${w}:${W}`,V.state==="granted"),c("permission",`runtime-flags:${U}:${w}:${W}`,JSON.stringify(V.raw))}}function ui(d,c){let w=d.split(`
|
|
31
|
+
`),D=c==="density"?"[0-9]+":"[0-9]+x[0-9]+",k=new RegExp(`^Physical ${c}: ${D}$`),P=new RegExp(`^Override ${c}: (${D})$`);if(!w[0]||!k.test(w[0])||w.length>2)throw new t(`Android baseline display ${c} is unreadable`);if(w.length===1)return null;let C=P.exec(w[1]);if(!C?.[1])throw new t(`Android baseline display ${c} is unreadable`);return C[1]}function _s(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 Ls(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 $s(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===aS||["density","nightMode"].includes(d.key))}function uw(d){let c=d.observations.find((w)=>w.kind==="shared-file"&&w.key===Cs);if(c?.value.state!=="present"||typeof c.value.value!=="string")return;try{let w=JSON.parse(c.value.value);return Array.isArray(w)&&w.every((D)=>typeof D==="string")?new Set(w):void 0}catch(w){e.debug("Android baseline Downloads inventory is not JSON",w);return}}function pw(d){let c=d.observations.filter((w)=>w.kind==="installed-app"&&w.key.startsWith("users:")&&w.value.state==="present").map((w)=>w.key);return c.length===1&&c[0]==="users:0"}function mw(d){let c;try{c=JSON.parse(d.key)}catch(D){e.debug("Android journal file key is not JSON; not a user_files scope",D);return}let w=d.kind==="media"?5:d.kind==="shared-file"?6:-1;return Array.isArray(c)&&c.length===w&&c[0]==="user_files"&&c[1]===null&&c[2]===null&&typeof c[3]==="string"&&(w===5||typeof c[5]==="string")?{namespace:c[3],user:c[4]}:void 0}function fw(d){let c=d.trim(),w=`${Ps}/${c}`;return c.length>0&&!/[/\\]/.test(c)&&Qe(w)?w:void 0}function zu(d,c){let w=c?mw(d):void 0;if(!c||!w)return;let D=fw(w.namespace),k=uw(c);return(w.user===0||w.user==="default"&&pw(c))&&D!==void 0&&k!==void 0&&!k.has(D)&&!c.observations.some((P)=>P.kind==="shared-file"&&P.key.startsWith(`${D}/`))?D:void 0}function Yu(d,c){if(!c||d.kind!=="shared-file"&&d.kind!=="media")return!1;let w=d.kind==="shared-file"?vH(d.key):void 0;return w!==void 0?!XP(c,w):zu(d,c)!==void 0}var ju={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((k)=>k.kind==="device-setting"&&k.priorValue.state==="absent"&&/^(?:global|system|secure):/.test(k.key)).map((k)=>k.key)),w=new Set(d.flatMap((k)=>(k.kind in ju)?[k.kind]:[])),D=new Set([...w].flatMap((k)=>ju[k]??[]));return(k)=>c.has(k)||D.has(k.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 yw(d){return vw.some((c)=>d===c||d.startsWith(`${c}.`))}function Sw(d,c,w){return d.get(`installed-app:user:${c}:${w}`)?.state==="present"&&!d.has(`installed-app:identity:${w}`)}function bw(d){let c=d.split(`
|
|
32
|
+
`).map((w)=>w.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((w)=>{let D=/^([A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*)\/[A-Za-z0-9_.$]+$/.exec(w);if(!D?.[1])throw new t("Android cleaning cannot read the URL handler inventory");return D[1]})}async function Qu(d,c,w,{revert:D,journalEntries:k=[]}){let P=new Set(k.flatMap((C)=>zu(C,d)??[]));await new ep(d,c,w,{revert:D,journal:{sessionCreated:hw(k),userFilesNamespaces:[...P].sort(),launches:ww(k)}}).clean()}function ww(d){let c=new Set,w=new Set;for(let D of d){let k=fZ(D);if(k===null)throw new t("Android cleaning cannot read a journaled app launch");let P=D.kind==="opened-url"?D.key.trim():"";if(k!==void 0)c.add(k);else if(P.startsWith("package:"))c.add(P.slice(8));else if(P)w.add(P)}return{packages:c,urls:w}}class ep{baseline;context;command;prior;revert;journal;constructor(d,c,w,{revert:D,journal:k}){this.baseline=d;this.context=c;this.command=w;this.revert=D,this.journal=k,this.prior=new Map(d.observations.map((P)=>[`${P.kind}:${P.key}`,P.value]))}restore(d,c,w){return this.revert({kind:d,key:c,priorValue:w,toolName:"keep-booted-cleaning"})}async clean(){let d=await Os(this.command),c=await this.sessionStartedPreinstalledApps(d);await this.cleanPackages(d);for(let[w,D]of c)await this.restore("preference",`app-data:${w}:${D}`,{state:"absent"});await this.cleanDisplay();for(let w of["global","system","secure"])for(let D of w==="global"?[0]:d)await this.cleanSettings(w,D);await this.cleanFiles();for(let w of this.journal.userFilesNamespaces)await this.removeNamespaceDirectory(w);await this.cleanTimezone(),await this.verifyLocale(),await this.verifyAccounts(d)}baselineString(d,c){let w=this.prior.get(`${d}:${c}`);return w?.state==="present"&&typeof w.value==="string"?w.value:void 0}async cleanTimezone(){let d=this.baselineString("clock","timezone");if(await this.command("shell getprop persist.sys.timezone")===d)return;if(!d)throw new t("Android cleaning cannot restore a time zone the baseline lacks");await this.restore("clock","timezone",{state:"present",value:d})}async verifyLocale(){let d=this.baselineString("device-setting","locale");if(d===void 0||await this.command("shell getprop persist.sys.locale")!==d)throw new t("Android cleaning found a changed device locale")}async verifyAccounts(d){let c=this.baseline.observations.filter((P)=>P.kind==="account"&&/^user:\d+$/.test(P.key)).map((P)=>Number(P.key.slice(5)));if(c.length===0)throw new t("Android baseline has no per-user account inventory");let w=Ms(await this.command("shell dumpsys account"),d),D=Es([]),k=[...new Set([...c,...d])].sort((P,C)=>P-C).filter((P)=>(this.baselineString("account",Ts(P))??D)!==(w.get(P)??D));if(k.length>0)throw new t(`Android cleaning found changed accounts for user ${k.join(", ")}; accounts cannot be restored in place`)}async sessionStartedPreinstalledApps(d){let c=[];for(let w of d){let D=new Set(this.journal.launches.packages);for(let C of this.journal.launches.urls){let M=await this.command(`shell cmd package query-activities --components --user ${w} -a android.intent.action.VIEW -d ${b(C)}`);for(let F of bw(M))D.add(F)}let k=[...D].filter((C)=>gw.test(C)&&Sw(this.prior,w,C)).sort(),P=k.find(yw);if(P)throw new t(`Android cleaning cannot clear data of core package ${P} the session started`);c.push(...k.map((C)=>[w,C]))}return c}async removeNamespaceDirectory(d){let c=b(d),w=b(d.slice(7)),D=`root=$(readlink -f /sdcard) && [ -n "$root" ] && if [ -e ${c} ] || [ -L ${c} ]; then [ ! -L ${c} ] && [ -d ${c} ] && [ "$(readlink -f ${c})" = "$root"${w} ] && find ${c} -depth -type d -exec rmdir {} +; fi && [ ! -e ${c} ] && [ ! -L ${c} ]`;await this.command(`shell sh -c ${b(D)}`)}async readDisplay(){let d=ui(await this.command("shell wm density"),"density"),c=ui(await this.command("shell wm size"),"size"),w=_s(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:w}]])}async cleanDisplay(){let d=await this.readDisplay();for(let[w,D]of d){let k=this.prior.get(`device-setting:${w}`);if(k&&!vn(D,k))await this.restore("device-setting",w,k)}let c=[...await this.readDisplay()].filter(([w,D])=>{let k=this.prior.get(`device-setting:${w}`);return k&&!vn(D,k)}).map(([w])=>w);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 w=li(await this.command(`shell pm list packages -3 --user ${c}`));for(let D of w)await this.cleanPackage(c,D)}}async cleanPackage(d,c){let w=`user:${d}:${c}`;if(this.prior.get(`installed-app:${w}`)?.state!=="present"){await this.restore("installed-app",w,{state:"absent"});return}let D=await this.command(`shell dumpsys package ${b(c)}`),k=gn(D,c,d);if(!k)throw new t(`Android cleaning cannot read runtime permissions for ${w}`);for(let[P,C]of k.runtimePermissions){let M=`runtime:${d}:${c}:${P}`,F=this.prior.get(`permission:${M}`);if(C.state==="granted"&&!(F?.state==="present"&&F.value===!0))await this.restore("permission",M,{state:"present",value:!1})}}async readSettings(d,c){let w=new Map;return Bs(await this.command(`shell settings --user ${c} list ${d}`),d,c,(D,k,P)=>{w.set(k,P===null?{state:"absent"}:{state:"present",value:P})}),w}async cleanSettings(d,c){let w=await this.readSettings(d,c),D=new Map,k=c===0?`${d}:`:`${d}:user:${c}:`,P=this.baseline.observations.filter((M)=>M.kind==="device-setting"&&M.key.startsWith(k)&&(c!==0||!M.key.startsWith(`${d}:user:`))),C=0;for(let M of new Set([...w.keys(),...P.map((F)=>F.key)])){let F=this.prior.get(`device-setting:${M}`),q=F??{state:"absent"};if(vn(w.get(M)??{state:"absent"},q))continue;if(!F&&!this.journal.sessionCreated(M)){C++;continue}try{await this.restore("device-setting",M,q)}catch(U){if(e.warn(`Android cleaning could not restore setting ${M}`,U),await this.context.assertOwned(),this.context.signal.throwIfAborted(),D.set(M,q),Ls(M))throw U}}if(D.size>0){let M=await this.readSettings(d,c),F=[...D].filter(([q,U])=>!vn(M.get(q)??{state:"absent"},U)).map(([q])=>q);if(F.length>0)throw new t(`Android cleaning settings remain dirty after failed restore: ${F.join(", ")}`)}}async cleanFiles(){for(let d of As){let c=`if [ -d ${b(d)} ]; then find ${b(d)} -type f -print; elif [ -e ${b(d)} ]; then exit 1; fi`,w=(await this.command(`shell sh -c ${b(c)}`)).split(`
|
|
33
|
+
`).filter(Boolean);for(let D of w){if(!D.startsWith(`${d}/`)||!Qe(D))throw new t("Android cleaning shared-file inventory is malformed");if(this.prior.get(`shared-file:${D}`)?.state!=="present")await this.restore("shared-file",D,{state:"absent"})}}}}var kw=s({store:_("preference"),scope:_("systemProperty"),appId:sP(),suite:sP(),userId:sP(),key:n()}),Aw=s({value:n()}),Pw=/^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,255}$/;function Iw(d){return d.startsWith("ro.")||d.startsWith("ctl.")||d==="sys.powerctl"}function yn(d){let c;try{c=JSON.parse(d)}catch(k){return e.debug("Preference journal key is not a JSON identity",k),null}let w=kw.safeParse(c);if(!w.success)return null;let D=w.data.key;return Pw.test(D)&&!Iw(D)?D:null}function tp(d){if(d.state==="absent")return"";if(d.state!=="present")return null;let c=Aw.safeParse(d.value);return c.success&&!/[\r\n\0]/.test(c.data.value)?c.data.value:null}class Hs{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>Fr)))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>Fr)throw new t("Android keep-booted capture requires a bounded preparation budget");let w=new AbortController,D=AbortSignal.any([c.signal,w.signal]),k=async()=>{D.throwIfAborted(),await c.assertOwned(),D.throwIfAborted()};try{await l(()=>this.captureSession(d,{...c,signal:D,assertOwned:k}),{timer:this.dependencies.timer,signal:D,timeoutMs:c.timeoutMs,label:"Android keep-booted baseline capture",onTimeout:()=>w.abort(new t("Android keep-booted capture budget exceeded"))})}catch(P){throw w.abort(P),await this.forget(c.resourceId),u(P,"Android keep-booted baseline capture failed")}}async captureSession(d,c){if(!c.sessionId)throw new t("Android keep-booted capture requires a session identity");let w=this.dependencies.timer.now()+c.timeoutMs,D=this.sessions.get(c.resourceId),k=c.incarnation??c.resourceId;if(D&&(D.scope.deviceId!==d.deviceId||D.scope.incarnation!==k))throw new t("Android keep-booted resource changed emulator identity");let P={deviceId:d.deviceId,incarnation:k,sessionUuid:c.sessionId},C=await this.dependencies.journal.getBaseline(P),M=this.dependencies.port(d);if(this.sessions.set(c.resourceId,this.nextSession(P,D,C!==null)),!C){let F=new AbortController,q=AbortSignal.any([c.signal,F.signal]),U=Math.min(c.timeoutMs,this.budgetMs??c.timeoutMs);await l(()=>this.captureBaseline(M,P,{...c,signal:q,timeoutMs:U,assertOwned:async()=>{q.throwIfAborted(),await c.assertOwned(),q.throwIfAborted()}}),{timer:this.dependencies.timer,signal:q,timeoutMs:U,label:"Android keep-booted journal capture",onTimeout:()=>F.abort(new t("Android keep-booted capture budget exceeded"))})}if(await c.assertOwned(),c.signal.throwIfAborted(),!this.sessions.get(c.resourceId)?.retired)await this.dependencies.fallback?.capture?.(d,{...c,timeoutMs:w-this.dependencies.timer.now()});await c.assertOwned(),c.signal.throwIfAborted()}async captureBaseline(d,c,w){await ln(this.dependencies.journal,d,{scope:c,signal:w.signal,assertOwned:w.assertOwned})}nextSession(d,c,w){return{scope:d,uses:c?.scope.sessionUuid===d.sessionUuid?c.uses:(c?.uses??0)+1,retired:c?.retired??w}}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 w=this.sessions.get(c.resourceId);if(!w||w.scope.sessionUuid!==c.sessionId||w.scope.deviceId!==d.deviceId||w.scope.incarnation!==(c.incarnation??c.resourceId))throw new t("Android keep-booted lacks the fenced session baseline");if(w.retired)throw new t("Android keep-booted restart requires incarnation retirement");return w}async reset(d,c,w,D){let k=D.deadlineMs??this.dependencies.timer.now()+(D.timeoutMs??1/0),P=this.resetSession(d,D),C=this.dependencies.port(d),M=new AbortController,F=D.signal?AbortSignal.any([D.signal,M.signal]):M.signal,q=async()=>{F.throwIfAborted();let z=me(F);try{await H(z,w)}catch(J){if(!z?.aborted)M.abort(J);throw u(J,"Android keep-booted ownership fence failed")}F.throwIfAborted()},U={},K,W,V={scope:P.scope,deadlineMs:k,signal:F,assertOwned:q};try{await q();let z=await this.whyEscalate(P,C,V,{context:D,phases:U});if(await q(),z){W=z;let J=this.dependencies.fallback;if(!J)throw new t(`Android keep-booted is non-clean (${z}); baseline fallback or destruction is required`);e.warn(`Android keep-booted escalating to baseline (${z})`);let X=Math.min(this.fallbackBudgetMs??Fr,k-this.dependencies.timer.now()-ys-1);if(X<=0)throw new t("Android keep-booted has no remaining fallback settlement budget");K={outcome:"pending",mode:"snapshot",phases:{}};let ee;try{await l(()=>(ee=this.measure("fallback",U,async()=>{let te=J.fullBaseline?D.assertBindingOwned:q;if(!te||J.fullBaseline&&!D.rebindIncarnation)throw new t("Android snapshot fallback requires incarnation rebinding");let oe=await J.reset(d,c,te,{...D,signal:F,timeoutMs:X,assertOwned:te,deadlineMs:this.dependencies.timer.now()+X,resetTiming:K});if(oe)K=oe;if(oe?.outcome==="pending")throw new t("Android snapshot fallback did not prove a clean reset");for(let[pe,ae]of Object.entries(K.phases))U[`snapshot:${pe}`]=ae;if(J.fullBaseline){let pe=await D.rebindIncarnation();await this.dependencies.journal.deleteResource(D.resourceId),P.scope={...P.scope,incarnation:pe},V.scope=P.scope,await this.captureBaseline(C,P.scope,{...D,incarnation:pe,signal:F,timeoutMs:X,assertOwned:q})}await q(),await this.measure("health",U,()=>D.healthCheck?.(V)??Promise.resolve()),await q()}),ee),{timer:this.dependencies.timer,signal:F,timeoutMs:X,label:"Android keep-booted fallback",onTimeout:()=>M.abort(new t("Android keep-booted fallback budget exceeded"))})}catch(te){throw M.abort(te),te}finally{await this.drainOperation(ee)}await q(),this.dependencies.recordingGaps?.clear(V.scope.sessionUuid),P.uses=0;let ne=K.mode;return{outcome:ne==="wipe-data"?"fallback:wipe-data":"fallback:snapshot",mode:ne,phases:U,fallbackReason:[z,K.fallbackReason].filter(Boolean).join("; ")}}return await q(),{outcome:"clean",mode:"keep-booted",phases:U}}catch(z){throw M.abort(z),e.warn(`Android keep-booted reset failed: ${r(z)}`,z),this.resetFailure(z,U,K,W)}}async whyEscalate(d,c,w,{context:D,phases:k}){if(d.uses>=this.maxUses)return"maxUses retirement";if(D.opaquePersistentChanges)return"opaque persistent changes (deviceSnapshot) cannot be journal-reverted";let P=this.dependencies.recordingGaps?.reasonFor(w.scope.sessionUuid);if(P!==void 0)return`device mutation recording failed (${P}); journal is incomplete`;let C=await this.dependencies.journal.listStrayIncarnations(w.scope);if(C.length>0)return`journaled mutations recorded under a different incarnation (${C.length}) cannot be journal-reverted`;let M=await this.dependencies.journal.list(w.scope),F=M.find((U)=>ES(U)&&!(D.foldPostureRestored&&U.key===Nn(...hZ)));if(F)return`opaque journaled mutation (${F.toolName}) cannot be journal-reverted`;let q=M.filter((U)=>U.kind==="preference"&&!k6.includes(U.key)&&!ip(U,c));if(q.length>0){let U;try{U=await this.dependencies.journal.getBaseline(w.scope)}catch(W){return e.warn("Android app-state baseline is unreadable; baseline fallback required",W),"journaled app state has an unreadable baseline"}let K=q.find((W)=>!PH(W,U));if(K)return`journaled ${K.kind} (${K.toolName}) cannot be baseline-cleaned`}return await this.unrevertibleReason(M,c,w.scope)??this.cleanWithDeadline(c,w,D,k)}async unrevertibleReason(d,c,w){let D=d.filter((C)=>C.kind!=="opaque"&&C.kind!=="preference"&&!$s(C)&&!c.canRevert(C)),k=null;if(D.some((C)=>C.kind==="shared-file"||C.kind==="media"))try{k=await this.dependencies.journal.getBaseline(w)}catch(C){return e.warn("Android file baseline is unreadable; baseline fallback required",C),"journaled files have an unreadable baseline"}let P=D.find((C)=>!Yu(C,k));return P?`journaled mutation ${P.kind}:${P.key} (${P.toolName}) cannot be journal-reverted`:void 0}resetFailure(d,c,w,D){if(d instanceof _i)w=d.reset;for(let[k,P]of Object.entries(w?.phases??{}))c[`snapshot:${k}`]=P;return new _i(u(d,"Android keep-booted requires baseline fallback or destruction").message,{outcome:"pending",mode:w?.mode??"keep-booted",phases:c,fallbackReason:[D,w?.fallbackReason].filter(Boolean).join("; ")||void 0},{cause:d instanceof _i?d.cause:d})}async measure(d,c,w){let D=this.dependencies.timer.now();try{await w()}finally{c[d]=this.dependencies.timer.now()-D}}async cleanWithDeadline(d,c,w,D){let k=(w.deadlineMs??this.dependencies.timer.now()+(w.timeoutMs??Fr))-this.dependencies.timer.now(),P=this.dependencies.fallback?Math.floor(k/3):k,C=Math.min(k,Fr,this.budgetMs??Math.max(un,P));if(C<=0)return"Android keep-booted cleaning budget exceeded";let M=new AbortController,F=AbortSignal.any([c.signal,M.signal]),q={...c,deadlineMs:this.dependencies.timer.now()+C,signal:F,assertOwned:async()=>{F.throwIfAborted(),await H(F,c.assertOwned),F.throwIfAborted()}},U;try{await l(()=>(U=this.clean(d,q,w,D),U),{timer:this.dependencies.timer,signal:F,timeoutMs:C,label:"Android keep-booted cleaning",onTimeout:()=>M.abort(new t("Android keep-booted cleaning budget exceeded"))});return}catch(K){return M.abort(K),e.warn("Android keep-booted cleaning failed",K),r(K)}finally{await this.drainOperation(U)}}async drainOperation(d){await l(Promise.allSettled(d?[d]:[]),{timer:this.dependencies.timer,timeoutMs:ys,label:"Android keep-booted command settlement"})}async clean(d,c,w,D){let k=await this.dependencies.journal.getBaseline(c.scope);if(!k)throw new t("Android keep-booted baseline is missing");await c.assertOwned();let P=[];await this.measure("journal",D,async()=>{P=await this.dependencies.journal.list(c.scope),await this.replayJournal(d,c,k,P)}),await this.measure("clean",D,()=>d.cleanBaseline(k,c,P)),await c.assertOwned(),await this.measure("health",D,()=>w.healthCheck?.(c)??Promise.resolve()),await c.assertOwned()}async replayJournal(d,c,w,D){for(let k of[...D].sort((P,C)=>C.sequence-P.sequence)){await c.assertOwned();let P=k.kind==="installed-app"&&k.priorValue.state==="absent"&&w.observations.some((C)=>C.kind===k.kind&&C.key===k.key&&C.value.state==="present");if(!Cw(k,d)||P){e.warn(`Android keep-booted skipped journal revert ${k.kind}:${k.key}`);continue}try{await d.revert(k,c)}catch(C){if(e.warn(`Android keep-booted journal revert failed ${k.kind}:${k.key}`,C),await c.assertOwned(),k.kind!=="device-setting"||!$s(k)||Ls(k.key)||GP(k.key)!==null)throw C}}}}function Cw(d,c){return d.kind==="preference"?ip(d,c):c.canRevert(d)}function ip(d,c){return d.kind==="preference"&&yn(d.key)!==null&&c.canRevert(d)}function pi(d){return d.priorValue.state==="present"?d.priorValue.value:void 0}var qs=(d)=>d?"enable":"disable",np={airplaneMode:(d)=>`shell cmd connectivity airplane-mode ${qs(d)}`,wifiEnabled:(d)=>`shell svc wifi ${qs(d)}`,bluetoothEnabled:(d)=>`shell svc bluetooth ${qs(d)}`,locationEnabled:(d)=>`shell cmd location set-location-enabled ${d}`},Tw=p(["off","none","priority","alarms"]),rp=s({level:a().int().min(0).max(100),charging:p(JD),faked:h()}),op=s({status:a().int().min(0).max(6),override:h()});function Ew(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 Bw(d){let c=rp.safeParse(d);if(!c.success)return null;let{level:w,charging:D,faked:k}=c.data;return(k?[...Ew(D),`shell dumpsys battery set level ${w}`]:["shell dumpsys battery reset"]).map((P)=>({command:P}))}function Ow(d){let c=p(Vk).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 Fw(d){let c=op.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 Nw(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 Lw(d,c){if(d.field==="inactive")return typeof c==="boolean"?[{command:`shell am set-inactive ${b(d.appId)} ${c}`}]:null;let w=p(XD).safeParse(c);return w.success?[{command:`shell am set-standby-bucket ${b(d.appId)} ${w.data}`}]:null}function sp(d,c){let w=pi(c);switch(d.field){case"battery":return Bw(w);case"doze":return Ow(w);case"thermal":return Fw(w);case"dataSaver":return typeof w==="boolean"?[{command:`shell cmd netpolicy set restrict-background ${w}`}]:null;case"batterySaver":return Nw(c,w);case"standby":case"inactive":return Lw(d,w)}}function Hw(d){let c=rp.parse(d);return async(w)=>{let D=await w.readBattery();return(c.faked?D.level===c.level&&D.charging===c.charging:!D.faked)?null:"battery differs from its prior state"}}function Uw(d){let c=op.parse(d);return async(w)=>{let D=await w.readThermal();return(c.override?D.override&&D.status===c.status:!D.override)?null:"thermal override differs from its prior state"}}function Kw(d){let c=p(Vk).parse(d);return async(w,D)=>{let k,P=await Wk({readDoze:async()=>{try{return await w.readDoze()}catch(C){throw k=u(C,"Android reset could not read back device state"),k}}},c,{...D,reading:await w.readDoze()});if(k)throw k;return P.settled?null:`Doze is ${P.reading.mode}, expected ${c}`}}function Ww(d,c){switch(d.field){case"battery":return Hw(c);case"thermal":return Uw(c);case"doze":return Kw(c);case"dataSaver":return async(w)=>await w.readDataSaver()===c?null:"Data Saver differs from its prior state";case"batterySaver":return async(w)=>{let D=await w.readBatterySaver();return(c===void 0?(D??!1)===!1:D===c)?null:"battery saver differs from its prior state"};case"standby":return async(w)=>await w.readStandbyBucket(d.appId)===c?null:"standby bucket differs from its prior state";case"inactive":return async(w)=>await w.readInactive(d.appId)===c?null:"inactive state differs from its prior state"}}function ap(d){if(d.kind!=="device-setting")return null;let c=GP(d.key);return c&&sp(c,d)!==null?Ww(c,pi(d)):null}function up(d){let c=pi(d);if(Object.hasOwn(np,d.key))return typeof c==="boolean"?[{command:np[d.key](c)}]:null;if(d.key==="doNotDisturb"){let D=Tw.safeParse(c);return D.success?[{command:`shell cmd notification set_dnd ${D.data}`}]:null}let w=GP(d.key);return w?sp(w,d):null}var Vw=s({delayMs:a().min(0).optional(),downloadKbps:a().min(0).optional(),uploadKbps:a().min(0).optional()});function pp(d){let c=Vw.safeParse(pi(d));if(d.key!=="device"||!c.success)return null;let{delayMs:w=0,downloadKbps:D=0,uploadKbps:k=0}=c.data,P=w>0?`${w}:${w}`:"none",C=D>0||k>0?`${k}:${D}`:"full";return[{command:`emu network delay ${P}`,success:"OK"},{command:`emu network speed ${C}`,success:"OK"},{command:"emu gsm data on",success:"OK"},{command:"shell svc wifi enable"}]}var jw=s({instant:n().refine((d)=>Number.isFinite(Date.parse(d))),automaticTime:h()});function mp(d,c){let w=jw.safeParse(pi(d));if(d.key!=="device"||!w.success)return null;let D=Math.floor(c/1000),k=Math.ceil(kl/1000),P=[`cur=$(date +%s); diff=$((cur - ${D}))`,`if [ "$diff" -gt ${k} ] || [ "$diff" -lt -${k} ]; then settings put global auto_time 0 && date -u @${D}; fi`,`settings put global auto_time ${w.data.automaticTime?1:0}`].join("; ");return[{command:`shell sh -c ${b(P)}`}]}var fp={fontScale:["system:font_scale"],timeFormat:["system:time_12_24"],textDirection:["global:debug.force_rtl","global:force_rtl"],increaseContrast:["secure:high_text_contrast_enabled"],reduceMotion:wN.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"]},zw=/^[+]?(?:\d+(?:\.\d*)?|\.\d+)$/;function Yw(d){if(d==="default")return[null];return typeof d==="number"&&Number.isFinite(d)&&d>0?[String(d)]:null}function Xw(d,c){if(typeof d!=="string")return null;let w=d.split(",");return w.length===c&&w.every((D)=>D==="null"||zw.test(D))?w.map((D)=>D==="null"?null:D):null}function Zw(d,c,w){if(c.state==="absent")return Array.from({length:w},()=>null);if(c.state!=="present")return null;if(d==="fontScale")return Yw(c.value);if(d==="timeFormat")return c.value==="12"||c.value==="24"?[c.value]:null;return Xw(c.value,w)}function hp(d){if(!Object.hasOwn(fp,d.key))return null;let c=fp[d.key],w=Zw(d.key,d.priorValue,c.length);return w?c.map((D,k)=>{let P=w[k];return{kind:"device-setting",key:D,priorValue:P===null?{state:"absent"}:{state:"present",value:P},toolName:d.toolName}}):null}var gp="posted-notifications-cancelled",eR=1e4,gi=/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/;class Us{adb;timer;dozeBackoff;certifiableKinds=fn;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)??up(d),clock:(d)=>this.timezoneCommands(d)??this.settingCommands(d)??mp(d,this.timer.now()),"network-condition":(d)=>pp(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,w=Q({initialDelayMs:250,multiplier:2,maxDelayMs:1000})){this.adb=d;this.timer=c;this.dozeBackoff=w}canRevert(d){return this.commands(d)!==null}baselineRevert(d,c){let w=d.kind==="permission"?/^runtime(?:-flags)?:(\d+):([^:]+):/.exec(d.key):null,D=d.kind==="installed-app"&&d.key.startsWith("identity:")?d.key.slice(9):w?.[2];if(d.priorValue.state==="absent"&&D){let P=c.find((C)=>C.kind==="installed-app"&&C.priorValue.state==="absent"&&/^user:\d+:/.test(C.key)&&(!w||C.key.startsWith(`user:${w[1]}:`))&&C.key.endsWith(`:${D}`));if(P)return{kind:P.kind,key:P.key,priorValue:P.priorValue,toolName:"baseline-diff"}}let k={kind:d.kind,key:d.key,priorValue:d.priorValue,toolName:"baseline-diff"};return["installed-app","permission","device-setting","shared-file"].includes(d.kind)&&this.canRevert(k)?k:nn(d)}capture(d){return Ju((c,w)=>this.execute(c,d,{timeoutMs:w}))}async cleanBaseline(d,c,w=[]){await Qu(d,c,(k,P)=>this.execute(k,c,{timeoutMs:P}),{revert:(k)=>this.revert(k,c),journalEntries:w});let D=await this.execute("shell cmd clipboard clear",c,{optionalClipboard:!0});if(this.unsupportedClipboard(D))e.warn("Android cleaning skipped unsupported clipboard clear");else if(this.failedOutput(D))throw new t("Android clipboard cleaning command failed")}unsupportedClipboard(d){return/Unknown command:|Can't find service:|No shell command implementation|Service .* not found/i.test(d)}failedOutput(d){return We(d,"")||/^(?:Failure \[.*\]|Error:.*|Unknown command:.*|Unknown option:.*|Permission Denial:.*|usage:.*|Can't find service:.*)\s*$/im.test(d.trim())}async revert(d,c){let w=this.commands(d);if(!w)throw new t(`Android cannot restore ${d.kind}:${d.key}`);if(d.kind==="installed-app"&&d.priorValue.state==="absent"&&await this.packageAbsent(d.key,c))return;for(let{command:D,success:k,confirms:P,timeoutMs:C,retryable:M,wakeSleptScreen:F}of w){let q=await this.execute(D,c,{timeoutMs:C,optionalClipboard:d.kind==="clipboard",retryable:M});if(d.kind==="clipboard"&&this.unsupportedClipboard(q)){e.warn("Android cleaning skipped unsupported journal clipboard clear");continue}if(!this.confirmed(q,{success:k,confirms:P}))throw new t("Android reset command failed to confirm success");if(F)await this.wakeBeforeReadBack(c)}await this.verifyPower(d,c)}confirmed(d,{success:c,confirms:w}){return(c===void 0||d===c)&&(w===void 0||w(d))&&!this.failedOutput(d)}powerClient(d){return new Hk({execute:async(c)=>mz(await this.execute(c.map(Yo).join(" "),d),""),isScreenOn:async()=>/mWakefulness=Awake/.test(await this.execute("shell dumpsys power | grep mWakefulness=",d))})}async wakeBeforeReadBack(d){try{await JH({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 w=ap(d);if(!w)return;let D=this.powerClient(c),k;try{k=await H(c.signal,()=>w(D,{timer:this.timer,backoff:this.dozeBackoff,budgetMs:c.deadlineMs===void 0?3000:Math.max(0,Math.min(3000,c.deadlineMs-this.timer.now()))}))}catch(P){throw u(P,"Android reset could not read back device state")}if(k!==null)throw new t(`Android reset could not confirm ${d.key} was restored: ${k}`)}async packageAbsent(d,c){let w=/^user:(\d+):(.+)$/.exec(d);if(!w)throw new t("Android reset requires a user-scoped package key");let D=await this.execute(`shell pm list packages --user ${w[1]}`,c);if(!ji(D,"android")||D.split(`
|
|
34
|
+
`).some((k)=>!/^package:[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)*$/.test(k.trim())))throw new t("Android reset cannot confirm package absence");return!ji(D,w[2])}async execute(d,c,{timeoutMs:w=2000,optionalClipboard:D=!1,retryable:k=!0}={}){try{let P=async(M)=>(await c.assertOwned(),c.signal.throwIfAborted(),this.adb.executeCommand(d,{signal:c.signal,timeoutMs:M,maxBuffer:4194304,noRetry:!0,waitForProcessSettlementAfterAbort:!0})),C=c.deadlineMs===void 0?await P(w):await Mt((M)=>P(k?M:Math.min(c.deadlineMs-this.timer.now(),Math.max(w,lt(c.deadlineMs-this.timer.now(),3)))),{timer:this.timer,deadlineMs:c.deadlineMs,signal:c.signal,label:"Android reset command",minAttemptMs:w,attempts:k?void 0:1});if(c.signal.throwIfAborted(),await c.assertOwned(),D&&this.unsupportedClipboard(`${C.stdout}
|
|
35
|
+
${C.stderr}`))return`${C.stdout}
|
|
36
|
+
${C.stderr}`;if(C.error||C.stderr.trim())throw new t("Android reset command failed");return C.stdout.replace(/\r?\n$/,"")}catch(P){throw u(P,"Android reset command failed")}}commands(d){return(Object.hasOwn(this.adapters,d.kind)?this.adapters[d.kind]:void 0)?.(d)??null}packageCommands({key:d,priorValue:c}){let w=/^user:(\d+):(.+)$/.exec(d);return c.state==="absent"&&w&&gi.test(w[2])?[{command:`shell am force-stop --user ${w[1]} ${b(w[2])}`},{command:`shell pm uninstall --user ${w[1]} ${b(w[2])}`,retryable:!1,success:"Success",timeoutMs:1e4}]:null}runtimePermissionCommands({key:d,priorValue:c}){let w=c.state==="present"?c.value:void 0,D=/^runtime:(\d+):([A-Za-z0-9_.]+):([A-Za-z0-9_.]+)$/.exec(d);return D&&gi.test(D[2])&&typeof w==="boolean"?[{command:`shell pm ${w?"grant":"revoke"} --user ${D[1]} ${b(D[2])} ${b(D[3])}`}]:null}appOpsCommands({key:d,priorValue:c}){let w=c.state==="present"?c.value:void 0,D=c.state==="absent",k=/^appops:(\d+):([A-Za-z0-9_.]+):([A-Za-z0-9_]+)$/.exec(d);return k&&gi.test(k[2])&&(D||typeof w==="string"&&["allow","ignore","deny","default","foreground"].includes(w))?[{command:`shell cmd appops set --user ${k[1]} ${b(k[2])} ${b(k[3])} ${D?"default":w}`}]:null}settingCommands(d){let{key:c,priorValue:w}=d,D=w.state==="present"?w.value:void 0,k=w.state==="absent",P=/^(global|secure|system):(?:(?:user:(\d+)):)?(?!user:)([A-Za-z0-9_][A-Za-z0-9_.:-]*)$/.exec(c);if(!P||!k&&typeof D!=="string")return null;if(["global:airplane_mode_on","global:wifi_on","global:mobile_data","global:zen_mode"].includes(c)&&!k)return this.connectivityCommands(d);return[{command:k?`shell settings --user ${P[2]??"0"} delete ${P[1]} ${P[3]}`:`shell settings --user ${P[2]??"0"} put ${P[1]} ${P[3]} ${b(D)}`}]}settingsBackedCommands(d){let c=hp(d);if(!c)return null;let w=c.map((D)=>this.settingCommands(D));return w.every((D)=>D!==null)?w.flat():null}appLocaleCommands({key:d,priorValue:c}){let w=bH(d),D=lZ(c);if(w===null||!gi.test(w)||!D)return null;let{userId:k,locales:P}=D;return[{command:`shell cmd locale set-app-locales ${b(w)} --user ${k} --locales ${b(P)}`,success:""},{command:`shell cmd locale get-app-locales ${b(w)} --user ${k}`,success:`Locales for ${w} for user ${k} are [${P}]`}]}connectivityCommands({key:d,priorValue:c}){let w=c.state==="present"?c.value:void 0;if(typeof w!=="string")return null;if(d==="global:zen_mode"){let k={"0":"off","1":"priority","2":"none","3":"alarms"};return Object.hasOwn(k,w)?[{command:`shell cmd notification set_dnd ${k[w]}`}]:null}if(w!=="0"&&w!=="1")return null;return[{command:d==="global:airplane_mode_on"?`shell cmd connectivity airplane-mode ${w==="1"?"enable":"disable"}`:`shell svc ${d==="global:wifi_on"?"wifi":"data"} ${w==="1"?"enable":"disable"}`}]}displayOverrideCommands({key:d,priorValue:c}){if(d!=="display:density"&&d!=="display:size")return null;let w=d.slice(8),D=c.state==="present"?c.value:void 0,k=c.state==="absent";return k||typeof D==="string"&&(w==="density"?/^\d+$/:/^\d+x\d+$/).test(D)?[{command:`shell wm ${w} ${k?"reset":D}`}]:null}screenStateCommands({key:d,priorValue:c}){return d===aS&&pZ(c)?[{command:"shell input keyevent KEYCODE_WAKEUP"},{command:"shell wm dismiss-keyguard"}]:null}volumeCommands({key:d,priorValue:c}){let w=mZ(d,c);return w===null?null:[{command:`shell sh -c ${b(w)}`,success:A6,timeoutMs:eR}]}nightModeCommands({key:d,priorValue:c}){let w=c.state==="present"?c.value:void 0;return d==="display:night-mode"&&typeof w==="string"&&["yes","no","auto"].includes(w)?[{command:`shell cmd uimode night ${w}`}]:null}timezoneCommands({key:d,priorValue:c}){let w=c.state==="present"?c.value:void 0;return d==="timezone"&&typeof w==="string"&&w.length>0?[{command:`shell cmd alarm set-timezone ${b(w)}`},{command:"shell getprop persist.sys.timezone",success:w}]: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 w=/^app-data:(\d+):([A-Za-z0-9_.]+)$/.exec(d);return c.state==="absent"&&w&&gi.test(w[2])?[{command:`shell am force-stop --user ${w[1]} ${b(w[2])}`},{command:`shell pm clear --user ${w[1]} ${b(w[2])}`,retryable:!1,success:"Success"}]:null}systemPropertyCommands({key:d,priorValue:c}){let w=yn(d),D=tp(c);return w===null||D===null?null:[{command:`shell setprop ${w} ${b(D)}`,success:""},{command:`shell getprop ${w}`,success:D}]}statusBarCommands({key:d,priorValue:c}){let w=c.state==="present"?c.value:void 0;if(d!=="device"||c.state!=="absent"&&typeof w!=="string")return null;return[{command:"shell am broadcast -a com.android.systemui.demo -e command exit"},{command:c.state==="absent"?"shell settings delete global sysui_demo_allowed":`shell settings put global sysui_demo_allowed ${b(w)}`}]}postedNotificationCommands({key:d}){let c=uZ(d);if(c===void 0)return null;let w=["out=$(cmd notification list) || exit 1",`if printf '%s\\n' "$out" | grep -Ev -e '^$' -e '^-?[0-9]+[|]' | grep -q .; then exit 1; fi`,`if printf '%s\\n' "$out" | grep -qF ${b(`|${c}|`)}; then exit 1; fi`,`echo ${gp}`].join("; ");return[{command:`shell am force-stop ${b(c)}`},{command:`shell sh -c ${b(w)}`,success:gp}]}notificationChannelCommands({key:d,priorValue:c}){let w=mI(d);if(w===void 0||c.state!=="absent")return null;let D=(k)=>SH(k)==="absent";return[{command:rN(w,"delete"),confirms:D},{command:rN(w,"query"),confirms:D},{command:`shell am force-stop ${b(w.appId)}`}]}fileCommands({key:d,priorValue:c}){if(c.state!=="absent"||!Qe(d))return null;let w=`root=$(readlink -f /sdcard) && [ -n "$root" ] && target=$(readlink -f ${b(d)}) && [ "$target" = "$root"${b(d.slice(7))} ] && [ ! -L ${b(d)} ] && rm -f -- ${b(d)}`;return[{command:`shell sh -c ${b(w)}`},{command:`shell am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d ${b(`file://${d}`)}`}]}}import{readFile as rR,rm as aR}from"fs/promises";import{resolve as Sp}from"path";class Gs{port;timer;incarnation;fullBaseline=!0;baselines=new Map;constructor(d,c,w){this.port=d;this.timer=c;this.incarnation=w}forget(d){this.baselines.delete(d)}capture(d,c){return this.bounded(c,async(w)=>{let D=await w("identity",(P)=>this.port.identity(d,P)),k=this.baselines.get(c.resourceId);if(k?.deviceId===d.deviceId&&this.matches(k.identity,D))return;if(c.fresh!==!0)throw new t("Android baseline capture requires a freshly created emulator, not unqualified adoption");if(this.forget(c.resourceId),k)await w("invalidate",(P)=>this.port.snapshot("delete",d,P));await this.save(d,c.resourceId,D,w)})}reset(d,c,w,D){let k=D.resetTiming??{outcome:"pending",mode:"snapshot",phases:{}};return k.mode="snapshot",this.bounded({...D,assertOwned:w,resetTiming:k},async(P)=>{let C=this.baselines.get(D.resourceId);try{if(D.opaquePersistentChanges)throw new t("Android session made opaque persistent changes a snapshot load cannot revert");let F=await P("identity",(q)=>this.port.identity(d,q));if(!C||C.deviceId!==d.deviceId||!this.matches(C.identity,F))throw new t("Android snapshot baseline is missing or incompatible");return await this.changeIncarnation(d,P,async(q)=>{await P("load",(K)=>this.port.snapshot("load",d,K)),await q(),await P("restore readiness",(K)=>this.port.waitForRestore(d,K)),await P("health",(K)=>this.port.health(d,K));let U=await P("restored identity",(K)=>this.port.identity(d,K));if(!this.matches(F,U))throw new t("Android snapshot restored an incompatible identity")}),k.outcome="clean",k}catch(F){e.warn("Android snapshot reset unavailable; attempting wipe-data replacement",F),k.mode="wipe-data",k.fallbackReason=r(F)}if(this.forget(D.resourceId),C)try{await P("invalidate",(F)=>this.port.snapshot("delete",d,F))}catch(F){e.warn("Android baseline invalidation failed; never reload it, require wipe-data",F)}let M;try{if(await P("reserve replacement boot",async(q)=>{M=await this.port.reserveBoot({replacingDeviceId:d.deviceId,signal:q.signal,timeoutMs:q.timeoutMs});try{await q.assertOwned()}catch(U){throw M.release(),u(U,"Android replacement boot lost ownership")}}),!M)throw new t("Android replacement boot was not reserved");let F=M;await F.run(()=>this.replace(d,D.resourceId,P,F))}finally{M?.release()}return k.outcome="fallback:wipe-data",k})}replace(d,c,w,D){return this.changeIncarnation(d,w,async(k)=>{await w("stop",(C)=>this.port.stop(d,C)),await k(),D.markReplacedDeviceGone(),await w("wipe-data launch",(C)=>this.port.launchWiped(d,C)),await w("readiness",(C)=>this.port.ready(d,C)),await w("wipe-data health",(C)=>this.port.health(d,C));let P=await w("wipe-data identity",(C)=>this.port.identity(d,C));await this.save(d,c,P,w)})}async changeIncarnation(d,c,w){let D=!1,k=!1,P=!1,C=async()=>{if(!P)P=!0,await this.incarnation.invalidate(d)};try{await c("prepare incarnation",async()=>{D=!0,await this.incarnation.prepareForIncarnationChange(d)}),await w(C),k=!0}finally{if(D)try{await C()}finally{await this.incarnation.settleIncarnationChange(d,{ready:k})}}}async save(d,c,w,D){await D("save",(P)=>this.port.snapshot("save",d,P));let k=await D("saved identity",(P)=>this.port.identity(d,P));if(!this.matches(w,k))throw new t("Android baseline identity changed during snapshot capture");this.baselines.set(c,{deviceId:d.deviceId,identity:{...w}})}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 w=d.resetTiming,D=new AbortController,k=d.signal?AbortSignal.any([D.signal,d.signal]):D.signal,P=d.timeoutMs??0,C=this.timer.now()+P,M=async()=>{k.throwIfAborted(),await d.assertOwned?.(),k.throwIfAborted()},F=async(q,U)=>{let K=this.timer.now();try{let W=C-this.timer.now();if(W<=0)throw new t("Android snapshot reset deadline exceeded");return await l(async()=>{await M();let V=await U({signal:k,timeoutMs:W,assertOwned:M});return await M(),V},{timer:this.timer,timeoutMs:W,signal:k,label:`Android snapshot ${q}`,timeoutError:()=>new t("Android snapshot reset deadline exceeded"),onTimeout:()=>D.abort(new t("Android snapshot reset deadline exceeded"))})}finally{if(w)w.phases[q]=(w.phases[q]??0)+this.timer.now()-K}};try{if(!Number.isFinite(P)||P<=0||!d.assertOwned)throw new t("Android snapshot reset requires a finite positive deadline");return await c(F)}catch(q){if(D.abort(q),w)throw new _i(u(q,"Android snapshot baseline reset failed; destroy required").message,{...w,outcome:"pending"},{cause:q});throw u(q,"Android snapshot baseline reset failed; destroy required")}}}var tR=2,iR=Q({initialDelayMs:500,multiplier:2,maxDelayMs:2000});async function vp(d,c){let{stopper:w,timer:D,signal:k,deadlineMs:P,assertOwned:C}=c,M=0;for(let F=1;;F++){await l(D.sleep(iR.delayForAttempt(F)),{timer:D,signal:k,label:"Android emulator liveness watch"}),await C();try{let q=await w.identify(d,{signal:k,deadlineMs:P});M=q.kind==="absent"||q.kind==="mismatch"?M+1:0}catch(q){k.throwIfAborted(),e.debug(`Android emulator liveness probe failed: ${r(q)}`),M=0}if(M>=tR)throw new t(`Android emulator process for ${d.serial} (${d.avdName}) exited during snapshot restore`)}}import{createHash as nR}from"crypto";class Ws{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 w=await this.dependencies.config.readConfig(d.name);if(await c.assertOwned(),!w?.systemImagePackage||!w.systemImagePath)throw new t("Android baseline lacks system-image metadata");let D=await this.dependencies.imageMetadata(w.systemImagePath,c.signal);await c.assertOwned();let k=await this.retryStep(c,async(C)=>(await c.assertOwned(),this.dependencies.emulator.executeCommand(["-version"],C,c.signal)));if(await c.assertOwned(),k.error||!k.stdout.trim())throw new t("Android baseline lacks emulator version");let P=await this.dependencies.readiness.ctrlProxyIdentity(d,c.signal);return await c.assertOwned(),{avdName:d.name,systemImage:`${w.systemImagePackage}:${nR("sha256").update(D).update(JSON.stringify(w.hardware??{})).digest("hex")}`,emulatorVersion:k.stdout.trim(),ctrlProxyVersion:P}}async snapshot(d,c,w){w=this.remainingStep(w),await this.dependencies.console.runExclusive(c.deviceId,async()=>{let D=await this.dependencies.adb.create(c).execute(Lg(d,V4).split(" "),{timeoutMs:w.timeoutMs,signal:w.signal,noRetry:!0,waitForProcessSettlementAfterAbort:!0,beforeDispatch:()=>this.assertTarget(c,w,!0)});w.signal.throwIfAborted();let k=Bg(d,V4,D);if(!k.ok&&!(d==="delete"&&y$(k.errorMessage)))throw new t(k.errorMessage??"Android baseline snapshot failed")})}async health(d,c){c=this.remainingStep(c);let w=this.dependencies.timer.now()+c.timeoutMs;await this.assertTarget(d,c);let k=await this.fencedAdb(d,c).executeCommand("shell getprop sys.boot_completed");if(k.stdout.trim()!=="1"||We(k.stdout,k.stderr))throw new t("Android snapshot target has not completed boot");if(!(await this.dependencies.clockRegistry.runExclusive(d.deviceId,async(C,M)=>{await this.assertTarget(d,c);let F=AbortSignal.any([c.signal,M]),q=new xp(this.fencedAdb(d,{...c,signal:F,timeoutMs:w-this.dependencies.timer.now()}),F),U=await q.ensureRoot();if(!U.success)throw new t(U.error);return YD(d,q,{initialAutomaticTime:1,clockChangedByUs:!0,rootedByUs:U.rootedByUs},{hostClock:this.dependencies.timer,invalidate:this.dependencies.invalidate,mutationSignal:F})})).verified)throw new t("Android snapshot clock resync did not verify");if(await c.assertOwned(),!await this.checkCtrlProxy(d,c,w))throw new t("Android snapshot CtrlProxy health check failed");await this.assertTarget(d,c)}checkCtrlProxy(d,c,w){let D=this.dependencies.timer,k=pn(D,w),P=new AbortController,C=AbortSignal.any([c.signal,P.signal]),M=()=>new t("Android snapshot CtrlProxy health check failed");return l(()=>mn(async(F)=>{await c.assertOwned();let q=await this.dependencies.ctrlProxyReady(d,{signal:C,timeoutMs:F,noRetry:!0});return await c.assertOwned(),q},{timer:D,deadlineMs:k,signal:C,label:"Android snapshot CtrlProxy health check"}),{timer:D,signal:c.signal,timeoutMs:Math.max(0,k-D.now()),label:"Android snapshot CtrlProxy health check",timeoutError:M,onTimeout:()=>P.abort(M())})}async stop(d,c){c=this.remainingStep(c);let w=this.dependencies.timer.now()+c.timeoutMs;await this.assertTarget(d,c);let D=await this.dependencies.processStopper.identify({serial:d.deviceId,avdName:d.name},{signal:c.signal,deadlineMs:w});if(await c.assertOwned(),D.kind!=="match")throw new t("Android reset cannot prove the owned emulator process exists");await this.dependencies.emulator.killDevice(d,{force:!0,beforeDispatch:()=>this.assertTarget(d,c),signal:c.signal,timeoutMs:c.timeoutMs,processStop:{stopper:this.dependencies.processStopper,expectedAvdName:d.name}});let k,P=()=>lt(w-this.dependencies.timer.now(),2),C=()=>{if(this.dependencies.timer.now()>=w)throw new t("Android reset emulator process did not exit before the deadline"+(k===void 0?"":`: ${r(k)}`))};for(;;){await c.assertOwned(),c.signal.throwIfAborted(),C();let M=!1;try{if(!(await this.dependencies.inventory({signal:c.signal,timeoutMs:P(),targetDeviceId:d.deviceId})).some((q)=>q.deviceId===d.deviceId||q.name===d.name)&&this.dependencies.timer.now()<w)M=!(await this.dependencies.emulator.getListedNonDeviceStatesAmong([d.deviceId],{signal:c.signal,timeoutMs:P()})).has(d.deviceId)}catch(F){c.signal.throwIfAborted(),e.debug("Android reset exit inventory poll failed; continuing to wait",F),k=F}if(await c.assertOwned(),c.signal.throwIfAborted(),C(),M&&await this.processExited(d,c,w))return;C(),await this.dependencies.timer.sleep(Math.min(100,w-this.dependencies.timer.now()))}}async processExited(d,c,w){let D=await this.dependencies.processStopper.identify({serial:d.deviceId,avdName:d.name},{signal:c.signal,deadlineMs:w});if(await c.assertOwned(),D.kind==="absent")return await this.dependencies.clearQuickBoot(d,c),await c.assertOwned(),!0;if(D.kind!=="match")throw new t("Android reset cannot prove the owned emulator process exited");return!1}async launchWiped(d,c){await c.assertOwned();let w=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(w.outcome!=="launched"||!w.process||w.targetDeviceId!==d.deviceId)throw w.dispose(),new t("Android wipe-data reset did not launch the exact reserved emulator");w.release(),await c.assertOwned(),await this.dependencies.emulator.waitForEmulatorReady(d.name,c.timeoutMs,w.process,{targetDeviceId:d.deviceId,signal:c.signal,options:{freshProvision:!0}})}async waitForRestore(d,c){await c.assertOwned();let{timer:w,processStopper:D}=this.dependencies,k=new AbortController,P=AbortSignal.any([c.signal,k.signal]),C=w.now()+c.timeoutMs;try{await l([this.dependencies.emulator.waitForEmulatorReady(d.name,c.timeoutMs,null,{targetDeviceId:d.deviceId,signal:P,options:{skipWakeAndUnlock:!0}}),vp({serial:d.deviceId,avdName:d.name},{stopper:D,timer:w,signal:P,deadlineMs:C,assertOwned:c.assertOwned})],{timer:w,signal:c.signal,label:"Android snapshot restore readiness"})}finally{k.abort()}}ready(d,c){return this.dependencies.readiness.ready(d,c)}fencedAdb(d,c){let w=this.dependencies.adb.create(d);return c=this.remainingStep(c),{executeCommand:(D,k)=>{let P=D.startsWith("shell date -u @");return this.retryStep(c,async(C)=>{await c.assertOwned(),c.signal.throwIfAborted();let M=c.timeoutMs,F=await w.executeCommand(D,{...k,timeoutMs:P?Math.min(M,Math.max(k?.timeoutMs??0,lt(M,3))):C,signal:c.signal,noRetry:!0,beforeDispatch:()=>c.assertOwned()});return await c.assertOwned(),F},{minAttemptMs:k?.timeoutMs,attempts:P?1:void 0})}}}remainingStep(d){let c=this.dependencies.timer,w=c.now()+d.timeoutMs;return{...d,get timeoutMs(){return w-c.now()}}}retryStep(d,c,w={}){return Mt(c,{timer:this.dependencies.timer,deadlineMs:this.dependencies.timer.now()+d.timeoutMs,signal:d.signal,label:"Android snapshot reset adb",...w})}async assertTarget(d,c,w=!1){await c.assertOwned();let D=await this.retryStep(c,async(k)=>(await c.assertOwned(),this.dependencies.emulator.resolveAvdNameForSerial(d.deviceId,{signal:c.signal,timeoutMs:k,consoleExclusiveOwner:w,throwOnTimeout:!0})));if(await c.assertOwned(),D!==d.name)throw new t("Android snapshot reset serial no longer hosts its owned AVD")}}function cR(d){return{recordingGaps:d.recordingGaps??new ro,lock:d.hostLock??Pl(d.owner)}}async function bp(d){let{recordingGaps:c,lock:w}=cR(d);w.acquire();let D;try{let k=zd(qy);await ER(d.registry,k),await MR(d,k);let P=await d.registry.ensureScope(qy);if(P.kind!=="ready")throw new t(`Session broker's private ownership scope is unavailable: ${P.kind}`);let C=d.registry.sessionBrokerStore(k),M=YN(d.config),F=d.registry.deviceMutationJournal(),q=kR(d.config,d.androidReset,d.timer,{journal:F,recordingGaps:c}),U=q?.ios,K=U?(ee,ne,te,{signal:oe,context:pe}={})=>{let ae=()=>U.resetWithTiming(ee,ne,te,oe);return pe?.runResetBoot?pe.runResetBoot(ae):ae()}:void 0,W;if(U)({resetIosBaseline:K,captureIosBaseline:W}=yR(d,M,{erase:U,journal:F,recordingGaps:c,store:C},K));let V=d.mutationSessions?(ee)=>{let ne=d.mutationSessions.peekSession(ee.sessionUuid);if(!ne||ne.sessionId!==ee.sessionUuid||ne.assignedDevice!==ee.deviceId)throw new t("Broker mutation scope must match the live native session and device");ne.mutationRecorder=new Xo(F,ee)}:void 0,z=new Qo({androidConfigReader:new Br,scope:qy,timer:d.timer,leaseKeepalive:OR(d),brokerDeviceAcquisition:d.acquisition,brokerExecutionRelease:d.release,registry:d.registry,bindingJournal:d.journal,bindMutationRecorder:V,...q?{resetBaseline:{ios:K,android:q.android,watch:q.watch},captureIosBaseline:W,isCurrentReset:(ee)=>TR(C,ee)}:{}});D=new e4({store:C,devices:z,timer:d.timer,owner:d.owner,limits:d.config.limits,catalog:d.catalog??Ol(d.config),defaults:(ee)=>{let ne=d.config.defaults[ee];if(!ne)throw new t(`Session-broker execution is not configured for ${ee} on this host`);return ne},sessionDisposition:d.sessionDisposition,reuseCleanDevices:M.mode!=="off",reuseAndroidCleanDevices:d.config.reuseAndroidCleanDevices,idleTtlMs:{android:d.config.androidIdleTtlMs}}),await D.recoverReceipts();let J=(ee)=>vR(d,C,k,{bindMutationRecorder:V,sessionUuid:ee});await hR(C,J,c);let X=new wp(D,k,w,{timer:d.timer,avdSnapshotCleanup:to(d.avdSnapshotCleanup,d.registry,d.timer),mutations:{recordingGaps:c,recorderFor:J}});if(!d.deferStart)X.start();return X}catch(k){throw await mR(D,w),u(k,"Session broker startup failed")}}async function mR(d,c){try{await d?.close()}catch(w){e.warn("Failed to close broker after startup failure",w)}finally{c.release()}}async function hR(d,c,w){let D;try{D=await d.listRecoverableRequests()}catch(k){e.warn("Cannot list recoverable session requests for mutation recorder recovery",k);return}for(let k of D){if(k.state!=="active"||!k.sessionId)continue;try{await c(k.sessionId)}catch(P){w.mark(k.sessionId,`recorder recovery: ${r(P)}`),e.warn(`Cannot recover mutation recorder for session ${k.sessionId}`,P)}}}async function gR(d,c){let w=await d.getSession(c);if(w?.state!=="active"||!w.resourceId)return"not-recordable";let D=await d.getResource(w.resourceId);return D&&Mn(D).platform==="watchos"?"not-recordable":D}async function vR(d,c,w,{bindMutationRecorder:D,sessionUuid:k}){if(!D||!d.mutationSessions)return;let P=d.mutationSessions.peekSession(k);if(!P)return;let C=await gR(c,k);if(C==="not-recordable")return;let M=C?await d.registry.getAssignment({scopeKey:w,bindingIndex:C.allocationIndex}):null;RR(M,k,P.stableDeviceId??P.assignedDevice),D(wR(k,P.assignedDevice,C,M));let F=d.mutationSessions.peekSession(k)?.mutationRecorder;if(!F)throw new t("Broker mutation recorder recovery did not attach a recorder to the active session");return F}function yR(d,c,w,D){let{erase:k,journal:P,recordingGaps:C,store:M}=w;if(c.mode==="keep-booted")return SR(d,c,k,{journal:P,recordingGaps:C,store:M});if(c.mode==="minimal")return{resetIosBaseline:bR(d,c.maxUses,P,{recordingGaps:C,store:M}),captureIosBaseline:void 0};return{resetIosBaseline:D,captureIosBaseline:void 0}}function SR(d,c,w,{journal:D,recordingGaps:k,store:P}){let C=vs(new L(null),d.timer),M=new ts({recordingGaps:k,journal:D,mutations:C,simctl:new L(null),timer:d.timer,health:Lu(d.timer),erase:w,maxUses:c.maxUses,fallback:c.fallback,budgetMs:zs(f.IOS_RESET_STEP_BUDGET_MS),budgetCeilingMs:zs(f.IOS_RESET_STEP_BUDGET_MAX_MS)});return{captureIosBaseline:(F)=>ln(D,C,F),resetIosBaseline:async(F,q,U,{signal:K,context:W}={})=>{let V=W?.resource.requestId?await P.getRequest(W.resource.requestId):void 0;if(!W||!V?.sessionId)throw new t("iOS keep-booted reset requires its durable released session identity");return M.resetWithTiming(F,q,U,{scope:{...W.scope,sessionUuid:V.sessionId},reuseCount:W.resource.reuseCount??0,signal:K,runResetBoot:W.runResetBoot})}}}function bR(d,c,w,{recordingGaps:D,store:k}){let P=new L(null),C=new rs({recordingGaps:D,journal:w,mutations:vs(P,d.timer),simctl:P,timer:d.timer,maxUses:c,budgetMs:zs(f.IOS_RESET_STEP_BUDGET_MS)});return async(M,F,q,{signal:U,context:K}={})=>{let W=K?.resource.requestId?await k.getRequest(K.resource.requestId):void 0;if(!K||!W?.sessionId)throw new t("iOS minimal reset requires its durable released session identity");return C.resetWithTiming(M,F,q,{scope:{...K.scope,sessionUuid:W.sessionId},reuseCount:K.resource.reuseCount??0,signal:U})}}function wR(d,c,w,D){if(!w)throw new t("Recovered broker session has no resource");return Xi({platform:Mn(w).platform,sessionUuid:d,resource:w,stableDeviceId:D.stableDeviceId??c,transportId:c,assignmentGeneration:D.generation,bootId:null})}function RR(d,c,w){if(!d||d.state!=="ready"||d.execOwner?.sessionUuid!==c||d.stableDeviceId!==w)throw new t("Cannot recover broker mutation recording without the exact native assignment")}function kR(d,c,w,{journal:D,recordingGaps:k}){if(d.reuseAndroidCleanDevices&&d.defaults.android&&!c)throw new t("Android baseline reset requires the daemon readiness ports");let P=YN(d).mode!=="off";return P||d.reuseAndroidCleanDevices?{ios:P?AR():void 0,watch:wu(d,w),android:d.reuseAndroidCleanDevices&&d.defaults.android?PR(c,w,d,{journal:D,recordingGaps:k}):void 0}:void 0}function AR(){return new Zo({simctl:new L(null),iosBootInstrumentation:Go.iosBootInstrumentation(),stopDevice:async(d)=>{let c=ni(await ai("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 PR(d,c,w,{journal:D,recordingGaps:k}){let P=new Br,C=CR(d.inventory,c),M;if(w.androidResetMode==="snapshot"||w.androidResetMode==="keep-booted"&&w.androidKeepBootedFallback==="snapshot"){if(!d.snapshot)throw new t("Android snapshot reset requires daemon readiness and identity ports");M=new Gs(new Ws({emulator:new oi({timer:c}),adb:v,config:P,console:Fs,clockRegistry:uf,processStopper:qf(c),clearQuickBoot:async(q,U)=>{let K=await P.resolveAvdDirectory(q.name);if(await U.assertOwned(),!K)throw new t("Android reset cannot locate its owned AVD to remove dirty quick-boot state");await aR(Sp(K,xw,lm),{recursive:!0,force:!0}),await U.assertOwned()},capacity:{reserveBoot:(q)=>{if(!Go.androidColdBootAdmitter())throw new t("Android snapshot replacement requires boot admission before stopping");return Cq("android",q)}},admitColdBoot:async(q,U)=>{let K=Go.androidColdBootAdmitter();if(!K)throw new t("Android snapshot wipe-data reset requires boot admission wiring");return await U.assertOwned(),K.admit({avdName:q.name,timeoutMs:U.timeoutMs,signal:U.signal})},readiness:d.snapshot,inventory:C,ctrlProxyReady:d.ctrlProxyReady,imageMetadata:async(q,U)=>{let K=fl();if(!K)throw new t("Android snapshot reset requires installed system-image metadata");return rR(Sp(K.androidHome,q,"source.properties"),{encoding:"utf8",signal:U})},timer:c,invalidate:(q)=>Vs(q,"Android broker baseline reset")}),c,$1)}let F=IR(w,{recordingGaps:k,journal:D,timer:c,snapshot:M,port:(q)=>new Us(v.create(q))});return new ks({postureReset:new io(v),timer:c,resetTimeoutMs:w.androidResetTimeoutMs,inventory:async(q)=>{let U=await C(q);return Promise.all(U.map(async(K)=>{q?.signal?.throwIfAborted();let W=await P.readConfig(K.name);return q?.signal?.throwIfAborted(),{...K,isRunning:!0,runtimeId:W?.systemImagePackage,deviceType:W?.deviceName,apiLevel:W?.apiLevel}}))},adb:(q)=>v.create(q),watchSession:(q)=>Wu(G,q),ctrlProxyReady:d.ctrlProxyReady,strategy:F})}function IR(d,{snapshot:c,...w}){return d.androidResetMode==="keep-booted"?new Hs({...w,maxUses:d.androidKeepBootedMaxUses,fallback:c,fallbackBudgetMs:c?d.androidResetTimeoutMs??Ds:void 0}):c}function CR(d,c){return(w)=>{w.signal?.throwIfAborted();let D=new AbortController,k=w.signal?AbortSignal.any([w.signal,D.signal]):D.signal;return l(()=>d({...w,signal:k}),{timer:c,timeoutMs:w.timeoutMs,signal:w.signal,label:"Android baseline reset inventory",onTimeout:()=>D.abort()})}}async function TR(d,c){let w=await d.getResource(c.resourceId);return w?.state==="resetting"&&w.revision===c.revision&&w.requestId===c.requestId&&w.scopeKey===c.scopeKey}async function MR(d,c){let w=d.liveSessionIds?.()??[];if(w.length===0)return;let D=await d.registry.sessionBrokerStore(c).listRequests(),k=new Set(D.flatMap((P)=>P.sessionId?[P.sessionId]:[]));for(let P of await d.registry.snapshotManagedDevices())if(P.scopeKey===c&&P.execSessionUuid)k.add(P.execSessionUuid);if(w.some((P)=>!k.has(P)))throw new t("Session-broker mode requires prior generic sessions to be drained before startup")}async function ER(d,c){let w=await d.sessionBrokerStore(c).listLiveResources(),D=new Set(w.filter((C)=>C.state!=="destroyed").map((C)=>C.allocationIndex)),k=(await d.snapshotManagedDevices()).some((C)=>C.scopeKey!==c||C.holder!=="session_broker"||C.bindingIndex===null||!D.has(C.bindingIndex)),P=(await d.listOpenBindingJournal()).some((C)=>C.scopeKey!==c||!D.has(C.bindingIndex));if(k||P)throw new t("Session-broker mode requires prior or unaccounted managed allocations to be drained; existing inventory remains untouched")}var BR=3600000;class wp{broker;scopeKey;lock;avdSnapshotCleanup;stopped=!1;lastPruneAtMs;running;closing;wake;timer;mutations;constructor(d,c,w,{timer:D,mutations:k,avdSnapshotCleanup:P}){this.broker=d;this.scopeKey=c;this.lock=w;this.timer=D,this.mutations=k,this.avdSnapshotCleanup=to(P)}markMutationUnrecorded(d,c){this.mutations.recordingGaps.mark(d,c)}async recoverMutationRecorder(d){try{if(this.stopped)throw new t("Cannot recover mutation recording from a stopped session broker");return await this.mutations.recorderFor?.(d)}catch(c){this.markMutationUnrecorded(d,`recorder recovery: ${r(c)}`),e.warn(`Cannot recover mutation recorder for session ${d}; proceeding without recording`,c);return}}start(){if(this.stopped)return;this.running??=this.loop()}close(){return this.closing??=this.stop(),this.closing}async stop(){this.stopped=!0,this.wake?.();try{await this.broker.markRestartHandoff()}catch(d){e.warn(`Session broker restart handoff failed: ${r(d)}`,d)}await this.running,await this.broker.close(),this.lock.release()}async loop(){let d=!0;while(!this.stopped){if(!d)await this.wait();if(this.stopped)return;try{await this.broker.recoverReceipts(),await this.broker.recoverCleanup()}catch(c){e.warn(`Session broker recovery remains pending: ${r(c)}`)}if(await this.expireIdlePool(),this.stopped)return;if(!d)await this.pruneIfDue();d=!1}}async expireIdlePool(){if(this.stopped)return;try{await this.broker.expireIdlePool()}catch(d){e.warn(`Session broker idle expiry failed: ${r(d)}`,d)}}async pruneIfDue(){let d=this.timer.now();if(this.lastPruneAtMs!==void 0&&d-this.lastPruneAtMs<BR)return;this.lastPruneAtMs=d;try{if(await this.broker.pruneReceipts()>=Q6)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()},w=this.timer.setTimeout(c,T7);this.wake=()=>{this.timer.clearTimeout(w),c()}})}}function OR(d){let{mutationSessions:c,timer:w}=d;return c?new pI({sessions:()=>c,timer:w}):void 0}var Pp=Ee+pl,Ip=Pp+Pp,xR=wt,_R=kt,LR=At,$R=5000,Cp=60000,HR=3;class js{deps;recovering=new Map;recoveredSessions=new Set;ownership=new Map;attempts=new Map;registryOpens=new Map;ownerReads=new Map;ownerClaims=new Map;background=new Map;retryExpedites=new Map;closing=new AbortController;releaseHolds=new Map;episodes=new Map;pacing;closed=!1;constructor(d){this.deps=d;this.pacing=new Me({timer:d.timer??i,initialDelayMs:xR,maxDelayMs:_R,maxBlockedWaitMs:LR,backoff:d.retryBackoff})}async reown(d,c){if(this.closed||d.length===0||this.deps.registryExists?.()===!1)return[];if(this.pruneReleasedSessions(),c?.rehydrated)this.markUnconfirmed(d.filter((D)=>!this.recoveredSessions.has(D)));let w=[];for(let D of d)w.push(...await this.reownInline(D));return w}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})},(w)=>{if(!this.closed)e.debug(`[Bindings] Recovery of ${d} failed before re-owning`,w);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 w=this.releaseHolds.get(d);if(!w){let D=Promise.withResolvers(),k=this.deps.timer??i;w={settled:D.promise,resolve:D.resolve,device:this.deps.deviceOf?.(d)??"unknown device",timeout:k.setTimeout(()=>this.resolveUnknownHold(d),Ip)},this.releaseHolds.set(d,w),this.expediteRetry(d)}return{settled:w.settled,capMs:Ip}}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 w=this.releaseHolds.get(d);if(!w)return;(this.deps.timer??i).clearTimeout(w.timeout),this.releaseHolds.delete(d),w.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 w=this.deps.timer??i;c.deadline=w.setTimeout(()=>{this.canAttempt(d)},Math.max(0,Cp-(w.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,w){if(this.closed)return;let D=this.episode(d);e.debug(c,w);let k=(this.deps.timer??i).now()-D.sinceMs;if(this.ownership.get(d)==="unconfirmed"&&!D.warned&&k>$R)D.warned=!0,e.warn(`[Bindings] Session ${d} ownership unconfirmed for ${k} ms (${D.attempts} attempts): ${r(w)}; retries continue`,w)}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 w=await this.attempt(d);if(!this.acceptResult(d,w.outcome,c.stop.signal))return[];if(this.settleOwnership(d,w.outcome),w.outcome==="retry")this.logRetry(d,w.error),this.retryInBackground(d);return w.assignments}catch(w){if(!this.canAttempt(d,c.stop.signal)){if(!this.closed)e.debug(`[Bindings] Re-owning managed execution ${d} failed after resolution`,w);return[]}return this.logUnconfirmed(d,`[Bindings] Re-owning managed execution ${d} failed: ${r(w)}`,w),this.retryInBackground(d),[]}}isAdmitted(d,c){return!this.closed&&!c?.aborted&&!this.recovering.has(d)&&this.isHeld(d)}acceptResult(d,c,w){return c==="confirmed"?this.isAdmitted(d,w):this.canAttempt(d,w)}canAttempt(d,c){if(!this.isAdmitted(d,c))return!1;let w=this.episodes.get(d);if(this.ownership.get(d)==="unconfirmed"&&w&&!w.inFlight&&w.attempts>=HR&&(this.deps.timer??i).now()-w.sinceMs>=Cp)return this.settleOwnership(d,"lost"),!1;return!0}automationRefusal(d){switch(this.ownershipState(d)){case"unconfirmed":{let c=this.episode(d);return new yA(d,c.attempts===0?0:(this.deps.timer??i).now()-c.sinceMs)}case"lost":return new gq(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 w=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()-w.sinceMs} ms (${w.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 w=c==="confirmed"?this.deps.onOwnershipConfirmed:this.deps.onOwnershipLost;try{w?.(d)}catch(D){e.warn(`[Bindings] Ownership-${c} hook failed for ${d}`,D)}}needsRetry(d){return this.canAttempt(d)&&this.ownership.get(d)==="unconfirmed"}logRetry(d,c=Error("binding ownership unconfirmed")){this.logUnconfirmed(d,`[Bindings] Re-owning managed execution ${d} failed; retrying: ${r(c)}`,c)}retryInBackground(d){if(!this.needsRetry(d)||this.background.has(d))return;let c=this.retryLoop(d).finally(()=>{this.background.delete(d)});this.background.set(d,c)}async retryLoop(d){let c=this.episode(d).stop.signal;for(let w=1;this.needsRetry(d);w++){let D=new AbortController;this.retryExpedites.set(d,D);try{if(await this.pacing.wait(this.pacing.delay(w),c,D.signal),!this.needsRetry(d))return;let k=await this.attempt(d,D.signal);if(!this.acceptResult(d,k.outcome,c))return;if(this.settleOwnership(d,k.outcome),k.outcome==="retry")this.logRetry(d,k.error)}catch(k){let P=this.canAttempt(d,c);if(!P&&!this.closed&&!c.aborted)e.debug(`[Bindings] Re-own retry no longer admitted for ${d}: ${r(k)}`);if(!P)return;this.logRetry(d,k)}finally{this.retryExpedites.delete(d)}}}attempt(d,c){let w=this.attempts.get(d);if(w)return w;let D=this.episode(d),k=this.pacing.run(async()=>{if(this.retryExpedites.delete(d),!this.canAttempt(d,D.stop.signal))return{assignments:[],outcome:"retry"};if(D.attempts===0){if(D.sinceMs=(this.deps.timer??i).now(),this.ownership.get(d)==="unconfirmed")this.startDeadline(d)}D.attempts++,D.inFlight=!0;try{return await this.boundedAttempt(d,D.stop.signal)}finally{D.inFlight=!1}},(P)=>P.outcome!=="retry",D.stop.signal,c).finally(()=>{this.attempts.delete(d)});return this.attempts.set(d,k),k}async boundedAttempt(d,c){let w=new AbortController,D=AbortSignal.any([this.closing.signal,c,w.signal]);try{return await l(()=>this.reownSession(d,D,c),{timer:this.deps.timer??i,timeoutMs:Ee,signal:D,onTimeout:()=>w.abort(Error(`Re-owning session ${d} attempt timed out`)),label:`Re-owning session ${d}`})}finally{w.abort()}}async registryStep(d,c,w,D){let k=!1;try{return await l(()=>{let P=c.get(d);if(!P)P=w(),c.set(d,P);return P.then((C)=>(k=!D.aborted,C),(C)=>{throw k=!D.aborted,C})},{timer:this.deps.timer??i,signal:D,label:`Re-owning session ${d} registry step`})}finally{if(k)c.delete(d)}}async readCurrentAssignments(d,c,w){let D=this.ownerClaims.get(d);if(D){let P=await this.registryStep(d,this.ownerClaims,()=>D,w);if(!this.closed)e.debug(`[Bindings] Session ${d} retained claim completed (${P.kind}); checking current ownership`)}let k=()=>this.registryStep(d,this.ownerReads,()=>c.findExecutionAssignments(d),w);if(this.ownerReads.has(d)){if(await k(),!this.closed)e.debug(`[Bindings] Session ${d} retained ownership read completed; checking current ownership`)}return await k()}async reownSession(d,c,w){let D={assignments:[],outcome:"retry"},k=await this.registryStep(d,this.registryOpens,()=>this.deps.registry(),c);if(!this.isAdmitted(d,c))return D;let P=await this.readCurrentAssignments(d,k,c);if(!this.isAdmitted(d,c))return D;if(D.outcome="confirmed",P.length===0)D.outcome="lost";let C=this.deps.owner();for(let M of P){if(!this.isAdmitted(d,c))return{...D,outcome:"retry"};if(M.execOwner&&Uc(M.execOwner,C))continue;let F;try{F=await this.registryStep(d,this.ownerClaims,()=>k.claimExecution({scopeKey:M.scopeKey,bindingIndex:M.bindingIndex},{generation:M.generation,stableDeviceId:M.stableDeviceId},{...C,sessionUuid:d},{supersedesSessionUuid:d}),c)}catch(q){if(this.isAdmitted(d,w))this.markUnconfirmed([d]);throw q}if(!this.isAdmitted(d,c))return{...D,outcome:"retry"};if(F.kind==="claimed")D.assignments.push(F.assignment);else this.markUnconfirmed([d]),this.recordRefusal(D,F.kind,M,d)}return D}recordRefusal(d,c,w,D){if(c==="binding_in_use"||c==="scope_not_valid"||c==="binding_missing"||c==="device_assigned_elsewhere"){if(d.outcome="lost",c==="binding_in_use"&&this.ownership.has(D))return}else if(d.outcome!=="lost")d.outcome="retry";d.error=Error(`Binding ${w.bindingIndex} of ${w.scopeKey} was not re-owned for session ${D}: ${c}`)}}class Ys{options;constructor(d){this.options=d}async retire(d){let{timer:c,devices:w,isOwnerLive:D}=this.options,k=new AbortController,P=this.options.signal?AbortSignal.any([k.signal,this.options.signal]):k.signal;try{await d.withLegacyRows(async(C,M)=>{await l(async()=>{this.assertOwnersDead(C,D);let F=new Map(C.devices.map((q)=>[JSON.stringify(q),q]));for(let q of F.values()){P.throwIfAborted(),this.assertOwnersDead(C,D);let U=await w.inspect(q,P);if(P.throwIfAborted(),!U)continue;if(!cc(U.name))throw new t(`Refusing to retire non-product device '${U.name}'; reconcile its legacy registry row manually.`);if(U.isRunningStateKnown===!1)throw new t(`Running state of legacy device '${U.name}' is unconfirmed`);if(U.isRunning){this.assertOwnersDead(C,D),await w.stop(U,P),P.throwIfAborted();let K=await w.inspect(q,P);if(K&&(K.isRunning||K.isRunningStateKnown===!1))throw new t(`Shutdown of legacy device '${U.name}' is unconfirmed`)}}P.throwIfAborted(),this.assertOwnersDead(C,D)},{timer:c,signal:P,timeoutMs:this.options.timeoutMs??30000,label:"Legacy slot device retirement",onTimeout:()=>k.abort()}),P.throwIfAborted(),await M()})}catch(C){throw(this.options.warn??e.warn)(`[Daemon] Legacy slot device retirement deferred: ${r(C)}`,C),u(C,"Legacy slot devices must be retired first; retry daemon startup after resolving the cause")}}assertOwnersDead(d,c){if(d.owners.some((w)=>c(w)))throw new t("A live execution or cleanup owner still holds legacy slot devices; let it exit and retry daemon startup")}}async function Tp(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 Qs{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 w=await this.manager.getDeviceImagesDetailed(d.platform,{signal:c,bypassIosDeviceListCache:!0}),D=await this.manager.getBootedDevicesDetailed(d.platform,{signal:c,bypassAndroidDeviceListCache:!0,bypassIosDeviceListCache:!0,skipPhysicalIosDiscovery:!0});this.assertComplete(d,w,D);let k=(F)=>d.stableId?(d.platform==="android"?F.name:F.deviceId)===d.stableId:F.name===d.name,P=w.devices.find(k),C=D.devices.find((F)=>k(F)&&(d.platform!=="android"||ce(F.deviceId)));if(D.transitionalSimulators?.some((F)=>k(F.device)))throw new t("Legacy simulator is transitioning; retry retirement after it settles");if(d.platform==="android"&&!C&&P?.isRunningStateKnown===!1)throw new t("Legacy Android running state is unconfirmed");if(d.platform==="android"&&!C)await this.assertAndroidStopped(d,c);return this.currentDevice(d,P,C)}currentDevice(d,c,w){let D=w??c;if(!D)return;return{...c,...w,name:D.name,platform:d.platform,isRunning:w!==void 0||c?.isRunning===!0,isRunningStateKnown:c?.isRunningStateKnown}}assertComplete(d,c,w){let D=d.platform==="ios"?w.succeededSources?.has("ios-simulator"):w.succeededPlatforms.has("android");if(!c.succeededPlatforms.has(d.platform)||!D)throw new t(`Cannot confirm legacy ${d.platform} device inventory; retry with the platform tooling available`);if(d.platform==="android"&&w.devices.some(En))throw new t("Cannot confirm legacy shutdown while an Android runtime has unresolved identity")}async assertAndroidStopped(d,c){let w=await this.android.readStates(c),D=await this.android.processes.read({signal:c});if(!D.value)throw new t(`Cannot confirm legacy emulator process absence: ${D.error??"process table unavailable"}`);for(let k of w){if(!ce(k.deviceId)||k.state==="device")continue;let P=fD(k.deviceId),C=D.value.filter(Sg).map((M)=>Gm(M.command)).filter((M)=>M.port===P);if(C.length!==1||!C[0].avdName||cc(C[0].avdName))throw new t("Cannot confirm legacy shutdown while an Android emulator is offline or unauthorized")}if(D.value.some((k)=>this.mayBeTargetProcess(k,d)))throw new t("Legacy emulator process is still running; retry retirement after it exits")}mayBeTargetProcess(d,c){if(!Sg(d))return!1;let{avdName:w}=Gm(d.command);return!w||w===(c.stableId??c.name)}async stop(d,c){if(!d.deviceId)throw new t(`Legacy device '${d.name}' has no confirmed runtime id`);await this.manager.killDevice({...d,deviceId:d.deviceId},{signal:c,timeoutMs:30000})}}async function Mp(d,c){if(c.isLive(d))return"live";try{let w=await c.getSession(d),D=c.timer.now();return w&&w.status==="released"&&w.release_reason&&yo(w.release_reason)&&w.released_at_ms!==null&&Ny(w,D)===void 0&&DN(w,D)?"recoverable-handoff":"gone"}catch(w){return e.warn(`Session ${d} disposition lookup failed: ${r(w)}`,w),"recoverable-handoff"}}class Zs{open;options;controller=new AbortController;backoff;task;retryWait;constructor(d,c){this.open=d;this.options=c;this.backoff=c.backoff??Q({initialDelayMs:5000,maxDelayMs:300000})}start(){if(this.controller.signal.aborted)return;this.task??=this.run().catch((d)=>{if(d instanceof 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((w)=>{let D=this.options.timer.setTimeout(()=>{this.retryWait=void 0,w()},c);this.retryWait={handle:D,resolve:w}})}return!1}async tryOpen(d,c){try{return await this.open(this.controller.signal),!0}catch(w){if(w instanceof Zr)throw w;if(!this.controller.signal.aborted)e.warn(`[Daemon] Binding registry upgrade deferred: ${r(w)} (attempt ${d}; retry delay ${c}ms)`,w);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 qR(d){return{inventory:(c)=>d().listBootedAndroidDevices({signal:c.signal,androidTargetDeviceId:c.targetDeviceId,skipAndroidProfileEnrichment:!0}),ctrlProxyReady:(c,w)=>d().verifyAndroidCtrlProxyServiceReady(c,w),snapshot:{ctrlProxyIdentity:(c,w)=>d().readAndroidCtrlProxySnapshotIdentity(c,w),ready:async(c,w)=>{await w.assertOwned(),await d().verifyDevice(c.deviceId,"android",{signal:w.signal,readiness:"automationReady"},c),await w.assertOwned()}}}}class ea{host;brokerExecutionRelease;sessionBrokerService;sessionBrokerConfig;bindingExecOwnerLiveness;bindingJournalInFlight=new Qt;bindingRedrive;maintainedRegistries=new WeakSet;registryClosing=!1;unsupportedRegistrySchema;constructor(d){this.host=d}installManagedExecutionRelease(){let d=new Vr({registry:()=>this.host.openBindingRegistry(),journal:{inFlight:this.bindingJournalInFlight},work:G,sessions:qi(this.host.services.sessionManager(),PN(()=>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,w,D,{snapshot:k,...P})=>d.onSessionReleased(k,P))}bindingOwnerLiveness(){return this.bindingExecOwnerLiveness??=kq(lc,this.host.services.sessionManager()),this.bindingExecOwnerLiveness}async reownRehydratedManagedExecutions(d){let c=d.filter((w)=>this.host.services.sessionManager().isLiveManagedExecutionSession(w));await this.host.lifecycle.managedExecutionReowner()?.reown(c,{rehydrated:!0})}bindingRegistryExists(){return this.host.bindingRegistry()!==void 0||th()}bindingJournalOwner(){return{daemonId:this.host.identity.daemonSessionId(),...Eq(()=>this.host.identity.processGenerationToken())}}installBrokerDeviceAcquisition(){let d=qi(this.host.services.sessionManager(),PN(()=>this.host.services.devicePool())),c=Su({registry:()=>this.host.openBindingRegistry(),discardAndroidSnapshotOnExit:()=>w7(this.sessionBrokerConfig),resourceBudgetPolicy:{limit:()=>this.sessionBrokerConfig?.limits.totalDeviceCap??null},sessions:{claimLivenessOwnership:(w,D)=>this.host.services.sessionManager().claimLivenessOwnership(w,D),adoptManagedExecutionLivenessPolicy:(w,D)=>this.host.services.sessionManager().adoptManagedExecutionLivenessPolicy(w,D),releaseSession:async(w)=>{await d.releaseSession(w)}},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 js({registry:()=>this.host.openBindingRegistry(),registryExists:()=>this.bindingRegistryExists(),owner:()=>this.bindingJournalOwner(),timer:this.host.services.timer(),isSessionHeld:(w)=>this.host.services.sessionManager().isLiveManagedExecutionSession(w),isSessionPresent:(w)=>this.host.services.sessionManager().hasSession(w)||this.host.services.sessionManager().getReleasingSession(w)!==null,deviceOf:(w)=>this.host.services.sessionManager().getHeldDeviceSessions().find((D)=>D.sessionId===w)?.deviceId??null,onOwnershipLost:(w)=>{this.host.cancelAndReleaseSession(w,"binding-ownership-lost",{cutCallsLearnRelease:!0}).catch((D)=>{e.warn(`[Daemon] Lost managed execution ${w} release failed`,D)})},onOwnershipConfirmed:(w)=>{this.warmConfirmedManagedExecution(w).catch((D)=>{e.warn(`[Daemon] Confirmed managed execution ${w} iOS warm-up failed`,D)})}})),this.host.services.daemonState().setBrokerExecutionReowner(this.host.lifecycle.managedExecutionReowner()),this.host.services.sessionManager().setReleaseDeviceHold((w)=>this.host.lifecycle.managedExecutionReowner()?.releaseDeviceHold(w))}startBackgroundRegistryUpgrade(){if(this.registryClosing||this.host.lifecycle.shutdownInProgress())return!1;if(this.host.lifecycle.sessionBrokerConfigPath())return!0;if(!this.host.identity.socketBindCommitted())return!1;if(!this.host.lifecycle.backgroundRegistryUpgrade()){let d=new Zs((c)=>this.host.openBindingRegistry(c),{timer:this.host.services.timer()});this.host.lifecycle.setBackgroundRegistryUpgrade(d),d.start()}return!0}openBindingRegistry(d,c){if(this.unsupportedRegistrySchema)return Promise.reject(this.unsupportedRegistrySchema);let w=this.host.bindingRegistry();if(w)return c?.quiet?w:w.then((k)=>(this.startBindingRegistryMaintenance(k),k));let D=_S({writerVersion:ri,migrate:this.host.lifecycle.sessionBrokerConfigPath()!==void 0||this.host.identity.socketBindCommitted(),timer:this.host.services.timer(),isExecOwnerLive:this.bindingOwnerLiveness(),legacyDeviceRetirement:new Ys({signal:d,timer:this.host.services.timer(),isOwnerLive:lc,devices:new Qs(new si,{processes:new nh(new re,{timer:this.host.services.timer(),processTableSupported:process.platform!=="win32",procFs:process.platform==="linux"?zy:void 0}),readStates:async(k)=>{let P=v.create(null),C=P.getDeviceStates;if(!C)throw new t("Android device-state discovery is unavailable for legacy retirement");return C.call(P,{signal:k,throwOnMissingAdb:!0})}})})});return this.host.setBindingRegistry(D),D.then((k)=>{if(!this.registryClosing)this.host.services.daemonState().setBindingRegistrySchemaProbe(k);if(this.host.deviceClaimMirrors().registryOpened(k.deviceClaims()),!c?.quiet)this.startBindingRegistryMaintenance(k)},()=>{return}),D.catch((k)=>{if(k instanceof Zr)this.host.deviceClaimMirrors().skip(),this.unsupportedRegistrySchema=k;if(e.debug(`[Daemon] Binding registry open failed: ${r(k)}`),this.host.bindingRegistry()===D)this.host.setBindingRegistry(void 0)}),D}startBindingRegistryMaintenance(d){if(this.maintainedRegistries.has(d))return;this.maintainedRegistries.add(d),this.brokerExecutionRelease?.recoverSettledBindings();let c=this.host.brokerDeviceAcquisition();if(c&&!this.host.lifecycle.sessionBrokerConfigPath()&&!this.bindingRedrive&&I(Y.NODE_ENV)!=="test")this.bindingRedrive=c.startJournalRedrive(d)}async closeManagedExecutionRelease(){this.registryClosing=!0,this.host.services.daemonState().setBindingRegistrySchemaProbe(void 0),await this.host.lifecycle.backgroundRegistryUpgrade()?.close(),this.host.lifecycle.setBackgroundRegistryUpgrade(void 0),await this.sessionBrokerService?.close(),this.sessionBrokerService=void 0,this.host.services.daemonState().setSessionBrokerService(void 0),this.brokerExecutionRelease?.close(),this.host.lifecycle.managedExecutionReowner()?.close();try{await this.bindingRedrive?.stop()}catch(c){e.warn(`[Daemon] Stopping journal redrive failed: ${r(c)}`,c)}this.bindingRedrive=void 0,this.host.brokerDeviceAcquisition()?.acquisition.close(),this.host.setBrokerDeviceAcquisition(void 0);let d=this.host.bindingRegistry();this.host.setBindingRegistry(void 0),this.host.deviceClaimMirrors().dispose(),await this.host.deviceClaimMirrors().idle();try{await this.host.deviceClaimMirrors().releaseOwnedClaims((await d)?.deviceClaims())}catch(c){e.warn(`[Daemon] Withdrawing this daemon's device claims failed: ${r(c)}`,c)}try{await(await d)?.close()}catch(c){e.warn(`[Daemon] Closing the binding registry failed: ${r(c)}`,c)}}async installSessionBroker(){if(!this.host.lifecycle.sessionBrokerConfigPath()||this.sessionBrokerService)return this.sessionBrokerService;let d=this.host.brokerDeviceAcquisition(),c=this.brokerExecutionRelease;if(!d||!c)throw new t("Session broker requires the provider's native ownership and cleanup machinery");let w=await this.host.openBindingRegistry(),D=await S7(this.host.lifecycle.sessionBrokerConfigPath());if(this.sessionBrokerConfig=D,this.sessionBrokerService=await bp({deferStart:!0,config:D,registry:w,acquisition:d.acquisition,release:c,journal:d.journalFor(w),mutationSessions:this.host.services.sessionManager(),owner:this.bindingJournalOwner(),timer:this.host.services.timer(),sessionDisposition:(k)=>Mp(k,{isLive:(P)=>this.host.services.sessionManager().peekSession(P)!==null,getSession:(P)=>this.host.readPersistedSession(P),timer:this.host.services.timer()}),liveSessionIds:()=>this.host.services.sessionManager().getAllSessions().map((k)=>this.host.services.sessionManager().ownershipSessionUuid(k.sessionId)),androidReset:qR(()=>this.host.services.deviceReadiness())}),this.host.services.daemonState().setSessionBrokerService(this.sessionBrokerService),!this.bindingRedrive&&I(Y.NODE_ENV)!=="test")this.bindingRedrive=d.startJournalRedrive(w);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 UR=3,KR=[1000,5000,30000,120000,300000],GR=2000;class ta{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)=>Ht.current(c)),this.retryDelays=d.retryDelaysMs??KR}skip(){this.skipped=!0;for(let d of this.intents.values())this.clearRetry(d);this.intents.clear()}claimed(d,c,w,D){if(this.skipped)return;let k=this.intents.get(d),P=k?.kind==="claim"&&k.owner.pid===c.pid&&k.owner.ownerToken===c.ownerToken;this.record(d,{kind:"claim",owner:c,claimedAtMs:P?k.claimedAtMs:this.options.timer.now(),...w===void 0?{}:{stillHeld:w},...D===void 0?{}:{isLiveForeignOwner:D}})}released(d,c){if(this.skipped)return;this.record(d,{kind:"release",owner:c,claimedAtMs:this.options.timer.now()})}async acquire(d,c,w){let D=this.skipped?void 0:await this.readStore();if(!D||this.skipped||this.disposed)return{outcome:"unavailable"};try{for(let P=0;P<UR;P++){let C=await this.acquireOnce(D,d,c,w);if(C)return C}let k=await D.get(this.options.platform,d);return k?{outcome:"refused",ownerPid:k.pid}:{outcome:"unavailable"}}catch(k){return e.warn(`[DeviceClaims] Cannot claim ${d} in the host-wide table; the claim files decide: ${r(k)}`,k),{outcome:"unavailable"}}}async acquireOnce(d,c,w,D){let k=await d.get(this.options.platform,c),P=k?.pid===w.pid&&k.ownerToken===w.ownerToken;if(k&&!P&&await this.isLiveOwner(k,D))return{outcome:"refused",ownerPid:k.pid};let C=P?k.claimedAtMs:this.options.timer.now();if(!await d.replaceIf(k,this.claimRow(c,w,C)))return;return this.recordAcquired(c,w,C),{outcome:"claimed"}}async isLiveOwner(d,c){if(d.processGenerationToken!==void 0&&this.generationVerdict(d)==="different")return!1;return c(d)}generationVerdict(d){return this.options.generationVerdict?.(d.pid,d.processGenerationToken)??Ht.compare(d.pid,d.processGenerationToken)}recordAcquired(d,c,w){let D=this.intents.get(d);if(D)this.clearRetry(D);this.intents.set(d,{kind:"claim",acquired:!0,owner:c,claimedAtMs:w,version:++this.versions,synced:!0,attempts:0})}async read(d){if(this.skipped)return;let c=await this.readStore();if(this.skipped)return;let w=await c?.get(this.options.platform,d);if(this.skipped||!w)return;if(w.processGenerationToken!==void 0&&this.generationVerdict(w)==="different")return;return w}async readStore(){let d;try{d=this.options.store()??(this.options.whenOpen?await l(this.options.whenOpen,{timer:this.options.timer,timeoutMs:GR,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,w]of this.intents)w.synced=!1,w.attempts=0,w.version=++this.versions,this.clearRetry(w),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 w of this.intents.values())c.set(`${w.owner.pid}:${w.owner.ownerToken}`,w.owner);for(let w of c.values()){if(this.skipped)return;await d.releaseOwnedBy(w)}}record(d,c){if(this.disposed||this.skipped)return;let w=this.intents.get(d);if(w)this.clearRetry(w);this.intents.set(d,{...c,version:++this.versions,synced:!1,attempts:0}),this.write(d)}write(d,c){let w=this.intents.get(d);if(!w||this.disposed||this.skipped||this.inFlight.has(d))return;if(w.kind==="claim"&&this.isGone(w)){this.clearRetry(w),this.intents.delete(d);return}let D=c??this.options.store();if(!D){this.probeRegistry(),this.scheduleRetry(d,w);return}let k=w.version,P=this.issue(D,d,w).then(()=>{if(this.intents.get(d)?.version===k)this.confirm(d,w)},(C)=>{if(e.warn(`[DeviceClaims] Cannot ${w.kind==="claim"?"record":"remove"} the claim on ${d} in the host-wide table: ${r(C)}`,C),this.intents.get(d)?.version===k)this.scheduleRetry(d,w)}).finally(()=>{this.inFlight.delete(d);let C=this.intents.get(d);if(C&&C.version!==k)this.write(d)});this.inFlight.set(d,P)}probeRegistry(){if(this.registryOpeningHandled||!this.options.openRegistry)return;try{if(this.options.registryFileExists?.())this.registryOpeningHandled=this.options.openRegistry()}catch(d){e.warn(`[DeviceClaims] Cannot start registry opening: ${r(d)}`,d)}}isGone(d){try{return d.stillHeld?.()===!1}catch(c){return e.debug(`[DeviceClaims] Cannot re-check a claim file: ${r(c)}`),!1}}async issue(d,c,w){if(w.kind==="release")return d.release(this.options.platform,c,w.owner);let D=await d.get(this.options.platform,c),k=D?.pid===w.owner.pid&&D.ownerToken===w.owner.ownerToken;if(w.acquired){if(D&&!k||!await d.replaceIf(D,this.claimRowFor(c,w,D)))this.dropIntent(c,w);return}if(D&&!k&&await this.heldByLiveForeignOwner(D,w))throw Error(`the row names live owner pid ${D.pid}; the claim file decides this claim until it is gone`);if(!await d.replaceIf(D,this.claimRowFor(c,w,D)))throw Error("the row changed while it was being written")}claimRowFor(d,c,w){let D=w?.pid===c.owner.pid&&w.ownerToken===c.owner.ownerToken;return this.claimRow(d,c.owner,D?w.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,w){let D=this.generationOf(c.pid);return{platform:this.options.platform,deviceId:d,kind:"allocation",...this.options.daemonSessionId===void 0?{}:{daemonSessionId:this.options.daemonSessionId},pid:c.pid,ownerToken:c.ownerToken,...D===void 0?{}:{processGenerationToken:D},...c.metadata===void 0?{}:{metadata:c.metadata},claimedAtMs:w,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 w=this.retryDelays[c.attempts];if(w===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)},w)}clearRetry(d){if(d.retry!==void 0)this.options.timer.clearTimeout(d.retry),d.retry=void 0}}function Ep(d){let c,w;return()=>{let D=d();if(D!==c)c=D,w=void 0,D?.then((k)=>{if(c===D)w=k.deviceClaims()},()=>{return});return w}}function Bp(d,c={}){let w=c.registry??hM,D=c.controllerFor??jU,k=c.timer??i,P=async(M,F,q)=>{if(q.aborted){e.warn(`[statusBar] Release cap expired before the status bar clear for session ${M} on ${F} could start; left the override in place`);return}let U=w.takeOwnedBy(F,M),K=U?D(U.device):null;if(!K)return;await Je(()=>K.clear(q))},C=(M,F,q)=>{let U=w.hasDeviceWork(F);if(!U&&w.get(F)?.sessionId!==M)return;if(q?.deviceIdentityReplaced){if(e.debug(`[statusBar] Cleanup for session ${M} on replaced serial ${F}: skipped status bar clear`),w.takeOwnedBy(F,M),U)w.runOnDevice(F,async()=>{w.takeOwnedBy(F,M)});return}let K=new AbortController,W=l(()=>w.runOnDevice(F,()=>P(M,F,K.signal)),{timer:k,timeoutMs:Sr,unref:!0,label:"Status bar clear",onTimeout:()=>K.abort()}).catch((V)=>{e.warn(`[statusBar] Failed to clear status bar override on ${F}: ${r(V)}`,V)});d.registerPendingDeviceCleanup(F,W,{name:"clear status bar override",leftover:"the released session's status bar override"})};d.onSessionRelease((M,F,q,U)=>{if(U?.upgradeOnly)return;C(M,F,U)}),d.onSessionDeviceUnbound(C)}function _p(d,c=hM){c.forget(d)}function Fp(d,c={}){let w=c.registry??$l,D=c.shellFor??ME,k=c.timer??i,P=(C,M,F)=>{let q=w.takeOwnedBy(M,C);if(!q)return;if(F?.deviceIdentityReplaced){e.debug(`Kill-profile restore for session ${C} on replaced serial ${M}: skipped device writes`);return}d.registerPendingDeviceCleanup(M,n8(q,D,k),{name:"restore kill profile",leftover:"the released session's battery, Doze, standby-bucket and appop changes"})};d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;P(C,M,q)}),d.onSessionDeviceUnbound(P)}function Np(d,c={}){let w=c.registry??Qb,D=c.consoleFor??T1,k=c.timer??i,P=(C,M,F)=>{let q=w.takeOwnedBy(M,C);if(!q)return;if(F?.deviceIdentityReplaced){e.debug(`Sensor restore for session ${C} on replaced serial ${M}: skipped emulator sensor writes`);return}d.registerPendingDeviceCleanup(M,z8(q,D,k),{name:"restore emulator sensors",leftover:"the released session's emulator sensor values"})};d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;P(C,M,q)}),d.onSessionDeviceUnbound(P)}function Lp(d,c=Lf){let w=(D,k,P)=>{let C=c.stopOwnedBy(k,D);if(!C)return;if(P?.deviceIdentityReplaced){e.debug(`Audio injections for session ${D} on replaced serial ${k} stopped`);return}d.registerPendingDeviceCleanup(k,C,{name:"stop emulator audio injection",leftover:"audio the released session was injecting into the emulator microphone"})};d.onSessionRelease((D,k,P,C)=>{if(C?.upgradeOnly)return;w(D,k,C)}),d.onSessionDeviceUnbound(w)}function Hp(d,c=Lf,w=i){return(D)=>{let k=c.stopOwnerless(D);if(!k)return;hS(d,D,k,{timer:w,capMs:Sr,label:"stop sessionless emulator audio injection"})}}var WR=5000;async function VR(d,c,w,D=Vs){let k=c(d.device),P=[];for(let C of d.actions)try{await Je(()=>l(()=>M6(k,C),{timer:w,timeoutMs:WR,label:`Restore display-profile ${C.facet}`}))}catch(M){P.push(C.facet),e.warn(`Failed to restore display-profile ${C.facet} on ${d.device.deviceId}: ${r(M)}`,M)}if(d.actions.some((C)=>["screenSize","cutout","navigationMode"].includes(C.facet)))D(d.device.deviceId,"Display geometry restored");return P}function qp(d,c={}){let w=c.registry??jl,D=c.portsFor??NE,k=c.timer??i,P=c.invalidate??Vs,C=(M,F,q)=>{let U=w.takeOwnedBy(F,M);if(!U)return;if(q?.deviceIdentityReplaced){e.debug(`Display-profile restore for session ${M} on replaced serial ${F}: skipped device writes`);return}d.registerPendingDeviceCleanup(F,VR(U,D,k,P),{name:"restore display profile",leftover:"the released session's screen size, display, overlay, force-dark and posture changes"})};d.onSessionRelease((M,F,q,U)=>{if(U?.upgradeOnly)return;C(M,F,U)}),d.onSessionDeviceUnbound(C)}function Up(d,c={}){let w=c.registry??Df,D=c.clientFor??GJ,k=c.timer??i,P=(C,M,F)=>{let q=w.takeOwnedBy(M,C);if(!q)return;if(F?.deviceIdentityReplaced){e.debug(`Keyboard-profile restore for session ${C} on replaced serial ${M}: skipped device writes`);return}d.registerPendingDeviceCleanup(M,YJ(q,D,k),{name:"restore keyboard profile",leftover:"the released session's AutoMobile keyboard behaviour profile"})};d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;P(C,M,q)}),d.onSessionDeviceUnbound(P)}function Kp(d,c=BU){d.onSessionRelease((w,D)=>{let k={deviceId:D,sessionUuid:w};if(!c.hasActiveConditions(k))return;d.registerPendingDeviceCleanup(D,c.restore(k),{name:"restore device condition",leftover:"the released session's device-condition fixtures"})}),d.onSessionDeviceUnbound((w,D)=>{let k={deviceId:D,sessionUuid:w};if(!c.hasActiveConditions(k))return;d.registerPendingDeviceCleanup(D,c.restore(k),{name:"restore device condition",leftover:"the unbound session's device-condition fixtures"})})}function Gp(d,c=Rb){d.onSessionRelease((w,D,k,P)=>{if(!P.upgradeOnly)c.clear(D)}),d.onSessionDeviceUnbound((w,D)=>c.clear(D))}function Jp(d,c=my){let w=(D,k,P,C)=>{if(C){c.forgetOwnerOnDevice(D,k);return}if(!c.hasOwnedMappings(D,k))return;d.registerPendingDeviceCleanup(k,c.releaseOwnerOnDevice(D,k),{name:"remove adb reverse mappings",leftover:P})};d.onSessionRelease((D,k,P,C)=>{if(C.upgradeOnly)return;w(D,k,"the released session's adb reverse mappings",C.deviceIdentityReplaced)}),d.onSessionDeviceUnbound((D,k,P)=>w(D,k,"the unbound session's adb reverse mappings",P?.deviceIdentityReplaced))}function zp(d,c=JJ){let w=(D,k,P)=>{let C=c();if(!C?.holdsHostPortFor(k))return;let M=d.getSessionForDevice(k);if(M!==null){e.info(`[AndroidAuto] keeping the Desktop Head Unit for ${k}: session ${M} still holds it after ${D} left it`);return}if(P?.deviceIdentityReplaced){jp(C,k,{deviceStopped:!0});return}d.registerPendingDeviceCleanup(k,jp(C,k,{releaseRedirect:!0}),{name:"stop the Android Auto Desktop Head Unit",leftover:"the released session's Desktop Head Unit and its host port 5277 redirect"})};d.onSessionRelease((D,k,P,C)=>{if(C.upgradeOnly)return;w(D,k,C)}),d.onSessionDeviceUnbound(w)}async function jp(d,c,w){try{await Je(async()=>await d.stopDesktopHeadUnit(c,w))}catch(D){e.warn(`[AndroidAuto] stopping the Desktop Head Unit for ${c} after its session ended failed: ${r(D)}`,D)}}function Yp(d,c,w=G){let D=new Set,k=async(C,M)=>{let F=M==="cli-idle-timeout"?d.getTerminalReleaseSnapshot(C.baseSessionId)?.cliIdleTimeoutMs:void 0;EI(w,C,new ac(C.sessionId,M,F)).catch((q)=>{e.warn(`[DeviceLabelMap] Failed to cancel executions of ${C.sessionId}`,q)}),await xs({manager:d,pool:c},C.deviceId,C.sessionId,{reason:M})},P=async(C,M,F)=>{let q=d.getSession(M);if(!q)return;let U={sessionId:M,baseSessionId:C,deviceId:q.assignedDevice,excludeExecutionId:Ue()?.execution?.executionId};try{if(rr(F))await k(U,F);else await uA(d,c,U,w);e.info(`[DeviceLabelMap] Released label session ${M} with its base ${C}`)}catch(K){e.warn(`[DeviceLabelMap] Failed to release label session ${M} with its base ${C}`,K)}};return d.onSessionRelease((C,M,F,q)=>{if(q?.upgradeOnly)return;let U=d.takeDerivedLabelSessions(C,F);if(U.length===0)return;let K=Promise.resolve().then(()=>Promise.all(U.map((W)=>P(C,W,F)))).then(()=>{return});D.add(K),K.finally(()=>D.delete(K))}),{settled:async()=>{while(D.size>0)await Promise.all(D)}}}function Xp(d,c,w,{shutdown:D,snapshot:k,upgradeOnly:P}){let C=d.takeRecordingIds(c);if(D.fallbacks?.has(c))return;if(w==="daemon-shutdown")D.announced?.add(c);let M={...C.length>0?{recordingIds:C}:{},...P?{upgradeOnly:!0}:{}};d.emit(c,w,k,Object.keys(M).length>0?M:void 0)}var JR=Ie([n(),a(),sP()]),jR=s({settingDefaults:s({name:n(),sessionId:n(),values:Nae(p(fS),JR)})});class ia{db;constructor({db:d}={}){this.db=d}getDb(){return this.db??_e()}async get(d){let c=await this.getDb().selectFrom("device_configs").select(["platform","config_json"]).where("device_id","=",d).executeTakeFirst();if(!c)return null;let w;try{w=jR.parse(JSON.parse(c.config_json))}catch(D){return e.warn(`Ignoring unreadable device setting defaults for ${d}: ${r(D)}`,D),null}return{platform:c.platform,...w.settingDefaults}}async put(d,c){let w={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(w).onConflict((D)=>D.column("device_id").doUpdateSet({platform:w.platform,config_json:w.config_json,updated_at:m`(datetime('now'))`})).execute()}async delete(d){await this.getDb().deleteFrom("device_configs").where("device_id","=",d).execute()}}function Qp(d,c={}){let w=(D,k)=>{(c.monitor?.()??xc()).stopMonitoring(k)};d.onSessionRelease((D,k,P,C)=>{if(!C?.upgradeOnly)w(D,k)}),d.onSessionDeviceUnbound(w)}var YR=(d)=>new HU(v.create(d));function tm(d,c={}){let w=c.registry??FE,D=c.appLinksFor??YR,k=(P,C,M)=>{let F=w.takeOwnedBy(C,P);if(F.length===0)return;if(M?.deviceIdentityReplaced){e.debug(`[appLinks] Restore for session ${P} on replaced serial ${C}: skipped pm writes`);return}d.registerPendingDeviceCleanup(C,u8(F,D),{name:"restore App Links state",leftover:"the released session's App Links verification and user selections"})};d.onSessionRelease((P,C,M,F)=>{if(F?.upgradeOnly)return;k(P,C,F)}),d.onSessionDeviceUnbound(k)}function im(d,c={}){let w=c.registry??g1,D=c.adbFor??((P)=>v.create(P)),k=(P,C,M)=>{let F=w.takeOwnedBy(C,P);if(F.traces.length===0&&F.deviceFiles.length===0)return;if(M?.deviceIdentityReplaced){e.info(`[profiling] Session ${P}'s ${C} was replaced; not cleaning up`);return}let q={name:C,platform:"android",deviceId:C},U=Je(async()=>y1(C,F,D(q),{timer:c.timer??i})).catch((K)=>(e.warn(`[profiling] Cleaning up session ${P}'s profiling state threw: ${r(K)}`,K),{deviceId:C,stoppedTraces:[],removedFiles:[],errors:[r(K)]}));d.registerPendingDeviceCleanup(C,U,{name:"stop released session's trace recorders and remove profiling files",leftover:"a perfetto recorder or a heap dump file the released session started"})};d.onSessionRelease((P,C,M,F)=>{if(!F?.upgradeOnly)k(P,C,F)}),d.onSessionDeviceUnbound(k)}function nm(d,c={}){let w=c.registry??by,D=(k,P)=>{w.clearOwnedBy(P,k)};d.onSessionRelease((k,P,C,M)=>{if(!M?.upgradeOnly)D(k,P)}),d.onSessionDeviceUnbound(D)}var QR={sync:(d)=>qK(d),resolveSessionKey:(d)=>t_(d)};function rm(d,c,w=QR){let D=(k,P)=>{if(!c.passiveWorkPolicy().allows("android","appearance-sync",P))return;let C=c.devicePool().getDevice(P);if(C?.platform!=="android")return;w.sync({deviceId:C.id,name:C.id,platform:"android",incarnation:C.incarnation,sessionKey:w.resolveSessionKey(k)})};d.onSessionCreated((k)=>{D(k.sessionId,k.assignedDevice)}),d.onDeviceOwnershipChange((k,P)=>{if(P!=="full")return;let C=d.getSessionForDevice(k);if(C)D(C,k)})}function ZR(d,c,w){let D=new Set([w,d.ownershipSessionUuid(w),d.getBaseSessionOfDerivedLabel(w)].filter((k)=>k!==void 0));return(k)=>{for(let P of D)c.markMutationUnrecorded(P,k)}}function sm(d,c,w){fie(d),Bc(d,{timer:c,gapMarkerFor:(F)=>ZR(d,w,F)}),Bp(d),tm(d),Fp(d),Np(d),Lp(d),qp(d),Up(d),Kp(d),Gp(d),Jp(d),zp(d),Qp(d),o7(d),s7(d),im(d),nm(d),Lc(d,{...St,markDeviceNeedsRecorderRecovery:_c(d)}),d.onDeviceOwnershipChange((F,q)=>{if(q==="full")w.deviceDataStreamServer()?.invalidateDeviceFrames(F);else w.deviceDataStreamServer()?.invalidateInitialDeviceFrames(F)}),d.setManagedExecutionRecoveryListener((F,q)=>w.managedExecutionReowner()?.noteRecovering(F,q)),d.setLateRehydrationListener((F)=>w.reownRehydratedManagedExecutions(F)),d.setActiveSessionExecutionChecker((F,q)=>w.hasActiveSessionExecution(F,q)),d.setSessionExecutionDeadlineLookup((F,q)=>w.latestSessionExecutionDeadlineMs(F,{onSessionClock:!0,...q})),G.setSessionClockOffsetProvider(()=>d.sessionNow()-c.now()),d.setExpiryReleaseExecutionCanceller((F,q,U,K)=>w.cancelExecutionsForExpiryRelease(F,q,U,K));let D=Nc(d),k=Oc(d,{timer:c}),P=Hp(d),C=new W6(new ia,new cA,(F)=>d.getSessionForDevice(F),{timer:c});JZ(C),ZZ(C);let M=XZ(d,C,c);d.setDeviceAcquisitionExecutionCanceller((F,q)=>{G.cancelSessionlessDeviceUse(F,{excludeExecutionId:Ue()?.execution?.executionId}),w.socketServer()?.liftSessionlessStrokesOn(F),D(F,q),k(F),P(F),M(F,q)}),d.onSessionCreated((F)=>{fe.clearReleasedSession(F.sessionId),w.setupNavigationGraphUpdateListener(fe.getInstanceForSession(F.sessionId))}),rm(d,w),d.onSessionRelease((F,q,U,K)=>{if(K?.upgradeOnly)return;w.deviceReadiness().clearExplicitDevicePin(q);let W=fe.findInstanceForSession(F);if(W)w.navigationGraphListenerManagers.delete(W);fe.releaseSession(F),xe.clearCache(q),ws.invalidate(q),E.getExistingInstance(q)?.releaseSessionBinding(F),x.getExistingInstance(q)?.releaseSessionBinding(F)}),Yp(d,PN(()=>w.devicePool())),d.onSessionDeviceUnbound((F,q)=>{w.socketServer()?.liftStrokesHeldByOn(F,q),w.deviceReadiness().clearExplicitDevicePin(q);let U=fe.getInstanceForSession(F);fe.resetSession(F),w.navigationGraphListenerManagers.delete(U),w.setupNavigationGraphUpdateListener(fe.getInstanceForSession(F)),xe.clearCache(q),ws.invalidate(q),E.getExistingInstance(q)?.releaseSessionBinding(F),x.getExistingInstance(q)?.releaseSessionBinding(F)}),d.onSessionRelease((F,q,U,{snapshot:K,...W})=>{if(Xp({takeRecordingIds:Fc,emit:(...V)=>Si.emit(...V)},F,U,{shutdown:{fallbacks:w.shutdownFallbackReleaseNotifications(),announced:w.shutdownReleaseNotifications()},snapshot:K,upgradeOnly:W?.upgradeOnly}),w.shutdownFallbackReleaseNotifications()?.has(F))return;if(K.terminal)Fq(F).catch((V)=>{e.warn(`[Appearance] Failed to drop config of released session ${F}`,V)})})}function am(d,c,w){return d.onSessionExecutionEnded((D,{admitted:k})=>{let P=new Set(D.map((C)=>st(C,c)??C));for(let C of P)c.recordToolCallEnded(C,{admitted:k});w.sessionExecutionsEnded(new Set([...D,...P]))})}function na({tracker:d,sessionManager:c,devicePool:w},D,k){let{recoveryOnly:P,...C}=k??{};if(P)return w.isSessionRecoveryInFlight(D);let M=st(D,c)??D;return C.sessionClockStartedAtOrBefore===void 0&&w.isSessionRecoveryInFlight(D)||d.hasActiveSessionUuidExecutions(D,C)||d.hasActiveAutolockSessionExecutions(D,C)||M!==D&&(d.hasActiveSessionUuidExecutions(M,C)||d.hasActiveAutolockSessionExecutions(M,C))}function ra({tracker:d,sessionManager:c,devicePool:w},D,k={}){if(w.isSessionRecoveryInFlight(D))return Number.POSITIVE_INFINITY;let P=st(D,c)??D,C=d.getLatestSessionExecutionDeadlineMs(D,k);if(P===D)return C;let M=d.getLatestSessionExecutionDeadlineMs(P,k);if(C===void 0||M===void 0)return C??M;return Math.max(C,M)}function dm(d,c,w,D={}){let k=D.excludeReads?{excludeReads:!0}:{};return{hasActiveExecutions:(P)=>na({tracker:d,sessionManager:c,devicePool:w},P,k),latestExecutionDeadlineMs:(P)=>ra({tracker:d,sessionManager:c,devicePool:w},P,{onSessionClock:!0,...k})}}function cm(d,c,w){return d.getAllDevices().filter((D)=>D.platform==="android"&&c.allows("android","appearance-sync",D.id)).map((D)=>({deviceId:D.id,name:D.id,platform:"android",incarnation:D.incarnation,sessionKey:t_(w.getSessionForDevice(D.id)??void 0)}))}var bn=1000;function tD(d,c){return d.attachClaimMirror(c),d}class oa{host;unsubscribeSessionExecutionEnded=null;constructor(d){this.host=d}createDevicePool(d,c){let w=new z1(this.sessionExecutionProbe({excludeReads:!0}),this.host.services.timer(),W1,()=>this.host.services.sessionManager().sessionNow()),D=Ep(()=>this.host.bindingRegistry()),k=(C)=>this.host.deviceClaimMirrors().register(new ta({platform:C,store:D,whenOpen:async()=>(await this.host.bindingRegistry())?.deviceClaims(),registryFileExists:th,openRegistry:()=>this.host.startBackgroundRegistryUpgrade(),timer:this.host.services.timer(),daemonSessionId:this.host.identity.daemonSessionId()})),P=k("android");return J1.create({deviceClaimMirrors:{android:P,ios:k("ios")},sessionManager:this.host.services.sessionManager(),daemonSessionId:this.host.identity.daemonSessionId(),timer:this.host.services.timer(),bindingExclusion:this.host.bindingExclusionFactory()(this.host.services.timer()),...this.host.foreignCtrlProxyForwardEvidence()?{foreignDeviceOwnership:tD(new rh(void 0,void 0,void 0,{timer:this.host.services.timer(),forwardEvidence:this.host.foreignCtrlProxyForwardEvidence()}),P)}:{},managedExecutionOwnership:()=>this.host.lifecycle.managedExecutionReowner(),missingDeviceMisses:this.host.lifecycle.deviceDisconnectMisses(),installedAppsRepository:this.host.services.installedAppsRepository(),deviceSessionRepository:this.host.services.deviceSessionRepository(),releaseSessionForDisconnectedDevice:(C,M,F,{shouldCommit:q,releaseOptions:U}={})=>this.host.cancelAndReleaseSession(C,F,{shouldCommit:q,deferFailureFallback:!0,releaseOptions:U}),ownerDisconnect:{release:async(C,M)=>{let F=w.keeps(C);if(F)return F;await this.host.cancelAndReleaseSession(C.sessionId,M,{expectedSession:C,cutCallsLearnRelease:!0})}},onDeviceReady:(C)=>this.host.onDeviceReadyForSessionRegistry(C),recoveryPolicy:d,onDeviceFramesInvalidated:(C)=>{this.host.lifecycle.deviceDataStreamServer()?.invalidateDeviceFrames(C),aa().deviceIdentityChanged(C)},onDeviceIncarnationAssigned:(C)=>this.host.lifecycle.recorderDeviceIncarnationListener()?.(C),onDeviceRemoved:(C,M)=>{if(aa().deviceRemoved(C),mie(C),Bk.retireDevice(C),_p(C),cn.getInstance().retireDevice(C),FE.retireDevice(C),$l.retireDevice(C),Qb.retireDevice(C),jl.retireDevice(C),xP.retireDevice(C),by.retireDevice(C),Df.retireDevice(C),ws.invalidate(C),this.host.services.deviceReadiness().clearExplicitDevicePin(C),this.host.services.deviceSessionRegistry().onDeviceDisconnected(C),this.host.lifecycle.deviceDataStreamServer()?.removeDeviceFrames(C),M==="android")E.evictAfterDeviceRemoval(C).catch((F)=>{e.warn(`[Daemon] Failed to stop Android CtrlProxy for removed device ${C}: ${r(F)}`,F)});if(M==="ios")ye.evictAfterDeviceRemoval(C).catch((F)=>{e.warn(`[Daemon] Failed to stop iOS CtrlProxy for removed device ${C}: ${r(F)}`)})},onDeviceStateChanged:this.host.deviceStateChangeNotifier(),emulatorLossIncidentStore:new tM({timer:this.host.services.timer(),idGenerator:this.host.services.idGenerator()}),ambientExecutionIdReader:LU,cancelDeviceSessionExecutions:Object.assign((C,M,F)=>this.cancelAndDrainDeviceSessionExecutions(C,M,F),{cancelDeviceExecutions:(C,M,F)=>this.cancelAndDrainDeviceExecutions(C,M,F)}),idGenerator:this.host.services.idGenerator(),deviceSessionContinuityEnabled:AF(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=am(G,this.host.services.sessionManager(),this.host.services.devicePool())}configureSessionLifecycleCallbacks(){sm(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,w,D)=>this.cancelExecutionsForExpiryRelease(d,c,w,D)})}getAppearanceSyncTargets(){return cm(this.host.services.devicePool(),this.host.services.passiveWorkPolicy(),this.host.services.sessionManager())}hasActiveSessionExecution(d,c){return na({tracker:G,sessionManager:this.host.services.sessionManager(),devicePool:this.host.services.devicePool()},d,c)}sessionExecutionProbe(d={}){let c={isSessionRecoveryInFlight:(w)=>this.host.services.devicePool().isSessionRecoveryInFlight(w)};return dm(G,this.host.services.sessionManager(),c,d)}latestSessionExecutionDeadlineMs(d,c={}){return ra({tracker:G,sessionManager:this.host.services.sessionManager(),devicePool:this.host.services.devicePool()},d,c)}cancelExecutionsForExpiryRelease(d,c,w,D){EI(G,{sessionId:d,baseSessionId:st(d,this.host.services.sessionManager()),deviceId:D,excludeExecutionId:w.excludeExecutionId},c).catch((k)=>{e.warn(`[Daemon] Failed to cancel executions of released session ${d}: ${r(k)}`,k)})}async cancelAndReleaseSession(d,c="explicit-release",w){let{allowExpired:D=!1,expectedSession:k,shouldCommit:P}=w??{},C=async(M)=>{if(P?.()===!1)return!1;let F=k?.assignedDevice??this.host.services.devicePool().getAllDevices().find((K)=>O(K)===d)?.id??null,q=null,U=!1;if(await xs({manager:this.host.services.sessionManager(),pool:this.host.services.devicePool()},F,d,{deferFailureFallback:w?.deferFailureFallback,release:async()=>{if(k)q=await this.host.services.sessionManager().releaseSession(d,c,{expectedOwner:{session:k,deviceId:k.assignedDevice}});else if(P){let K=await this.host.services.sessionManager().releaseSessionUnlessSuperseded(d,c,{commitFence:P,allowExpired:D,...w?.releaseOptions});if(K.superseded)return e.info(`Kept session ${d}: a newer identity confirmation superseded its release (reason=${c})`),U=!0,null;q=K.deviceId}else q=await this.host.services.sessionManager().releaseSession(d,c,{allowExpired:D,...w?.releaseOptions});if(!this.isSessionDeviceAssigned(q,d))q=null;return q}}),U)return!1;if(!q||this.isSessionDeviceAssigned(q,d))return e.info(`Cancelled session ${d} (${M} executions); no device freed (reason=${c})`),!1;return e.info(`Cancelled session ${d} (${M} executions) and released device ${q} (reason=${c})`),!0};if(w?.cutCallsLearnRelease){let M=G.getActiveDeviceSessionExecutionCount(d);return this.host.services.sessionManager().cancelExecutionsCutByRelease(d,c),C(M)}return n7(d,c,C)}isSessionDeviceAssigned(d,c){return d!==null&&O(this.host.services.devicePool().getDevice(d))===c}async cancelAndDrainDeviceExecutions(d,c,w){let D=await G.cancelDeviceExecutions(d,c,w);if(D===0)return 0;if(!await G.waitForDeviceExecutionsToEnd(d,bn,w))e.warn(`[Daemon] Timed out after ${bn}ms draining cancelled executions for device ${d}`);return D}async cancelAndDrainDeviceSessionExecutions(d,c,w){let D=await G.cancelDeviceSessionExecutions(d,c,w);if(D===0)return 0;if(!await G.waitForDeviceSessionExecutionsToEnd(d,bn,w))e.warn(`[Daemon] Timed out after ${bn}ms draining cancelled executions for device session ${d}`);return D}}async function um(d,c,w,D=tQ){if(d.timedOut)return e.info("[Appearance] Startup rehydration timed out; keeping per-session appearance rows"),[];let k=new Set(d.skipped.filter(({reason:P})=>P!=="not-recoverable").map(({sessionUuid:P})=>P));try{let P=[...w.liveDaemonSessionIds].some((M)=>M!==w.ownDaemonSessionId),C=await D(async(M)=>k.has(M)||nD(c.findSession(M))||await iD(M,w,P));if(C.length>0)e.info(`[Appearance] Dropped ${C.length} stale per-session appearance rows`);return C}catch(P){return e.warn(`[Appearance] Startup appearance-row sweep failed: ${r(P)}`,P),[]}}async function iD(d,c,w){try{let D=await c.getPersistedSession(d);if(D===void 0)return w;return D.status==="active"}catch(D){return e.warn(`[Appearance] Could not read session ${d} during startup sweep; keeping its row: ${r(D)}`,D),!0}}function nD(d){return d!==null&&d!==void 0}import{createServer as dA}from"http";import{AsyncLocalStorage as rD}from"async_hooks";var hm=new rD;function gm(d,c){return hm.run(d,c)}function vm(){return hm.getStore()}var oD=/^00-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/,sD=/^(?:[a-z][a-z0-9_*/-]{0,255}|[a-z0-9][a-z0-9_*/-]{0,240}@[a-z][a-z0-9_*/-]{0,13})$/,aD=/^[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]$/,fm=/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/,cD=/^(?:[\x21\x23-\x24\x26-\x2b\x2d-\x3a\x3c-\x5b\x5d-\x7e]|%[0-9a-fA-F]{2})*$/;function Rn(d){return d.replace(/^[ \t]+|[ \t]+$/g,"")}function lD(d){if(typeof d!=="string"||d.length>512||/[^\x20-\x7e\t]/.test(d))return;let c=d.split(",");if(c.length>32)return;let w=new Set;for(let D of c){let k=Rn(D);if(k==="")continue;let P=k.indexOf("="),C=k.slice(0,P),M=k.slice(P+1);if(P<0||!sD.test(C)||!aD.test(M)||w.has(C))return;w.add(C)}return d}function pD(d,c){let w=d.indexOf("=");if(w<0)return c&&fm.test(Rn(d));return fm.test(Rn(d.slice(0,w)))&&cD.test(Rn(d.slice(w+1)))}function hD(d){if(typeof d!=="string"||d.length>8192||/[^\x20-\x7e\t]/.test(d))return;let c=d.split(",");if(c.length>180)return;return c.every((D)=>D.split(";").every((k,P)=>pD(k,P>0)))?d:void 0}function ym(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d,w=c[pV];if(typeof w!=="string"||w.length!==55)return;let D=oD.exec(w);if(!D||/^0+$/.test(D[1])||/^0+$/.test(D[2]))return;return Object.freeze({traceparent:w,traceId:D[1],parentId:D[2],traceFlags:D[3],tracestate:lD(c[mV]),baggage:hD(c[fV])})}var sa=600000,Sm=15000;class da{deps;maintenanceAdmissionToken;maintenanceAdmissionExpiresAt;maintenanceAdmissionExpiryTimer;maintenanceAdmissionAbortController;maintenanceRestartConsumed=!1;acceptanceRestartAdmissionToken;acceptanceRestartAdmissionOwnerSessionId;acceptanceRestartAdmissionCommitted=!1;acceptanceRestartAdmissionExpiresAt;acceptanceRestartAdmissionExpiryTimer;constructor(d){this.deps=d}releaseAll(){this.releaseDaemonMaintenanceAdmission(this.maintenanceAdmissionToken),this.releaseAcceptanceRestartAdmission(this.acceptanceRestartAdmissionToken)}prepareDaemonRestart(d){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};let c=G.prepareForDaemonRestart();if(c!=="accepted")return{accepted:!1,reason:c};if(!this.deps.onRestartAccepted)return G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"};try{return this.deps.onRestartAccepted(),{accepted:!0}}catch(w){return e.warn("Failed to initiate an admitted daemon restart",w),G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"}}}prepareDaemonMaintenance(d){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};this.expireDaemonMaintenanceAdmission();let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"sessions_unavailable"};let w=c.length,D=G.prepareForDaemonMaintenance(w);if(D!=="accepted")return{accepted:!1,reason:D};let k=this.deps.idGenerator.next();return this.maintenanceAdmissionToken=k,this.maintenanceAdmissionExpiresAt=this.deps.timer.now()+sa,this.maintenanceAdmissionExpiryTimer=this.deps.timer.setTimeout(()=>this.releaseDaemonMaintenanceAdmission(k),sa),this.maintenanceAdmissionAbortController=new AbortController,this.maintenanceRestartConsumed=!1,{accepted:!0,maintenanceToken:k}}completeDaemonMaintenance(d){if(!this.deps.generationMatches(d)||!this.daemonMaintenanceAdmissionMatches(d.maintenanceToken))return{completed:!1};return this.releaseDaemonMaintenanceAdmission(d.maintenanceToken),{completed:!0}}daemonMaintenanceAdmissionMatches(d){return this.expireDaemonMaintenanceAdmission(),typeof d==="string"&&this.maintenanceAdmissionToken!==void 0&&d===this.maintenanceAdmissionToken}expireDaemonMaintenanceAdmission(){if(this.maintenanceAdmissionToken!==void 0&&this.maintenanceAdmissionExpiresAt!==void 0&&this.maintenanceAdmissionExpiresAt<=this.deps.timer.now())this.releaseDaemonMaintenanceAdmission(this.maintenanceAdmissionToken)}releaseDaemonMaintenanceAdmission(d){if(typeof d!=="string"||this.maintenanceAdmissionToken===void 0||d!==this.maintenanceAdmissionToken)return;if(this.maintenanceAdmissionExpiryTimer!==void 0)this.deps.timer.clearTimeout(this.maintenanceAdmissionExpiryTimer);this.maintenanceAdmissionAbortController?.abort(Error("Daemon maintenance admission expired or was released")),G.clearDaemonMaintenancePreparation(),this.maintenanceAdmissionToken=void 0,this.maintenanceAdmissionExpiresAt=void 0,this.maintenanceAdmissionExpiryTimer=void 0,this.maintenanceAdmissionAbortController=void 0,this.maintenanceRestartConsumed=!1}restartAdmittedDaemon(d){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};if(!this.daemonMaintenanceAdmissionMatches(d.maintenanceToken))return{accepted:!1,reason:"maintenance_token_invalid"};if(this.maintenanceRestartConsumed)return{accepted:!1,reason:"maintenance_token_consumed"};let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"sessions_unavailable"};if(c.length>0)return{accepted:!1,reason:"active_sessions"};let w=G.prepareForAdmittedDaemonRestart();if(w!=="accepted")return{accepted:!1,reason:w};if(!this.deps.onRestartAccepted)return G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"};this.maintenanceRestartConsumed=!0;try{return this.deps.onRestartAccepted(),{accepted:!0}}catch(D){return e.warn("Failed to initiate a maintenance-admitted daemon restart",D),G.clearDaemonRestartPreparation(),{accepted:!1,reason:"shutdown_unavailable"}}}restartAcceptanceSession(d,c){if(!this.deps.generationMatches(d))return{accepted:!1,reason:"generation_changed"};if(c===void 0)return{accepted:!1,reason:"restart_pending"};this.expireAcceptanceRestartAdmission();let w=this.acceptanceSessionRestartScope(d.scope);if(!w)return{accepted:!1,reason:"scope_invalid"};if(w.expiresAt<=this.deps.timer.now())return{accepted:!1,reason:"scope_expired"};let D=this.deps.currentIdentity();if(!t7(this.deps.liveAcceptanceStartupSecret,D,w,d.acceptanceCapability))return{accepted:!1,reason:"acceptance_capability_invalid"};let k=this.acceptanceRestartSessionRefusal(w);if(k)return k;let P=G.prepareForDaemonRestart();if(P!=="accepted")return{accepted:!1,reason:P==="active_operations"?"active_operations":"restart_pending"};let C=this.deps.idGenerator.next(),M=Math.min(Sm,w.expiresAt-this.deps.timer.now());return this.acceptanceRestartAdmissionToken=C,this.acceptanceRestartAdmissionOwnerSessionId=c,this.acceptanceRestartAdmissionCommitted=!1,this.acceptanceRestartAdmissionExpiresAt=this.deps.timer.now()+M,this.acceptanceRestartAdmissionExpiryTimer=this.deps.timer.setTimeout(()=>this.releaseAcceptanceRestartAdmission(C),M),{accepted:!0,restartToken:C}}acceptanceRestartSessionRefusal(d){let c=this.deps.getAllSessions();if(!c)return{accepted:!1,reason:"session_not_found"};let w=c.find((D)=>D.sessionId===d.sessionUuid);if(!w)return{accepted:!1,reason:"session_not_found"};if(w.platform!==d.platform||w.stableDeviceId!==d.stableDeviceId||c.length!==1)return{accepted:!1,reason:c.length!==1&&c.some((D)=>D.sessionId!==d.sessionUuid)?"unrelated_sessions":"session_identity_mismatch"};return}releaseAcceptanceRestart(d,c){if(!this.deps.generationMatches(d)||!this.acceptanceRestartAdmissionMatches(d.restartToken,c))return{released:!1};return this.releaseAcceptanceRestartAdmission(d.restartToken),{released:!0}}commitAcceptanceRestart(d,c){if(!this.deps.generationMatches(d)||!this.acceptanceRestartAdmissionMatches(d.restartToken,c))return{committed:!1};return this.acceptanceRestartAdmissionCommitted=!0,{committed:!0}}acceptanceRestartAdmissionMatches(d,c){return this.expireAcceptanceRestartAdmission(),typeof d==="string"&&c!==void 0&&d===this.acceptanceRestartAdmissionToken&&c===this.acceptanceRestartAdmissionOwnerSessionId}expireAcceptanceRestartAdmission(){if(this.acceptanceRestartAdmissionToken!==void 0&&this.acceptanceRestartAdmissionExpiresAt!==void 0&&this.acceptanceRestartAdmissionExpiresAt<=this.deps.timer.now())this.releaseAcceptanceRestartAdmission(this.acceptanceRestartAdmissionToken)}releaseAcceptanceRestartAdmissionForOwner(d){if(this.acceptanceRestartAdmissionCommitted||d!==this.acceptanceRestartAdmissionOwnerSessionId)return;this.releaseAcceptanceRestartAdmission(this.acceptanceRestartAdmissionToken)}releaseAcceptanceRestartAdmission(d){if(typeof d!=="string"||d!==this.acceptanceRestartAdmissionToken)return;if(this.acceptanceRestartAdmissionExpiryTimer!==void 0)this.deps.timer.clearTimeout(this.acceptanceRestartAdmissionExpiryTimer);G.clearDaemonRestartPreparation(),this.acceptanceRestartAdmissionToken=void 0,this.acceptanceRestartAdmissionOwnerSessionId=void 0,this.acceptanceRestartAdmissionCommitted=!1,this.acceptanceRestartAdmissionExpiresAt=void 0,this.acceptanceRestartAdmissionExpiryTimer=void 0}acceptanceSessionRestartScope(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d,w=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||!vD(c.expiresAt)||!gD(w))return;return{sessionUuid:c.sessionUuid,platform:c.platform,stableDeviceId:c.stableDeviceId,controls:{androidSiblingAvdName:w.androidSiblingAvdName,androidDuplicateSerial:w.androidDuplicateSerial,iosSameNameSiblingUdid:w.iosSameNameSiblingUdid},expiresAt:c.expiresAt}}}function gD(d){return!(!d||typeof d!=="object"||typeof d.androidSiblingAvdName!=="string"||typeof d.androidDuplicateSerial!=="string"||typeof d.iosSameNameSiblingUdid!=="string")}function vD(d){return typeof d==="number"&&Number.isFinite(d)}function wm(d,c){let w=c?.aborted?c.reason:d instanceof Cr?d:void 0;if(w===void 0)return;return{name:w instanceof Error?w.name:"Error",message:r(w)}}var bm=-32602;function yD(d){if(!(d instanceof Error)||!("toPayload"in d))return;let{toPayload:c}=d;if(typeof c!=="function")return;let w=c.call(d);if(w===null||typeof w!=="object"||Array.isArray(w))return;let D=Object.fromEntries(Object.entries(w));return typeof D.code==="string"&&typeof D.retryable==="boolean"?D:void 0}function SD(d){if(!(d instanceof Error))return;let c=(P)=>Reflect.get(d,P),w=c("sessionUuid");if(typeof w!=="string")return;let D=c("remainingMs");if(d.name==="SessionSuspectError"&&typeof D==="number")return{code:nu,retryable:!0,details:{sessionUuid:w,remainingMs:D}};let k=c("release");if(d.name!=="TerminalSessionError"||k===null||typeof k!=="object")return;return{code:$o,retryable:!1,nextAction:ti,details:{sessionUuid:w,...bD(k)}}}function bD(d){let c=Reflect.get(d,"releaseReason"),w=typeof c==="string"?c:void 0,D=Reflect.get(d,"ownerPid"),k=Reflect.get(d,"cliIdleTimeoutMs");return{...w===void 0?{}:{reason:w},...fi(w),...Ql(w,typeof k==="number"?k:void 0),...typeof D==="number"?{ownerPid:D}:{}}}function Rm(d){let{code:c}=Dm(d);return c===nu||c===$o}function Dm(d){let c=SD(d);if(c)return c;let w=PI(d);if(w)return{code:$o,retryable:!1,nextAction:ti,details:x6(w)};let D=yD(d);if(!D)return Zp(d)??{};let{code:k,retryable:P,retryAfterMs:C,nextAction:M,...F}=D;return{...typeof k==="string"?{code:k}:{},...typeof P==="boolean"?{retryable:P}:{},...typeof C==="number"?{retryAfterMs:C}:{},...typeof M==="string"?{nextAction:M}:{},...Object.keys(F).length>0?{details:F}:{}}}function RD(d){let c=IJ(d);return c===void 0?{}:{code:pm,details:{toolName:c}}}function vi(d,c){return{...Dm(d),...d instanceof Xs?{overloadFailure:d.failure}:{},...d instanceof Cr&&d.code?{code:d.code}:{},...d instanceof Cr&&d.code===Xu?{retryable:!0}:{},...d instanceof ge&&"code"in d&&d.code===bm?{code:bm}:{},...EJ(d)?{code:Zu}:{},...RD(d),..._J(d)?{code:mm}:{},...c?{requestFailureCause:c}:{}}}class Ot{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,w,{holderSessionId:D,admissionStillHolds:k=!0}={}){if(!k||!this.deps.isSocketLive(d))return await this.cancelOne(c,w,d),"cancelled";let P=this.bySocket.get(d)??new Map;return P.set(Ot.key(c.deviceId,w),{targetDevice:c,gestureId:w,...D!==void 0?{holderSessionId:D}:{}}),this.bySocket.set(d,P),"owned"}onEndAcked(d,c,w){let D=this.bySocket.get(d);if(!D)return;if(D.delete(Ot.key(c,w)),D.size===0)this.bySocket.delete(d)}async cancelAllFor(d){let c=this.bySocket.get(d);if(this.bySocket.delete(d),!c)return;for(let{targetDevice:w,gestureId:D}of c.values())await this.cancelOne(w,D,d)}async cancelAllHeldBy(d){await this.cancelAllMatching((c)=>c.holderSessionId===d)}async cancelAllHeldByOn(d,c){await this.cancelAllMatching((w)=>w.holderSessionId===d&&w.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[w,D]of this.bySocket){for(let[k,P]of D)if(d(P))D.delete(k),c.push({...P,socketSessionId:w});if(D.size===0)this.bySocket.delete(w)}await Promise.all(c.map(({targetDevice:w,gestureId:D,socketSessionId:k})=>this.cancelOne(w,D,k)))}async cancelIfDeviceChangedHands(d,c,w,D){let k=this.bySocket.get(d)?.get(Ot.key(c,w));if(!k||k.holderSessionId===D)return!1;return this.onEndAcked(d,c,w),await this.cancelOne(k.targetDevice,w,d),!0}async cancelOne(d,c,w){try{await this.deps.cancelGesture(d,c)}catch(D){e.warn(`Failed to cancel orphaned gesture ${c} on ${d.deviceId} owned by socket ${w}: ${r(D)}`)}}}class ca{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 w of this.pending)if(w.socket===d&&w.idleDeadline&&w.idleDeadline.value>=c)return!0;return!1}[Symbol.iterator](){return this.pending[Symbol.iterator]()}}import{AsyncResource as MD}from"async_hooks";function DD(d){return aee(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 w=DD(d);return this.enter(()=>this.inner.send(w,c))}close(){return this.inner.close()}}var kD=/^[\t\n\r ]+|[\t\n\r ]+$/g;function AD(d,c){let w=d[c];return typeof w==="string"?w:void 0}function PD(d){return d?d.replace(kD,""):void 0}function la(d){return d!==void 0&&d.trim().length>0}function In(d){let c=ID(d),w=c(Rre,"boundSessionUuid"),D=c(Are,"releasedSessionUuid"),k=c(Pre,"toolSelectionProfileUuid"),P=D!==void 0&&D.trim()===w?.trim();return{...la(w)&&!P?{initialSessionToolBinding:w}:{},...la(D)?{initialReleasedSession:D}:{},...la(k)?{initialToolSelectionProfile:k}:{}}}function ID(d){if("headers"in d){let{headers:c}=d;return(w)=>AD(c,w)}return(c,w)=>PD(d[w])}function Cn(d,c,w){return zK({...d,...w.era!==void 0&&{era:w.era},...w.taskOwnerKey!==void 0&&{taskOwnerKey:w.taskOwnerKey},sessionContext:{...c,sessionId:w.requestScopeId},daemonMode:!0,requestMcpSessionId:w.requestMcpSessionId,...w.trustedForwarder===!0&&{trustForwardedMcpSessionId:!0},stateless:!0,taskLeaseKeepalive:xJ()})}var ED=td("MCP client relay",()=>import("./chunk-ndt1ccxm.js"));function ua(d){let c=new MD(d);return{run:(w)=>c.runInAsyncScope(w)}}class km{deps;root;inFlight=new Map;accepting=!0;constructor(d){this.deps=d;this.root=d.serverScope??ua("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??ED,{LoopbackMcpClient:w}=c.loaded()??await c.load();if(!this.accepting)throw new Pa(jb);let D={requestScopeId:this.deps.idGenerator.next(),requestMcpSessionId:d.sessionKey,trustedForwarder:!0,...d.taskOwnerKey!==void 0&&{taskOwnerKey:d.taskOwnerKey}},k=(W)=>this.root.run(W),P=k(()=>this.deps.createServer(In(d),D)),[C,M]=gee.createLinkedPair(),F=new w({name:"auto-mobile-daemon-client",version:"1.0.0"},{capabilities:{}}),q=F.close.bind(F),U,K={requestScopeId:D.requestScopeId,close:(W)=>(U??=this.closeForward(K,D,P,{closeClient:q,reason:W}),U)};F.close=()=>K.close(),this.inFlight.set(D.requestScopeId,K);try{await k(()=>P.connect(new kn(M,(W)=>W()))),await F.connect(new kn(C,k))}catch(W){throw await K.close(),W}return F}async closeForward(d,c,w,{closeClient:D,reason:k}){try{await this.deps.cancelScopeExecutions(c.requestScopeId,k??this.deps.closeReason())}finally{if(this.inFlight.get(c.requestScopeId)===d)this.inFlight.delete(c.requestScopeId);let P=await Promise.allSettled([D(),w.close()]);for(let C of P)if(C.status==="rejected")e.warn(`In-process MCP forward ${c.requestScopeId} teardown failed: ${Vp(C.reason)}`);if(c.requestMcpSessionId===void 0)this.deps.forgetScopeBindings(c.requestScopeId)}}}var pa="mcp_forward_closed";function Bn(d){return new km({idGenerator:d.idGenerator??B,refreshResources:_U,createServer:(c,w)=>Cn(d.base(),c,w),cancelScopeExecutions:(c,w)=>G.cancelSessionExecutions(c,w),forgetScopeBindings:(c)=>SE(c),closeReason:d.closeReason??(()=>pa)})}class pt extends t{}var Am=2000,ma=100,ga=3,Pm=250;function Im(d){if(d===null||typeof d!=="object"||Array.isArray(d))return null;let c=d.id;return typeof c==="string"?c:null}function Cm(d,c){return d?.aborted===!0&&(c?.message==="Daemon MCP client disconnected"||d.reason instanceof pt)}function Tm(d){if(d)e.error(`Original MCP request failure cause: ${d.name}: ${d.message}`)}function Mm(d,c){return d===void 0?c.now():d}function Em(d){return structuredClone(d??{})}var Bm=new Set(["getAndroid","getApple","startDevice","provisionDevice"]),xm=1000,va=1000,_m=1000;function BD(d,c){let w=`${d}.bind.lock`;return{acquire:()=>Fi(w,{ownerToken:c,ownerGeneration:Ht}),release:()=>ki(w,process.pid,c)}}var OD={getOwnerStatus(){let d=Eo();if(!d||d.pid===process.pid)return"unknown";return at(d.pid,{debugLog:e.debug})?"live":"dead"}};function Fm(d,c,w){return{reachability:d.reachability??new dR,ownerLiveness:d.ownerLiveness??OD,bindLock:d.bindLock??BD(c,w)}}var Nm=(d,c)=>Kf().getRegisteredTool(d)?.isDeviceReadOnlyCall?.(c)===!0,Lm=":read",ya="device:",Sa=900000,Ze=(d)=>typeof d==="string"&&d.trim().length>0;function Hm(d,c){return d instanceof pt||c&&d instanceof Error&&d.message==="Daemon MCP client disconnected"}function He(d){d?.throwIfAborted()}class ba{callbacks;shapeToolCallError;inboundFrameLimit;server=null;serverClosePromise=null;closing=!1;acceptingRequests=!1;requestTimeoutEnv;get maxInboundFrameBytes(){return this.inboundFrameLimit()}lifecycleGeneration=0;socketFileIdentity=null;adbClientFactory;sessions=new Map;clientSockets=new Map;acceptedClientConnections=0;controlConnections=new WeakMap;activeRequestHandlers=new Set;pendingSocketRequests=new ca;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=Nm;mcpClientFactory=(d,c,w)=>this.callbacks().createMcpClient(d,c,w);releaseToolCallRecording=KM;forgetSessionToolBindings=(d)=>SE(d);appendTextFactory=(d)=>this.callbacks().createSocketAppendTextInput(d);appendTextInputs=new Map;confirmedLegacyScaleDevices=new Set;ownedGestures=new Ot({isSocketLive:(d)=>this.clientSockets.has(d),cancelGesture:(d,c)=>this.callbacks().cancelGestureOnDevice(d,c)});constructor(d,c,w,D){this.callbacks=c;this.shapeToolCallError=w;this.inboundFrameLimit=D;let[k=Lt,P=R.daemonState(),C=i,M=null,F={},q=B,U={},K=v]=d;this.socketPath=k,this.daemonState=P,this.clearConnectionDevicePin=F.clearConnectionDevicePin,this.timer=C,this.requestTimeoutEnv=F.requestTimeoutEnv,this.onFrameTrace=F.onFrameTrace,this.mcpDispatcher=F.mcpDispatcher??Bn({base:()=>({acceptanceDiscoveryCapability:F.acceptanceDiscoveryCapability})}),this.idGenerator=q;let W=Fm(U,k,B.next());this.socketReachability=W.reachability,this.socketOwnerLiveness=W.ownerLiveness,this.socketReclaimLock=W.bindLock,this.adbClientFactory=K,this.featureFlagService=M,this.handshakeEnforced=F.enforce??Ere,this.sessionToolSelectionService=F.sessionToolSelectionService,this.daemonIdentity=F.identity??Zq(),this.identityStartedAt=Mm(F.identityStartedAt,this.timer),this.processGenerationToken=F.processGenerationToken,this.startupOptions=Em(F.startupOptions),this.onRepublishIdentity=F.onRepublishIdentity,this.identityDbPath=F.dbPath,this.identityPidFilePath=F.pidFilePath,this.startupCompletion=F.startupCompletion,this.observeStartupCompletion(),this.identitySockets=F.sockets,this.identityProcessStartedAt=F.processStartedAt,this.onRestartAccepted=F.onRestartAccepted,this.liveAcceptanceStartupSecret=F.liveAcceptanceStartupSecret,this.acceptanceDiscoveryCapability=F.acceptanceDiscoveryCapability,this.restartAdmission=new da({timer:this.timer,idGenerator:this.idGenerator,generationMatches:(V)=>this.callbacks().daemonGenerationMatches(V),currentIdentity:()=>this.callbacks().currentGenerationIdentity(),getAllSessions:()=>this.daemonState.getSessionManager().getAllSessions?.(),onRestartAccepted:this.onRestartAccepted,liveAcceptanceStartupSecret:this.liveAcceptanceStartupSecret}),e.info(`UnixSocketServer initialized with in-process MCP dispatcher: "${k}"`)}observeStartupCompletion(){this.startupCompletion?.then(()=>{this.startupCompleted=!0},(d)=>{e.debug(`Daemon startup completion rejected: ${r(d)}`)})}}import{createServer as xD}from"net";import{unlink as _D}from"fs/promises";import{existsSync as FD}from"fs";import ND from"path";class wa{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async start(){if(this.callbacks.beginAccepting(),!ul())await ll();if(await Au(ND.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(FD(this.state.socketPath))await this.callbacks.reclaimExistingSocketBeforeBind();this.state.server=xD(this.callbacks.connectionHandlerWithFanOut()),await new Promise((d,c)=>{this.state.server.listen(this.state.socketPath,()=>{this.state.socketFileIdentity=iz(this.state.socketPath),e.info(`Unix socket server listening on ${this.state.socketPath}`),OB(this.state.socketPath).then(d).catch(c)}),this.state.server.on("error",(w)=>{e.error(`Unix socket server error: ${w}`),c(w)})})}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=Er.subscribe((d)=>{this.callbacks.broadcastListChanged(d)}),this.state.resourceUpdatedUnsubscribe?.(),this.state.resourceUpdatedUnsubscribe=Rw.subscribe((d)=>{this.callbacks.broadcastResourceUpdated(d)}),this.state.sessionReleaseUnsubscribe?.(),this.state.sessionReleaseUnsubscribe=Si.subscribe((d,c,w,D)=>{this.callbacks.clearBoundMcpClientsForReleasedSession(d),this.callbacks.liftStrokesHeldBy(d),this.callbacks.broadcastSessionReleased(d,c,w,D?.recordingIds)}),this.state.sessionDeviceReboundUnsubscribe?.(),this.state.sessionDeviceReboundUnsubscribe=pq.subscribe((d)=>this.callbacks.broadcastSessionDeviceRebound(d)),(d)=>this.callbacks.handleConnection(d)}async reclaimExistingSocketBeforeBind(){let d=await this.state.socketReachability.probe(this.state.socketPath,_m);if(d!=="absent"||this.state.socketOwnerLiveness.getOwnerStatus()!=="dead")throw new t((d==="unknown"?`Refusing to bind: the AutoMobile daemon socket ${this.state.socketPath} probe is inconclusive; the socket could not be verified as dead. `:`Refusing to bind: the AutoMobile daemon socket ${this.state.socketPath} is still reachable or its former owner is not positively known to be dead. `)+"A startup lock and an inconclusive liveness probe do not authorize unlinking a socket that may still be live. Stop the running daemon or run `--daemon restart` to replace it.");await _D(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(qw(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"),w=!0;try{await l(Promise.allSettled(d),{timer:this.state.timer,timeoutMs:va,label:"Session release notification drain",timeoutError:()=>c})}catch(D){if(D!==c)throw D;w=!1}if(!w)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=qw(this.state.socketFileIdentity,this.state.socketPath),w=this.callbacks.closeListeningServer(c);for(let k of this.state.pendingSocketRequests)if(!k.admitted)this.callbacks.writeShutdownSocketResponse(k);await this.callbacks.drainActiveRequestHandlers();for(let k of this.state.pendingSocketRequests)this.callbacks.writeShutdownSocketResponse(k);this.callbacks.destroyClientSockets(d),await w,this.state.sessions.clear(),this.state.clientSockets.clear(),this.state.notificationSubscribers.clear(),this.state.resourceSubscriptions.clear(),this.state.server=null,this.state.boundMcpClientKeysBySocketSession.clear();for(let k of this.state.forwardKeyIdleTimers.values())this.state.timer.clearTimeout(k);this.state.forwardKeyIdleTimers.clear(),this.state.mcpForwardTails.clear(),this.state.mcpForwardIdleCloseKeys.clear(),this.state.appendTextInputs.clear(),this.state.socketFileIdentity=null}writeShutdownSocketResponse(d){this.callbacks.writeTerminalSocketResponse(d,{id:d.id,type:"mcp_response",success:!1,error:lg,...C0(x0(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 w=this.state.timer.setTimeout(()=>c.destroy(),va);c.once("close",()=>this.state.timer.clearTimeout(w)),c.end()}}async drainActiveRequestHandlers(){let d=Array.from(this.state.activeRequestHandlers);if(d.length===0)return;let c=Symbol("request handler drain timeout"),w=!0;try{await l(Promise.allSettled(d),{timer:this.state.timer,timeoutMs:xm,label:"Unix socket request drain",timeoutError:()=>c})}catch(D){if(D!==c)throw D;w=!1}if(!w)e.warn(`Timed out waiting for ${d.length} in-flight Unix socket request handler(s) to finish during shutdown`)}}var LD="input/";function $D(d){return d.startsWith(LD)}function qm(d,c){return $D(d)||c.has(d)}async function Um(d,c,w,{socketSessionId:D,input:k}){return c.handler==="gesture"?await d.gesture(w,c.gestureKind,D,k):await d[c.handler](w,D,k)}var HD=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??{},[cp]:d.timeoutMs};return await d.mcpClient.callTool({name:"getNavigationGraph",arguments:c},d.options)}]]);function Km(d){return HD.get(d.request.method)?.(d)}var Vm=new WeakMap;function Jm(d){let c="result"in d?d.result:void 0,w=c&&typeof c==="object"?Vm.get(c):void 0;if(w===void 0)return JSON.stringify(d)+`
|
|
37
|
+
`;return"{"+Object.entries(d).flatMap(([D,k])=>{let P=D==="result"?w:JSON.stringify(k);return P===void 0?[]:[`${JSON.stringify(D)}:${P}`]}).join(",")+`}
|
|
38
|
+
`}function qD(d){if(d==="tools/list")return"tools";return d==="resources/list"?"resources":void 0}class On{refreshResources;timer;entries=new Map;inFlightRefresh;constructor(d,c){this.refreshResources=d;this.timer=c}static MAX_ENTRIES=128;forgetSocket(d){for(let[c,w]of this.entries)if(w.socketSessionId===d)this.entries.delete(c)}async read(d,c){let w=qD(d.request.method);if(!w)return await c();d.signal?.throwIfAborted();let{route:D}=d,k=JSON.stringify([w,d.socketSessionId,D.clientKey,D.sessionUuid,D.toolSelectionProfileUuid,D.releasedSessionUuid]),P=this.entries.get(k);if(w==="resources"&&P?.generation===Er.generation(w)){if(!await this.awaitWarmRefresh(d))return P.result;d.signal?.throwIfAborted()}let C=Er.generation(w);if(P?.generation===C)return this.entries.delete(k),this.entries.set(k,P),P.result;this.entries.delete(k);let M=await c();return d.signal?.throwIfAborted(),this.retain(w,k,C,{result:M,socketSessionId:d.socketSessionId}),M}async awaitWarmRefresh(d){let c=this.inFlightRefresh??=this.refreshResources().finally(()=>{this.inFlightRefresh=void 0}),w=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:()=>w}),!0}catch(D){if(D!==w)throw D;return e.debug(`[DiscoveryCache] ${w.message}; the refresh keeps running.`),!1}}retain(d,c,w,{result:D,socketSessionId:k}){if(w!==Er.generation(d)||!D||typeof D!=="object")return;if(Vm.set(D,JSON.stringify(D)),this.entries.set(c,{generation:w,result:D,socketSessionId:k}),this.entries.size>On.MAX_ENTRIES){let P=this.entries.keys().next().value;if(P!==void 0)this.entries.delete(P)}}}function jm(d,c,w){let D={type:"daemon_notification",method:p3[w]};for(let k of d)if(c.hasSocket(k))c.write(k,D)}function zm(d,c,w){for(let[D,k]of d){if(!c.hasSocket(D))continue;for(let P of w(k))c.write(D,{type:"daemon_notification",method:NC,uri:P})}}function Qm(d,c,w){let D=w.params?.uri;if(typeof D!=="string"||D.length===0)return{id:w.id,type:"mcp_response",success:!1,error:"Resource subscription requires params.uri"};if(w.method===UA){let k=d.get(c)??new Set;k.add(D),d.set(c,k)}else{let k=d.get(c);if(k?.delete(D),k?.size===0)d.delete(c)}return{id:w.id,type:"mcp_response",success:!0,result:{}}}function Zm(d,c,w,D){let{releasedSessionId:k,reason:P,release:C,recordingIds:M}=D,F={type:"daemon_notification",method:NB,sessionId:k,...P!==void 0?{reason:P}:{},...fi(P),...C!==void 0?{release:C}:{},...M&&M.length>0?{recordingIds:M}:{}};for(let q of d){if(!c.hasSocket(q))continue;let U=Promise.withResolvers();w.add(U.promise),c.write(q,F,()=>{w.delete(U.promise),U.resolve()})}}function ef(d,c,w){let{requestId:D,progressToken:k,progress:P,total:C,message:M}=w;if(!d.hasSocket(c))return;d.write(c,{type:"daemon_notification",method:zS,requestId:D,progressToken:k,progress:P,...C!==void 0?{total:C}:{},...M!==void 0?{message:M}:{}})}function tf(d,c,w,D){let k={type:"daemon_notification",method:zN,...D};for(let P of d){if(!c.hasSocket(P))continue;let C=Promise.withResolvers();w.add(C.promise),c.write(P,k,()=>{w.delete(C.promise),C.resolve()})}}class nf{#t;get signal(){return this.#t}adopt(d){this.#t=d}}function xn(d,c,w,D=process.env){let k=$0(d,D),P=new AbortController;return{id:d.id,socketSessionId:c,receivedAtMs:w,totalTimeoutMs:k,deadline:new vh(w,k),signal:P.signal,cancellation:P,owner:new nf}}var UD=0,Ra=0;function Da(){return++UD}function rf(){return Ra}class Aa{pending=[];runningLanes=new Set;runningCount=0;barrierRunning=!1;get pendingCount(){return this.pending.length}run(d,c,w){return new Promise((D,k)=>{let P=d!==void 0&&(this.runningLanes.has(d)||this.pending.some((K)=>K.lane===d)),C,M=()=>{if(C!==void 0)w?.timer.clearTimeout(C);w?.signal.removeEventListener("abort",q)},F=(K)=>{let W=this.pending.indexOf(U);if(W<0)return;this.pending.splice(W,1),M(),k(K),this.pump()},q=()=>F(w?.signal.reason),U={lane:d,run:()=>{if(M(),w&&w.timer.now()>=w.deadlineMs)return k(w.timeoutError(P)),Promise.resolve();return c().then(D,k)}};if(this.pending.push(U),w){if(w.signal.addEventListener("abort",q,{once:!0}),w.signal.aborted){q();return}let K=w.deadlineMs-w.timer.now();if(K<=0){F(w.timeoutError(P));return}C=w.timer.setTimeout(()=>F(w.timeoutError(P)),K)}this.pump()})}pump(){if(this.barrierRunning)return;let d=new Set,c=0;while(c<this.pending.length){let w=this.pending[c];if(w.lane===void 0){if(c===0&&this.runningCount===0)this.start(this.pending.shift());return}if(this.runningLanes.has(w.lane)||d.has(w.lane)){d.add(w.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)Ra=Math.max(Ra,Da()),this.barrierRunning=!1;else this.runningLanes.delete(d.lane);this.pump()})}}var KD=new Set(["getAndroid","getApple","startDevice","provisionDevice","setActiveDevice","setToolEnabled"]),sf=["sessionUuid","device",zo,$m,vu];function Ia(d){let c=d.params?.name;if(d.method!=="tools/call"||typeof c!=="string"||KD.has(c))return;let w=WD(d.params?.arguments);if(w!==void 0)return`device:${w}`;if(et(c,d.params?.arguments))return"host:inventory";return}function et(d,c){return L0(d)&&GD(c)}function GD(d){return d===void 0||typeof d==="object"&&d!==null&&!Array.isArray(d)&&!("deviceId"in d)&&!sf.some((c)=>(c in d))}function WD(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c="deviceId"in d?d.deviceId:void 0;if(typeof c!=="string"||c.length===0)return;return sf.some((w)=>(w in d))?void 0:c}var VD=g({id:y(),type:A(["mcp_request","daemon_request"]),method:y(),params:gr().optional()}).passthrough();function af(d){return VD.safeParse(d).success}var zD=g({platform:A(["android","ios"])}).passthrough();function df(d){let c=zD.safeParse(d);return c.success?c.data.platform:void 0}var Ca=16777216;class Ta{admitted=0;headEnd=0;drainedAtSample=0;watchdog;socket;timer;onStalled;maxQueuedBytes;stallTimeoutMs;constructor(d,c,w,{maxQueuedBytes:D=16777216,stallTimeoutMs:k=60000}={}){this.socket=d,this.timer=c,this.onStalled=w,this.maxQueuedBytes=D,this.stallTimeoutMs=k}admit(d){let c=this.socket.writableLength;if(c===0)this.headEnd=this.admitted+d;else if(this.bytesBehindHead(c)+d>this.maxQueuedBytes)return c+d;this.admitted+=d;return}written(){if(this.socket.writableLength===0)this.clearWatchdog();else if(!this.watchdog&&this.socket.writableLength>this.stallWatchMinBytes)this.armWatchdog()}flushed(){if(this.socket.writableLength===0)this.clearWatchdog()}dispose(){this.clearWatchdog()}get stallWatchMinBytes(){return Math.min(1048576,this.maxQueuedBytes)}bytesBehindHead(d){return Math.min(d,Math.max(0,this.admitted-this.headEnd))}armWatchdog(){this.drainedAtSample=this.admitted-this.socket.writableLength,this.watchdog=this.timer.setTimeout(()=>this.checkProgress(),this.stallTimeoutMs)}checkProgress(){this.watchdog=void 0;let d=this.socket.writableLength;if(d===0)return;if(this.admitted-d>this.drainedAtSample){if(d>this.stallWatchMinBytes)this.armWatchdog();return}this.onStalled({queuedBytes:d,stalledMs:this.stallTimeoutMs})}clearWatchdog(){if(this.watchdog)this.timer.clearTimeout(this.watchdog),this.watchdog=void 0}}var QD=new Set(["EPIPE","ECONNRESET","ERR_STREAM_DESTROYED","ECONNABORTED"]);function ZD(d){return"code"in d&&typeof d.code==="string"&&QD.has(d.code)}class Ma{socket;sessionId;timer;maxInboundFrameBytes;guard;idleTimeout;peerEndGrace;started=!1;handlers;constructor(d,c,w,D){this.socket=d;this.sessionId=c;this.timer=w;this.maxInboundFrameBytes=D}outboundWriteGuard(){if(!this.guard)this.guard=new Ta(this.socket,this.timer,(d)=>{e.warn(`Daemon RPC socket ${this.sessionId} reader stalled: no queued bytes freed for ${d.stalledMs}ms with ${d.queuedBytes} bytes queued; destroying`),this.socket.destroy()});return this.guard}startBackpressureIdle(){if(!this.started||this.idleTimeout||this.socket.destroyed)return;this.socket.setTimeout(0),this.idleTimeout=this.armIdleTimeout()}refreshIdle(){if(!this.started||!this.idleTimeout||this.socket.destroyed)return;this.timer.clearTimeout(this.idleTimeout),this.idleTimeout=this.armIdleTimeout()}responseFlushed(){if(!this.started||this.socket.destroyed)return;if(this.idleTimeout){if(this.socket.writableLength===0)this.refreshIdle()}else this.socket.setTimeout(uD)}start(d){let{socket:c,sessionId:w,timer:D}=this;if(this.started=!0,this.handlers=d,c.setTimeout(uD),c.on("timeout",()=>this.onIdleTimeout(d)),c.on("drain",()=>this.refreshIdle()),c.on("drain",()=>this.guard?.flushed()),d.trace){let C=d.trace.bind(d);c.on("drain",()=>C("socket_drain")),c.on("pause",()=>C("socket_pause")),c.on("end",()=>C("socket_end")),c.on("finish",()=>C("socket_finish"))}let k=D.now(),P=new rd(this.maxInboundFrameBytes,{onLine:(C)=>d.onLine(C,k),onOverflow:()=>d.onOverflow()});c.on("data",(C)=>{if(P.hasOverflowed)return;this.refreshIdle(),k=D.now(),P.push(C)}),c.on("end",()=>{if(c.destroyed||this.peerEndGrace)return;this.peerEndGrace=D.setTimeout(()=>{if(!c.destroyed)e.debug(`Daemon RPC socket ${w} peer closed with ${c.writableLength} bytes unflushed; destroying`),c.destroy()},Sre)}),c.on("close",(C)=>{if(this.peerEndGrace)D.clearTimeout(this.peerEndGrace);if(this.idleTimeout)D.clearTimeout(this.idleTimeout);this.started=!1,this.guard?.dispose(),d.trace?.("socket_close",{hadError:C}),d.onClose(C)}),c.on("error",(C)=>{if(ZD(C))e.debug(`Socket peer closed for ${w}: ${r(C)}`);else e.error(`Socket error for ${w}:`,C);if(d.onError(C),!c.destroyed)c.destroy()})}armIdleTimeout(){return this.timer.setTimeout(()=>this.onIdleTimeout(this.handlers),uD)}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 ${uD}ms, destroying`),this.socket.destroy()}}class _n extends Error{queuedBytes;limitBytes;reason="queue_overflow";constructor(d,c){super(`Daemon RPC socket queued bytes exceeded ${c}`);this.queuedBytes=d;this.limitBytes=c;this.name="DaemonSocketQueueOverflowError"}}class Ea{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}handleConnection(d){if(!this.state.acceptingRequests){d.end();return}let c=this.state.idGenerator.next(),w={sessionId:c,createdAt:this.state.timer.now(),requestQueue:new Aa,requestCancellations:new Map};this.state.sessions.set(c,w),this.state.clientSockets.set(c,d),this.state.acceptedClientConnections++,e.info(`New client connection: ${c}`),this.callbacks.connectionFor(d,c).start({onLine:(D,k)=>{if(D.trim())this.callbacks.trackRequestHandler(this.callbacks.processSocketRequestLine(c,d,D,k))},onOverflow:()=>this.callbacks.rejectOversizedFrame(c,d),hasLiveRequest:()=>this.callbacks.hasLiveSocketRequest(d),trace:this.state.onFrameTrace?(D,k)=>this.callbacks.traceFrame(D,"*",{details:k}):void 0,onClose:()=>{this.state.controlConnections.delete(d),e.info(`Client disconnected: ${c}`),this.state.pendingSocketRequests.deleteForSocket(d),this.callbacks.releaseSocketSession(c,d)},onError:()=>this.callbacks.releaseSocketSession(c,d)})}connectionFor(d,c){let w=this.state.controlConnections.get(d);if(!w)w=new Ma(d,c,this.state.timer,this.state.maxInboundFrameBytes),this.state.controlConnections.set(d,w);return w}rejectOversizedFrame(d,c){e.warn(`Daemon RPC socket ${d} sent a frame over ${this.state.maxInboundFrameBytes} bytes; rejecting`);let w={id:null,type:"mcp_response",success:!1,error:"Invalid request: frame too large",code:-32600};this.callbacks.writeFrame(c,d,w,{onFlushed:()=>{if(!c.destroyed)c.destroy()}})}hasLiveSocketRequest(d){return this.state.pendingSocketRequests.hasLiveRequest(d,this.state.timer.now())}async processSocketRequestLine(d,c,w,D){let k=null,P,C,M,F=(W)=>{},q=!1,U=()=>q&&this.state.clientSockets.get(d)===c&&!c.destroyed,K=(W)=>{if(C?.terminal)return;if(C)this.callbacks.writeTerminalSocketResponse(C,W,P);else this.callbacks.writeFrame(c,d,W,{deviceId:P});q=!0};try{let W;try{W=JSON.parse(w)}catch(te){throw M=-32700,u(te,"Parse error in daemon socket request")}if(k=Im(W),!af(W))throw M=-32600,new t("Invalid daemon socket request");let V=W,z=[us,$w,zT].includes(V.method),J=xn(V,d,D,this.state.requestTimeoutEnv),X={id:V.id,sessionId:d,socket:c,admitted:z,terminal:!1,idleDeadline:z?void 0:J.deadline};if(C=X,this.state.pendingSocketRequests.add(X),this.announceResolvedBudget(c,d,V,{resolvedMs:J.totalTimeoutMs,controlFrame:z}),P=this.state.onFrameTrace?this.callbacks.frameDeviceId(V):void 0,this.state.onFrameTrace)this.callbacks.traceFrame("frame_parsed",V.id,{deviceId:P});(()=>{try{if(V.method==="tools/call"&&this.state.daemonState.isInitialized())F=this.state.daemonState.getDevicePool().beginMcpToolCall?.(d)??F}catch(te){e.warn(`Could not begin MCP tool-call ownership claim: ${r(te)}`,te)}})();let ne=await this.callbacks.handleRequest(d,c,V,{receivedAtMs:D,handling:{onAdmitted:(te)=>{X.admitted=!0,X.idleDeadline=z?void 0:te},context:J}});if(ne)K(ne);else this.state.pendingSocketRequests.delete(X),this.state.controlConnections.get(c)?.responseFlushed()}catch(W){if(Hm(W,c.destroyed))e.debug(`Client cancelled request ${k} from ${d}`);else e.error(`Error processing request ${k} from ${d}:`,W);let V={id:k,type:"mcp_response",success:!1,error:r(W),...M===void 0?{}:{code:M},...vi(W,void 0)};K(V)}finally{F(U())}}writeTerminalSocketResponse(d,c,w){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:w})}withCanonicalToolCallDeviceIds(d){let c=d.params?.arguments;if(d.method!=="tools/call"||!dH(c)||!this.state.daemonState.isInitialized?.())return d;let w=S6(this.state.daemonState.getDevicePool?.(),c);return w===c?d:{...d,params:{...d.params,arguments:w}}}frameDeviceId(d){let c=d.params?.arguments?.deviceId;return typeof c==="string"?c:void 0}traceFrame(d,c,{deviceId:w,error:D,details:k}={}){if(this.state.onFrameTrace)this.state.onFrameTrace({event:d,atMs:this.state.timer.now(),wallMs:performance.now(),requestId:c,deviceId:w,error:D,...k})}releaseSocketSession(d,c){if(this.state.clientSockets.get(d)!==c)return;this.callbacks.abortMcpRequests(d),this.callbacks.forgetSocketDiscovery(d),this.callbacks.trackRequestHandler(G.cancelSessionExecutions(d,"socket_disconnect").then(()=>{return}).catch((w)=>{e.warn(`Cancelling executions of socket ${d} failed: ${r(w)}`)})),this.state.restartAdmission.releaseAcceptanceRestartAdmissionForOwner(d),this.state.sessions.delete(d),this.state.clientSockets.delete(d),this.state.notificationSubscribers.delete(d),this.state.resourceSubscriptions.delete(d),this.callbacks.clearBoundMcpClientKey(d),this.callbacks.releaseDevicePoolMcpSessionBindings(d),this.callbacks.clearConnectionDevicePin(d),this.state.daemonState.getBrokerConnectionScopes?.().unbind(d),this.state.releaseToolCallRecording(d),this.state.forgetSessionToolBindings(d),this.callbacks.forgetLateSessionToolBindings(d),this.callbacks.trackRequestHandler(this.state.ownedGestures.cancelAllFor(d))}forgetLateSessionToolBindings(d){if(!G.hasActiveSessionExecutions(d))return;G.waitForSessionExecutionsToEnd(d,Sa).then((c)=>{if(this.state.forgetSessionToolBindings(d),!c)e.warn(`Socket ${d} still had executions ${Sa}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,w){let D=c.get(d);if(!D)return;c.delete(d);for(let k of D)k.abort(Error(w))}mcpRequestSignal(d,c=this.state.clientSockets.get(d),w){let D=new AbortController,k=()=>D.abort(w?.reason);if(w?.aborted)k();else w?.addEventListener("abort",k,{once:!0});let P=this.state.mcpRequestAbortControllers.get(d)??new Set;P.add(D),this.state.mcpRequestAbortControllers.set(d,P);let C=this.state.clientSockets.get(d);if(!c||C!==c||c.destroyed)D.abort(Error("Daemon MCP client disconnected"));return{signal:D.signal,dispose:()=>{if(w?.removeEventListener("abort",k),P.delete(D),P.size===0&&this.state.mcpRequestAbortControllers.get(d)===P)this.state.mcpRequestAbortControllers.delete(d)}}}isMcpRequestOwnerCurrent(d,c){let w=this.state.clientSockets.get(d);return!c.aborted&&w!==void 0&&!w.destroyed}get notificationTransport(){return{hasSocket:(d)=>this.state.clientSockets.has(d),write:(d,c,w)=>{let D=this.state.clientSockets.get(d);if(D)this.callbacks.writeFrame(D,d,c,{onFlushed:w})}}}broadcastListChanged(d){jm(this.state.notificationSubscribers,this.notificationTransport,d)}broadcastResourceUpdated(d){zm(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((w)=>this.callbacks.holdsSession(w,d.sessionId));tf(c,this.notificationTransport,this.state.pendingSessionReleaseWrites,d)}broadcastSessionReleased(d,c,w,D){Zm(this.state.notificationSubscribers,this.notificationTransport,this.state.pendingSessionReleaseWrites,{releasedSessionId:d,reason:c,release:w,recordingIds:D})}pushProgressNotification(d,c){ef(this.notificationTransport,d,c)}announceResolvedBudget(d,c,w,{resolvedMs:D,controlFrame:k}){if(k||w.type!=="mcp_request"||w.acceptsRequestBudget!==!0||D===w.timeoutMs)return;this.callbacks.writeFrame(d,c,{type:"daemon_notification",method:W0,requestId:w.id,timeoutMs:D})}writeFrame(d,c,w,{onFlushed:D,deviceId:k}={}){if(this.state.onFrameTrace&&w.type==="mcp_response"){this.callbacks.traceFrame("response_write_started",w.id??"null",{deviceId:k}),this.callbacks.writeFrameData(d,c,w,{onFlushed:(P)=>{this.callbacks.traceFrame("response_write_callback",w.id??"null",{deviceId:k,error:P?.message,details:{writableLengthInCallback:d.writableLength}}),D?.()},onWritten:(P,C)=>{this.callbacks.traceFrame("response_write_returned",w.id??"null",{deviceId:k,details:{byteLength:C,writableLengthAfterWrite:P}})}});return}this.callbacks.writeFrameData(d,c,w,{onFlushed:D})}writeFrameData(d,c,w,{onFlushed:D,onWritten:k}){if(d.destroyed){D?.(Error("socket destroyed"));return}try{let P=Jm(w),C=Buffer.byteLength(P),M=this.callbacks.connectionFor(d,c).outboundWriteGuard(),F=M.admit(C);if(F!==void 0){let U=new _n(F,Ca);e.warn(`Daemon RPC socket ${c} write queue exceeded limit; queuedBytes=${F}, limitBytes=${Ca}; destroying`),D?.(U),d.destroy();return}let q=d.write(P,(U)=>{if(!U&&!d.destroyed&&d.writableLength===0)this.state.controlConnections.get(d)?.refreshIdle(),M.flushed();D?.(U)});if(M.written(),k)k(d.writableLength,C);if(!q)this.state.controlConnections.get(d)?.startBackpressureIdle(),e.debug(`Daemon RPC socket ${c} backpressured; awaiting drain`)}catch(P){if(D?.(P instanceof Error?P:Error(r(P))),e.warn(`Daemon RPC write failed for ${c}: ${P}`),!d.destroyed)d.destroy()}}}var ve=(d)=>mo((c)=>Boolean(c),{message:d});function xt(d){return(c)=>{let w=c!==null&&typeof c==="object"&&!Array.isArray(c)?c:{},D=d.safeParse(w);if(!D.success)throw Error(D.error.issues[0].message);return D.data}}var lf=xt(g({key:ve("setFeatureFlag requires 'key' (string) and 'enabled' (boolean) params"),enabled:mo((d)=>typeof d==="boolean",{message:"setFeatureFlag requires 'key' (string) and 'enabled' (boolean) params"}),config:mo(()=>!0)})),Ba="setSessionToolEnabled requires sessionUuid, a user-configurable toolName, and enabled boolean params",pf=xt(g({sessionUuid:ve(Ba),toolName:mo((d)=>Boolean(d)&&Kf().isUserConfigurableTool(d),{message:Ba}),enabled:mo((d)=>typeof d==="boolean",{message:Ba})})),cf="updateService requires 'deviceId' (string) and 'platform' (string) params",mf=xt(g({deviceId:ve(cf),platform:ve(cf).refine((d)=>d==="android"||d==="ios",(d)=>({message:`Invalid platform: ${d}. Must be 'android' or 'ios'.`})),force:gr()}).transform(({deviceId:d,platform:c,force:w})=>({deviceId:d,platform:c,force:w===!0}))),yi="setKeyValue requires deviceId, appId, fileName, key, and type params",ff=xt(g({platform:mo(()=>!0),deviceId:ve(yi),appId:ve(yi),fileName:ve(yi),key:ve(yi),type:ve(yi),value:mo(()=>!0)})),Ln="removeKeyValue requires deviceId, appId, fileName, and key params",hf=xt(g({platform:mo(()=>!0),deviceId:ve(Ln),appId:ve(Ln),fileName:ve(Ln),key:ve(Ln)})),Oa="clearKeyValueFile requires deviceId, appId, and fileName params",gf=xt(g({platform:mo(()=>!0),deviceId:ve(Oa),appId:ve(Oa),fileName:ve(Oa)}));var ek={"ide/status":"startupProbe","ide/ping":"startupProbe","ide/updateService":"deviceMutation","ide/setKeyValue":"deviceMutation","ide/removeKeyValue":"deviceMutation","ide/clearKeyValueFile":"deviceMutation"};function vf(d){return new Set(Object.entries(ek).filter(([,c])=>c===d).map(([c])=>c))}var yf=vf("startupProbe"),xa=vf("deviceMutation"),tt={"ide/setFeatureFlag":lf,"ide/setSessionToolEnabled":pf,"ide/updateService":mf,"ide/setKeyValue":ff,"ide/removeKeyValue":hf,"ide/clearKeyValueFile":gf};var Re=(d,c)=>mo(d,{message:c}),ft=(d,c)=>mo((w)=>w===void 0||d(w),{message:c}),_a=(d)=>typeof d==="string",Fa=(d)=>typeof d==="string"&&d.length>0,nt=(d)=>typeof d==="number"&&Number.isFinite(d),Rf=(d)=>typeof d==="number"&&Number.isInteger(d),kf=(d)=>typeof d==="boolean",bi=(d)=>Re((c)=>c==="android"||c==="ios",`${d} requires platform 'android' or 'ios'`),Ft=(d)=>ft(_a,`${d} deviceId must be a string when provided`),wi=(d)=>ft(Fa,`${d} frameContext must be a non-empty string when provided`),wf=["home","back","menu","power","volume_up","volume_down","recent","app_switch"],tk=g({platform:bi("input/tap"),x:Re(nt,"input/tap requires numeric x and y params"),y:Re(nt,"input/tap requires numeric x and y params"),duration:ft(Rf,"input/tap duration must be an integer number of milliseconds when provided"),deviceId:Ft("input/tap"),frameContext:wi("input/tap")}).transform(({platform:d,deviceId:c,x:w,y:D,duration:k,frameContext:P})=>({platform:d,deviceId:c,x:w,y:D,duration:k,frameContext:P})),$n="input/swipe requires numeric startX, startY, endX, and endY params",ik=g({platform:bi("input/swipe"),startX:Re(nt,$n),startY:Re(nt,$n),endX:Re(nt,$n),endY:Re(nt,$n),durationMs:ft((d)=>Rf(d)&&d>=1&&d<=60000,"input/swipe durationMs must be integer milliseconds between 1 and 60000"),deviceId:Ft("input/swipe"),frameContext:wi("input/swipe")}).transform(({platform:d,deviceId:c,startX:w,startY:D,endX:k,endY:P,durationMs:C,frameContext:M})=>({platform:d,deviceId:c,startX:w,startY:D,endX:k,endY:P,durationMs:C??300,frameContext:M})),nk=["platform","deviceId","text","submit","mode","frameContext","sessionUuid"],rk=g({platform:bi("input/typeText"),text:Re(Fa,"input/typeText requires non-empty string text param"),submit:ft(kf,"input/typeText submit must be a boolean when provided"),deviceId:Ft("input/typeText"),frameContext:wi("input/typeText"),mode:ft((d)=>d==="append",'input/typeText mode must be "append" when provided')}).transform(({platform:d,deviceId:c,text:w,submit:D,mode:k,frameContext:P})=>({platform:d,deviceId:c,text:w,submit:D??!1,append:k==="append",frameContext:P})),ok=g({platform:bi("input/pressButton"),button:mo(_a,{message:"input/pressButton requires button"}).refine((d)=>wf.includes(d),{message:`input/pressButton button must be one of: ${wf.join(", ")}`}),deviceId:Ft("input/pressButton"),frameContext:wi("input/pressButton")}).transform(({platform:d,deviceId:c,button:w,frameContext:D})=>({platform:d,deviceId:c,button:w==="app_switch"?"recent":w,responseButton:w,frameContext:D})),sk=["platform","deviceId","key","frameContext","sessionUuid"],ak=g({platform:bi("input/key"),key:mo(_a,{message:"input/key requires key"}).refine(KJ,{message:`input/key key must be one of: ${lM.join(", ")}`}),deviceId:Ft("input/key"),frameContext:wi("input/key")}).transform(({platform:d,deviceId:c,key:w,frameContext:D})=>({platform:d,deviceId:c,key:w,frameContext:D}));function Af(d){let c=`${d} requires numeric x and y params`;return g({platform:Re((w)=>w==="android",`${d} is only supported on platform 'android'`),gestureId:Re(Fa,`${d} requires a non-empty gestureId`),x:Re(nt,c),y:Re(nt,c),deviceId:Ft(d),cancel:ft(kf,`${d} cancel must be a boolean when provided`)}).transform(({platform:w,deviceId:D,gestureId:k,x:P,y:C,cancel:M})=>({platform:w,deviceId:D,gestureId:k,x:P,y:C,cancel:M===!0}))}function ht(d,c,w){return(D)=>{if(!D||typeof D!=="object"||Array.isArray(D))throw Error(`${d} requires params object`);if(w){let P=Object.keys(D).filter((C)=>!w.includes(C));if(P.length>0)throw Error(`${d} unsupported params: ${P.join(", ")}`)}let k=c.safeParse(D);if(!k.success)throw Error(k.error.issues[0].message);return k.data}}var Hn=ht("input/tap",tk),qn=ht("input/swipe",ik),Kn=ht("input/typeText",rk,nk),Gn=ht("input/pressButton",ok),Wn=ht("input/key",ak,sk),dk=new Map(["input/gestureStart","input/gestureMove","input/gestureEnd"].map((d)=>[d,ht(d,Af(d))]));function Nt(d,c){return(dk.get(c)??ht(c,Af(c)))(d)}var Pf=[{method:"input/tap",handler:"tap",parse:Hn,dispatchHeld:!0},{method:"input/swipe",handler:"swipe",parse:qn,dispatchHeld:!0},{method:"input/typeText",handler:"typeText",parse:Kn,dispatchHeld:!0},{method:"input/pressButton",handler:"pressButton",parse:Gn,dispatchHeld:!0},{method:"input/key",handler:"key",parse:Wn,dispatchHeld:!0},{method:"input/gestureStart",handler:"gesture",gestureKind:"start",parse:(d)=>Nt(d,"input/gestureStart"),dispatchHeld:!1},{method:"input/gestureMove",handler:"gesture",gestureKind:"move",parse:(d)=>Nt(d,"input/gestureMove"),dispatchHeld:!1},{method:"input/gestureEnd",handler:"gesture",gestureKind:"end",parse:(d)=>Nt(d,"input/gestureEnd"),dispatchHeld:!1}],ck=new Map(Pf.map((d)=>[d.method,d]));function Cf(d){return ck.get(d)}var $t=new Set(Pf.filter((d)=>d.dispatchHeld).map((d)=>d.method)),Vn={start:"input/gestureStart",move:"input/gestureMove",end:"input/gestureEnd"};async function Tf(d,c,w,D){let k=O0(c.tasks)?.declared===!0,P=await d.callTool({name:c.params.name,arguments:w,...k&&{_meta:e5()}},D);return k?UQ(P)??P:P}async function Mf(d,c,w){if(!tV(c.method))throw Error(`Unsupported daemon method: ${c.method}`);let D={...c.params};delete D._meta;let k=O0(c.tasks)?.declared===!0,P=await d.request({method:c.method,params:{...D,...k&&{_meta:e5()}}},BQ,w);return $Q(P)}function Ef(d,c){let w=HQ(d);if(!w)return;return e.debug(`[TASKS] ${c.method} answered ${w.code}: ${w.message}`),{id:c.id,type:"mcp_response",success:!1,error:r(d),code:w.code,jsonRpcError:w}}class ke extends Error{charsSent;constructor(d,c){super(d);this.charsSent=c;this.name="InputTypeTextAppendError"}}class qt extends Error{failure;constructor(d){super(V0(d));this.failure=d;this.name="ReleasedBoundSessionError"}}function lk(d,c,w,D){return d?.context??xn(c,w,D)}class Na{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async handleRequest(d,c,w,{receivedAtMs:D=this.state.timer.now(),handling:k}={}){let P=lk(k,w,d,D),C=this.state.sessions.get(d);if(!C)return{id:w.id,type:"mcp_response",success:!1,error:"Session not found",code:fc};if(!this.state.acceptingRequests)return this.callbacks.shuttingDownBeforeStartResponse(w);let M=this.callbacks.rejectOnHandshakeMismatch(w);if(M)return M;if(w=this.callbacks.withCanonicalToolCallDeviceIds(w),w.method===zT)return this.state.notificationSubscribers.add(d),{id:w.id,type:"mcp_response",success:!0,result:{subscribed:!0}};if([UA,z0].includes(w.method))return this.callbacks.handleResourceSubscription(d,w);if(w.method===us){let X=await CN(w,this.state.daemonState);return{id:w.id,type:"mcp_response",...X}}let F=this.callbacks.unqueuedRequest(C,c,w,P);if(F)return F;let{totalTimeoutMs:q,deadline:U}=P,K=this.callbacks.registerRequestCancellation(C,P),W=this.callbacks.socketAdmissionCancellation(w,d,c,K.signal),V,z=()=>this.runAdmittedRequest({request:w,sessionId:d,ownerSocket:c,receivedAtMs:D,context:P,cancellation:K,onInputDispatch:()=>V?.()}),J=this.state.onFrameTrace?this.callbacks.frameDeviceId(w):void 0;if(this.state.onFrameTrace)this.callbacks.traceFrame("admission_requested",w.id,{deviceId:J});return C.requestQueue.run(Ia(w),()=>{if(!this.state.acceptingRequests)return Promise.resolve(this.callbacks.shuttingDownBeforeStartResponse(w));if(k?.onAdmitted?.(U),this.state.onFrameTrace)this.callbacks.traceFrame("admission_granted",w.id,{deviceId:J});return this.callbacks.isProvisionDeviceCall(w)?this.callbacks.runProvisionBarrier(z,K.signal,()=>this.callbacks.mcpForwardFailureResponse({error:K.signal.reason,request:w,sessionId:d,ownerSocket:c,signal:K.signal})):$t.has(w.method)?this.callbacks.runCancellableInputHandler((X)=>(V=X,z()),W.signal):this.callbacks.runCancellableQueuedHandler(z,K.signal)},{timer:this.state.timer,deadlineMs:U.value,signal:W.signal,timeoutError:(X)=>new Cr({toolName:w.method==="tools/call"?w.params?.name??w.method:w.method,timeoutMs:q,origin:"UnixSocketServer.handleRequest",code:Xu,detail:X?`timed out in queue (waiting in queue for ${Ia(w)})`:"timed out in queue before admission"})}).then(async(X)=>X&&!X.success?await this.callbacks.provisionCancellationReply(w,X,K.signal.aborted?K.signal:P.owner.signal)??X:X).finally(()=>{W.dispose(),K.dispose()})}unqueuedRequest(d,c,w,D){if(w.method===$w)return this.callbacks.cancelSocketRequest(d,w);if(tV(w.method))return this.callbacks.relayTaskRequest(d,c,w,D);return}async relayTaskRequest(d,c,w,D){let k=d.sessionId,P=this.callbacks.registerRequestCancellation(d,D),C=this.callbacks.mcpRequestSignal(k,c,P.signal);try{await this.callbacks.waitForStartup(w,D.deadline,C.signal);let M=await this.callbacks.forwardMcpRequest({request:w,route:this.callbacks.sharedMcpForwardRoute(`method:${w.method}`),socketSessionId:k,signal:C.signal,totalTimeoutMs:D.totalTimeoutMs,deadline:D.deadline});return{id:w.id,type:"mcp_response",success:!0,result:M}}catch(M){return Ef(M,w)??this.callbacks.mcpForwardFailureResponse({error:M,request:w,sessionId:k,ownerSocket:c,signal:C.signal})}finally{C.dispose(),P.dispose()}}runProvisionBarrier(d,c,w){let D=d();return this.callbacks.trackRequestHandler(D.then(()=>{},()=>{})),new Promise((k,P)=>{let C=()=>k(w());if(c.aborted)C();else c.addEventListener("abort",C,{once:!0});D.then(k,P).finally(()=>c.removeEventListener("abort",C))})}shuttingDownBeforeStartResponse(d){return{id:d.id,type:"mcp_response",success:!1,error:lg,...C0(x0())}}isProvisionDeviceCall(d){return d.method==="tools/call"&&d.params?.name==="provisionDevice"}async provisionCancellationReply(d,c,w){let D=this.state.forwardedCallKeys.get(d);if(!c||!this.callbacks.isProvisionDeviceCall(d)||D===void 0||!(w?.reason instanceof pt))return;let k=await $U.await(D,uM+Am,this.state.timer);return k===void 0?void 0:{id:d.id,type:"mcp_response",success:!0,result:k}}mcpForwardFailureResponse({error:d,request:c,sessionId:w,ownerSocket:D,signal:k}){let P=r(d),C=wm(d,k);if(Cm(k,C)){if(e.debug(`MCP forward abandoned for ${w}: ${C?.message}`),D.destroyed)return}else{let M=d instanceof Error?d.stack:"no stack";e.error(`Error forwarding request to MCP server: ${P}`),Tm(C),e.error(`Error stack: ${M}`),e.error(`Full error: ${JSON.stringify(d)}`)}return{id:c.id,type:"mcp_response",success:!1,error:P,...d instanceof qt?{boundSessionLoss:d.failure}:{},...vi(d,C),...(d instanceof ke||d instanceof ac)&&d.charsSent!==void 0?{charsSent:d.charsSent}:{}}}async waitForStartup(d,c,w){if(!this.state.startupCompletion||this.state.startupCompleted)return;let D=c.value-this.state.timer.now(),k=()=>new t(`Daemon still starting; retry ${d.method} after startup completes`);if(D<=0)throw k();let P=this.state.startupCompletion.then(void 0,(C)=>{throw new t(`Daemon startup failed: ${r(C)}`,{cause:C})});await l(P,{timer:this.state.timer,timeoutMs:D,signal:w,label:"Daemon startup",timeoutError:k})}registerRequestCancellation(d,{id:c,cancellation:w}){return d.requestCancellations.set(c,w),{signal:w.signal,dispose:()=>{if(d.requestCancellations.get(c)===w)d.requestCancellations.delete(c)}}}cancelSocketRequest(d,c){let w=c.params?.requestId;if(typeof w!=="string"||w.length===0)return{id:c.id,type:"mcp_response",success:!1,error:`${$w} requires a non-empty string params.requestId`};let D=d.requestCancellations.get(w);if(!D)return e.debug(`[SocketCancel] socketSession=${d.sessionId} cancel for request ${w} found no in-flight request (already answered or never seen)`),{id:c.id,type:"mcp_response",success:!0,result:{cancelled:!1}};d.requestCancellations.delete(w);let k=new pt(`Request ${w} was cancelled by its client (client-side timeout or abort); the daemon abandoned it so the next request on this connection can run.`);return e.warn(`[SocketCancel] socketSession=${d.sessionId} ${k.message}`),D.abort(k),{id:c.id,type:"mcp_response",success:!0,result:{cancelled:!0}}}requireRemainingMcpForwardBudget(d,c,w,D){let k=this.callbacks.remainingMcpForwardBudget({deadline:w}),P=Math.max(0,c-k);if(k>0&&(P===0||k>ma))return k;let C=d.method==="tools/call"?d.params?.name??d.method:d.method;if(k<=0)throw new Cr({toolName:C,timeoutMs:c,origin:"UnixSocketServer.handleRequest",detail:`spent ${c-k}ms ${D}`,...D==="waiting in queue"?{code:Xu}:{}});if(P>0){let M={code:"daemon_overloaded",retryable:!0,retryAfterMs:Pm,reason:"insufficient_forward_budget",queueWaitMs:P,remainingTimeoutMs:Math.max(0,k)};throw new Xs(`Daemon overloaded while handling ${C}: spent ${P}ms ${D}, leaving ${M.remainingTimeoutMs}ms of the ${c}ms deadline. Retry after ${M.retryAfterMs}ms.`,M)}throw new Cr({toolName:C,timeoutMs:c,origin:"UnixSocketServer.handleRequest",detail:`spent ${c-k}ms ${D}`})}socketAdmissionCancellation(d,c,w,D){if(!$t.has(d.method))return{signal:D,dispose:()=>{}};return this.callbacks.mcpRequestSignal(c,w,D)}async runCancellableInputHandler(d,c){let w=new AbortController,D=!1,k=()=>{if(!D)w.abort(c?.reason)};if(c?.addEventListener("abort",k,{once:!0}),c?.aborted)k();try{return await this.callbacks.runCancellableQueuedHandler(()=>d(()=>{w.signal.throwIfAborted(),D=!0,c?.removeEventListener("abort",k)}),w.signal)}finally{c?.removeEventListener("abort",k)}}async runCancellableQueuedHandler(d,c){if(!c)return await d();c.throwIfAborted();let w=d();return this.callbacks.trackRequestHandler(w.then(()=>{},()=>{})),await l(w,{timer:this.state.timer,signal:c,label:"Cancelled socket request"})}async runAdmittedRequest(d){let{request:c,sessionId:w,ownerSocket:D,receivedAtMs:k,context:P,cancellation:C}=d,{deadline:M,owner:F}=P;try{if(c.method.startsWith("daemon/")){let U=await CN(c,this.state.daemonState,{signal:C.signal,context:{socketSessionId:w}});return{id:c.id,type:"mcp_response",...U}}if(!yf.has(c.method))F.adopt(C.signal),await this.callbacks.waitForStartup(c,M,C.signal);let q=await this.callbacks.runLocalSocketRequest(c,w,D,{cancelSignal:C.signal,receivedAtMs:k,onOwnerSignal:(U)=>F.adopt(U),onInputDispatch:d.onInputDispatch});if(q!==void 0)return{id:c.id,type:"mcp_response",success:!0,result:q};return await this.runAdmittedMcpForward(d)}catch(q){return this.callbacks.mcpForwardFailureResponse({error:q,request:c,sessionId:w,ownerSocket:D,signal:F.signal})}}async runAdmittedMcpForward(d){let{request:c,sessionId:w,ownerSocket:D,context:k,cancellation:P}=d,{totalTimeoutMs:C,deadline:M}=k,F,q=()=>{};try{if(c.method==="tools/call")await this.callbacks.restoreSelectorSessions(c.params?.arguments,w),F=this.callbacks.beginMcpSessionOwnerCall(c.params?.arguments,w,P.signal);let U=this.callbacks.getMcpForwardRoute(c,w),K=U instanceof Promise?await U:U,W=this.callbacks.mcpRequestSignal(w,D,P.signal);q=W.dispose,k.owner.adopt(W.signal);let V=await this.callbacks.runMcpForwardForCurrentRoute(K,c,w,{fn:async(z)=>{let J=this.callbacks.requireRemainingMcpForwardBudget(c,C,M,"waiting in queue"),X=Math.max(0,C-J),ee=this.callbacks.describeMcpForwardRequest(c);e.debug(`[McpForward] start executionKey=${z.executionKey} clientKey=${z.clientKey} socketSession=${w} requestId=${c.id} ${ee} queueWaitMs=${X} remainingTimeoutMs=${J}`);let ne=this.state.timer.now();try{let te=this.callbacks.wasRequestSessionActive(c),oe=await this.callbacks.forwardMcpRequest({request:c,route:z,socketSessionId:w,signal:W.signal,totalTimeoutMs:C,deadline:M});if(this.callbacks.isMcpRequestOwnerCurrent(w,W.signal))this.callbacks.recordBoundMcpClientKey(c,w,z,{sessionWasActiveBeforeForward:te,response:oe});return oe}finally{e.debug(`[McpForward] end executionKey=${z.executionKey} clientKey=${z.clientKey} socketSession=${w} requestId=${c.id} ${ee} forwardMs=${this.state.timer.now()-ne}`)}},chainWait:{remainingMs:()=>this.callbacks.remainingMcpForwardBudget({deadline:M}),timeoutError:(z)=>new Cr({toolName:c.method==="tools/call"?c.params?.name??c.method:c.method,timeoutMs:C,origin:"UnixSocketServer.handleRequest",detail:`spent ${C-this.callbacks.remainingMcpForwardBudget({deadline:M})}ms waiting in queue for ${z}`,code:Xu})}});if(J4(V))return{id:c.id,type:"mcp_response",success:!1,error:lg,...C0(DQ(V))};return{id:c.id,type:"mcp_response",success:!0,result:V}}finally{F?.(),q()}}}class La{timer;idGenerator;flights=new rt;joinable=new Map;constructor(d,c){this.timer=d;this.idGenerator=c}read(d,c,w=0){let{request:D,route:k}=d;if(D.method!=="tools/call"||D.tasks!==void 0||!et(D.params?.name,D.params?.arguments))return;let P={...D.params?.arguments};delete P[lp],delete P[dp];let C=Dr({name:D.params?.name,args:P,toolSelectionProfileUuid:k.toolSelectionProfileUuid??k.sessionUuid}),M=d.deadline.value-this.timer.now();if(M<=0)return Promise.reject(this.timeoutError(d));return l(()=>this.joinFlight(C,d,c,w),{timer:this.timer,signal:d.signal,timeoutMs:M,label:`Host inventory ${D.params?.name}`,timeoutError:()=>this.timeoutError(d)})}timeoutError(d){return new Cr({toolName:d.request.params?.name??"host inventory",timeoutMs:d.totalTimeoutMs,origin:"UnixSocketServer.handleRequest",detail:"waiting for shared host inventory"})}joinFlight(d,c,w,D){let k=this.selectFlight(d,c,D);return this.flights.run(k.startOrder,async()=>{try{return await w(this.sharedContext(c,k))}finally{if(this.joinable.get(d)===k)this.joinable.delete(d)}},c.signal)}selectFlight(d,c,w){let D=this.joinable.get(d);if(D&&D.startOrder>w&&D.deadlineMs>=c.deadline.value)return D;let k=this.timer.now(),P=Math.max(BA,c.totalTimeoutMs,c.deadline.value-k),C={startOrder:Da(),deadlineMs:k+P,timeoutMs:P};return this.joinable.set(d,C),C}sharedContext(d,c){let w={...d.request,timeoutMs:c.timeoutMs,progressToken:void 0};return{...d,request:w,socketSessionId:`host:inventory:${this.idGenerator.next()}`,signal:void 0,totalTimeoutMs:c.timeoutMs,deadline:new vh(c.deadlineMs-c.timeoutMs,c.timeoutMs)}}}import{AsyncLocalStorage as pk}from"async_hooks";var Ha=new pk;function Bf(d,c,w){return Ha.run({sessionKey:d,...w!==void 0&&{taskOwnerKey:w}},c)}function Of(){return Ha.getStore()?.sessionKey}function xf(){return Ha.getStore()?.taskOwnerKey}var Ff=300000;function Nf(d,c,w,{idleCloseKey:D,chainWait:k}={}){if(D){let U=d.idleCloseKeys.get(c)??new Set;U.add(D),d.idleCloseKeys.set(c,U)}let P=d.tails.get(c),C=P??Promise.resolve(),F=(P&&k?mk(d.timer,c,P,k):C).then(()=>{if(D)d.onAcquired(D);return w()}),q=Promise.all([C,F.then(()=>{return},()=>{return})]).then(()=>{return});return d.tails.set(c,q),q.finally(()=>{if(d.tails.get(c)===q){d.tails.delete(c);let U=d.idleCloseKeys.get(c);d.idleCloseKeys.delete(c);for(let K of U??[])d.onDrained(K)}}),F}async function mk(d,c,w,D){try{await l(w,{timer:d,timeoutMs:Math.max(0,D.remainingMs()),label:`MCP forward wait for ${c}`})}catch(k){throw e.warn(`[McpForward] chain wait expired executionKey=${c}: ${r(k)}`),D.timeoutError(c)}}class Ka{state;resolveCallbacks;discoveryCache;inventoryForward;constructor(d,c){this.state=d;this.resolveCallbacks=c;this.inventoryForward=new La(d.timer,d.idGenerator),this.discoveryCache=new On(()=>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=CQ(this.state.daemonIdentity,Y4(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:Y4(d)}}}runKeyedMcpForward(d,c,w,D){return Nf({tails:this.state.mcpForwardTails,idleCloseKeys:this.state.mcpForwardIdleCloseKeys,timer:this.state.timer,onAcquired:(k)=>this.callbacks.clearForwardKeyIdleTimer(k),onDrained:(k)=>this.callbacks.scheduleForwardKeyIdle(k)},d,c,{idleCloseKey:w,chainWait:D})}async runMcpForwardForCurrentRoute(d,c,w,{fn:D,chainWait:k}){if(c.method==="tools/call"&&et(c.params?.name,c.params?.arguments))return await D(d);let P=[d.executionKey],C=d;for(;;){let M=C,F=await this.callbacks.runKeyedMcpForward(M.executionKey,()=>this.callbacks.runMcpForwardAttempt(M,c,w,D),void 0,k);if(F.kind==="done")return F.value;if(C=F.route,P.push(C.executionKey),P.length>ga+1)throw new t(`MCP request ${c.id} was re-routed more than ${ga} times while waiting to run (execution keys: ${P.join(" -> ")}). The target device or session kept changing; retry once it is stable.`);e.debug(`[McpForward] rekey requestId=${c.id} initialExecutionKey=${M.executionKey} currentExecutionKey=${C.executionKey}`)}}async runMcpForwardAttempt(d,c,w,D){let k=this.callbacks.getMcpForwardRoute(c,w),P=k instanceof Promise?await k:k;if(P.executionKey!==d.executionKey)return{kind:"reroute",route:P};if(d.sessionUuid!==void 0&&P.clientKey!==d.clientKey&&!this.callbacks.hasActiveDaemonSession(d.sessionUuid))return e.debug(`[McpForward] released-session re-resolve requestId=${c.id} releasedSession=${d.sessionUuid} clientKey=${d.clientKey} -> ${P.clientKey}`),{kind:"done",value:await D(P)};return{kind:"done",value:await D(d)}}async forwardMcpRequest(d){d.signal?.throwIfAborted();let c=this.inventoryForward.read(d,(k)=>this.forwardUncachedMcpRequest(k),rf());if(c)return await c;let w=d.request.method;if(w!=="tools/list"&&w!=="resources/list"||w==="resources/list"&&!this.state.mcpDispatcher.refreshResources)return await this.forwardUncachedMcpRequest(d);this.callbacks.requireRemainingMcpForwardBudget(d.request,d.totalTimeoutMs,d.deadline,"preparing discovery");let D=await this.callbacks.withAdmittedBoundSession(d.request.params,()=>this.discoveryCache.read(d,()=>this.forwardUncachedMcpRequest(d)));return d.signal?.throwIfAborted(),this.callbacks.requireRemainingMcpForwardBudget(d.request,d.totalTimeoutMs,d.deadline,"refreshing discovery"),D}async forwardUncachedMcpRequest(d){let c=await Bf(d.socketSessionId,()=>this.state.mcpClientFactory(d.route.sessionUuid,d.route.toolSelectionProfileUuid,d.route.releasedSessionUuid),O0(d.request.tasks)?.ownerKey);try{d.signal?.throwIfAborted();let w=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,w,{socketSessionId:d.socketSessionId,deadline:d.deadline,originalTimeoutMs:d.totalTimeoutMs,signal:d.signal})}finally{await Promise.resolve().then(()=>c.close()).catch((w)=>{e.warn(`Closing an MCP forward failed: ${r(w)}`,w)})}}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 k9(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)||_r(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,w,{socketSessionId:D,deadline:k,originalTimeoutMs:P,signal:C}){C?.throwIfAborted();let M=this.callbacks.mcpRequestOptions(w,C),F=Km({mcpClient:d,request:c,timeoutMs:w,options:M,admitted:(q,U)=>this.callbacks.withAdmittedBoundSession(q,U),readAdmissionArgs:(q)=>this.callbacks.boundSessionAdmissionArgs(q)});if(F)return await F;switch(c.method){case"tools/call":{let q=c.progressToken,U=this.state.idGenerator.next();this.state.forwardedCallKeys.set(c,U),zJ(U,k);let K=()=>nG(U),W=M;if(q!==void 0){let V=new AbortController,z=(ne)=>this.state.timer.setTimeout(()=>V.abort(`Request timed out after ${Math.max(ne,0)}ms`),Math.max(ne,0)),J=z(w),X=Math.max(k.ceiling-this.state.timer.now(),w),ee=U;K=()=>{this.state.timer.clearTimeout(J),nG(ee)},W={...M,signal:this.callbacks.combineMcpRequestSignals(C,V.signal),timeout:X,maxTotalTimeout:X,onprogress:(ne)=>{this.state.timer.clearTimeout(J),k.extendOnProgress(this.state.timer.now(),P),J=z(k.value-this.state.timer.now()),this.callbacks.pushProgressNotification(D,{requestId:c.id,progressToken:q,progress:ne.progress,total:ne.total,message:ne.message})}}}try{return await this.callbacks.withAdmittedBoundSession(c.params.arguments,()=>{let V=this.callbacks.withSocketSessionAutolockKey(c.params.arguments,D,w);return this.callbacks.traceCallTool(c,()=>Tf(d,c,this.callbacks.withLiveDeadlineKey(V,U),W))},D).catch(async(V)=>{let z=CE(U);if(!z?.hasPending())return this.callbacks.textForwardFailure(U,c.params.name,V);let J=z.timeoutError(V),X=k.value-this.state.timer.now();if(X>0)try{await l(z.settled(),{timeoutMs:X,timer:this.state.timer,label:"Dispatched text settlement"})}catch(ee){e.debug("Dispatched text settlement wait ended",ee)}return this.state.shapeToolCallError(J,{toolName:c.params.name,source:"MCP"})})}finally{K()}}default:return await Mf(d,c,M)}}textForwardFailure(d,c,w){let D=CE(d)?.timeoutError(w);if(D)return this.state.shapeToolCallError(D,{toolName:c,source:"MCP"});throw w}async traceCallTool(d,c){if(!this.state.onFrameTrace)return await c();let w=this.callbacks.frameDeviceId(d);this.callbacks.traceFrame("callTool_entered",d.id,{deviceId:w});try{return await c()}finally{this.callbacks.traceFrame("callTool_settled",d.id,{deviceId:w})}}withLiveDeadlineKey(d,c){if(c===void 0||!d||typeof d!=="object"||Array.isArray(d))return d;return{...d,[Ov]:c}}withSocketSessionAutolockKey(d,c,w){let D=this.state.timer.now()+w;if(d===null||d===void 0)return{__mcpSessionId:c,...this.callbacks.oneShotCliMarker(c),[cp]:w,[dg]:D};if(!d||typeof d!=="object"||Array.isArray(d))return d;let k={...d},P=this.callbacks.honoursBoundSessionMarker(k,c);if(delete k[dp],delete k[$m],delete k[lp],this.callbacks.recordOneShotCliConnection(c,k),delete k[VT],delete k[zo],delete k[vu],P)delete k.sessionUuid;return{...k,__mcpSessionId:c,...this.callbacks.oneShotCliMarker(c),[cp]:w,[dg]:D}}recordOneShotCliConnection(d,c){let w=c[qT]===!0;delete c[qT];let D=this.state.sessions.get(d);if(w&&D)D.oneShotCli=!0}oneShotCliMarker(d){return this.state.sessions.get(d)?.oneShotCli?{[VT]:!0}:{}}async createMcpClient(d,c,w){return await this.state.mcpDispatcher.connect({boundSessionUuid:d,toolSelectionProfileUuid:c,releasedSessionUuid:w,sessionKey:Of(),taskOwnerKey:xf()})}scheduleForwardKeyIdle(d){this.callbacks.clearForwardKeyIdleTimer(d);let c=this.state.timer.setTimeout(()=>{this.callbacks.onForwardKeyIdle(d)},Ff);this.state.forwardKeyIdleTimers.set(d,c)}clearForwardKeyIdleTimer(d){let c=this.state.forwardKeyIdleTimers.get(d);if(!c)return;this.state.timer.clearTimeout(c),this.state.forwardKeyIdleTimers.delete(d)}onForwardKeyIdle(d){if(this.state.forwardKeyIdleTimers.delete(d),this.state.mcpForwardTails.has(d)||this.callbacks.isMcpClientKeyBound(d))return;let c="device:";if(d.startsWith(c))this.state.appendTextInputs.delete(d.slice(c.length))}}class Ga{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 w=this.callbacks.getToolsCallForwardRoute(d.params?.arguments,c,d.params?.name),D=(k)=>et(d.params?.name,d.params?.arguments)?{...k,executionKey:"host:inventory"}:this.callbacks.withDeviceReadLane(k,d,c);return w instanceof Promise?w.then(D):D(w)}return this.callbacks.withAdmittedBoundSession(this.callbacks.boundSessionAdmissionArgs(d),(w)=>this.callbacks.getAdmittedMcpForwardRoute(d,c,w))}withDeviceReadLane(d,c,w){let D=c.params?.name,k=c.params?.arguments;if(!d.executionKey.startsWith(ya)||typeof D!=="string"||!this.callbacks.isDeviceReadToolCall(D,k))return d;let P=d.executionKey.slice(ya.length),C=this.callbacks.getDeviceHolderSession(P);if(!C)return d;let M=this.state.daemonState.getSessionManager(),F=(K)=>K?st(K,M):void 0,q=F(C);if([d.sessionUuid,this.callbacks.getSessionUuid(k),this.callbacks.getDeviceLabelSession(k),this.callbacks.resolveImplicitAutolockSession(w,k),this.state.daemonState.getDevicePool().resolveOwnedDeviceSessionForMcpSession?.(w,P)].some((K)=>F(K)===q))return d;return{...d,executionKey:`${d.executionKey}${Lm}`}}getDeviceLabelSession(d){let c=this.callbacks.getSessionUuid(d),w=d;return c&&typeof w?.device==="string"&&w.device.length>0?this.callbacks.resolveDeviceLabelSession(c,w.device):void 0}isDeviceReadToolCall(d,c){try{return this.state.deviceReadToolCallClassifier(d,c)}catch(w){return e.debug(`[McpForward] read classification failed for ${d}: ${w}`),!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,w){let D=this.callbacks.getBoundMcpClientRoute(c,w);if(d.method==="tools/list"||d.method==="resources/list"||d.method==="resources/list-templates")return this.callbacks.getDiscoveryForwardRoute(d,c,D);if(d.method==="ide/getNavigationGraph")return this.callbacks.getNavigationGraphForwardRoute(d,c,D);if(d.method==="resources/read")return this.callbacks.getResourceReadForwardRoute(d,c);return this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getDiscoveryForwardRoute(d,c,w){if(d.method==="tools/list"){let P=this.callbacks.getSessionUuid(d.params),C=this.callbacks.getToolSelectionProfileUuid(d.params);if(P)return this.callbacks.sessionScopedForwardRoute(c,P,void 0,{toolSelectionProfileUuid:C});if(C)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,C,void 0);return w??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}let D=this.callbacks.getSessionUuid(d.params),k=this.callbacks.getToolSelectionProfileUuid(d.params);if(D)return this.callbacks.sessionScopedForwardRoute(c,D,void 0,{toolSelectionProfileUuid:k});if(k)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,k,void 0);return w??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getNavigationGraphForwardRoute(d,c,w){let D=this.callbacks.getSessionUuid(d.params),k=this.callbacks.getRequestArgumentScopeKey(d.params);if(D)return this.callbacks.sessionScopedForwardRoute(c,D,k);if(k)return w?{...w,executionKey:k}:this.callbacks.sharedMcpForwardRoute(k);return w??this.callbacks.sharedMcpForwardRoute(`method:${d.method}`)}getResourceReadForwardRoute(d,c){let w=this.callbacks.getSessionUuid(d.params);if(w){let k=d.params?.[vu]===w?w:void 0;return this.callbacks.sessionScopedForwardRoute(c,w,void 0,{releasedSessionUuid:k===w?k:void 0})}let D=d.params?.uri;return this.callbacks.sharedMcpForwardRoute(typeof D==="string"?`resource:${D}`:"resource:unknown")}beginMcpSessionOwnerCall(d,c,w){let D=this.callbacks.ownedSessionsOwnerToken(d);if(D===void 0||!this.callbacks.isMcpRequestOwnerCurrent(c,w))return;try{if(!this.state.daemonState.isInitialized())return;let k=this.state.daemonState.getDevicePool().beginMcpSessionOwnerCall?.(c,D);return()=>{try{k?.()}catch(P){e.warn(`Unable to end MCP session owner call: ${r(P)}`,P)}}}catch(k){e.warn(`Unable to begin MCP session owner call: ${r(k)}`,k);return}}getToolsCallForwardRoute(d,c,w){return this.callbacks.withAdmittedBoundSession(d,(D)=>this.callbacks.getAdmittedToolsCallForwardRoute(d,c,w,D),c)}getAdmittedToolsCallForwardRoute(d,c,w,D){let k=this.callbacks.getRequestArgumentScopeKey(d),P=this.callbacks.getBoundMcpClientRoute(c,D),C=this.callbacks.getSessionUuid(d),M=this.callbacks.getToolSelectionProfileUuid(d)??P?.toolSelectionProfileUuid;if(this.callbacks.isUnboundDeviceAcquisitionTool(w,C))return this.callbacks.acquisitionMcpForwardRoute(c,w,M);if(this.callbacks.hasImplicitDeviceSelector(d))return this.callbacks.selectorMcpForwardRoute(c,d,k,M);if(C)return this.callbacks.profileReaffirmForwardRoute({args:d,socketSessionId:c,toolName:w,sessionUuid:C,toolSelectionProfileUuid:M,scopedKey:k,boundRoute:P})??this.callbacks.sessionScopedForwardRoute(c,C,k,{toolSelectionProfileUuid:M});if(M)return this.callbacks.toolSelectionProfileScopedForwardRoute(c,M,k);if(k){if(P)return{...P,executionKey:k};return this.callbacks.sharedMcpForwardRoute(k)}if(P)return this.callbacks.hostInventoryOrBoundRoute(P,w,d);let F=this.callbacks.getImplicitAutolockScopeKey(c,d);if(F)return this.callbacks.sharedMcpForwardRoute(F);return this.callbacks.sharedMcpForwardRoute(`socket:${c}`)}hostInventoryOrBoundRoute(d,c,w){return et(c,w)?{...d,executionKey:"host:inventory"}:d}isUnboundDeviceAcquisitionTool(d,c){return typeof d==="string"&&Bm.has(d)&&!c}profileReaffirmForwardRoute(d){let{args:c,socketSessionId:w,toolName:D,sessionUuid:k,toolSelectionProfileUuid:P,scopedKey:C,boundRoute:M}=d;if(D!==Rt||k!==P)return;let F=this.callbacks.getAcquiredDeviceSessionUuid(c,k)??M?.sessionUuid;if(!F||!this.callbacks.hasActiveDaemonSession(F))return;return this.callbacks.sessionScopedForwardRoute(w,F,C,{toolSelectionProfileUuid:P})}getAcquiredDeviceSessionUuid(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return;let w=d[zo];return Ze(w)&&w!==c?w:void 0}selectorMcpForwardRoute(d,c,w,D){let k=w??this.callbacks.getImplicitAutolockScopeKey(d,c)??`socket:${d}`;return D?this.callbacks.toolSelectionProfileScopedForwardRoute(d,D,k):this.callbacks.sharedMcpForwardRoute(k)}hasImplicitDeviceSelector(d){if(!d||typeof d!=="object"||Array.isArray(d))return!1;let c=d;if(c.device)return!1;if(this.callbacks.getSessionUuid(d))return!1;return c.platform==="android"||c.platform==="ios"||typeof c.deviceId==="string"}sharedMcpForwardRoute(d){return{executionKey:d,clientKey:d}}acquisitionMcpForwardRoute(d,c,w){let D=`socket:${d}:acquisition:${c}`;return{executionKey:D,clientKey:w?`${D}:tool-selection:${w}`:D,toolSelectionProfileUuid:w}}sessionMcpClientKey(d,c,w,D){let k=w?`:tool-selection:${w}`:"";return`socket:${d}:session:${c}${k}${D?":released-resource":""}`}toolSelectionProfileMcpClientKey(d,c){return`socket:${d}:tool-selection:${c}`}sessionScopedForwardRoute(d,c,w,{toolSelectionProfileUuid:D,releasedSessionUuid:k}={}){return{executionKey:w??`session:${c}`,clientKey:this.callbacks.sessionMcpClientKey(d,c,D,k),sessionUuid:c,toolSelectionProfileUuid:D,releasedSessionUuid:k}}toolSelectionProfileScopedForwardRoute(d,c,w){return{executionKey:w??`tool-selection:${c}`,clientKey:this.callbacks.toolSelectionProfileMcpClientKey(d,c),toolSelectionProfileUuid:c}}}class Wa{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async restoreSelectorSessions(d,c){let w=this.callbacks.ownedSessionsOwnerToken(d);if(w!==void 0&&this.state.clientSockets.has(c))try{if(this.state.daemonState.isInitialized())this.state.daemonState.getDevicePool().declareMcpSessionLivenessOwnerToken?.(c,w)}catch(F){e.warn(`Unable to declare MCP session owner token: ${r(F)}`,F)}let D=this.callbacks.selectorSessionIds(d);if(!D)return;let k=this.state.daemonState.getDevicePool(),P=this.state.clientSockets.get(c),C=await k.restoreOwnedDeviceSessionsForMcpSession?.(D,c,w)??[];if(this.callbacks.releaseBindingsIfSocketDisconnected(c,P,k))return;let M=new Set(C.map((F)=>F.sessionId));await k.restoreAutolockSessionsForMcpSession?.(D.filter((F)=>!M.has(F)),c),this.callbacks.releaseBindingsIfSocketDisconnected(c,P,k),this.callbacks.failIfCallTargetsRefusedRestore(d,C)}failIfCallTargetsRefusedRestore(d,c){let w=d&&typeof d==="object"&&!Array.isArray(d)?d:{};for(let{sessionId:D,deviceId:k,reason:P}of c)if(e.warn(`[McpForward] skipped restoring owned session ${D} on ${k}: ${P}`),w.sessionUuid===D||w.deviceId===k)throw wD(k)}ownedSessionsOwnerToken(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[lp];return typeof c==="string"&&c.trim()!==""?c:void 0}selectorSessionIds(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[$m];return Array.isArray(c)&&c.every(Ze)?[...new Set(c)]:void 0}releaseBindingsIfSocketDisconnected(d,c,w){if(!c||this.state.clientSockets.get(d)===c)return!1;return w.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,w,{sessionWasActiveBeforeForward:D,response:k}){if(d.method!=="tools/call")return;if(go(d.params?.name))return;let P=this.callbacks.getSessionUuid(d.params?.arguments);if(!P){this.callbacks.recordGeneratedToolSelectionProfile(d,k,c,w);return}if(this.callbacks.isReleasedBoundSession(d.params?.arguments,c)&&this.callbacks.isRetryableSessionRecoveryResult(k,P))return;this.callbacks.recordSessionBoundMcpClientKey(c,w,w.sessionUuid??P,{sessionWasActiveBeforeForward:D,toolName:d.params?.name,args:d.params?.arguments})}holdsSession(d,c){let w=c.split(":",1)[0]??c,D=this.state.boundMcpClientKeysBySocketSession.get(d)?.sessionUuid;if(D!==void 0&&(D===c||D===w))return!0;if(!this.state.daemonState.isInitialized())return!1;let k=this.state.daemonState.getDevicePool();return k.isSessionOwnedByConnection?.(c,d)===!0||k.isSessionOwnedByConnection?.(w,d)===!0}isSessionOwnedByOtherConnection(d,c){return this.state.daemonState.isInitialized()&&this.state.daemonState.getDevicePool().isSessionOwnedByOtherConnection?.(d,c)===!0}honoursBoundSessionMarker(d,c){let w=this.callbacks.getSessionUuid(d);if(d[zo]!==w)return!1;if(w===void 0||!c||!this.state.daemonState.isInitialized())return!0;let D=this.state.daemonState.getSessionManager(),k=D.ownershipSessionUuid?.(w)??w,P=D.peekSession?.(k)?.livenessOwnerToken;return!P||this.callbacks.ownedSessionsOwnerToken(d)===P||!this.callbacks.isSessionOwnedByOtherConnection(w,c)}isRetryableSessionRecoveryResult(d,c){if(!d||typeof d!=="object"||!("isError"in d)||d.isError!==!0)return!1;let w=Tn(d)?.payload.error;return w?.code==="session_recovery_pending"&&w.retryable===!0&&w.sessionUuid===c}recordSessionBoundMcpClientKey(d,c,w,{sessionWasActiveBeforeForward:D,toolName:k,args:P}){if(this.callbacks.isReleasedBoundSession(P,d)){this.callbacks.clearBoundMcpClientKey(d);return}if(this.callbacks.isSessionOwnedByOtherConnection(w,d))return;if(this.callbacks.targetsOneCallOnly(P,w))return;let C=this.callbacks.hasActiveDaemonSession(w);if((D||k==="executePlan")&&!C){this.callbacks.clearBoundMcpClientKey(d);return}this.state.boundMcpClientKeysBySocketSession.set(d,{clientKey:c.clientKey,executionKey:c.executionKey,sessionUuid:w,toolSelectionProfileUuid:c.toolSelectionProfileUuid,requiresLiveDaemonSession:D||C})}targetsOneCallOnly(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return!1;let w=d[zo];return Ze(w)&&w!==c}recordGeneratedToolSelectionProfile(d,c,w,D){let k=this.callbacks.getGeneratedToolSelectionProfileUuid(d,c);if(!k)return!1;return this.state.boundMcpClientKeysBySocketSession.set(w,{clientKey:D.clientKey,executionKey:D.executionKey,toolSelectionProfileUuid:k,requiresLiveDaemonSession:!1}),!0}getBoundMcpClientRoute(d,c){let w=this.state.boundMcpClientKeysBySocketSession.get(d);if(!w)return;if(!w.requiresLiveDaemonSession||!this.state.daemonState.isInitialized()||c!==void 0&&w.sessionUuid===c)return{clientKey:w.clientKey,executionKey:w.executionKey,sessionUuid:w.sessionUuid,toolSelectionProfileUuid:w.toolSelectionProfileUuid};if(w.sessionUuid&&this.callbacks.hasActiveDaemonSession(w.sessionUuid))return{clientKey:w.clientKey,executionKey:w.executionKey,sessionUuid:w.sessionUuid,toolSelectionProfileUuid:w.toolSelectionProfileUuid};this.callbacks.clearBoundMcpClientKey(d);return}getToolSelectionProfileUuid(d){if(!d||typeof d!=="object"||Array.isArray(d))return;let c=d[dp];return Ze(c)?c:void 0}getGeneratedToolSelectionProfileUuid(d,c){if(d.params?.name!==Rt)return;return ah(c)}clearBoundMcpClientKey(d){if(!this.state.boundMcpClientKeysBySocketSession.get(d))return;this.state.boundMcpClientKeysBySocketSession.delete(d)}clearBoundMcpClientsForReleasedSession(d){for(let[c,w]of this.state.boundMcpClientKeysBySocketSession)if(w.sessionUuid===d)this.callbacks.clearBoundMcpClientKey(c)}isMcpClientKeyBound(d){for(let c of this.state.boundMcpClientKeysBySocketSession.values())if(c.clientKey===d)return!0;return!1}getSessionForDevice(d){if(!this.state.daemonState.isInitialized())return;try{return this.state.daemonState.getSessionManager().getSessionForDevice?.(d)??void 0}catch(c){e.debug(`Unable to resolve session for device ${d}: ${c}`);return}}getSessionIncarnation(d){if(!d||!this.state.daemonState.isInitialized())return;try{return this.state.daemonState.getSessionManager().getSession(d)??void 0}catch(c){e.debug(`Unable to capture session ${d}: ${c}`);return}}hasActiveDaemonSession(d){if(!this.state.daemonState.isInitialized())return!1;try{return this.state.daemonState.getSessionManager().getSession(d)!==null}catch(c){throw e.warn(`Unable to resolve bound session ${d}: ${r(c)}`,c),new qt({code:q0,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 w=d,D=this.callbacks.getSessionUuid(w);return D!==void 0&&this.callbacks.honoursBoundSessionMarker(w,c)&&!this.callbacks.hasActiveDaemonSession(D)}boundSessionAdmissionArgs(d){let c=this.callbacks.getSessionUuid(d.params);return d.method==="resources/read"&&c!==void 0&&d.params?.[vu]===c&&d.params?.uri===`automobile:device-session/${c}/screenshot`?void 0:d.params}withAdmittedBoundSession(d,c,w){if(!this.callbacks.isReleasedBoundSession(d,w))return c();let D=this.callbacks.getSessionUuid(d);return this.callbacks.admitReleasedBoundSession(D).then(()=>c(D))}async admitReleasedBoundSession(d){try{if(await this.state.daemonState.getSessionManager().isReleasedSessionInRestartRecoveryWindow?.(d))return}catch(w){e.warn(`Unable to read restart recovery window for bound session ${d}: ${r(w)}`,w)}let c=this.state.daemonState.getSessionManager().getTerminalReleaseSnapshot?.(d)??await this.callbacks.expiredBoundSessionRelease(d);throw new qt({code:q0,sessionUuid:d,reason:c?.releaseReason??"session-not-found",...fi(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 w=Ze(d.sessionUuid),D=typeof d.device==="string"&&d.device.length>0;if(w&&D)return this.callbacks.sessionToScopeKey(this.callbacks.resolveDeviceLabelSession(d.sessionUuid,d.device));if(typeof d.deviceId==="string"&&d.deviceId.length>0)return`device:${d.deviceId}`;if(w)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 w=this.callbacks.resolveImplicitAutolockSession(d,c);return w?this.callbacks.sessionToScopeKey(w):void 0}resolveImplicitAutolockSession(d,c){if(!this.state.daemonState.isInitialized())return;try{let w=this.callbacks.getRequestPlatform(c),D=this.state.daemonState.getDevicePool().resolveAutolockSessionForMcpSession?.(d,w);if(!D)return;return D}catch(w){e.debug(`Unable to resolve autolock session for MCP session ${d}: ${w}`);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 w=this.state.daemonState.getSessionManager().getDeviceLabels(d);if(!w)return d;let D=w[c];return typeof D==="string"&&D.length>0?D:d}catch(w){return e.debug(`Unable to resolve device label ${c} for session ${d}: ${w}`),d}}getAssignedDeviceForSession(d){if(!this.state.daemonState.isInitialized())return;try{return this.state.daemonState.getSessionManager().getSession(d)?.assignedDevice}catch(c){e.debug(`Unable to resolve device for session ${d}: ${c}`);return}}}import{createHash as fk}from"crypto";class Va{ports;constructor(d){this.ports=d}routes=new Map([["ide/status",(d,c,w)=>this.ideStatus(d,c,w)],["ide/updateService",(d,c,w)=>this.ideUpdateService(d,c,w)],["ide/setKeyValue",(d,c,w)=>this.ideSetKeyValue(d,c,w)],["ide/removeKeyValue",(d,c,w)=>this.ideRemoveKeyValue(d,c,w)],["ide/clearKeyValueFile",(d,c,w)=>this.ideClearKeyValueFile(d,c,w)]]);async ideStatus(d,c,w){let D=this.ports.acceptanceDiscoveryCapability();return{structuredSessionNotFound:!0,structuredToolErrorCodes:!0,version:this.ports.daemonIdentity().version,pid:process.pid,launchNonce:I(f.DAEMON_LAUNCH_NONCE),buildId:this.ports.daemonIdentity().build.buildId,entryScript:this.ports.daemonIdentity().build.entryScript,acceptanceCapabilityFingerprint:D?fk("sha256").update(D).digest("hex").slice(0,8):null,startedAt:this.ports.identityStartedAt(),processStartedAt:this.ports.identityProcessStartedAt(),dbPath:this.ports.identityDbPath(),reportedPidFilePath:this.ports.identityPidFilePath(),reportedSocketPath:this.ports.socketPath(),reportedSockets:IB(this.ports.identitySockets()??{}),unavailableSockets:cY(),effectiveDebug:fu(),options:this.ports.startupOptions(),...wd(this.ports.processGenerationToken()),activeProvisioning:G.hasActiveToolExecution("provisionDevice",{scope:"global"}),releaseVersion:sn(De()),android:{ctrlProxy:{expectedSha256:Gv(),url:Ym()}},ios:{xcTestService:{expectedSha256:sR(),expectedAppHash:Oz,url:oR()}}}}async ideUpdateService(d,c,w){let D=tt["ide/updateService"](d.params),{devices:k,deviceId:P}=await this.ports.resolveIdeActionDevices(D.platform,D.deviceId,w?.signal);await this.ports.reconcileDiscoveryObservation(k,"socket:ide/updateService"),this.ports.assertDeviceActionable(P,"to update the accessibility service");let C=k.find((M)=>M.deviceId===P);if(!C)throw Error(`Device not found: ${D.deviceId}`);if(await this.ports.daemonState().getDevicePool().isShutdownReserved?.(C.deviceId))throw Error(`Device '${C.deviceId}' is shutting down.`);if(await this.assertIdeMutationOwnership(d,C,"ide/updateService",{force:D.force,ideMutation:w}),D.platform==="android"){w?.signal.throwIfAborted(),w?.dispatching(),E.resumeAfterDeviceStart(C.deviceId);let F=await le.getInstance(C).ensureCompatibleVersion({allowDownloadWhenInstalled:!0,bypassVersionCheckCache:!0});return{success:new Set(["compatible","upgraded","installed","reinstalled"]).has(F.status),message:`Accessibility service ${F.status}${F.error?`: ${F.error}`:""}`,status:F}}else{let M=ye.getInstance(C);return w?.signal.throwIfAborted(),w?.dispatching(),x.resumeAfterDeviceStart(C.deviceId),await M.forceRestart(),{success:!0,message:"CtrlProxy iOS restarted"}}}async ideSetKeyValue(d,c,w){let D=tt["ide/setKeyValue"](d.params);await this.ports.assertSocketToolEnabled(D.deviceId,"setKeyValue");let{platform:k,client:P,device:C}=await this.resolveKeyValueMutationClient(D.platform,D.deviceId,d,{action:"ide/setKeyValue",ideMutation:w}),{appId:M,fileName:F,key:q}=D,U=!1,K;if(D.value===null||D.value===void 0)({usedDirectFileFallback:U,resolution:K}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:w,viaSdk:(J)=>P.removePreference(M,F,q,{onDispatch:J}),viaDirectFile:(J)=>HE(J,C.deviceId,{appId:M,fileName:F},q)}));else{let J={key:q,value:D.value,type:D.type};b1(k,J.type),{usedDirectFileFallback:U,resolution:K}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:w,viaSdk:(X)=>P.setPreference(M,F,J,{onDispatch:X}),viaDirectFile:(X)=>w1(X,C.deviceId,{appId:M,fileName:F},J)})}let W=K?.resolvedStore,V=K?.effectiveValueDiffers,z=S1(U?Zb(M,F):void 0,V);return{success:!0,...W?{resolvedStore:W}:{},...V?{effectiveValueDiffers:V}:{},...z?{warning:z}:{}}}async ideRemoveKeyValue(d,c,w){let D=tt["ide/removeKeyValue"](d.params);await this.ports.assertSocketToolEnabled(D.deviceId,"removeKeyValue");let{platform:k,client:P,device:C}=await this.resolveKeyValueMutationClient(D.platform,D.deviceId,d,{action:"ide/removeKeyValue",ideMutation:w}),{appId:M,fileName:F,key:q}=D,{usedDirectFileFallback:U,resolution:K}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:w,viaSdk:(z)=>P.removePreference(M,F,q,{onDispatch:z}),viaDirectFile:(z)=>HE(z,C.deviceId,{appId:M,fileName:F},q)}),W=K?.resolvedStore,V=U?Zb(M,F):void 0;return{success:!0,...W?{resolvedStore:W}:{},...V?{warning:V}:{}}}async ideClearKeyValueFile(d,c,w){let D=tt["ide/clearKeyValueFile"](d.params);await this.ports.assertSocketToolEnabled(D.deviceId,"clearKeyValueFile");let{platform:k,client:P,device:C}=await this.resolveKeyValueMutationClient(D.platform,D.deviceId,d,{action:"ide/clearKeyValueFile",ideMutation:w}),{appId:M,fileName:F}=D,{usedDirectFileFallback:q,resolution:U}=await this.ports.runIdeKeyValueMutation(k,C,M,{fileName:F,ideMutation:w,viaSdk:(V)=>P.clearPreferenceStore(M,F,{onDispatch:V}),viaDirectFile:(V)=>R1(V,C.deviceId,M,{fileName:F})}),K=U?.resolvedStore,W=q?Zb(M,F):void 0;return{success:!0,...K?{resolvedStore:K}:{},...W?{warning:W}:{}}}async assertIdeMutationOwnership(d,c,w,{force:D=!1,ideMutation:k}={}){let P=c.deviceId,C=Lz(d.method,d.params);if(!this.ports.daemonState().isInitialized())return;await this.assertFrameTargetProven(c,w,()=>C),this.ports.assertBrokerConnectionControl(k?.socketSessionId,w,{deviceId:P,requesterSessionUuid:C});let M=this.ports.daemonState().getSessionManager();await Zv({action:w,deviceId:P,platform:c.platform,requesterSessionUuid:C,sessionManager:M,gate:this.ports.daemonState().getDevicePool()}),await Xm({deviceId:P,platform:c.platform,gate:this.ports.daemonState().getDevicePool()});let F=M.getSessionForDevice?.(P)??void 0;if(!D)Pu({action:w,deviceId:P,ownerSessionUuid:F,requesterSessionUuid:C,sessionManager:M,remedy:"pass the holding session's sessionUuid, or wait for the holder to release the device."});if(F)await this.admitIdeMutationOnHolderSession(G.startExecution(w,void 0,F),{deviceId:P,holderSessionUuid:F,force:D},k)}async admitIdeMutationOnHolderSession(d,c,w){w?.track(d,!c.force);try{if(G.bindDeviceExecution(d.id,c.deviceId),c.force)return;if(await this.ports.admitInputAsControlCall(d,c.deviceId,c.holderSessionUuid,w?.signal),w)w.admit(d);else G.markSessionAdmitted(d.id)}finally{if(!w)G.endExecution(d.id)}}async runTrackedIdeMutation(d,c,w){let D=new AbortController,k,P,C,M=w?AbortSignal.any([w,D.signal]):D.signal,F={socketSessionId:d,signal:M,admit:(q)=>{C=q},dispatching:()=>{if(C)G.markSessionAdmitted(C.id)},track:(q,U)=>{if(k=q,!U)return;P=q;let K=q.abortController.signal;if(K.aborted){D.abort(K.reason);return}K.addEventListener("abort",()=>D.abort(K.reason),{once:!0})}};try{return M.throwIfAborted(),await H(M,()=>c(F))}catch(q){throw om(P?.cancelReason)??q}finally{if(k)G.endExecution(k.id)}}async listBootedDevicesForIdeAction(d,c,w){w?.throwIfAborted();let D=_t.getInstance(),k=tu(await D.getBootedDevicesDetailed(d),this.ports.daemonState()?.isInitialized()?this.ports.daemonState().getDevicePool().getAllDevices?.():void 0);if(!k.devices.map((P)=>P.deviceId).includes(c)&&g0(k,d,c)){let P=k.discoveryErrors?.[d];throw d==="android"?new en(P):new ze(d,P)}return w?.throwIfAborted(),k.devices}async resolveIdeActionDevices(d,c,w){let D=await this.canonicalFrameDiscovery(d,await this.ports.listBootedDevicesForIdeAction(d,c,w),c);return{devices:D.devices,deviceId:D.deviceId??c}}async canonicalFrameDiscovery(d,c,w){return await AN(this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool():void 0,d,c,w)}async assertFrameTargetProven(d,c,w){if(!this.ports.daemonState().isInitialized())return;let D=this.ports.daemonState().getSessionManager();await TN(this.ports.daemonState().getDevicePool(),d,c,{heldBySession:Boolean(D.getSessionForDevice?.(d.deviceId)),sessions:pA(D),requester:w,sessionManager:D})}canonicalFrameDeviceId(d){return em(this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool():void 0,d)}async resolveKeyValueMutationClient(d,c,w,{action:D,ideMutation:k}){let P=d??"android";if(P!=="android"&&P!=="ios")throw Error(`Invalid platform: ${P}. Must be 'android' or 'ios'.`);let{devices:C,deviceId:M}=await this.ports.resolveIdeActionDevices(P,c,k?.signal);await this.ports.reconcileDiscoveryObservation(C,"socket:ide/keyValueMutation"),this.ports.assertDeviceActionable(M,"to mutate stored values");let F=C.find((U)=>U.deviceId===M);if(!F)throw Error(`Device not found: ${c}`);await this.assertIdeMutationOwnership(w,F,D,{ideMutation:k}),k?.signal.throwIfAborted();let q=P==="ios"?x.getInstance(F):E.getInstance(F,this.ports.adbClientFactory());return{platform:P,client:q,device:F}}async runIdeKeyValueMutation(d,c,w,D){let k=!1,{fileName:P}=D,C=()=>{if(k)return;k=!0,D.ideMutation?.dispatching()};if(d!=="android")return D.ideMutation?.signal.throwIfAborted(),{usedDirectFileFallback:!1,resolution:await D.viaSdk(C)||void 0};let M;return{...await P1(w,P,()=>this.ports.adbClientFactory().create(c),{viaSdk:async()=>{D.ideMutation?.signal.throwIfAborted(),M=await D.viaSdk(C)||void 0},viaDirectFile:(q)=>(D.ideMutation?.signal.throwIfAborted(),C(),D.viaDirectFile(q).catch(iN))}),resolution:M}}}function $f(d){return new Map([["ide/listFeatureFlags",async()=>({flags:await d.requireFeatureFlagService().listFlags()})],["ide/setFeatureFlag",async(c,w)=>{let D=d.requireFeatureFlagService(),k=tt["ide/setFeatureFlag"](c.params);return d.assertBrokerHostMutation(w,"ide/setFeatureFlag"),await D.setFlag(k.key,k.enabled,k.config)}],["ide/setSessionToolEnabled",async(c,w)=>{let D=tt["ide/setSessionToolEnabled"](c.params);return d.assertBrokerControl(w,"ide/setSessionToolEnabled",{requesterSessionUuid:D.sessionUuid}),await d.sessionToolSelection().setEnabled(D.sessionUuid,D.toolName,D.enabled),d.emitToolsListChanged(),{sessionUuid:D.sessionUuid,toolName:D.toolName,enabled:D.enabled}}],["ide/ping",async()=>({ok:!0,timestamp:d.now()})]])}function Hf(d){return new Map([[UH,async(c)=>await d.republishIdentity(c.params)],[HH,async(c)=>d.restart.prepareDaemonRestart(c.params)],[qH,async(c)=>d.restart.prepareDaemonMaintenance(c.params)],[VH,async(c)=>d.restart.completeDaemonMaintenance(c.params)],[WH,async(c)=>d.restart.restartAdmittedDaemon(c.params)],[zH,async(c,w)=>d.restart.restartAcceptanceSession(c.params,w)],[jH,async(c,w)=>d.restart.commitAcceptanceRestart(c.params,w)],[KH,async(c,w)=>d.restart.releaseAcceptanceRestart(c.params,w)]])}function Uf(d,c){let w=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(`${w} outcome is indeterminate:`)))return Object.assign(c,{requestDispatched:!0});let D=r(c),k=d==="input/key"?rc.indeterminateError(c):d==="input/tap"?Sn(D):new t(`${d==="input/swipe"?"Swipe":"Button press"} outcome is indeterminate: the request was dispatched but no result was confirmed (${D}). Do not retry automatically.`);return Object.assign(k,{requestDispatched:!0})}class ja{ports;constructor(d){this.ports=d}requireCurrentFrameContext(d,c,w){if(c===void 0)return;if(Et()?.getCurrentFrameContext(d)!==c)throw Error(`${w} frameContext is stale or unavailable; observe a fresh frame before retrying`)}inputRequester(d,c){let w=Lz(d.method,d.params);return()=>{if(w||!c||!this.ports.daemonState().isInitialized())return w;let D=df(d.params);if(!D)return;return this.ports.daemonState().getDevicePool().resolveAutolockSessionForMcpSession?.(c,D)}}async resolveInputTargetDevice(d,c,w,{action:D,bypassAndroidDeviceListCache:k=!1,requester:P}){let C=await this.ports.selectInputTargetDevice(d,c,w,{action:D,bypassAndroidDeviceListCache:k});return await this.ports.assertFrameTargetProven(C,D,P),this.ports.assertBrokerConnectionInputTarget(w,D,C.deviceId),this.ports.captureInputTargetOwner(C),C}assertBrokerConnectionInputTarget(d,c,w){this.ports.assertBrokerConnectionControl(d,c,{deviceId:w})}assertBrokerConnectionControl(d,c,w){if(!this.ports.daemonState().isInitialized())return;let D=this.ports.daemonState().getSessionManager(),k=xv({binding:this.ports.daemonState().getBrokerConnectionScopes?.().get(d),action:c,deviceId:w.deviceId,requesterSessionUuid:w.requesterSessionUuid,grantedDeviceOf:(P)=>D.getSession(P)?.assignedDevice});if(k)throw k}assertBrokerConnectionHostMutation(d,c){if(!this.ports.daemonState().isInitialized())return;let w=_w({binding:this.ports.daemonState().getBrokerConnectionScopes?.().get(d),action:c});if(w)throw w}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,w,{action:D,bypassAndroidDeviceListCache:k=!1}){let{devices:P,deviceId:C}=await this.ports.discoverInputTargetDevices(d,D,k,c);if(C){let q=P.find((U)=>U.deviceId===C);if(!q)throw Error(`Device not found: ${c}`);return q}let M=this.ports.daemonState().isInitialized()?this.ports.daemonState().getDevicePool().resolveAutolockSessionForMcpSession?.(w,d):void 0,F=M?this.ports.daemonState().getSessionManager().getSession(M)?.assignedDevice:void 0;if(F){let q=P.find((U)=>U.deviceId===F);if(!q)throw Error(`Device not found: ${F}`);return q}if(P.length===1)return P[0];if(P.length===0)throw Error(`No booted ${d} devices found for ${D}`);throw Error(`${D} requires deviceId when multiple ${d} devices are booted`)}async runTrackedKeyedDeviceInput(d,c,w,D){let k=`device:${c.deviceId}`;return await this.ports.runTrackedDeviceInput(d,c,async(P,C)=>this.ports.runKeyedMcpForward(k,()=>(P?.throwIfAborted(),this.ports.runHeldInputOperation(d,P,w,()=>{D?.onDispatch?.(),C?.()})),k,D?.chainWait),{ownerSignal:D?.ownerSignal,requester:D?.requester})}inputDeviceGate(d,c,w,{budgetStartMs:D,input:k}){let P=()=>w-(this.ports.timer().now()-D);return{onDispatch:k?.onDispatch,ownerSignal:k?.signal,requester:k?.requester,chainWait:{remainingMs:P,timeoutError:(C)=>new Cr({toolName:d,timeoutMs:w,origin:c,detail:`spent ${w-P()}ms waiting in queue for ${C}`,code:Xu})}}}async runHeldInputOperation(d,c,w,D){if(!$t.has(d)||d==="input/typeText")return w(c,D);let k=!1,P=()=>{if(!k)D(),k=!0};try{let C=await w(c,P);return c?.throwIfAborted(),C}catch(C){if(k&&c?.aborted)throw Uf(d,C);if(c?.reason instanceof DOMException&&c.reason.name==="AbortError")o(c);throw c?.throwIfAborted(),C}}dispatchFencedInput(d,c,w,{send:D,onDispatch:k}){return this.ports.runHeldInputOperation(`input/${d.toLowerCase()}`,c,(P,C)=>this.ports.holdDispatchedInputRequest(c,w,D,{onDispatch:C,label:`${d} request`}),()=>k?.())}async reconcileDiscoveryObservation(d,c){if(!this.ports.daemonState().isInitialized())return;await this.ports.daemonState().getDevicePool().reconcileDiscoveryObservation?.(d,c)}assertDeviceActionable(d,c){if(!this.ports.daemonState().isInitialized())return;this.ports.daemonState().getDevicePool().assertDeviceActionable?.(d,c)}async assertInputBindingGate(d,c,w){if(!this.ports.daemonState().isInitialized())return;await Zv({action:d,deviceId:c.deviceId,platform:c.platform,requesterSessionUuid:w?.(),sessionManager:this.ports.daemonState().getSessionManager(),gate:this.ports.daemonState().getDevicePool()}),await Xm({deviceId:c.deviceId,platform:c.platform,gate:this.ports.daemonState().getDevicePool()})}async runTrackedDeviceInput(d,c,w,{ownerSignal:D,requester:k}){this.ports.assertDeviceActionable(c.deviceId,"to run");let P=this.ports.daemonState().isInitialized()?this.ports.daemonState().getSessionManager():void 0,C=P?.getSessionForDevice?.(c.deviceId)??void 0;if(await this.ports.assertInputBindingGate(d,c,k),Pu({action:d,deviceId:c.deviceId,ownerSessionUuid:C,requesterSessionUuid:C?k?.():void 0,sessionManager:P}),C)this.ports.daemonState().getDevicePool().assertSessionReadyForAutomation?.(C);let M=this.ports.inputTargetOwners().get(c);if(M!==void 0&&M!==C)throw new cd(M,c.deviceId,`Session ${M} no longer owns device '${c.deviceId}' (it was rebound or released after this input resolved its target); the input was not sent.`);let F=G.startExecution(d,void 0,C),q=F.abortController.signal;try{G.bindDeviceExecution(F.id,c.deviceId),q.throwIfAborted(),await this.ports.admitInputAsControlCall(F,c.deviceId,C,D);let U=()=>G.markSessionAdmitted(F.id);if(!C)G.markSessionlessDeviceUse(F.id,c.deviceId);let K=(W)=>$t.has(d)?this.ports.runCancellableInputHandler((V)=>w(W,()=>{V(),U()}),W):w(W,U);return await this.ports.answeringSessionRelease(F,()=>ol({execution:{...ru(F),deviceBinding:{bindDeviceExecution:(W)=>G.bindDeviceExecution(F.id,W)}}},()=>this.ports.runFencedInputOperation(q,D,K)))}finally{G.endExecution(F.id)}}async admitInputAsControlCall(d,c,w,D){if(!w)return;let k=d.abortController.signal;await CB({deviceId:c,holderSessionUuid:w,sessionManager:this.ports.daemonState().getSessionManager(),execution:ru(d),signal:D?AbortSignal.any([k,D]):k}),await this.ports.answeringSessionRelease(d,async()=>d.abortController.signal.throwIfAborted())}async answeringSessionRelease(d,c){try{return await c()}catch(w){let D=om(d.cancelReason);if(D&&w instanceof Error&&"requestDispatched"in w&&w.requestDispatched===!0){let k=new ac(D.sessionUuid,D.releaseReason,D.details.idleTimeoutMs),P=d.toolName==="input/typeText"||w instanceof ke?"the text request":"the request";if(k.message=`${D.message} Cancellation arrived after ${P} had been dispatched; its outcome is indeterminate.`,w instanceof ke)k.charsSent=w.charsSent;throw k}throw D??w}}runFencedInputOperation(d,c,w){let D=c?AbortSignal.any([d,c]):d;return D.throwIfAborted(),H(D,()=>w(D))}async discoverInputTargetDevices(d,c,w,D){let k=await _t.getInstance().getBootedDevicesDetailed(d,{bypassAndroidDeviceListCache:w}),P=await this.ports.canonicalFrameDiscovery(d,k.devices,D);if(await this.ports.reconcileDiscoveryObservation(P.devices,`socket:${c}`),!k.succeededPlatforms.has(d))throw Error(`Unable to discover booted ${d} devices for ${c}`);return P}}class za{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async runLocalSocketRequest(d,c,w,{cancelSignal:D,receivedAtMs:k,onOwnerSignal:P,onInputDispatch:C}){if(!qm(d.method,xa))return await this.callbacks.handleLocalSocketRequest(d,{socketSessionId:c});let M=this.callbacks.mcpRequestSignal(c,w,D);P(M.signal);try{return await this.callbacks.handleLocalSocketRequest(d,{socketSessionId:c,signal:M.signal,receivedAtMs:k,onInputDispatch:C})}finally{M.dispose()}}async handleLocalSocketRequest(d,{socketSessionId:c,signal:w,receivedAtMs:D,onInputDispatch:k}={}){if(d.method.startsWith("input/"))w?.throwIfAborted();let P={onDispatch:k,signal:w,receivedAtMs:D,requester:d.method.startsWith("input/")?this.callbacks.inputRequester(d,c):void 0},C=Cf(d.method);if(C)return await this.callbacks.dispatchInputRoute(C,d,c,P);return await this.callbacks.dispatchIdeSocketRequest(d,c,w)}async dispatchInputRoute(d,c,w,D){return await Um(this.inputRouteHandlers,d,c,{socketSessionId:w,input:D})}inputRouteHandlers={tap:(d,c,w)=>this.callbacks.handleInputTap(d,c,w),swipe:(d,c,w)=>this.callbacks.handleInputSwipe(d,c,w),typeText:(d,c,w)=>this.callbacks.handleInputTypeText(d,c,w),pressButton:(d,c,w)=>this.callbacks.handleInputPressButton(d,c,w),key:(d,c,w)=>this.callbacks.handleInputKey(d,c,w),gesture:(d,c,w,D)=>this.callbacks.handleInputGesture(d,c,w,D)};async dispatchIdeSocketRequest(d,c,w){if(!xa.has(d.method))return await this.callbacks.handleIdeSocketRequest(d,c);return w?.throwIfAborted(),await this.callbacks.runTrackedIdeMutation(c,(D)=>this.callbacks.handleIdeSocketRequest(d,c,D),w)}ideDeviceRoutes=new Va({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,w)=>this.callbacks.assertBrokerConnectionControl(d,c,w),admitInputAsControlCall:(...d)=>this.callbacks.admitInputAsControlCall(...d),listBootedDevicesForIdeAction:(d,c,w)=>this.callbacks.listBootedDevicesForIdeAction(d,c,w),resolveIdeActionDevices:(d,c,w)=>this.callbacks.resolveIdeActionDevices(d,c,w),runIdeKeyValueMutation:(d,c,w,D)=>this.callbacks.runIdeKeyValueMutation(d,c,w,D)});ideRouteHandlers=new Map([...$f({requireFeatureFlagService:()=>this.callbacks.requireFeatureFlagService(),sessionToolSelection:()=>this.state.sessionToolSelectionService??mc(),assertBrokerHostMutation:(d,c)=>this.callbacks.assertBrokerConnectionHostMutation(d,c),assertBrokerControl:(d,c,w)=>this.callbacks.assertBrokerConnectionControl(d,c,w),emitToolsListChanged:()=>Er.emit("tools"),now:()=>this.state.timer.now()}),...Hf({republishIdentity:(d)=>this.callbacks.republishDaemonIdentity(d),restart:{prepareDaemonRestart:(d)=>this.state.restartAdmission.prepareDaemonRestart(d),prepareDaemonMaintenance:(d)=>this.state.restartAdmission.prepareDaemonMaintenance(d),completeDaemonMaintenance:(d)=>this.state.restartAdmission.completeDaemonMaintenance(d),restartAdmittedDaemon:(d)=>this.state.restartAdmission.restartAdmittedDaemon(d),restartAcceptanceSession:(d,c)=>this.state.restartAdmission.restartAcceptanceSession(d,c),commitAcceptanceRestart:(d,c)=>this.state.restartAdmission.commitAcceptanceRestart(d,c),releaseAcceptanceRestart:(d,c)=>this.state.restartAdmission.releaseAcceptanceRestart(d,c)}}),...this.ideDeviceRoutes.routes]);async handleIdeSocketRequest(d,c,w){let D=this.ideRouteHandlers.get(d.method);return D?await D(d,c,w):void 0}async runTrackedIdeMutation(d,c,w){return await this.ideDeviceRoutes.runTrackedIdeMutation(d,c,w)}async listBootedDevicesForIdeAction(d,c,w){return await this.ideDeviceRoutes.listBootedDevicesForIdeAction(d,c,w)}async resolveIdeActionDevices(d,c,w){return await this.ideDeviceRoutes.resolveIdeActionDevices(d,c,w)}async canonicalFrameDiscovery(d,c,w){return await this.ideDeviceRoutes.canonicalFrameDiscovery(d,c,w)}async assertFrameTargetProven(d,c,w){return await this.ideDeviceRoutes.assertFrameTargetProven(d,c,w)}canonicalFrameDeviceId(d){return this.ideDeviceRoutes.canonicalFrameDeviceId(d)}async runIdeKeyValueMutation(d,c,w,D){return await this.ideDeviceRoutes.runIdeKeyValueMutation(d,c,w,D)}async assertSocketToolEnabled(d,c){let D=Kf().getRegisteredTool(c)?.defaultEnabled??!1;if(!this.state.daemonState.isInitialized()){await kG(c,D,[void 0],{sessionToolSelectionService:this.state.sessionToolSelectionService,remediationMethodName:D4});return}let k=this.state.daemonState.getSessionManager(),P=k.getSessionForDevice?.(this.callbacks.canonicalFrameDeviceId(d))??void 0,C=st(P,k);await kG(c,D,[C,P],{sessionToolSelectionService:this.state.sessionToolSelectionService,remediationMethodName:D4})}inputDeviceGatingInstance;get inputDeviceGating(){return this.inputDeviceGatingInstance??=new ja({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,w){return this.inputDeviceGating.requireCurrentFrameContext(d,c,w)}inputRequester(d,c){return this.inputDeviceGating.inputRequester(d,c)}async resolveInputTargetDevice(d,c,w,D){return await this.inputDeviceGating.resolveInputTargetDevice(d,c,w,D)}assertBrokerConnectionInputTarget(d,c,w){return this.inputDeviceGating.assertBrokerConnectionInputTarget(d,c,w)}assertBrokerConnectionControl(d,c,w){return this.inputDeviceGating.assertBrokerConnectionControl(d,c,w)}assertBrokerConnectionHostMutation(d,c){return this.inputDeviceGating.assertBrokerConnectionHostMutation(d,c)}captureInputTargetOwner(d){return this.inputDeviceGating.captureInputTargetOwner(d)}async selectInputTargetDevice(d,c,w,{action:D,bypassAndroidDeviceListCache:k=!1}){return await this.inputDeviceGating.selectInputTargetDevice(d,c,w,{action:D,bypassAndroidDeviceListCache:k})}async runTrackedKeyedDeviceInput(d,c,w,D){return await this.inputDeviceGating.runTrackedKeyedDeviceInput(d,c,w,D)}inputDeviceGate(d,c,w,{budgetStartMs:D,input:k}){return this.inputDeviceGating.inputDeviceGate(d,c,w,{budgetStartMs:D,input:k})}async runHeldInputOperation(d,c,w,D){return await this.inputDeviceGating.runHeldInputOperation(d,c,w,D)}dispatchFencedInput(d,c,w,{send:D,onDispatch:k}){return this.inputDeviceGating.dispatchFencedInput(d,c,w,{send:D,onDispatch:k})}async reconcileDiscoveryObservation(d,c){return await this.inputDeviceGating.reconcileDiscoveryObservation(d,c)}assertDeviceActionable(d,c){return this.inputDeviceGating.assertDeviceActionable(d,c)}async assertInputBindingGate(d,c,w){return await this.inputDeviceGating.assertInputBindingGate(d,c,w)}async runTrackedDeviceInput(d,c,w,D={}){return await this.inputDeviceGating.runTrackedDeviceInput(d,c,w,D)}async admitInputAsControlCall(d,c,w,D){return await this.inputDeviceGating.admitInputAsControlCall(d,c,w,D)}async answeringSessionRelease(d,c){return await this.inputDeviceGating.answeringSessionRelease(d,c)}runFencedInputOperation(d,c,w){return this.inputDeviceGating.runFencedInputOperation(d,c,w)}async discoverInputTargetDevices(d,c,w,D){return await this.inputDeviceGating.discoverInputTargetDevices(d,c,w,D)}mcpRequestOptions(d,c){return c?{timeout:d,signal:c}:{timeout:d}}combineMcpRequestSignals(d,c){return d?AbortSignal.any([d,c]):c}}function Ya(d,c){if(c.signal?.aborted)return c.signal.reason;let{deviceId:w,holderSessionId:D}=c,k=(P)=>`${d} on device '${w}' was lifted: ${P} before the stroke's start was acknowledged.`;return D?new cd(D,w,k(`session ${D} no longer holds the device`)):new ut(d,w,void 0,{message:k("a session acquired the device")})}var Gf=5000;class Xa{ports;constructor(d){this.ports=d}async handleInputGesture(d,c,w,D){let k=Vn[c],P=this.ports.parseInputGestureParams(d.params,k),C,{targetDevice:M,result:F}=await this.ports.runInputRoute(d,w,D,{action:k,origin:"UnixSocketServer.handleInputGesture",args:P,checksFrame:!1,around:(q,U)=>this.ports.liftingStrokeOnSessionRefusal(c,w,q,{gestureId:P.gestureId,run:U}),dispatch:async({targetDevice:q,signal:U,dispatching:K,remainingTimeoutMs:W})=>{K?.();let V=E.getInstance(q,v);if(c!=="start")return this.ports.forwardGestureFrame(V,c,P,W);return C=this.ports.captureStrokeAdmission(q.deviceId,U),this.ports.forwardGestureStart(V,P,W,C)}});if(!F.success)throw Error(F.error??`${k} failed on ${P.platform}`);if(w)await this.ports.trackAckedGestureFrame(c,w,M,{gestureId:P.gestureId,startAdmission:C});return{action:k,platform:P.platform,deviceId:M.deviceId,success:!0,gestureId:P.gestureId,point:{x:P.x,y:P.y},...c==="end"?{cancel:P.cancel}:{}}}async trackAckedGestureFrame(d,c,w,{gestureId:D,startAdmission:k}){if(d==="end"){this.ports.ownedGestures().onEndAcked(c,w.deviceId,D);return}if(d!=="start")return;let P=!k||this.ports.strokeAdmissionStillHolds(k);if(await this.ports.ownedGestures().onStartAcked(c,w,D,{holderSessionId:k?.holderSessionId,admissionStillHolds:P}),k&&!P)throw Ya(Vn.start,k)}async liftingStrokeOnSessionRefusal(d,c,w,{gestureId:D,run:k}){try{return await k()}catch(P){if(d!=="start"&&Rm(P)){try{await this.ports.cancelGestureOnDevice(w,D)}catch(C){e.warn(`Failed to lift gesture ${D} on ${w.deviceId} after its session refused a frame: ${r(C)}`)}if(c)this.ports.ownedGestures().onEndAcked(c,w.deviceId,D)}else if(d!=="start"&&c)await this.ports.ownedGestures().cancelIfDeviceChangedHands(c,w.deviceId,D,this.ports.getSessionForDevice(w.deviceId));throw P}}captureStrokeAdmission(d,c){let w=Ue()?.execution?.executionId,D=w?G.getAdmittedSessionUse(w):void 0;return{deviceId:d,...D!==void 0?{holderSessionId:D}:{},holderIncarnation:this.ports.getSessionIncarnation(D),...c?{signal:c}:{}}}strokeAdmissionStillHolds(d){if(d.signal?.aborted)return!1;if(this.ports.getSessionForDevice(d.deviceId)!==d.holderSessionId)return!1;return this.ports.getSessionIncarnation(d.holderSessionId)===d.holderIncarnation}async forwardGestureStart(d,c,w,D){let k=await this.ports.forwardGestureFrame(d,"start",c,w);if(!k.success||this.ports.strokeAdmissionStillHolds(D))return k;try{await d.requestGestureEnd(c.gestureId,0,0,{cancel:!0,timeoutMs:Gf})}catch(P){e.warn(`Failed to lift gesture ${c.gestureId} on ${D.deviceId} whose holder left before its start was acked: ${r(P)}`)}throw Ya(Vn.start,D)}liftSessionlessStrokesOn(d){this.ports.trackRequestHandler(this.ports.ownedGestures().cancelAllUnheldOn(d))}liftStrokesHeldByOn(d,c){if(this.ports.getSessionForDevice(c)===d)return;this.ports.trackRequestHandler(this.ports.ownedGestures().cancelAllHeldByOn(d,c))}liftStrokesHeldBy(d){return this.ports.ownedGestures().cancelAllHeldBy(d)}cancelGestureOnDevice(d,c){return this.ports.runKeyedMcpForward(`device:${d.deviceId}`,async()=>E.getInstance(d,v).requestGestureEnd(c,0,0,{cancel:!0,timeoutMs:Gf}),`device:${d.deviceId}`)}forwardGestureFrame(d,c,w,D){let{gestureId:k,x:P,y:C,cancel:M}=w;switch(c){case"start":return d.requestGestureStart({gestureId:k,x:P,y:C,timeoutMs:D});case"move":return d.requestGestureMove(k,P,C,{timeoutMs:D});case"end":return d.requestGestureEnd(k,P,C,{cancel:M,timeoutMs:D})}}}class Qa{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}remainingBudgetAfterProbe(d,c,w,D){let k=c-(this.state.timer.now()-d);if(k<=0)throw new Cr({toolName:w,timeoutMs:c,origin:`UnixSocketServer.${D}`,detail:"iOS screen-scale probe consumed the request budget"});return k}async toIosRunnerCoordinates(d,c,w,{probeTimeoutMs:D,validateCanonicalCoordinates:k}){let P=d.getScreenScaleMetadata();if(P)return this.state.confirmedLegacyScaleDevices.delete(c),k?.(P),w.map((F)=>uY(F,P.nativeScale));if(this.state.confirmedLegacyScaleDevices.has(c))return w;let C;try{C=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,D)}catch(F){throw u(F,`Could not determine iOS screen scale for ${c}; the input coordinate scale probe failed`)}if(!C)throw new t(`Could not determine iOS screen scale for ${c}: the hierarchy probe returned no data. Retry once the device has produced a hierarchy.`);let M=d.getScreenScaleMetadata();if(!M)return this.state.confirmedLegacyScaleDevices.add(c),w;return k?.(M),w.map((F)=>uY(F,M.nativeScale))}requireCoordinatesWithinKnownScreenGeometry(d,c){if(!c)return;let[w,D]=d;if(w<0||w>=c.pixelWidth||D<0||D>=c.pixelHeight)throw Error(`input/tap coordinates x=${w}, y=${D} are outside device canonical pixel bounds x: 0..${c.pixelWidth-1}, y: 0..${c.pixelHeight-1}`)}inputRouteClock(d,c){return{queueEnterMs:c?.receivedAtMs??this.state.timer.now(),totalTimeoutMs:$0(d)}}remainingInputBudgetMs(d,c,w,D){let k=this.state.timer.now()-w,P=D-k;if(P<=0)throw new Cr({toolName:d,timeoutMs:D,origin:c,detail:`spent ${k}ms waiting in queue`});return P}async runInputRoute(d,c,w,D){let{queueEnterMs:k,totalTimeoutMs:P}=this.callbacks.inputRouteClock(d,w),{args:C}=D,M=await this.callbacks.resolveInputTargetDevice(C.platform,C.deviceId,c,{action:D.action,bypassAndroidDeviceListCache:D.bypassAndroidDeviceListCache??!1,requester:w?.requester}),F=()=>this.callbacks.runTrackedKeyedDeviceInput(d.method,M,async(U,K)=>{He(U);let W=D.reresolve?await D.reresolve(M):M;if(D.checksFrame)this.callbacks.requireCurrentFrameContext(M.deviceId,C.frameContext,D.action);let V=this.callbacks.remainingInputBudgetMs(d.method,D.origin,k,P);return await D.dispatch({targetDevice:M,executionDevice:W,signal:U,dispatching:K,remainingTimeoutMs:V,queueEnterMs:k,totalTimeoutMs:P})},this.callbacks.inputDeviceGate(d.method,D.origin,P,{budgetStartMs:k,input:w})),q=await(D.around?D.around(M,F):F());return{targetDevice:M,result:q}}async handleInputTap(d,c,w){let D=this.callbacks.parseInputTapParams(d.params),{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,w,{action:"input/tap",origin:"UnixSocketServer.handleInputTap",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>{if(D.platform==="android"){let X=E.getInstance(C,v);return this.callbacks.requireCoordinatesWithinKnownScreenGeometry([D.x,D.y],X.getScreenScaleMetadata?.()??null),await this.callbacks.dispatchFencedInput("Tap",M,q,{send:(ee,ne)=>X.requestTapCoordinates({x:D.x,y:D.y,duration:D.duration,timeoutMs:q,frameContext:D.frameContext,onDispatch:ne,signal:ee}),onDispatch:F})}let W=x.getInstance(C),[V,z]=await this.callbacks.toIosRunnerCoordinates(W,C.deviceId,[D.x,D.y],{probeTimeoutMs:q,validateCanonicalCoordinates:(X)=>this.callbacks.requireCoordinatesWithinKnownScreenGeometry([D.x,D.y],X)}),J=this.callbacks.remainingBudgetAfterProbe(U,K,d.method,"handleInputTap");return He(M),await this.callbacks.dispatchFencedInput("Tap",M,J,{send:(X,ee)=>W.requestTapCoordinates({x:V,y:z,duration:D.duration,timeoutMs:J,frameContext:D.frameContext,signal:X,onDispatch:ee}),onDispatch:F})}});if(!P.success)throw Error(P.error??`input/tap failed on ${D.platform}`);return{action:"input/tap",platform:D.platform,deviceId:k.deviceId,success:!0,coordinates:{x:D.x,y:D.y}}}async handleInputSwipe(d,c,w){let D=this.callbacks.parseInputSwipeParams(d.params),{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,w,{action:"input/swipe",origin:"UnixSocketServer.handleInputSwipe",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>{if(D.platform==="android"){let ne=E.getInstance(C,v);return await this.callbacks.dispatchFencedInput("Swipe",M,q,{send:(te,oe)=>ne.requestSwipe({x1:D.startX,y1:D.startY,x2:D.endX,y2:D.endY,duration:D.durationMs,timeoutMs:q,contextOptions:D.frameContext,onDispatch:oe,signal:te}),onDispatch:F})}let W=x.getInstance(C),[V,z,J,X]=await this.callbacks.toIosRunnerCoordinates(W,C.deviceId,[D.startX,D.startY,D.endX,D.endY],{probeTimeoutMs:q}),ee=this.callbacks.remainingBudgetAfterProbe(U,K,d.method,"handleInputSwipe");return He(M),await this.callbacks.dispatchFencedInput("Swipe",M,ee,{send:(ne,te)=>W.requestDrag({x1:V,y1:z,x2:J,y2:X,pressDurationMs:0,dragDurationMs:D.durationMs,holdDurationMs:0,timeoutMs:ee,frameContext:D.frameContext,signal:ne,onDispatch:te}),onDispatch:F})}});if(!P.success)throw Error(P.error??`input/swipe failed on ${D.platform}`);return{action:"input/swipe",platform:D.platform,deviceId:k.deviceId,success:!0,start:{x:D.startX,y:D.startY},end:{x:D.endX,y:D.endY},durationMs:D.durationMs}}async handleInputGesture(d,c,w,D){return await this.inputStrokes.handleInputGesture(d,c,w,D)}async trackAckedGestureFrame(d,c,w,{gestureId:D,startAdmission:k}){return await this.inputStrokes.trackAckedGestureFrame(d,c,w,{gestureId:D,startAdmission:k})}async liftingStrokeOnSessionRefusal(d,c,w,{gestureId:D,run:k}){return await this.inputStrokes.liftingStrokeOnSessionRefusal(d,c,w,{gestureId:D,run:k})}captureStrokeAdmission(d,c){return this.inputStrokes.captureStrokeAdmission(d,c)}strokeAdmissionStillHolds(d){return this.inputStrokes.strokeAdmissionStillHolds(d)}async forwardGestureStart(d,c,w,D){return await this.inputStrokes.forwardGestureStart(d,c,w,D)}liftSessionlessStrokesOn(d){return this.inputStrokes.liftSessionlessStrokesOn(d)}liftStrokesHeldByOn(d,c){return this.inputStrokes.liftStrokesHeldByOn(d,c)}liftStrokesHeldBy(d){return this.inputStrokes.liftStrokesHeldBy(d)}cancelGestureOnDevice(d,c){return this.inputStrokes.cancelGestureOnDevice(d,c)}forwardGestureFrame(d,c,w,D){return this.inputStrokes.forwardGestureFrame(d,c,w,D)}async handleInputPressButton(d,c,w){let D=this.callbacks.parseInputPressButtonParams(d.params),{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,w,{action:"input/pressButton",origin:"UnixSocketServer.handleInputPressButton",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>await new Dn(C,null,this.state.timer,{holdRequest:(V,z,J,X)=>this.callbacks.holdDispatchedInputRequest(V,U+K-this.state.timer.now(),J,{onDispatch:X,label:"Button press request"})}).press(D.button,{timeoutMs:q,frameContext:D.frameContext,signal:M,onDispatch:F})});if(!P.success)throw Error(P.error??`input/pressButton failed on ${D.platform}`);return{action:"input/pressButton",platform:D.platform,deviceId:k.deviceId,success:!0,button:D.responseButton}}async handleInputKey(d,c,w){let D=this.callbacks.parseInputKeyParams(d.params);if(D.platform==="ios")throw Error(jJ);let{targetDevice:k,result:P}=await this.callbacks.runInputRoute(d,c,w,{action:"input/key",origin:"UnixSocketServer.handleInputKey",args:D,checksFrame:!0,dispatch:async({targetDevice:C,signal:M,dispatching:F,remainingTimeoutMs:q,queueEnterMs:U,totalTimeoutMs:K})=>await this.callbacks.executeSocketInputKey(new rc(C,{adbFactory:v,timer:this.state.timer}),{key:D.key,frameContext:D.frameContext,totalTimeoutMs:K,remainingTimeoutMs:q,signal:M,dispatching:F})});if(!P.success)throw Error(P.error??`input/key failed on ${D.platform}`);return{action:"input/key",platform:D.platform,deviceId:k.deviceId,success:!0,key:D.key}}executeSocketInputKey(d,c){let{key:w,frameContext:D,totalTimeoutMs:k,remainingTimeoutMs:P,signal:C,dispatching:M}=c,F=!1,q=(U,K)=>d.press(w,P,D,{modifiers:[],signal:U,onDispatch:K});return this.callbacks.runHeldInputOperation("input/key",C,(U,K)=>this.callbacks.runInputOperationWithTimeout({toolName:"input/key",origin:"UnixSocketServer.handleInputKey",totalTimeoutMs:k,remainingTimeoutMs:P},()=>this.callbacks.holdDispatchedInputRequest(C,P,q,{onDispatch:()=>{F=!0,K?.()},label:"Key request"}),(W)=>F?rc.indeterminateError(W):void 0),()=>M?.())}inputStrokesInstance;get inputStrokes(){return this.inputStrokesInstance??=new Xa({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 Wf({timer:d,signal:c,timeoutMs:w,label:D,send:k,onDispatch:P}){c?.throwIfAborted();let C=d.now()+w,M=new AbortController,F=!1,q,U=()=>{if(!F){M.abort(c?.reason);return}q=d.setTimeout(()=>{let W=new t(`${D} deadline expired after dispatch`);M.abort(W)},Math.max(0,C-d.now()))};c?.addEventListener("abort",U,{once:!0});let K=c?M.signal:void 0;try{let W=H(K,()=>k(K,()=>{K?.throwIfAborted(),F=!0,P?.()}));return await l(W,{timer:d,signal:K,label:D})}finally{if(q!==void 0)d.clearTimeout(q);c?.removeEventListener("abort",U)}}class Za{state;resolveCallbacks;constructor(d,c){this.state=d;this.resolveCallbacks=c}get callbacks(){return this.resolveCallbacks()}async handleInputTypeText(d,c,w){let D=this.callbacks.parseInputTypeTextParams(d.params),k,P=(F)=>{k=F},{targetDevice:C,result:M}=await this.callbacks.runInputRoute(d,c,w,{action:"input/typeText",origin:"UnixSocketServer.handleInputTypeText",args:D,bypassAndroidDeviceListCache:D.append,reresolve:async(F)=>D.append&&D.platform==="android"?await this.callbacks.resolveInputTargetDevice(D.platform,F.deviceId,c,{action:"input/typeText",bypassAndroidDeviceListCache:!0,requester:w?.requester}):F,checksFrame:!0,dispatch:async({executionDevice:F,signal:q,dispatching:U,remainingTimeoutMs:K,totalTimeoutMs:W})=>{let V=D.submit?"done":void 0,z=!1,J=()=>{w?.onDispatch?.(),z=!0,U?.()};try{return await this.callbacks.runInputOperationWithTimeout({toolName:d.method,origin:"UnixSocketServer.handleInputTypeText",totalTimeoutMs:W,remainingTimeoutMs:K},()=>this.callbacks.executeInputTypeText(D.platform,F,D.text,{imeAction:V,timeoutMs:K,append:D.append,frameContext:D.frameContext,onConfirmedAppendCharsSent:P,signal:q,dispatching:J}),(X)=>D.append&&k!==void 0?new ke(X.message,k):void 0)}catch(X){if(z&&q?.aborted)throw this.callbacks.indeterminateTextError(X,q.reason,k);throw X}}});if(!M.success){if(D.append&&M.charsSent!==void 0)throw new ke(M.error??`input/typeText failed on ${D.platform}`,M.charsSent);throw Error(M.error??`input/typeText failed on ${D.platform}`)}return{action:"input/typeText",platform:D.platform,deviceId:C.deviceId,success:!0,textLength:D.text.length,submitted:D.submit}}indeterminateTextError(d,c,w){let D=`Text input outcome is indeterminate: the request was dispatched but no result was confirmed when cancellation arrived (${r(c)}). Do not retry automatically. Observe before retrying.`,k=w??(d instanceof ke?d.charsSent:void 0),P=k===void 0?new t(D,{cause:d}):new ke(D,k);return Object.assign(P,{requestDispatched:!0})}holdDispatchedInputRequest(d,c,w,{onDispatch:D,label:k="Text input request"}={}){return Wf({timer:this.state.timer,signal:d,timeoutMs:c,label:k,send:w,onDispatch:D})}createSocketInputAdbFactory(d){return{create:(c,w)=>{let D=v.create(c,w);return new Proxy(D,{get:(k,P,C)=>{if(P==="execute")return(F,q={})=>{if(F[0]!=="shell"||F[1]!=="input")return D.execute(F,q);return this.callbacks.holdDispatchedInputRequest(q.signal,Math.min(q.timeoutMs??1/0,d.deadline()-this.state.timer.now()),(U,K)=>D.execute(F,{...q,signal:U,beforeDispatch:async(W)=>{await q.beforeDispatch?.(W),U?.throwIfAborted(),K()}}),{onDispatch:d.onDispatch,label:d.label})};let M=Reflect.get(k,P,C);return typeof M==="function"?M.bind(k):M}})}}}createSocketAppendTextInput(d){let c=0,w,D=this.callbacks.createSocketInputAdbFactory({deadline:()=>c,onDispatch:()=>w?.(),label:"Text input request"}),k=new vV(d,D,{timer:this.state.timer});return{appendText:(P,C={})=>(c=this.state.timer.now()+(C.timeoutMs??0),w=C.onDispatch,k.appendText(P,{timeoutMs:C.timeoutMs,beforeKeyEvents:C.beforeKeyEvents,signal:C.signal}))}}async executeInputTypeText(d,c,w,D){let{imeAction:k,timeoutMs:P,append:C=!1,frameContext:M,onConfirmedAppendCharsSent:F,signal:q,dispatching:U}=D,K=!1,W=()=>{if(!K)K=!0,U?.()},V=this.state.timer.now()+P,z=d==="android"?{platform:d,client:E.getInstance(c,v)}:{platform:d,client:x.getInstance(c)},{client:J}=z,X;if(C&&z.platform==="android"){let ee=await this.callbacks.executeAndroidAppendText({targetDevice:c,text:w,deadline:V,totalTimeoutMs:P,frameContext:M,client:z.client,signal:q,onDispatch:W});if(ee.charsSent!==void 0)F?.(ee.charsSent);if(He(q),!ee.success)return{success:!1,error:ee.error,...ee.charsSent!==void 0?{charsSent:ee.charsSent}:{}};X=ee.charsSent}else{let ee=C&&z.platform==="ios"?z.client:null,ne=await this.callbacks.holdDispatchedInputRequest(q,V-this.state.timer.now(),(te,oe)=>ee?ee.requestAppendText(w,P,void 0,{frameContext:M,abortSignal:te,onDispatch:oe}):J.requestSetText(w,{timeoutMs:P,frameContext:M,abortSignal:te,onDispatch:oe}),{onDispatch:W});if(He(q),!ne.success)return{success:!1,error:ne.error}}return await this.callbacks.runImeActionWithinBudget(J,k,V,{totalTimeoutMs:P,appendCharsSent:X,signal:q,onDispatch:W})}async executeAndroidAppendText(d){let{targetDevice:c,text:w,deadline:D,totalTimeoutMs:k,frameContext:P,client:C,signal:M,onDispatch:F}=d,q=D-this.state.timer.now();if(q<=0)return{success:!1,error:`input/typeText exceeded ${k}ms budget before append key events`};let U=P===void 0?void 0:()=>this.callbacks.validateAppendFrameContext(C,P,D,k),K=this.callbacks.getAppendTextInput(c),W=async(z,J,X,ee)=>await z.appendText(J,{timeoutMs:X,beforeKeyEvents:ee,signal:M,onDispatch:F}),V=await W(K.input,w,q,U);if(V.success||!K.fromCache||M?.aborted||V.failureSource==="runner")return V;return await this.callbacks.retryAppendTextWithRebuiltHelper(c,w,V,{deadline:D,beforeKeyEvent:U,run:W})}async retryAppendTextWithRebuiltHelper(d,c,w,D){let{deadline:k,beforeKeyEvent:P,run:C}=D,M=w.charsSent;if(M===void 0)return w;let F=c.slice(M);if(F.length===0)return w;this.callbacks.evictDeviceInputCache(d.deviceId);let q=k-this.state.timer.now();if(q<=0)return w;let U=await C(this.callbacks.getAppendTextInput(d).input,F,q,M===0?P:void 0);return U.charsSent===void 0?{success:U.success,...U.error!==void 0?{error:U.error}:{}}:{...U,charsSent:M+U.charsSent}}async validateAppendFrameContext(d,c,w,D){let k=w-this.state.timer.now();if(k<=0)return{success:!1,error:`input/typeText exceeded ${D}ms budget before append frame context validation`};let P=await d.validateFrameContext(c,k);return P.success?{success:!0}:{success:!1,error:P.error??"Frame context is stale or unavailable; observe a fresh frame before retrying",failureSource:"runner"}}async runImeActionWithinBudget(d,c,w,D){let{totalTimeoutMs:k,appendCharsSent:P,signal:C,onDispatch:M}=D,F=(U)=>P!==void 0?{...U,charsSent:P}:U;if(!c)return F({success:!0});He(C);let q=w-this.state.timer.now();if(q<=0)return F({success:!1,error:`input/typeText exceeded ${k}ms budget before submit`});try{let U=await this.callbacks.holdDispatchedInputRequest(C,q,(K,W)=>d.requestImeAction(c,q,void 0,{abortSignal:K,onDispatch:W}),{onDispatch:M});if(He(C),!U.success){let K=Ev(c,U.error||"unknown error");return e.warn(`[input/typeText] ${K}`),F({...U,error:K})}return F(U)}catch(U){let K=Ev(c,r(U)||"unknown error");if(e.warn(`[input/typeText] ${K}`,U),C?.aborted)throw U;if(P===void 0){if(U instanceof Error)throw U.message=K,U;throw new t(K,{cause:U})}return{success:!1,error:K,charsSent:P}}}async runInputOperationWithTimeout(d,c,w){let{toolName:D,origin:k,totalTimeoutMs:P,remainingTimeoutMs:C}=d,M=!1,F=c();try{return await l(F,{timer:this.state.timer,timeoutMs:C,label:"Input operation",timeoutError:()=>{M=!0;let q=new Cr({toolName:D,timeoutMs:P,origin:k,detail:`operation exceeded remaining budget ${C}ms`});return w?.(q)??q}})}finally{if(M)await F.catch(()=>{return})}}parseInputTapParams(d){return Hn(d)}parseInputSwipeParams(d){return qn(d)}parseInputTypeTextParams(d){return Kn(d)}parseInputPressButtonParams(d){return Gn(d)}parseInputKeyParams(d){return Wn(d)}parseInputGestureParams(d,c){return Nt(d,c)}evictDeviceInputCache(d){if(this.state.appendTextInputs.delete(d))e.debug(`[UnixSocketServer] Evicted cached append helper for device ${d}`)}getAppendTextInput(d){let c=no(d.deviceId),w=this.state.appendTextInputs.get(d.deviceId);if(w&&w.incarnationToken===c)return{input:w.input,fromCache:!0};if(w)e.debug(`[UnixSocketServer] Rebuilding cached append helper for ${d.deviceId}: pool incarnation changed from ${w.incarnationToken} to ${c}`);let D=this.state.appendTextFactory(d);return this.state.appendTextInputs.set(d.deviceId,{input:D,incarnationToken:c}),{input:D,fromCache:!1}}}function hk(d){return{start:d.start.bind(d),startDetached:d.startDetached.bind(d),stopAcceptingAndFanOut:d.stopAcceptingAndFanOut.bind(d),beginAccepting:d.beginAccepting.bind(d),connectionHandlerWithFanOut:d.connectionHandlerWithFanOut.bind(d),reclaimExistingSocketBeforeBind:d.reclaimExistingSocketBeforeBind.bind(d),isListening:d.isListening.bind(d),getClientConnectionCount:d.getClientConnectionCount.bind(d),getAcceptedClientConnectionCount:d.getAcceptedClientConnectionCount.bind(d),quiesce:d.quiesce.bind(d),drainSessionReleaseNotifications:d.drainSessionReleaseNotifications.bind(d),close:d.close.bind(d),writeShutdownSocketResponse:d.writeShutdownSocketResponse.bind(d),closeListeningServer:d.closeListeningServer.bind(d),destroyClientSockets:d.destroyClientSockets.bind(d),drainActiveRequestHandlers:d.drainActiveRequestHandlers.bind(d)}}function gk(d){return{handleConnection:d.handleConnection.bind(d),connectionFor:d.connectionFor.bind(d),rejectOversizedFrame:d.rejectOversizedFrame.bind(d),hasLiveSocketRequest:d.hasLiveSocketRequest.bind(d),processSocketRequestLine:d.processSocketRequestLine.bind(d),writeTerminalSocketResponse:d.writeTerminalSocketResponse.bind(d),withCanonicalToolCallDeviceIds:d.withCanonicalToolCallDeviceIds.bind(d),frameDeviceId:d.frameDeviceId.bind(d),traceFrame:d.traceFrame.bind(d),releaseSocketSession:d.releaseSocketSession.bind(d),forgetLateSessionToolBindings:d.forgetLateSessionToolBindings.bind(d),trackRequestHandler:d.trackRequestHandler.bind(d),abortMcpRequests:d.abortMcpRequests.bind(d),abortRequestControllers:d.abortRequestControllers.bind(d),mcpRequestSignal:d.mcpRequestSignal.bind(d),isMcpRequestOwnerCurrent:d.isMcpRequestOwnerCurrent.bind(d),broadcastListChanged:d.broadcastListChanged.bind(d),broadcastResourceUpdated:d.broadcastResourceUpdated.bind(d),handleResourceSubscription:d.handleResourceSubscription.bind(d),broadcastSessionDeviceRebound:d.broadcastSessionDeviceRebound.bind(d),broadcastSessionReleased:d.broadcastSessionReleased.bind(d),pushProgressNotification:d.pushProgressNotification.bind(d),writeFrame:d.writeFrame.bind(d),writeFrameData:d.writeFrameData.bind(d)}}function vk(d){return{handleRequest:d.handleRequest.bind(d),unqueuedRequest:d.unqueuedRequest.bind(d),relayTaskRequest:d.relayTaskRequest.bind(d),runProvisionBarrier:d.runProvisionBarrier.bind(d),shuttingDownBeforeStartResponse:d.shuttingDownBeforeStartResponse.bind(d),isProvisionDeviceCall:d.isProvisionDeviceCall.bind(d),provisionCancellationReply:d.provisionCancellationReply.bind(d),mcpForwardFailureResponse:d.mcpForwardFailureResponse.bind(d),waitForStartup:d.waitForStartup.bind(d),registerRequestCancellation:d.registerRequestCancellation.bind(d),cancelSocketRequest:d.cancelSocketRequest.bind(d),requireRemainingMcpForwardBudget:d.requireRemainingMcpForwardBudget.bind(d),socketAdmissionCancellation:d.socketAdmissionCancellation.bind(d),runCancellableInputHandler:d.runCancellableInputHandler.bind(d),runCancellableQueuedHandler:d.runCancellableQueuedHandler.bind(d)}}function yk(d){return{forgetSocketDiscovery:d.forgetSocketDiscovery.bind(d),rejectOnHandshakeMismatch:d.rejectOnHandshakeMismatch.bind(d),runKeyedMcpForward:d.runKeyedMcpForward.bind(d),runMcpForwardForCurrentRoute:d.runMcpForwardForCurrentRoute.bind(d),runMcpForwardAttempt:d.runMcpForwardAttempt.bind(d),forwardMcpRequest:d.forwardMcpRequest.bind(d),remainingMcpForwardBudget:d.remainingMcpForwardBudget.bind(d),wasRequestSessionActive:d.wasRequestSessionActive.bind(d),describeMcpForwardRequest:d.describeMcpForwardRequest.bind(d),daemonGenerationMatches:d.daemonGenerationMatches.bind(d),currentGenerationIdentity:d.currentGenerationIdentity.bind(d),republishDaemonIdentity:d.republishDaemonIdentity.bind(d),publishIdentity:d.publishIdentity.bind(d),requireFeatureFlagService:d.requireFeatureFlagService.bind(d),handleIdeRequest:d.handleIdeRequest.bind(d),textForwardFailure:d.textForwardFailure.bind(d),traceCallTool:d.traceCallTool.bind(d),withLiveDeadlineKey:d.withLiveDeadlineKey.bind(d),withSocketSessionAutolockKey:d.withSocketSessionAutolockKey.bind(d),recordOneShotCliConnection:d.recordOneShotCliConnection.bind(d),oneShotCliMarker:d.oneShotCliMarker.bind(d),createMcpClient:d.createMcpClient.bind(d),scheduleForwardKeyIdle:d.scheduleForwardKeyIdle.bind(d),clearForwardKeyIdleTimer:d.clearForwardKeyIdleTimer.bind(d),onForwardKeyIdle:d.onForwardKeyIdle.bind(d)}}function Sk(d){return{getMcpForwardRoute:d.getMcpForwardRoute.bind(d),withDeviceReadLane:d.withDeviceReadLane.bind(d),getDeviceLabelSession:d.getDeviceLabelSession.bind(d),isDeviceReadToolCall:d.isDeviceReadToolCall.bind(d),getDeviceHolderSession:d.getDeviceHolderSession.bind(d),getAdmittedMcpForwardRoute:d.getAdmittedMcpForwardRoute.bind(d),getDiscoveryForwardRoute:d.getDiscoveryForwardRoute.bind(d),getNavigationGraphForwardRoute:d.getNavigationGraphForwardRoute.bind(d),getResourceReadForwardRoute:d.getResourceReadForwardRoute.bind(d),beginMcpSessionOwnerCall:d.beginMcpSessionOwnerCall.bind(d),getToolsCallForwardRoute:d.getToolsCallForwardRoute.bind(d),getAdmittedToolsCallForwardRoute:d.getAdmittedToolsCallForwardRoute.bind(d),hostInventoryOrBoundRoute:d.hostInventoryOrBoundRoute.bind(d),isUnboundDeviceAcquisitionTool:d.isUnboundDeviceAcquisitionTool.bind(d),profileReaffirmForwardRoute:d.profileReaffirmForwardRoute.bind(d),getAcquiredDeviceSessionUuid:d.getAcquiredDeviceSessionUuid.bind(d),selectorMcpForwardRoute:d.selectorMcpForwardRoute.bind(d),hasImplicitDeviceSelector:d.hasImplicitDeviceSelector.bind(d),sharedMcpForwardRoute:d.sharedMcpForwardRoute.bind(d),acquisitionMcpForwardRoute:d.acquisitionMcpForwardRoute.bind(d),sessionMcpClientKey:d.sessionMcpClientKey.bind(d),toolSelectionProfileMcpClientKey:d.toolSelectionProfileMcpClientKey.bind(d),sessionScopedForwardRoute:d.sessionScopedForwardRoute.bind(d),toolSelectionProfileScopedForwardRoute:d.toolSelectionProfileScopedForwardRoute.bind(d)}}function bk(d){return{restoreSelectorSessions:d.restoreSelectorSessions.bind(d),holdsSession:d.holdsSession.bind(d),failIfCallTargetsRefusedRestore:d.failIfCallTargetsRefusedRestore.bind(d),ownedSessionsOwnerToken:d.ownedSessionsOwnerToken.bind(d),selectorSessionIds:d.selectorSessionIds.bind(d),releaseBindingsIfSocketDisconnected:d.releaseBindingsIfSocketDisconnected.bind(d),releaseDevicePoolMcpSessionBindings:d.releaseDevicePoolMcpSessionBindings.bind(d),clearConnectionDevicePin:d.clearConnectionDevicePin.bind(d),recordBoundMcpClientKey:d.recordBoundMcpClientKey.bind(d),isSessionOwnedByOtherConnection:d.isSessionOwnedByOtherConnection.bind(d),honoursBoundSessionMarker:d.honoursBoundSessionMarker.bind(d),isRetryableSessionRecoveryResult:d.isRetryableSessionRecoveryResult.bind(d),recordSessionBoundMcpClientKey:d.recordSessionBoundMcpClientKey.bind(d),targetsOneCallOnly:d.targetsOneCallOnly.bind(d),recordGeneratedToolSelectionProfile:d.recordGeneratedToolSelectionProfile.bind(d),getBoundMcpClientRoute:d.getBoundMcpClientRoute.bind(d),getToolSelectionProfileUuid:d.getToolSelectionProfileUuid.bind(d),getGeneratedToolSelectionProfileUuid:d.getGeneratedToolSelectionProfileUuid.bind(d),clearBoundMcpClientKey:d.clearBoundMcpClientKey.bind(d),clearBoundMcpClientsForReleasedSession:d.clearBoundMcpClientsForReleasedSession.bind(d),isMcpClientKeyBound:d.isMcpClientKeyBound.bind(d),getSessionForDevice:d.getSessionForDevice.bind(d),getSessionIncarnation:d.getSessionIncarnation.bind(d),hasActiveDaemonSession:d.hasActiveDaemonSession.bind(d),getSessionUuid:d.getSessionUuid.bind(d),isReleasedBoundSession:d.isReleasedBoundSession.bind(d),boundSessionAdmissionArgs:d.boundSessionAdmissionArgs.bind(d),withAdmittedBoundSession:d.withAdmittedBoundSession.bind(d),admitReleasedBoundSession:d.admitReleasedBoundSession.bind(d),expiredBoundSessionRelease:d.expiredBoundSessionRelease.bind(d),getRequestArgumentScopeKey:d.getRequestArgumentScopeKey.bind(d),getObjectRequestArgumentScopeKey:d.getObjectRequestArgumentScopeKey.bind(d),sessionToScopeKey:d.sessionToScopeKey.bind(d),getImplicitAutolockScopeKey:d.getImplicitAutolockScopeKey.bind(d),resolveImplicitAutolockSession:d.resolveImplicitAutolockSession.bind(d),getRequestPlatform:d.getRequestPlatform.bind(d),resolveDeviceLabelSession:d.resolveDeviceLabelSession.bind(d),getAssignedDeviceForSession:d.getAssignedDeviceForSession.bind(d)}}function wk(d){return{runLocalSocketRequest:d.runLocalSocketRequest.bind(d),handleLocalSocketRequest:d.handleLocalSocketRequest.bind(d),dispatchInputRoute:d.dispatchInputRoute.bind(d),dispatchIdeSocketRequest:d.dispatchIdeSocketRequest.bind(d),handleIdeSocketRequest:d.handleIdeSocketRequest.bind(d),runTrackedIdeMutation:d.runTrackedIdeMutation.bind(d),listBootedDevicesForIdeAction:d.listBootedDevicesForIdeAction.bind(d),resolveIdeActionDevices:d.resolveIdeActionDevices.bind(d),canonicalFrameDiscovery:d.canonicalFrameDiscovery.bind(d),assertFrameTargetProven:d.assertFrameTargetProven.bind(d),canonicalFrameDeviceId:d.canonicalFrameDeviceId.bind(d),runIdeKeyValueMutation:d.runIdeKeyValueMutation.bind(d),assertSocketToolEnabled:d.assertSocketToolEnabled.bind(d),requireCurrentFrameContext:d.requireCurrentFrameContext.bind(d),inputRequester:d.inputRequester.bind(d),resolveInputTargetDevice:d.resolveInputTargetDevice.bind(d),assertBrokerConnectionInputTarget:d.assertBrokerConnectionInputTarget.bind(d),assertBrokerConnectionControl:d.assertBrokerConnectionControl.bind(d),assertBrokerConnectionHostMutation:d.assertBrokerConnectionHostMutation.bind(d),captureInputTargetOwner:d.captureInputTargetOwner.bind(d),selectInputTargetDevice:d.selectInputTargetDevice.bind(d),runTrackedKeyedDeviceInput:d.runTrackedKeyedDeviceInput.bind(d),inputDeviceGate:d.inputDeviceGate.bind(d),runHeldInputOperation:d.runHeldInputOperation.bind(d),dispatchFencedInput:d.dispatchFencedInput.bind(d),reconcileDiscoveryObservation:d.reconcileDiscoveryObservation.bind(d),assertDeviceActionable:d.assertDeviceActionable.bind(d),assertInputBindingGate:d.assertInputBindingGate.bind(d),runTrackedDeviceInput:d.runTrackedDeviceInput.bind(d),admitInputAsControlCall:d.admitInputAsControlCall.bind(d),answeringSessionRelease:d.answeringSessionRelease.bind(d),runFencedInputOperation:d.runFencedInputOperation.bind(d),discoverInputTargetDevices:d.discoverInputTargetDevices.bind(d),mcpRequestOptions:d.mcpRequestOptions.bind(d),combineMcpRequestSignals:d.combineMcpRequestSignals.bind(d)}}function Rk(d){return{remainingBudgetAfterProbe:d.remainingBudgetAfterProbe.bind(d),toIosRunnerCoordinates:d.toIosRunnerCoordinates.bind(d),requireCoordinatesWithinKnownScreenGeometry:d.requireCoordinatesWithinKnownScreenGeometry.bind(d),inputRouteClock:d.inputRouteClock.bind(d),remainingInputBudgetMs:d.remainingInputBudgetMs.bind(d),runInputRoute:d.runInputRoute.bind(d),handleInputTap:d.handleInputTap.bind(d),handleInputSwipe:d.handleInputSwipe.bind(d),handleInputGesture:d.handleInputGesture.bind(d),trackAckedGestureFrame:d.trackAckedGestureFrame.bind(d),liftingStrokeOnSessionRefusal:d.liftingStrokeOnSessionRefusal.bind(d),captureStrokeAdmission:d.captureStrokeAdmission.bind(d),strokeAdmissionStillHolds:d.strokeAdmissionStillHolds.bind(d),forwardGestureStart:d.forwardGestureStart.bind(d),liftSessionlessStrokesOn:d.liftSessionlessStrokesOn.bind(d),liftStrokesHeldByOn:d.liftStrokesHeldByOn.bind(d),liftStrokesHeldBy:d.liftStrokesHeldBy.bind(d),cancelGestureOnDevice:d.cancelGestureOnDevice.bind(d),forwardGestureFrame:d.forwardGestureFrame.bind(d),handleInputPressButton:d.handleInputPressButton.bind(d),handleInputKey:d.handleInputKey.bind(d),executeSocketInputKey:d.executeSocketInputKey.bind(d)}}function kk(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 Vf(d,c){let w=new wa(d,()=>W),D=new Ea(d,()=>W),k=new Na(d,()=>W),P=new Ka(d,()=>W),C=new Ga(d,()=>W),M=new Wa(d,()=>W),F=new za(d,()=>W),q=new Qa(d,()=>W),U=new Za(d,()=>W),K={...hk(w),...gk(D),...vk(k),...yk(P),...Sk(C),...bk(M),...wk(F),...Rk(q),...kk(U)},W={...K,...c};return{implementations:K,callbacks:W}}class Ri{runtime;operations;callbacks;constructor(...d){this.runtime=new ba(d,()=>this.operations,Ks,()=>this.maxInboundFrameBytes);let c=Vf(this.runtime,{start:(...w)=>this.start(...w),startDetached:(...w)=>this.startDetached(...w),stopAcceptingAndFanOut:(...w)=>this.stopAcceptingAndFanOut(...w),handleConnection:(...w)=>this.handleConnection(...w),releaseSocketSession:(...w)=>this.releaseSocketSession(...w),abortMcpRequests:(...w)=>this.abortMcpRequests(...w),mcpRequestSignal:(...w)=>this.mcpRequestSignal(...w),broadcastResourceUpdated:(...w)=>this.broadcastResourceUpdated(...w),pushProgressNotification:(...w)=>this.pushProgressNotification(...w),writeFrameData:(...w)=>this.writeFrameData(...w),handleRequest:(...w)=>this.handleRequest(...w),mcpForwardFailureResponse:(...w)=>this.mcpForwardFailureResponse(...w),requireRemainingMcpForwardBudget:(...w)=>this.requireRemainingMcpForwardBudget(...w),runKeyedMcpForward:(...w)=>this.runKeyedMcpForward(...w),getMcpForwardRoute:(...w)=>this.getMcpForwardRoute(...w),restoreSelectorSessions:(...w)=>this.restoreSelectorSessions(...w),recordBoundMcpClientKey:(...w)=>this.recordBoundMcpClientKey(...w),clearBoundMcpClientKey:(...w)=>this.clearBoundMcpClientKey(...w),forwardMcpRequest:(...w)=>this.forwardMcpRequest(...w),remainingMcpForwardBudget:(...w)=>this.remainingMcpForwardBudget(...w),getRequestArgumentScopeKey:(...w)=>this.getRequestArgumentScopeKey(...w),handleLocalSocketRequest:(...w)=>this.handleLocalSocketRequest(...w),handleIdeSocketRequest:(...w)=>this.handleIdeSocketRequest(...w),listBootedDevicesForIdeAction:(...w)=>this.listBootedDevicesForIdeAction(...w),runIdeKeyValueMutation:(...w)=>this.runIdeKeyValueMutation(...w),toIosRunnerCoordinates:(...w)=>this.toIosRunnerCoordinates(...w),handleInputTap:(...w)=>this.handleInputTap(...w),handleInputSwipe:(...w)=>this.handleInputSwipe(...w),handleInputGesture:(...w)=>this.handleInputGesture(...w),captureStrokeAdmission:(...w)=>this.captureStrokeAdmission(...w),strokeAdmissionStillHolds:(...w)=>this.strokeAdmissionStillHolds(...w),liftSessionlessStrokesOn:(...w)=>this.liftSessionlessStrokesOn(...w),liftStrokesHeldByOn:(...w)=>this.liftStrokesHeldByOn(...w),liftStrokesHeldBy:(...w)=>this.liftStrokesHeldBy(...w),handleInputTypeText:(...w)=>this.handleInputTypeText(...w),handleInputPressButton:(...w)=>this.handleInputPressButton(...w),handleInputKey:(...w)=>this.handleInputKey(...w),requireCurrentFrameContext:(...w)=>this.requireCurrentFrameContext(...w),resolveInputTargetDevice:(...w)=>this.resolveInputTargetDevice(...w),captureInputTargetOwner:(...w)=>this.captureInputTargetOwner(...w),runTrackedKeyedDeviceInput:(...w)=>this.runTrackedKeyedDeviceInput(...w),dispatchFencedInput:(...w)=>this.dispatchFencedInput(...w),runTrackedDeviceInput:(...w)=>this.runTrackedDeviceInput(...w),answeringSessionRelease:(...w)=>this.answeringSessionRelease(...w),handleIdeRequest:(...w)=>this.handleIdeRequest(...w),withSocketSessionAutolockKey:(...w)=>this.withSocketSessionAutolockKey(...w),scheduleForwardKeyIdle:(...w)=>this.scheduleForwardKeyIdle(...w),clearForwardKeyIdleTimer:(...w)=>this.clearForwardKeyIdleTimer(...w),evictDeviceInputCache:(...w)=>this.evictDeviceInputCache(...w),isListening:(...w)=>this.isListening(...w),getClientConnectionCount:(...w)=>this.getClientConnectionCount(...w),getAcceptedClientConnectionCount:(...w)=>this.getAcceptedClientConnectionCount(...w),quiesce:(...w)=>this.quiesce(...w),drainSessionReleaseNotifications:(...w)=>this.drainSessionReleaseNotifications(...w),close:(...w)=>this.close(...w)});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=cre;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,w,D){return this.operations.runKeyedMcpForward(d,c,w,D)}getMcpForwardRoute(...d){return this.operations.getMcpForwardRoute(...d)}restoreSelectorSessions(...d){return this.operations.restoreSelectorSessions(...d)}recordBoundMcpClientKey(...d){return this.operations.recordBoundMcpClientKey(...d)}clearBoundMcpClientKey(...d){return this.operations.clearBoundMcpClientKey(...d)}forwardMcpRequest(...d){return this.operations.forwardMcpRequest(...d)}remainingMcpForwardBudget(...d){return this.operations.remainingMcpForwardBudget(...d)}getRequestArgumentScopeKey(...d){return this.operations.getRequestArgumentScopeKey(...d)}handleLocalSocketRequest(...d){return this.operations.handleLocalSocketRequest(...d)}handleIdeSocketRequest(...d){return this.operations.handleIdeSocketRequest(...d)}listBootedDevicesForIdeAction(...d){return this.operations.listBootedDevicesForIdeAction(...d)}runIdeKeyValueMutation(...d){return this.operations.runIdeKeyValueMutation(...d)}toIosRunnerCoordinates(...d){return this.operations.toIosRunnerCoordinates(...d)}handleInputTap(...d){return this.operations.handleInputTap(...d)}handleInputSwipe(...d){return this.operations.handleInputSwipe(...d)}handleInputGesture(...d){return this.operations.handleInputGesture(...d)}captureStrokeAdmission(...d){return this.operations.captureStrokeAdmission(...d)}strokeAdmissionStillHolds(...d){return this.operations.strokeAdmissionStillHolds(...d)}liftSessionlessStrokesOn(...d){return this.operations.liftSessionlessStrokesOn(...d)}liftStrokesHeldByOn(...d){return this.operations.liftStrokesHeldByOn(...d)}liftStrokesHeldBy(...d){return this.operations.liftStrokesHeldBy(...d)}handleInputTypeText(...d){return this.operations.handleInputTypeText(...d)}handleInputPressButton(...d){return this.operations.handleInputPressButton(...d)}handleInputKey(...d){return this.operations.handleInputKey(...d)}requireCurrentFrameContext(...d){return this.operations.requireCurrentFrameContext(...d)}resolveInputTargetDevice(...d){return this.operations.resolveInputTargetDevice(...d)}captureInputTargetOwner(...d){return this.operations.captureInputTargetOwner(...d)}runTrackedKeyedDeviceInput(d,c,w,D){return this.operations.runTrackedKeyedDeviceInput(d,c,w,D)}dispatchFencedInput(d,c,w,D){return this.operations.dispatchFencedInput(d,c,w,D)}runTrackedDeviceInput(d,c,w,D={}){return this.operations.runTrackedDeviceInput(d,c,w,D)}answeringSessionRelease(d,c){return this.operations.answeringSessionRelease(d,c)}handleIdeRequest(...d){return this.operations.handleIdeRequest(...d)}withSocketSessionAutolockKey(...d){return this.operations.withSocketSessionAutolockKey(...d)}scheduleForwardKeyIdle(...d){return this.operations.scheduleForwardKeyIdle(...d)}clearForwardKeyIdleTimer(...d){return this.operations.clearForwardKeyIdleTimer(...d)}evictDeviceInputCache(...d){return this.operations.evictDeviceInputCache(...d)}isListening(...d){return this.operations.isListening(...d)}getClientConnectionCount(...d){return this.operations.getClientConnectionCount(...d)}getAcceptedClientConnectionCount(...d){return this.operations.getAcceptedClientConnectionCount(...d)}quiesce(...d){return this.operations.quiesce(...d)}drainSessionReleaseNotifications(...d){return this.operations.drainSessionReleaseNotifications(...d)}close(...d){return this.operations.close(...d)}get testHooks(){let d=this;return{sessions:this.runtime.sessions,get acceptingRequests(){return d.runtime.acceptingRequests},set acceptingRequests(c){d.runtime.acceptingRequests=c},input:this.callbacks,ide:this.callbacks,transport:this.callbacks,routing:this.callbacks,release:this.callbacks,restoreSelectorSessions:(c,w)=>this.callbacks.restoreSelectorSessions(c,w),getMcpForwardRoute:(c,w)=>this.callbacks.getMcpForwardRoute(c,w),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:Ud(()=>this.callbacks.broadcastListChanged.bind(this),(c)=>{this.callbacks.broadcastListChanged=c}),waitForStartup:Ud(()=>this.callbacks.waitForStartup.bind(this),(c)=>this.callbacks.waitForStartup=c)}}}async function Jf(d){await d.writeEarlyOwnerRecord(),await d.initializeDatabase()}var Ak=200;class jf extends qa{authenticator;auditRepository;constructor(d=Bt(dz),c=i,w=new Om,D={}){super(d,c,"PerformanceStream");this.auditRepository=w,this.authenticator=D.authenticator??An("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:w,sinceId:D}=c,k=await this.auditRepository.listResultsSince(c),P=k.length>0?k[k.length-1]:void 0;return{success:!0,results:k,lastTimestamp:P?.timestamp??w,lastId:P?.id??D}}createPollQuery(d){let c=AU(d.startTime,"startTime"),w=AU(d.endTime,"endTime"),D=AU(d.sinceTimestamp,"sinceTimestamp"),k=kU(d.sinceId),P=TU(d.limit,Ak);return{startTime:c,endTime:w,limit:P,deviceId:d.deviceId?.trim()||void 0,sessionId:d.sessionId?.trim()||void 0,packageName:d.packageName?.trim()||void 0,sinceTimestamp:D,sinceId:k}}createErrorResponse(d,c){return{success:!1,error:c}}}var ed=new Pn;function zf(){return ed.instance?.getSocketPath()??Bt(dz)}async function Yf(){await ed.start(()=>new jf)}async function Xf(){await ed.stop()}var Pk=100,Ck=new XR;function Mk(d){return typeof d==="object"&&d!==null&&"command"in d}class Zf extends qa{authenticator;maxFrameBytes=lre;repository;constructor(d=Bt(lz),c=i,w=Ck,D={}){super(d,c,"FailuresStream");this.repository=w,this.authenticator=D.authenticator??An("failuresStream",{allowObserverSessions:!0})}handleUntypedRequest(d){if(!Mk(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=oy(d.sinceTimestamp,"sinceTimestamp"),w=kU(d.sinceId),D=TU(d.limit,Pk),k=oy(d.startTime,"startTime"),P=oy(d.endTime,"endTime"),C=RE(d.dateRange);if(C&&!k){let F=this.timer.now();P=P??F,k=P-wE(C)}let M=await this.repository.getNotificationsSince({sinceTimestamp:c,sinceId:w,startTime:k,endTime:P,limit:D,type:d.type,acknowledged:d.acknowledged});return{success:!0,notifications:M.notifications,lastTimestamp:M.lastTimestamp,lastId:M.lastId}}async handlePollGroups(d){let c=oy(d.startTime,"startTime"),w=oy(d.endTime,"endTime"),D=RE(d.dateRange);if(D&&!c){let P=this.timer.now();w=w??P,c=w-wE(D)}let k=await this.repository.getAggregatedGroups({startTime:c,endTime:w,type:d.type,severity:d.severity});return{success:!0,groups:k.groups,totals:k.totals}}async handlePollTimeline(d){let c=EU(d.aggregation),w=oy(d.startTime,"startTime"),D=oy(d.endTime,"endTime"),k=RE(d.dateRange),P=this.timer.now();if(k)D=D??P,w=D-wE(k);else D=D??P,w=w??D-86400000;let C=await this.repository.getTimelineData({startTime:w,endTime:D,aggregation:c});return{success:!0,dataPoints:C.dataPoints,previousPeriodTotals:C.previousPeriodTotals}}async handleAcknowledge(d){let c=d.notificationIds;if(!c||!Array.isArray(c))throw Error("notificationIds is required for acknowledge command");for(let w of c)if(typeof w!=="number"||!Number.isInteger(w)||w<0)throw Error(`Invalid notification ID: ${String(w)}`);return await this.repository.acknowledgeNotifications(c),{success:!0,acknowledgedCount:c.length}}}var id=new Pn;function ih(){return id.instance?.getSocketPath()??Bt(lz)}async function oh(){await id.start(()=>new Zf)}async function sh(){await id.stop()}var Ek=1n<<63n,xk=1n<<62n,_k=1n<<61n,Fk=1n<<59n,Nk=1n<<60n,od=59n,l5=0b11n<<od,dh=(1n<<od)-1n;function ch(d=0,c=0){let w=Buffer.allocUnsafe(12);return w.writeInt32BE(1748121140,0),w.writeInt32BE(d,4),w.writeInt32BE(c,8),w}function Di(d,{isConfig:c=!1,isKeyFrame:w=!1,rotation:D=null}={}){let k=d&dh;if(c){if(k|=Ek,D!==null)k|=_k,k|=(BigInt(D)&0b11n)<<od}if(w)k|=xk;return k}function lh(d,c){let w=Buffer.allocUnsafe(12);return w.writeBigInt64BE(BigInt.asIntN(64,d),0),w.writeInt32BE(c,8),w}function gt(d,c){return Buffer.concat([lh(d,c.length),c])}function uh(d){return gt(Fk|BigInt(d)&dh,Buffer.alloc(0))}function ph(){return gt(Nk,Buffer.alloc(0))}var Lk=1n<<61n,$k={downgraded_to_viewer:1,device_removed:2,identity_quarantined:3,daemon_shutdown:4,session_ended:5,device_restored:6};function sd(d){return lh(Lk|BigInt($k[d]),0)}var ad=Buffer.from([0,0,0,1]),dd=30000,qk=500,Uk=8,ld=1000,mh=6000,Ut=9000;function Kk(d){return d.platform==="android"?$4:sQ}class ud{host;deps;captureRegistry;timer;outboundStalls;constructor(d,c,w,{timer:D,outboundStalls:k}){this.host=d;this.deps=c;this.captureRegistry=w;this.timer=D,this.outboundStalls=k}async createSource(d,c,w){let{device:D}=d,k=D.deviceId,P=()=>{if(this.host.getCapture(k)!==d||d.generation!==w)return;if(d.lastSourceDataMs=this.timer.now(),d.firstEvidenceMs??=d.lastSourceDataMs,d.sourceFrameSequence++,d.lastIdleMs=null,d.encodedSinceSourceFrame=!1,!d.heartbeatTimer)this.startHeartbeat(k,d)},C=(M,F)=>{let q=this.host.getCapture(k);if(q!==d||d.generation!==w||M.length===0)return;if(F){if(q.lastEncodedDataMs=this.timer.now(),q.firstEvidenceMs??=q.lastEncodedDataMs,q.encodedSinceSourceFrame=!0,!q.heartbeatTimer)this.startHeartbeat(k,q)}this.broadcast(k,M)};return this.captureRegistry.acquire({device:D,create:(M)=>this.deps.createCaptureSource({...M,onError:M.onError}),hasConsumers:d.pendingSubscribers.size>0||d.subscribers.size>0,flexibleHints:c.fps===void 0?["fps"]:[],options:{device:D,onData:(M)=>C(M,!0),onReplayData:(M)=>C(M,!1),onSourceFrame:P,onSourceIdle:()=>{if(this.host.getCapture(k)!==d||d.generation!==w||!d.encodedSinceSourceFrame)return;d.lastIdleMs=this.timer.now()},onEncodedAccessUnit:()=>{if(this.host.getCapture(k)!==d||d.generation!==w)return;for(let M of d.parser.flush())this.broadcastNal(k,d,M);this.cacheCompletedAccessUnits(d,d.keyFrameAssembler.flush()),d.keyFrameAuBytes=0,d.lastEncodedBoundarySequence=d.sourceFrameSequence},onIdleAttestationSupport:(M)=>{if(this.host.getCapture(k)===d&&d.generation===w&&D.platform==="ios")d.legacySimulatorHelper=!M},onRotation:(M)=>{let F=this.host.getCapture(k);if(F===d&&d.generation===w)F.rotation=M},onDroppedFrames:(M)=>{if(this.host.getCapture(k)!==d||d.generation!==w||!Number.isSafeInteger(M)||M<0||!this.sourceEvidenceIsRecent(d,this.timer.now()))return;let q=uh(M);for(let U of d.subscribers)this.writePacketToSubscriber(k,d,U,{packet:q,isConfig:!1,isKeyFrame:!1})},onError:(M)=>{if(this.host.getCapture(k)===d&&d.generation===w)e.warn(`[VideoStream] capture failed for ${k}: ${M}`),this.host.stopCapture(k)},bitrateBps:c.bitrateKbps?c.bitrateKbps*1000:void 0,size:c.size,quality:c.quality,fps:c.fps??Kk(D)}})}resetForNewEncoder(d){this.clearHeartbeatTimer(d),d.parser=new tc,d.keyFrameAssembler=new _f,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 w=this.host.getCapture(d);if(!w||c.length===0)return;for(let D of w.parser.push(c))this.broadcastNal(d,w,D)}broadcastNal(d,c,w){let D=Is(w);this.cacheCompleteKeyFrame(c,w,D);let k=D===Md||D===Nd;if(D===Md)c.sps=Buffer.from(w);if(D===Nd)c.pps=Buffer.from(w);let P=D===iy,C=k?c.rotation:null,M=gt(Di(this.deps.nowUs(),{isConfig:k,isKeyFrame:P,rotation:C}),Buffer.concat([ad,w]));for(let F of c.subscribers)this.writePacketToSubscriber(d,c,F,{packet:M,isConfig:k,isKeyFrame:P})}cacheCompleteKeyFrame(d,c,w){let D=d.keyFrameAssembler.push(c);if(d.keyFrameAuBytes+=c.length,this.cacheCompletedAccessUnits(d,D),w===Md||w===Nd)d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;if(d.keyFrameAuBytes>JO)d.keyFrameAssembler=new _f,d.keyFrameAuBytes=0}cacheCompletedAccessUnits(d,c){for(let w of c){let D=w.reduce((P,C)=>P+C.length,0);if(d.keyFrameAuBytes-=D,D>JO){d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;continue}let k=Buffer.concat(w.filter((P)=>Is(P)!==Md&&Is(P)!==Nd).flatMap((P)=>[ad,P]));if(w.some((P)=>Is(P)===iy))d.latestKeyFrameAu=k,d.latestInterFrameAus=[],d.cachedGopBytes=k.length;else if(d.latestKeyFrameAu)if(d.cachedGopBytes+k.length>JO)d.latestKeyFrameAu=null,d.latestInterFrameAus=[],d.cachedGopBytes=0;else d.latestInterFrameAus.push(k),d.cachedGopBytes+=k.length}}replayKeyFrame(d,c,w){if(!d.sps||!d.pps||!d.latestKeyFrameAu)return;this.writePacketToSubscriber(w,d,c,{packet:gt(Di(this.deps.nowUs(),{isKeyFrame:!0}),d.latestKeyFrameAu),isConfig:!1,isKeyFrame:!0});for(let D of d.latestInterFrameAus)this.writePacketToSubscriber(w,d,c,{packet:gt(Di(this.deps.nowUs(),{}),D),isConfig:!1,isKeyFrame:!1})}replayCurrentIosKeyFrame(d,c,w){if(d.platform==="ios"&&c.lastIdleMs!==null&&c.encodedSinceSourceFrame&&c.lastEncodedBoundarySequence===c.sourceFrameSequence&&this.timer.now()-c.lastIdleMs<=Ut)this.replayKeyFrame(c,w,d.deviceId)}writePacketToSubscriber(d,c,w,{packet:D,isConfig:k,isKeyFrame:P}){if(w.destroyed){this.host.detach(w);return}if(this.shouldSkipPacket(c,w,k,P))return;if(!w.write(D)){e.debug(`[VideoStream] subscriber is behind on ${d}; dropping to next key frame`),c.backpressuredSubscribers.add(w),c.waitingForKeyFrame.add(w);let C=()=>{let F=this.outboundStalls.get(w);if(!F)return;this.timer.clearTimeout(F.timeout),this.outboundStalls.delete(w);let q=this.host.getCapture(d);if(q!==c||!q.subscribers.has(w))return;q.backpressuredSubscribers.delete(w),this.requestKeyFrameForWaitingSubscriber(d,w)},M=this.timer.setTimeout(()=>{if(!this.outboundStalls.has(w))return;e.warn(`[VideoStream] subscriber stalled on ${d}; detaching`),this.host.detach(w),w.destroy()},this.deps.outboundStallTimeoutMs??dd);this.outboundStalls.set(w,{timeout:M,onDrain:C}),w.once("drain",C)}}shouldSkipPacket(d,c,w,D){if(d.waitingForReplacement.has(c)||d.backpressuredSubscribers.has(c))return!0;if(!d.waitingForKeyFrame.has(c))return!1;if(!D)return!w;if(d.generation>0&&(!d.sps||!d.pps))return!0;return d.waitingForKeyFrame.delete(c),!1}requestKeyFrameForWaitingSubscriber(d,c,w=Uk){let D=this.host.getCapture(d);if(!D)return;if(c.destroyed||!D.waitingForKeyFrame.has(c))return;if(D.waitingForReplacement.has(c))return;let k=D.source;if(!k?.requestKeyFrame)return;if(k.requestKeyFrame()||w<=0)return;this.timer.setTimeout(()=>this.requestKeyFrameForWaitingSubscriber(d,c,w-1),qk)}replayParameterSets(d,c){let w=[d.sps,d.pps].filter((k)=>k!==null);if(w.length===0)return;let D=Buffer.concat(w.flatMap((k)=>[ad,k]));c.write(gt(Di(this.deps.nowUs(),{isConfig:!0,rotation:d.rotation}),D))}clearSubscriberStall(d){let c=this.outboundStalls.get(d);if(c)this.timer.clearTimeout(c.timeout),d.off("drain",c.onDrain),this.outboundStalls.delete(d)}startHeartbeat(d,c){c.heartbeatTimer=this.timer.setInterval(()=>{if(this.host.getCapture(d)!==c||!c.source)return;if(!this.hasFreshSourceEvidence(d,c)){if(this.host.getCapture(d)===c)this.host.stopCapture(d,!0);return}if(c.lastEncodedDataMs===null||c.lastSourceDataMs===null&&!this.idleEvidenceIsRecent(c,this.timer.now()))return;let w=ph();for(let D of c.subscribers){if(D.destroyed||c.waitingForKeyFrame.has(D)||c.backpressuredSubscribers.has(D))continue;D.write(w)}},ld)}hasFreshSourceEvidence(d,c){if(c.lastSourceDataMs===null||c.lastEncodedDataMs===null)return this.incompleteEvidenceIsRecent(c);return this.hasFreshCompleteSourceEvidence(d,c)}incompleteEvidenceIsRecent(d){let c=this.timer.now();return d.source!==null&&d.firstEvidenceMs!==null&&(this.idleEvidenceIsRecent(d,c)||c-d.firstEvidenceMs<Ut)}hasFreshCompleteSourceEvidence(d,c){let{source:w,lastSourceDataMs:D,lastEncodedDataMs:k}=c;if(!w||D===null||k===null)return!1;let P=this.timer.now();if(this.sourceEvidenceIsRecent(c,P)&&c.lastIdleMs!==null)return!0;if(Math.max(P-D,P-k,0)>=mh&&(c.lastLivenessProbeMs===null||P-c.lastLivenessProbeMs>=mh))try{if(w.requestKeyFrame?.("probe"))c.lastLivenessProbeMs=P}catch(M){e.warn(`[VideoStream] liveness key-frame request failed for ${d}: ${M}`)}return this.sourceEvidenceIsRecent(c,P)}sourceEvidenceIsRecent(d,c){if(d.lastSourceDataMs===null||d.lastEncodedDataMs===null)return!1;if(d.legacySimulatorHelper)return!0;if(this.idleEvidenceIsRecent(d,c))return!0;return Math.max(c-d.lastSourceDataMs,c-d.lastEncodedDataMs,0)<=Ut}idleEvidenceIsRecent(d,c){return d.lastIdleMs!==null&&d.encodedSinceSourceFrame&&c-d.lastIdleMs<=Ut}producerEvidenceIsStale(d){let c=this.timer.now();return(d.lastSourceDataMs===null||c-d.lastSourceDataMs>Ut)&&(d.lastIdleMs===null||c-d.lastIdleMs>Ut)}clearHeartbeatTimer(d){if(d.heartbeatTimer)this.timer.clearInterval(d.heartbeatTimer),d.heartbeatTimer=null}}function fh(){return new Pn}function Ai(d){return d!==null&&"setHasConsumers"in d&&typeof d.setHasConsumers==="function"}var Pi="to stream video",Gk=new Set(["low","medium","high"]),hh=5,gh=60,yh=1e6,Sh=3000,bh=200,pd=5000;function md(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 Jn(d,c,w){return Number.isInteger(d)&&d>=c&&d<=w}function Jk(d){return d===void 0||Gk.has(d)?null:`Unsupported quality "${d}"; expected low, medium, or high.`}function jk(d){return d===void 0||Jn(d,hh,gh)?null:`Invalid fps ${d}; expected an integer between ${hh} and ${gh}.`}function zk(d){return d===void 0||Jn(d,1,yh)?null:`Invalid bitrateKbps ${d}; expected an integer between 1 and ${yh}.`}function Yk(d){if(d===void 0)return null;let{width:c,height:w}=d??{};return Jn(c,2,Number.MAX_SAFE_INTEGER)&&Jn(w,2,Number.MAX_SAFE_INTEGER)?null:`Invalid size ${JSON.stringify(d)}; expected integer width/height >= 2.`}function Yn(d){return Xk(d.platform)??Jk(d.quality)??jk(d.fps)??zk(d.bitrateKbps)??Yk(d.size)}function Xk(d){return d===void 0||d==="android"||d==="ios"?null:`Invalid platform ${JSON.stringify(d)}; expected "android" or "ios".`}function Rh(d,c){if(c instanceof Wp)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),...Ic(c)}}async function Dh(d,c,w="either",{timer:D=i,signal:k}={}){return YO(d,c,w,{timer:D,signal:k,source:"video-stream-resolve"})}async function Qk(d,c,w){return Dh(d,c,w)}function kh(d=new si){return{captureRegistry:QO(),ownershipChanges:()=>R.sessionManager()??null,deviceLifecycle:aa,sessionReleases:Si,observerReleases:tb,resolveDevice:(c,w)=>Qk(d,c,w),createCaptureSource:async(c)=>{let w=await _0();return ZO({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},w)},nowUs:()=>BigInt(Math.round(performance.now()*1000))}}var Qn=fh();function fd(){return Qn.instance?.getSocketPath?.()??Bt(mB)}class Ah extends lR{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=Bt(mB),w=i,{authenticator:D=An("video-stream subscribe",{allowObserverSessions:!0}),admissionGate:k=Ns}={}){super(c,w,"VideoStream",{idleTimeoutMs:0});this.deps=d;this.authenticator=D,this.admissionGate=k,this.pipeline=new ud({getCapture:(P)=>this.captures.get(P),detach:(P)=>this.detach(P),stopCapture:(P,C)=>this.stopCapture(P,C)},d,d.captureRegistry??WK(),{timer:w,outboundStalls:this.outboundStalls})}activeDeviceIds(){return[...this.captures.keys()]}subscriberCount(d){let c=this.captures.get(d);return c?c.pendingSubscribers.size+c.subscribers.size:0}async start(){await super.start(),this.removeOwnershipListener=this.deps.ownershipChanges?.()?.onDeviceOwnershipChange((c)=>{this.reauthorizeSubscribers(c)})??null;let d=()=>{for(let c of this.captures.keys())this.reauthorizeSubscribers(c)};this.removeSessionReleaseListener=this.deps.sessionReleases?.subscribe(d)??null,this.removeObserverReleaseListener=this.deps.observerReleases?.subscribe(d)??null,this.subscribeDeviceLifecycle()}subscribeDeviceLifecycle(){let d=this.deps.deviceLifecycle?.();this.removeDeviceRestoredListener=d?.onDeviceRestored((c)=>{this.endDeviceSubscribers(c,"device_restored")})??null,this.removeDeviceRemovedListener=d?.onDeviceRemoved((c)=>{this.endDeviceSubscribers(c,"device_removed")})??null,this.removeIdentityChangedListener=d?.onDeviceIdentityChanged((c)=>{if(!this.captures.has(c))return;try{this.admissionGate.assertDeviceActionable(c,Pi)}catch(w){e.warn(`[VideoStream] identity no longer actionable for ${c}: ${r(w)}`),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:pd,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 ${pd}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 w=this.parseJson(c);if(!w){this.sendJson(d,{type:"video_stream_response",success:!1,error:"Invalid JSON"}),d.end();return}if(w.action!=="subscribe"){this.sendJson(d,{id:w.id,type:"video_stream_response",success:!1,error:`Unsupported video stream action: ${w.action}`}),d.end();return}let D=Yn(w);if(D){this.sendJson(d,{id:w.id,type:"video_stream_response",success:!1,error:D}),d.end();return}this.subscribing.add(d);try{if(this.authenticator.authorize({sessionUuid:w.sessionUuid,deviceId:w.deviceId,admitViewer:!0}),w.deviceId!==void 0)this.admissionGate.assertDeviceActionable(w.deviceId,Pi);let k=await this.deps.resolveDevice(w.deviceId,w.platform);this.admissionGate.assertDeviceActionable(k.deviceId,Pi),Rp(this.authenticator,{sessionUuid:w.sessionUuid,deviceId:k.deviceId,admitViewer:!0});let P=await this.attach(d,k,w);if(P)this.acknowledgeSubscriber(d,P,w)}catch(k){if(e.warn(`[VideoStream] subscribe failed: ${k}`),this.detach(d),!d.destroyed)this.sendJson(d,Rh(w.id,k)),this.endSocketBounded(d)}finally{this.subscribing.delete(d)}}acknowledgeSubscriber(d,c,w){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 Rp(this.authenticator,{sessionUuid:w.sessionUuid,deviceId:c.device.deviceId,admitViewer:!0});if(!this.socketDeviceIds.has(d)||d.destroyed)return;if(this.sendJson(d,{id:w.id,type:"video_stream_response",success:!0,action:"subscribe",deviceId:c.device.deviceId,framing:"h264",heartbeatMs:ld,subscriptionKind:this.socketSubscriptionKinds.get(d)}),d.destroyed){this.detach(d);return}d.write(ch(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 w of[...c.pendingSubscribers,...c.subscribers])this.reconcileSubscriber(w,d)}reconcileSubscriber(d,c){if(!this.socketDeviceIds.has(d))return;let w=this.socketSubscriptionKinds.get(d)??"owner",D={sessionUuid:this.socketSessionUuids.get(d),deviceId:c};try{let k=this.authenticator.resolveSubscriptionIdentity?.(D);if(!k){this.authenticator.authorize({...D,requireOwnership:!0});return}let P=jO({...k,kind:w});if(P.action==="end")this.endSubscriber(d,c,P.reason);else if(P.action==="downgrade"){if(this.socketSubscriptionKinds.set(d,"viewer"),e.info(`[VideoStream] downgraded subscriber: deviceId=${c} kind=viewer reason=downgrade`),this.acknowledgedSubscribers.has(d)&&!d.destroyed)d.write(sd("downgraded_to_viewer"))}}catch(k){this.endSubscriber(d,c,"session_ended",{authorizationError:k})}}endDeviceSubscribers(d,c){let w=this.captures.get(d);if(!w)return;for(let D of[...w.pendingSubscribers,...w.subscribers]){let k=this.socketSubscriptionKinds.get(D)??"owner";this.endSubscriber(D,d,KO({kind:k,event:c}).reason)}}endSubscriber(d,c,w,D={}){if(!this.socketDeviceIds.has(d)&&!this.subscribing.has(d))return;let k=this.socketSubscriptionKinds.get(d),P=`[VideoStream] ending subscriber: deviceId=${c} kind=${k} reason=${w}`;if("authorizationError"in D||w==="device_removed"||w==="identity_quarantined")e.warn(P);else e.info(P);try{if(!d.destroyed){if(this.acknowledgedSubscribers.has(d))d.write(sd(w));this.sendJson(d,{type:"video_stream_response",success:!1,action:"unsubscribe",deviceId:c,terminal:!0,reason:w,subscriptionKind:this.socketSubscriptionKinds.get(d),error:`Video stream ended: ${w} for ${c}`}),this.endSocketBounded(d)}}catch(C){if(e.warn(`[VideoStream] failed to end subscriber for ${c}: ${r(C)}`),!d.destroyed)d.destroy()}finally{this.subscribing.delete(d),this.detach(d)}}endSocketBounded(d){if(d.destroyed||this.endingSockets.has(d))return;let c=()=>{let D=this.endingSockets.get(d);if(D)this.timer.clearTimeout(D.timeout),this.endingSockets.delete(d);d.off("close",c)},w=this.timer.setTimeout(()=>{d.destroy()},this.deps.outboundStallTimeoutMs??dd);this.endingSockets.set(d,{timeout:w,onClose:c}),d.once("close",c),d.end(),d.destroySoon()}checkSubscriberActionable(d,c){try{return this.admissionGate.assertDeviceActionable(c,Pi),!0}catch(w){return e.warn(`[VideoStream] identity no longer actionable for ${c}: ${r(w)}`),this.endSubscriber(d,c,"identity_quarantined"),!1}}async attach(d,c,w){if(this.closed)throw new t("Video stream server is closed");let D=c.deviceId,k=this.pendingStops.get(D);if(k){if(await k,this.closed)throw new t("Video stream server is closed");if(d.destroyed)throw new t(`Video stream subscriber disconnected while stopping ${D}`)}Rp(this.authenticator,{sessionUuid:w.sessionUuid,deviceId:D,admitViewer:!0});let P=this.authenticator.resolveSubscriptionIdentity?.({sessionUuid:w.sessionUuid,deviceId:D}),C=P?wU(P):"owner";if(this.socketSubscriptionKinds.set(d,C),!this.checkSubscriberActionable(d,D))return null;let M=this.captures.get(D);if(M){if(this.clearIdleTimer(M),this.updateDesiredHints({deviceId:D,capture:M,request:w,identity:P,subscriptionKind:C}),M.pendingSubscribers.add(d),Ai(M.source))M.source.setHasConsumers(!0);return this.socketDeviceIds.set(d,D),this.socketSessionUuids.set(d,w.sessionUuid),this.socketSubscriptionKinds.set(d,C),await M.startup,this.promoteSubscriber(M,d,!0),this.scheduleReconfigure(D,M),M}let F=md(C,P)?w:{},q={device:c,desiredHints:{quality:F.quality,fps:F.fps,bitrateKbps:F.bitrateKbps,size:F.size},appliedHints:{quality:F.quality,fps:F.fps,bitrateKbps:F.bitrateKbps,size:F.size},hintKind:C,generation:0,reconfigureTimer:null,reconfiguring:null,source:null,startup:Promise.resolve(),pendingSubscribers:new Set([d]),subscribers:new Set,backpressuredSubscribers:new Set,waitingForKeyFrame:new Set,waitingForReplacement:new Set,sps:null,pps:null,parser:new tc,keyFrameAssembler:new _f,keyFrameAuBytes:0,latestKeyFrameAu:null,latestInterFrameAus:[],cachedGopBytes:0,sourceFrameSequence:0,lastEncodedBoundarySequence:null,rotation:null,idleTimer:null,heartbeatTimer:null,firstEvidenceMs:null,lastSourceDataMs:null,lastIdleMs:null,encodedSinceSourceFrame:!1,legacySimulatorHelper:!1,lastEncodedDataMs:null,lastLivenessProbeMs:null};return this.captures.set(D,q),this.socketDeviceIds.set(d,D),this.socketSessionUuids.set(d,w.sessionUuid),this.socketSubscriptionKinds.set(d,C),q.startup=(async()=>{try{let U=await this.pipeline.createSource(q,q.appliedHints,q.generation);if(this.captures.get(D)!==q||!this.hasSubscribers(q)&&!q.idleTimer)throw await U.stop().catch((K)=>{e.warn(`[VideoStream] failed to stop abandoned capture for ${D}: ${K}`)}),new t(`Video capture for ${D} was stopped during startup.`);if(q.source=U,Ai(U))U.setHasConsumers(this.hasSubscribers(q));if(await U.start(),this.captures.get(D)!==q||!this.hasSubscribers(q)&&!q.idleTimer)throw q.source=null,await U.stop().catch((K)=>{e.warn(`[VideoStream] failed to stop abandoned capture for ${D}: ${K}`)}),new t(`Video capture for ${D} was stopped during startup.`)}catch(U){if(this.pipeline.clearHeartbeatTimer(q),this.captures.get(D)===q)this.captures.delete(D);throw u(U,`Failed to start video capture for ${D}`)}})(),await q.startup,this.promoteSubscriber(q,d,!0),q}updateDesiredHints({deviceId:d,capture:c,request:w,identity:D,subscriptionKind:k}){if(!md(k,D))return;let P=k==="owner"&&c.hintKind==="viewer",C=P?{}:c.desiredHints;if(k==="owner")c.hintKind="owner";if(c.desiredHints={quality:w.quality??C.quality,fps:w.fps??C.fps,bitrateKbps:w.bitrateKbps??C.bitrateKbps,size:P?w.size:C.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 w=this.reconfigureCapture(d,c,{...c.desiredHints});c.reconfiguring=w,w.finally(()=>{c.reconfiguring=null,this.releaseReplacementWaiters(c),this.scheduleReconfigure(d,c)})},bh)}retainSharedHints(d,c){if(!d.source||!TJ(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,w){let D=c.source;if(!D||this.captures.get(d)!==c)return;if(this.retainSharedHints(c,w))return;c.generation++,c.source=null,this.pipeline.resetForNewEncoder(c);try{if(await D.stop(),this.captures.get(d)!==c)return;let k=await this.pipeline.createSource(c,w,c.generation);if(this.captures.get(d)!==c){await k.stop();return}if(c.source=k,Ai(k))k.setHasConsumers(this.hasSubscribers(c));if(await k.start(),this.captures.get(d)!==c){await k.stop();return}c.appliedHints=w,e.info(`[VideoStream] ${d} shared capture quality changed`);let P=c.waitingForKeyFrame.values().next().value;if(P)this.pipeline.requestKeyFrameForWaitingSubscriber(d,P)}catch(k){if(e.warn(`[VideoStream] failed to reconfigure capture for ${d}: ${k}`),this.captures.get(d)===c)c.source??=D,this.stopCapture(d)}}hasSubscribers(d){return d.pendingSubscribers.size>0||d.subscribers.size>0}promoteSubscriber(d,c,w){if(c.destroyed){d.pendingSubscribers.delete(c);return}if(!d.pendingSubscribers.delete(c))return;if(d.subscribers.add(c),w)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 w=this.captures.get(c);if(!w)return;if(w.pendingSubscribers.delete(d),w.subscribers.delete(d),w.backpressuredSubscribers.delete(d),w.waitingForKeyFrame.delete(d),w.waitingForReplacement.delete(d),!this.hasSubscribers(w)){if(w.reconfigureTimer)this.timer.clearTimeout(w.reconfigureTimer),w.reconfigureTimer=null;if(Ai(w.source))w.source.setHasConsumers(!1);this.clearIdleTimer(w),w.idleTimer=this.timer.setTimeout(()=>{if(w.idleTimer=null,this.captures.get(c)===w&&!this.hasSubscribers(w))this.stopCapture(c)},Sh)}}clearIdleTimer(d){if(d.idleTimer)this.timer.clearTimeout(d.idleTimer),d.idleTimer=null}stopCapture(d,c=!1){let w=this.pendingStops.get(d);if(w)return w;let D=this.captures.get(d);if(!D)return Promise.resolve();if(this.captures.delete(d),this.clearIdleTimer(D),this.pipeline.clearHeartbeatTimer(D),D.reconfigureTimer)this.timer.clearTimeout(D.reconfigureTimer),D.reconfigureTimer=null;for(let P of[...D.pendingSubscribers,...D.subscribers])this.detach(P),this.endSocketBounded(P);D.pendingSubscribers.clear(),D.subscribers.clear(),D.backpressuredSubscribers.clear(),D.waitingForKeyFrame.clear(),D.waitingForReplacement.clear();let k=(async()=>{try{try{if(c&&D.source)await kJ(D.source,this.pipeline.producerEvidenceIsStale(D));else await D.source?.stop()}catch(P){e.warn(`[VideoStream] failed to stop capture for ${d}: ${P}`)}try{await D.startup}catch(P){e.debug(`[VideoStream] startup settled during stop for ${d}: ${P}`)}await D.reconfiguring}finally{this.pendingStops.delete(d)}})();return this.pendingStops.set(d,k),k}}async function Ph(d){await Qn.start(()=>new Ah(kh(d?.getPlatformDeviceManager())))}async function Ih(){await Qn.stop()}function ot(){return{control:Lt,appearance:OK(),"device-snapshot":xK(),"failures-push":Nie(),"failures-stream":ih(),"observation-stream":xne(),"performance-push":Wne(),"performance-stream":zf(),"telemetry-push":Tne(),"device-gesture-recording":EK(),"video-recording":AK(),"video-stream":fd(),"webrtc-stream":FK()}}import Zk from"fs";import be from"path";var eA="terminal-release-intents.jsonl",Th="terminal-release-intents",gd=".jsonl";function Ch(d,c){return be.join(d,Th,`${encodeURIComponent(c)}${gd}`)}function tA(d,c,w){let D;try{D=JSON.parse(d)}catch(k){e.warn(`[TerminalReleaseJournal] Discarded corrupt line ${c} of ${w}: ${r(k)}`,k);return}if(typeof D==="object"&&D!==null){let k=D,{sessionId:P,reason:C,at:M}=k;if(typeof P==="string"&&P.length>0){if(k.lifted===!0)return{kind:"lifted",sessionId:P};if(typeof C==="string"&&C.length>0&&Number.isFinite(M))return{kind:"intent",intent:{sessionId:P,reason:C,at:M}}}}e.warn(`[TerminalReleaseJournal] Discarded corrupt line ${c} of ${w}: invalid journal record`);return}function Mh(d,c,w){let D=!1;for(let[k,P]of d.entries()){let C=tA(P,k+1,w);if(C?.kind==="intent")c.set(C.intent.sessionId,C.intent);else if(C?.kind==="lifted")c.delete(C.sessionId);else D=!0}return D}function iA(d){return`${JSON.stringify({sessionId:d,lifted:!0})}
|
|
39
|
+
`}function vd(d){return`${JSON.stringify({sessionId:d.sessionId,reason:d.reason,at:d.at})}
|
|
40
|
+
`}class Eh{filePath;fileSystem;peerJournalPath;intents=new Map;loaded=!1;directorySynced=!1;constructor(d,c,w){this.filePath=d;this.fileSystem=c;this.peerJournalPath=w}loadUnconfirmed(){return this.ensureLoaded(),Array.from(this.intents.values())}readDeadDaemon(d){let c=this.peerPath(d);return c===void 0?[]:Oh(c,this.fileSystem)}discardDeadDaemon(d){let c=this.peerPath(d);if(c===void 0)return;try{this.fileSystem.remove(c)}catch(w){e.warn(`[TerminalReleaseJournal] Could not remove the settled journal ${c}: `+r(w),w)}}peerPath(d){let c=this.peerJournalPath?.(d);return c===this.filePath?void 0:c}record(d){this.ensureLoaded(),this.intents.set(d.sessionId,d);try{return this.appendDurable(vd(d)),"durable"}catch(c){return e.warn(`[TerminalReleaseJournal] Failed to record the terminal release intent of session ${d.sessionId}: ${r(c)}`,c),"volatile"}}resolve(d,c){let w=this.ensureLoaded(),D=this.intents.get(d);if(!D||c!==void 0&&D.reason!==c)return;if(this.intents.delete(d),w&&this.compact(this.intents))return;try{this.appendDurable(iA(d))}catch(k){e.warn(`[TerminalReleaseJournal] Failed to record the lifted fence of session ${d}: `+r(k),k)}}appendDurable(d){this.fileSystem.appendDurable(this.filePath,d,!this.directorySynced),this.directorySynced=!0}ensureLoaded(){if(this.loaded)return!0;let d;try{d=this.fileSystem.readText(this.filePath)}catch(w){return e.warn(`[TerminalReleaseJournal] Failed to read ${this.filePath}; unconfirmed terminal releases from a previous daemon cannot be applied yet: ${r(w)}`,w),!1}this.loaded=!0;let c=new Map(this.intents);if(this.intents.clear(),d!==void 0)this.replay(d);for(let[w,D]of c)this.intents.set(w,D);return!0}replay(d){let c=d.split(`
|
|
41
|
+
`),w=c.pop()??"",D=Mh(c,this.intents,this.filePath)||w.length>0;if(w.length>0)e.warn(`[TerminalReleaseJournal] Discarded a torn tail of ${this.filePath}; ${this.intents.size} intent(s) kept`);if(D||c.length!==this.intents.size)this.compact(this.intents)}compact(d){try{if(d.size===0)this.fileSystem.remove(this.filePath),this.directorySynced=!1;else this.fileSystem.replaceDurable(this.filePath,Array.from(d.values(),vd).join(""));return!0}catch(c){return e.warn(`[TerminalReleaseJournal] Failed to compact ${this.filePath}: ${r(c)}`,c),!1}}}function nA(d=Zk,c=process.platform){let w=(D,k)=>{let P=d.openSync(D,k);try{d.fsyncSync(P)}finally{d.closeSync(P)}};return{listNames(D){try{return d.readdirSync(D).sort(BO)}catch(k){if(k.code==="ENOENT")return[];throw k}},readText(D){try{return d.readFileSync(D,"utf-8")}catch(k){if(k.code==="ENOENT")return;throw k}},appendDurable(D,k,P=!0){let C=d.mkdirSync(be.dirname(D),{recursive:!0,mode:448}),M=d.openSync(D,"a",384);try{d.writeSync(M,k),d.fsyncSync(M)}finally{d.closeSync(M)}if(P&&c!=="win32"){if(w(be.dirname(D),"r"),C!==void 0){w(be.dirname(C),"r");let F=be.relative(C,be.dirname(D)),q=C;for(let U of F?F.split(be.sep):[])q=be.join(q,U),w(be.dirname(q),"r")}}},replaceDurable(D,k){let P=`${D}.${process.pid}.tmp`,C=d.openSync(P,"w",384);try{d.writeSync(C,k),d.fsyncSync(C)}finally{d.closeSync(C)}try{d.renameSync(P,D)}catch(M){throw d.rmSync(P,{force:!0}),M}if(c!=="win32")w(be.dirname(D),"r")},remove(D){d.rmSync(D,{force:!0})}}}var rA=nA();function Bh(d){let c=d.dataDir??$p(),w=d.fileSystem??rA,D=Ch(c,d.daemonSessionId);return aA(D,oA(c,d,w),w),new Eh(D,w,(k)=>Ch(c,k))}function oA(d,c,w){let D=new Set(c.liveDaemonSessionIds);D.delete(c.daemonSessionId);let k=D.size===0?[be.join(d,eA)]:[],P=be.join(d,Th),C;try{C=w.listNames(P)}catch(M){return e.warn(`[TerminalReleaseJournal] Failed to list ${P}; terminal releases of earlier daemons are applied by a later startup: ${r(M)}`,M),k}for(let M of C){if(!M.endsWith(gd))continue;let F=sA(M.slice(0,-gd.length));if(F!==void 0&&F!==c.daemonSessionId&&!D.has(F))k.push(be.join(P,M))}return k}function sA(d){try{return decodeURIComponent(d)}catch(c){e.debug(`[TerminalReleaseJournal] Ignoring journal file ${d}: ${r(c)}`);return}}function Oh(d,c){let w;try{w=c.readText(d)}catch(k){e.warn(`[TerminalReleaseJournal] Failed to read ${d}; its terminal releases are applied by a later startup: ${r(k)}`,k);return}let D=new Map;if(w!==void 0){let k=w.split(`
|
|
42
|
+
`),P=k.pop()??"";if(Mh(k,D,d),P.length>0)e.warn(`[TerminalReleaseJournal] Discarded a torn tail of ${d}`)}return Array.from(D.values())}function aA(d,c,w){for(let D of c){let k=Oh(D,w);if(k===void 0)continue;if(k.length>0)try{w.appendDurable(d,k.map(vd).join(""))}catch(P){e.warn(`[TerminalReleaseJournal] Failed to adopt ${D}; its terminal releases are applied by a later startup: ${r(P)}`,P);continue}try{w.remove(D)}catch(P){e.warn(`[TerminalReleaseJournal] Adopted but could not remove ${D}: ${r(P)}`,P)}}}function Zn(d,c,w){if(!c.isIosPassiveWorkEnabled())return[];let D=d.filter((P)=>P.platform==="ios"&&c.allows("ios","startup-warmup",P.id)),k=D.filter((P)=>w?.(P.id));if(k.length>0)e.info(`[Daemon] Skipping gated CtrlProxy iOS warm-up devices: ${k.map((P)=>P.id).join(", ")}`);return D.filter((P)=>!k.includes(P))}async function xh(d,c,w){let D=Symbol("iOS startup budget");try{return await l(d,{timer:c,timeoutMs:w,unref:!0,label:"iOS startup budget",timeoutError:()=>D}),!0}catch(k){if(k!==D)throw k;return!1}}async function er(d,c){let w={ready:[],deferred:[]},D=c.pendingPrefetch();if(D!==null){if(e.info(`[Daemon] CtrlProxy iOS runner prefetch in flight; waiting up to ${c.perDeviceTimeoutMs}ms before verifying ${d.length} iOS device(s)`),!await xh(D,c.timer,c.perDeviceTimeoutMs))return e.info(`[Daemon] CtrlProxy iOS runner prefetch still in flight after ${c.perDeviceTimeoutMs}ms; deferring CtrlProxy iOS setup for ${d.length} iOS device(s) to the first tool call`),w.deferred.push(...d),w}return await Promise.all(d.map(async(k)=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Skipping CtrlProxy iOS startup for ${k}: daemon shutdown is in progress`);return}e.info(`[Daemon] Setting up CtrlProxy iOS for iOS device ${k}`);try{let P=c.verifyIosDevice(k,{skipCtrlProxyDownload:!0});if(!await xh(P,c.timer,c.perDeviceTimeoutMs)){e.warn(`[Daemon] CtrlProxy iOS warm-up timed out for ${k}: phase=runner-setup after ${c.perDeviceTimeoutMs}ms; deferring to the resident startup`),w.deferred.push(k),P.then(()=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Deferred CtrlProxy iOS startup for ${k} completed after daemon shutdown began; ignoring`);return}e.info(`[Daemon] Deferred CtrlProxy iOS startup completed for ${k} after warm-up timeout`)},(C)=>{if(c.isShuttingDown?.()??!1){e.info(`[Daemon] Deferred CtrlProxy iOS startup for ${k} failed after daemon shutdown began; ignoring: ${r(C)}`);return}e.warn(`[Daemon] Deferred CtrlProxy iOS startup failed for ${k}: ${r(C)}`,C)});return}await P,e.info(`[Daemon] CtrlProxy iOS ready for iOS device ${k}`),w.ready.push(k)}catch(P){if(P instanceof Tk)e.info(`[Daemon] Deferring CtrlProxy iOS setup for ${k} to the first tool call: ${P.message}`),w.deferred.push(k);else e.warn(`[Daemon] Failed to initialize CtrlProxy iOS for ${k}: ${P}`)}})),w}async function yd(d,c){if(await c(d))return d;let w=d>=Dw&&d<=Mv,D=w?Array.from({length:Mv-d},(k,P)=>d+1+P):[];for(let k of D)if(await c(k))return k;if(!w)throw Error(`Port ${d} is not available (outside the fallback range ${Dw}-${Mv})`);throw Error(D.length===0?`Port ${d} is not available (no higher port in the fallback range ${Dw}-${Mv})`:`No available ports in range ${d}-${Mv}`)}var _h={"enter process":"process entry","entered daemon process":"process entry","tool-call-end activity subscription":"process entry","forward lease owner":"process entry","database prologue":"incumbent window","terminal release journal":"incumbent window","binding registry":"incumbent window","daemon collaborators":"incumbent window","http token prepare":"incumbent window","http ingress":"incumbent window","device discovery":"incumbent window","session rehydration":"incumbent window","session broker":"incumbent window","iOS services":"incumbent window","recorder teardown redrive":"incumbent window","control socket bind":"incumbent window","socket bind commit":"incumbent window","http token publish":"incumbent window","background registry upgrade":"after bind","session broker recovery":"after bind","services after socket bind":"after bind","heartbeat monitor":"after bind","maintenance monitors":"after bind","startup report":"after bind","startup failure tracker reset":"after bind"};async function Sd(d,c=()=>{}){for(let w of d)try{let D=w.run();if(D instanceof Promise)await D}catch(D){throw c(w.name),D}}function de(d,c){return{name:d,run:c}}class bd{host;sessionBrokerRecovery;androidAvdProvenanceWarmPromise;startupLiveDaemonSessionIds=new Set;constructor(d){this.host=d}applyRuntimeOptions(d){if(d.networkMockable)N.setNetworkMockableEnabled(!0);if(d.dismissKeyboardAfterInput)N.setDismissKeyboardAfterInputEnabled(!0);if(d.eventAllMarkers&&d.eventAllMarkers.length>0)N.setEventAllMarkers(d.eventAllMarkers);if(d.debugPerf)fB(!0);if(d.noUiPerfMode)N.setUiPerfMode(!1);if(d.noNavigationScreenshots)N.setNavigationScreenshotsEnabled(!1);if(d.noWaitForPollingOverhead)N.setWaitForPollingOverheadEnabled(!1);if(d.memPerfAudit)N.setMemPerfAuditMode(!0);if(d.predictiveUi)N.setPredictiveUiEnabled(!0)}applyAccessibilityOptions(d){if(d.rawElementSearch)N.setRawElementSearchEnabled(!0);if(d.skipCtrlProxyDownload)N.setSkipCtrlProxyDownload(!0);if(d.runnerReadinessTimeoutMs!==void 0)N.setRunnerReadinessTimeoutMs(d.runnerReadinessTimeoutMs);if(d.noA11yIncludeNotImportantViews)N.setA11yIncludeNotImportantViews(!1);if(d.noA11yReportViewIds)N.setA11yReportViewIds(!1);if(d.noA11yRetrieveInteractiveWindows)N.setA11yRetrieveInteractiveWindows(!1);if(d.noOcclusion)N.setOcclusionEnabled(!1)}async start(){await this.host.startOn(this.processStartHost())}async startOn(d){this.host.setStartHost(d),this.host.setEnteredDaemonProcess(!1);try{await this.startUntilReady(),this.host.resolveStartupCompletion()()}catch(c){throw this.host.lifecycle.selfExitRecorder().record("startup-failure"),this.host.rejectStartupCompletion()(c),c}}async startUntilReady(){await this.host.startThroughSocketBind();try{await this.host.startAfterSocketBind()}catch(d){throw e.error(`Daemon startup failed after the socket bind; stopping: ${r(d)}`),this.host.rejectStartupCompletion()(d),await this.host.stopAfterFailedStartup(),d}}async stopAfterFailedStartup(){if(this.host.lifecycle.shutdownInProgress())return;let d=Symbol("post-bind startup failure stop timeout");try{await l(()=>this.host.stop(),{timer:this.host.services.timer(),timeoutMs:a0,label:"Post-bind startup failure stop",timeoutError:()=>d})}catch(c){e.warn(c===d?`Stopping after a failed startup exceeded ${a0}ms`:`Stopping after a failed startup failed: ${r(c)}`,c)}}processStartHost(){return{writeExitRecord:(d)=>e7(Lt,d,this.host.exitRecordFileSystem()),enterProcess:()=>this.host.enterDaemonProcess(),publishForwardLeaseOwner:()=>{Ire(Lt)},writeEarlyOwnerRecord:()=>this.host.writeEarlyOwnerRecord(),openTerminalReleaseJournal:(d)=>Bh(d),prepareHttpToken:()=>this.host.prepareHttpToken(),publishHttpToken:()=>this.host.publishHttpToken(),startHttpIngress:()=>this.host.startHttpIngress(),sweepStaleAppearanceConfigs:async(d)=>{await um(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 CM;return await this.host.redriveUnconfirmedCaptureTeardowns(this.host.services.sessionManager(),{recordingRepository:d.recordingRepository,liveDaemonSessionIds:new Set([...d.liveDaemonSessionIds].filter((w)=>w!==this.host.identity.daemonSessionId())),ownedCaptureIds:()=>d.videoRecorderService.listActiveRecordingIds(),onStartupOrphans:this.host.setStartupOrphanCaptures,onDeviceProcessStarted:(w)=>this.host.services.devicePool().setDeviceProcessStartedListener(w),onDeviceIncarnationAssigned:(w)=>{this.host.lifecycle.setRecorderDeviceIncarnationListener(w)},getDeviceIncarnation:(w)=>this.host.services.devicePool().getDeviceIncarnation(w),getDevice:(w)=>{let D=this.host.services.devicePool().getDevice(w);return D?{deviceId:D.id,name:D.name,platform:D.platform}:void 0},forceStopOrphanedCapture:(w,D,k)=>k?c.forceStopOrphanedCapture(w,D,k):c.forceStopOrphanedCapture(w,D),now:()=>this.host.services.timer().now(),timer:this.host.services.timer()})}catch(d){return e.warn("[Daemon] Recorder teardown initialization failed; continuing startup",d),!1}},bindControlSocket:()=>this.host.bindControlSocket(),startServicesAfterSocketBind:()=>this.host.startServicesAfterSocketBind(),startMaintenanceMonitors:()=>this.host.startMaintenanceMonitors()}}enterDaemonProcess(){mae(vm),e.enableStdoutLogging();let d=gU();process.env[Ub]??=$O(d),hae(),process.chdir(d),e.info("Starting AutoMobile daemon..."),this.host.setupShutdownHandlers()}async startThroughSocketBind(){await Sd(this.startThroughSocketBindStages(),(d)=>{if(_h[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",()=>Dt.runPhase("daemonDatabaseInitialization",()=>Jf({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..."),Dt.startPhase("deviceDiscovery"),await this.host.initializeDevicePoolWithTimeout(5000),Dt.endPhase("deviceDiscovery")}),de("session rehydration",()=>this.rehydrateStartupSessions()),de("session broker",async()=>{this.sessionBrokerRecovery=await this.host.installSessionBroker()}),de("iOS services",()=>Dt.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(),Dt.endPhase("socketServerStart")}),de("background registry upgrade",()=>{if(e.info("Unix socket server started"),!this.host.lifecycle.sessionBrokerConfigPath()&&th())this.host.startBackgroundRegistryUpgrade()})]}prepareStartupBindingRegistry(){if(this.host.lifecycle.sessionBrokerConfigPath()!==void 0)return Tp({brokerConfigured:!0,registryExists:th(),open:()=>this.host.openBindingRegistry()});if(th())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 Dt.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()));Dt.startPhase("httpServerStart"),await this.host.services.httpIngress().start(),Dt.endPhase("httpServerStart")}async bindControlSocket(){return e.info(`Daemon host: "${this.host.host()}", port: ${this.host.identity.port()}`),e.info(`MCP_STREAMABLE_PATH: "${Mw}"`),e.info(`Creating UnixSocketServer at "${Lt}"`),this.host.lifecycle.setSocketServer(new Ri(Lt,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:br,sockets:ot(),dbPath:Dp(),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..."),Dt.startPhase("socketServerStart"),await this.host.lifecycle.socketServer().start(),this.host.recordControlSocketIdentity(),this.host.lifecycle.socketServer()}async startServicesAfterSocketBind(){Dt.startPhase("auxiliarySocketServerStart"),await this.host.startAuxiliarySocket("video-recording",TK),await this.host.startAuxiliarySocket("device-gesture-recording",()=>IK(this.host.services.deviceReadiness())),await this.host.startAuxiliarySocket("device-snapshot",CK),await this.host.startAuxiliarySocket("appearance",MK),await this.host.startAuxiliarySocket("performance-stream",Yf),await this.host.startAuxiliarySocket("observation-stream",()=>qz(this.host.services.timer())),this.host.configureDeviceDataStreamServer(),await this.host.startAuxiliarySocket("performance-push",zne),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("failures-stream",oh),await this.host.startAuxiliarySocket("failures-push",Fie),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("telemetry-push",kne),this.host.setupDeviceSessionRouting(),await this.host.startAuxiliarySocket("webrtc-stream",LK),await this.host.startAuxiliarySocket("video-stream",()=>Ph(this.host.services.deviceReadiness())),Dt.endPhase("auxiliarySocketServerStart"),$K({getTargets:()=>this.host.getAppearanceSyncTargets(),isEnabled:()=>this.host.services.passiveWorkPolicy().isAppearanceSyncEnabled(),beforeApply:(d)=>qd(d,["nightMode"])}),xY(),this.host.startAdbMissingDeviceListener(),this.host.startDeviceDisconnectMonitor(),await this.host.writePidFile(),this.host.identity.setCompleteIdentityPublished(!0),e.info(`DaemonState initialized: ${this.host.services.daemonState().isInitialized()}, device count: ${this.host.services.devicePool().getTotalDeviceCount()}`),this.host.startHealthCheckTimer()}startMaintenanceMonitors(){this.host.startNavigationRetentionMonitor(),this.host.startForwardLeaseIdleReleaser(),this.host.startPrivateDaemonOrphanWatchdog()}async startAfterSocketBind(){await Sd(this.startAfterSocketBindStages())}startAfterSocketBindStages(){return[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",()=>{Dt.emit("daemon",{host:this.host.host(),port:this.host.identity.port(),socketPath:Lt,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 ${Lt}, HTTP port ${this.host.identity.port()}`)}),de("startup failure tracker reset",()=>{this.host.startupFailureTracker().reset()})]}warmAndroidAvdProvenanceCache(){this.androidAvdProvenanceWarmPromise=Promise.resolve().then(()=>Rs.getInstance().getByName(this.host.avdManagerFactory()(),this.host.services.timer())).catch((d)=>{e.debug(`Android AVD provenance startup warm failed: ${r(d)}`)})}async findAvailablePort(d){return yd(d,(c)=>this.isPortAvailable(c))}async isPortAvailable(d){return new Promise((c)=>{let w=dA(),D=!1,k=i.setTimeout(()=>{if(!D)D=!0,w.close(()=>{}),c(!1)},1000);w.once("error",()=>{if(!D)D=!0,clearTimeout(k),c(!1)}),w.listen(d,this.host.host(),()=>{if(!D)D=!0,clearTimeout(k),w.close(()=>{c(!0)})})})}async initializeDevicePoolWithTimeout(d){let c=Symbol("device pool initialization timeout");try{await l(()=>this.host.initializeDevicePool(),{timer:this.host.services.timer(),timeoutMs:d,unref:!0,label:"Device pool initialization",timeoutError:()=>c})}catch(D){if(D!==c)throw D;e.warn(`Device pool initialization timed out after ${d}ms`)}let w=this.host.services.devicePool().getTotalDeviceCount();if(w===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 ${w} device(s)`)}async initializeDevicePool(){try{let d=await this.host.services.devicePool().refreshDevicesWithOutcome(),c=this.host.services.devicePool().getAllDevices();if(c.length>0){let w=this.host.services.devicePool().getAllDevices().filter((D)=>cr(D.platform));for(let D of w)this.host.services.deviceSessionRegistry().onDeviceConnected({deviceId:D.id,platform:D.platform,incarnation:D.incarnation});e.info(`Device pool initialized with ${c.length} devices: ${c.map((D)=>D.id).join(", ")}`)}else if(d.failure===void 0)e.warn("No devices detected during daemon startup. Device pool is empty."),e.warn("Start an emulator or connect a physical device before creating sessions.")}catch(d){e.error(`Failed to initialize device pool: ${d}`)}}async initializeIosServices(){if(!this.host.services.passiveWorkPolicy().isIosPassiveWorkEnabled()){e.info("[Daemon] Skipping iOS CtrlProxy warm-up for live acceptance");return}let d=Zn(this.host.services.devicePool().getAllDevices(),this.host.services.passiveWorkPolicy(),(w)=>{let D=this.host.services.sessionManager().getSessionForDevice(w);return D!==null&&this.host.lifecycle.managedExecutionReowner()?.ownershipState(D)!==void 0});if(d.length===0){e.debug("[Daemon] No iOS devices to initialize CtrlProxy iOS for");return}e.info(`[Daemon] Initializing CtrlProxy iOS for ${d.length} iOS device(s)...`);let c=this.host.services.iosDeviceVerifier()();await er(d.map((w)=>w.id),{timer:this.host.services.timer(),perDeviceTimeoutMs:5000,pendingPrefetch:()=>it.pendingPrefetch(),isShuttingDown:()=>this.host.lifecycle.shutdownInProgress(),verifyIosDevice:(w,D)=>c.verifyIosDevice(w,D)})}async initializeDatabase(){try{await this.host.databaseInitializer().initialize(),await this.host.toolSelectionProfileProvenanceLoader().load();let d=new Set(this.host.identity.incumbentOwnerGuard().withLiveIncumbent(this.host.liveDaemonSessionIdProvider().collectLiveDaemonSessionIds()));this.startupLiveDaemonSessionIds=d,await this.host.services.installedAppsRepository().clearOldDaemonSessions(this.host.identity.daemonSessionId(),d),await this.host.services.deviceSessionRepository().markStaleActiveSessionsExpired(this.host.identity.daemonSessionId(),this.host.services.timer().now(),$I,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 PU(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 Nh(d,c){if(d.observeResultIncludeElements)N.setObserveResultIncludeElementsEnabled(!0);if(d.toolResultsNoStructuredContent)N.setToolResultsNoStructuredContentEnabled(!0);if(d.actionsDiffObserve)N.setActionsDiffObserveEnabled(!0);if(d.actionsCompactMetadata!==void 0)N.setActionsCompactMetadataEnabled(d.actionsCompactMetadata);if(c.actionsCompactMetadata=N.isActionsCompactMetadataEnabled(),d.actionsNoObserve)N.setActionsNoObserveEnabled(!0);if(d.toolOutputsDir)N.setToolOutputsDir(d.toolOutputsDir)}import{writeSync as mA}from"fs";import{mkdir as fA}from"fs/promises";import{dirname as hA,isAbsolute as vA}from"path";class Rd{boundSocketIdentities=new Map;host;files;platform;databasePath;reportStartupFailure;constructor(d,c={stat:pg},w=process.platform,{databasePath:D=Dp,reportStartupFailure:k=(P)=>{mA(2,`${P}
|
|
43
|
+
`)}}={}){this.host=d,this.files=c,this.platform=w,this.databasePath=D,this.reportStartupFailure=k}async persistPidFileData(d,c){await fA(hA(br),{recursive:!0}),c?.throwIfAborted(),await xre(br,d,c),this.host.setPidFileWritten(!0)}async writeEarlyOwnerRecord(){if(!ul())await ll();this.host.identity.incumbentOwnerGuard().captureIncumbentBeforeOverwrite();let d=this.host.identity.incumbentOwnerGuard().supersededOwnerForEarlyRecord(),c={pid:process.pid,launchNonce:I(f.DAEMON_LAUNCH_NONCE),daemonSessionId:this.host.identity.daemonSessionId(),socketPath:Lt,port:this.host.identity.port(),dbPath:this.databasePath(),startedAt:this.host.identity.generationStartedAt(),processStartedAt:this.host.identity.processStartedAt(),...wd(this.host.identity.processGenerationToken()),version:ri,launchLogPath:this.launchLogPath(),assetVersion:sn(De()),options:this.host.services.options(),...d===void 0?{}:{supersededOwner:d}};await this.host.persistPidFileData(c),this.host.identity.incumbentOwnerGuard().recordContenderEarlyOwner(c),e.info(`Early daemon owner record written to ${br} (dbPath ${c.dbPath})`)}async writePidFile(d){if(!ul())await ll();d?.throwIfAborted();let c=Ho(),w={pid:process.pid,launchNonce:I(f.DAEMON_LAUNCH_NONCE),daemonSessionId:this.host.identity.daemonSessionId(),socketPath:Lt,sockets:IB(ot()),port:this.host.identity.port(),dbPath:this.databasePath(),startedAt:this.host.identity.generationStartedAt(),processStartedAt:this.host.identity.processStartedAt(),...wd(this.host.identity.processGenerationToken()),version:ri,launchLogPath:this.launchLogPath(),assetVersion:sn(De()),entryScript:c.entryScript,buildId:c.buildId,options:this.host.services.options()};await this.host.persistPidFileData(w,d),d?.throwIfAborted(),e.info(`PID file written to ${br}`)}republishIdentity(){return r7(this.host.identity.completeIdentityPublished(),{pid:process.pid,startedAt:this.host.identity.generationStartedAt(),processGenerationToken:this.host.identity.processGenerationToken()},{readRecord:()=>Eo(),writeRecord:()=>this.writePidFile(),isProcessRunning:(d)=>at(d,{debugLog:e.debug})},IB(ot()))}launchLogPath(){let d=I(f.DAEMON_LAUNCH_LOG_PATH);return d&&vA(d)?d:null}async cleanupDaemonFilesForShutdown(){if(!this.host.identity.socketBindCommitted())this.restoreIncumbentOwnerRecord();await Bv(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(Lt)}recordSocketIdentity(d){try{let{dev:c,ino:w}=this.files.stat(d);this.boundSocketIdentities.set(d,{dev:c,ino:w})}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(w){let D=vne(d,w);if(!D){if(w instanceof yl)this.reportHeldSocketFailure(w);throw w}e.warn(`[Daemon] ${D.code}: ${d} disabled at ${D.socketPath}`,w);return}bne(d),this.recordSocketIdentity(ot()[d])}reportHeldSocketFailure(d){try{this.reportStartupFailure(d.message)}catch(c){e.debug(`Unable to report startup failure: ${r(c)}`,c)}}getDaemonFileCleanupOptions(){let d=this.host.identity.socketBindCommitted(),c=d?[...this.boundSocketIdentities.keys()]:[],w=this.boundSocketIdentities;if(this.host.pidFileWritten())return{expectedPid:process.pid,socketBindCommitted:d,socketPaths:c,socketFileIdentities:w};let D=Eo();return D&&D.pid!==process.pid?{expectedPid:process.pid,socketBindCommitted:d,socketPaths:c,socketFileIdentities:w}:{socketBindCommitted:d,socketPaths:c,socketFileIdentities:w}}}var tr=3000,SA=3000,Dd=2,RA=1080,DA=2340,kA=1170,AA=2532;function $h(d,c,w){return d.filter((D)=>{if(c.allows(D.platform,"observation-stream",D.id))return!0;return w?.(D),!1})}async function Hh(d,c,w){let D=c.filter((M)=>d===null||M.id===d),k=w.maxConcurrency??Dd;if(!Number.isInteger(k)||k<1)throw RangeError("Initial observation frame concurrency must be a positive integer");if(w.coordinator){if(!w.subscriber)throw Error("Coalesced initial frames require a subscriber target");let{coordinator:M,subscriber:F}=w;await Promise.all(D.map(async(q)=>{try{let U=await M.request(q.id,()=>qh(q,w),F.signal,w.maxConcurrency);if(U&&!F.signal.aborted&&(w.isDeviceAllowed?.(q.id)??!0))Uh(q.id,U.frame,w,{...F,replay:U.replay})}catch(U){e.warn(`[Daemon] Failed to push initial observation frame for ${q.id}: ${r(U)}`,U)}}));return}let P=0;async function C(){while(P<D.length){let M=D[P++];await PA(M,w)}}await Promise.all(Array.from({length:Math.min(k,D.length)},()=>C()))}async function PA(d,c){try{let w=await qh(d,c);if(w)Uh(d.id,w,c)}catch(w){e.warn(`[Daemon] Failed to push initial observation frame for ${d.id}: ${r(w)}`,w)}}async function qh(d,c){let w={deviceId:d.id,name:d.name,platform:d.platform};if(d.platform!=="android"&&d.platform!=="ios")return;let D=c.streamServer.getLiveFrameGeneration?.(d.id),k=c.streamServer.getDeviceSessionUuid?.(d.id),P=d.platform==="android"?IA(c.androidClientFactory(w)):CA(c.iosClientFactory(w));if(!await P.client.ensureConnected())throw Error(`Failed to connect CtrlProxy to ${d.id}`);e.info(`[Daemon] Capturing initial observation frame for ${d.id}`);let C=c.streamServer.getCurrentFrameContextGeneration?.(d.id),M=await P.hierarchy();if(!M)throw Error(`No hierarchy available for initial observation frame on ${d.id}`);let F=M.hierarchy,q={hierarchy:F,frameContext:M.frameContext??F.frameContext,frameContextGeneration:C,liveFrameGeneration:D,deviceSessionUuid:k,recordHierarchy:(K)=>P.client.recordInitialObservationStreamHierarchy(F,K)},U=await Promise.resolve().then(()=>P.screenshot()).then((K)=>K,(K)=>{q.screenshotFailure={error:K};return});if(U){let K=d.platform==="android"?_A(F):FA(F);q.screenshot={...U,...K}}return q}function IA(d){return{client:d,hierarchy:async()=>{let c=await OA(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:iie(c),frameContext:c.frameContext,rotation:c.rotation}:void 0}}}function CA(d){return{client:d,hierarchy:async()=>{let c=await xA(d);return c?{hierarchy:d.convertToViewHierarchyResult(c.hierarchy),frameContext:c.frameContext}:null},screenshot:async()=>{let c=await d.requestScreenshotWithoutObservationStreamPush(SA);return c.success&&c.data?{data:c.data,metadata:hd(DR,c.format),frameContext:c.frameContext,rotation:c.rotation}:void 0}}}function Uh(d,c,w,D){if(!TA(d,c,w.streamServer))return;if(D&&!D.replay&&c.hierarchyDelivered){Lh(d,c,c.captureSequence??null,{streamServer:w.streamServer,subscriber:D});return}let k=w.streamServer.pushHierarchyUpdate(d,c.hierarchy,c.frameContext,D?{...D,liveFrameGeneration:c.liveFrameGeneration,deviceSessionUuid:c.deviceSessionUuid,captureSequence:c.captureSequence,frameContextGeneration:c.frameContextGeneration}:void 0);if(!D||c.captureSequence===void 0&&k!==null)c.recordHierarchy(k);if(k!==null)c.hierarchyDelivered=!0,c.captureSequence=k,c.frameContextGeneration=w.streamServer.getCurrentFrameContextGeneration?.(d);Lh(d,c,k,{streamServer:w.streamServer,subscriber:D})}function TA(d,c,w){if(c.liveFrameGeneration!==void 0&&w.getLiveFrameGeneration&&c.liveFrameGeneration!==w.getLiveFrameGeneration(d))return!1;if(c.deviceSessionUuid!==void 0&&w.getDeviceSessionUuid&&c.deviceSessionUuid!==w.getDeviceSessionUuid(d))return!1;return c.frameContextGeneration===void 0||c.frameContextGeneration===w.getCurrentFrameContextGeneration?.(d)}function Lh(d,c,w,{streamServer:D,subscriber:k}){let P=c.screenshot;if(P&&(!k||w!==null)&&(!k||k.replay||!c.screenshotDelivered)){if(D.pushScreenshotUpdate(d,P.data,{screenWidth:P.width,screenHeight:P.height,metadata:P.metadata,options:{...EA(w,c.frameContext,P.frameContext),...MA(c.hierarchy),initialFrameSubscriber:k?{...k,liveFrameGeneration:c.liveFrameGeneration,deviceSessionUuid:c.deviceSessionUuid}:void 0,rotation:P.rotation,...P.frameContext===void 0?{}:{frameContext:P.frameContext}}}))c.screenshotDelivered=!0}if(c.screenshotFailure)throw c.screenshotFailure.error}function MA(d){let c=Uu(d);return c?{coordinateSpace:fR,nativeScale:c.nativeScale}:{}}function EA(d,c,w){if(d===null||c!==void 0&&w!==void 0&&c!==w)return{};return{captureSequence:d}}async function OA(d){let c=await d.getLatestHierarchy(!1,tr,void 0,{skipWaitForFresh:!0});if(c.hierarchy&&c.fresh)return{hierarchy:c.hierarchy,frameContext:c.frameContext};let w=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,tr);return w?{hierarchy:w.hierarchy,frameContext:w.frameContext}:null}async function xA(d){let c=await d.getLatestHierarchy(!1,tr,void 0,{skipWaitForFresh:!0});if(c.hierarchy&&c.fresh)return{hierarchy:c.hierarchy,frameContext:c.frameContext};let w=await d.requestHierarchySyncWithoutObservationStreamPush(void 0,!1,void 0,tr);return w?{hierarchy:w.hierarchy,frameContext:w.frameContext}:null}function _A(d){return{width:d.screenWidth??RA,height:d.screenHeight??DA}}function FA(d){let c=Uu(d);if(c)return{width:c.pixelWidth,height:c.pixelHeight};let w=d.screenScale??1;return{width:d.screenWidth?Math.round(d.screenWidth*w):kA,height:d.screenHeight?Math.round(d.screenHeight*w):AA}}var NA=1000,LA=20000,$A=60000;class kd{timer;maxConcurrency;getLiveFrameGeneration;getDeviceSessionUuid;captures=new Map;queue=[];recent;active=0;constructor(d=i,c=Dd,w=()=>0,D){this.timer=d;this.maxConcurrency=c;this.getLiveFrameGeneration=w;this.getDeviceSessionUuid=D;if(!Number.isInteger(c)||c<1)throw RangeError("Initial observation frame concurrency must be a positive integer");this.recent=new on(d,{ttlMs:NA,maxEntries:32})}request(d,c,w,D){if(D!==void 0){if(!Number.isInteger(D)||D<1)throw RangeError("Initial observation frame concurrency must be a positive integer");this.maxConcurrency=D}if(w.aborted)return Promise.resolve(void 0);let k=this.recent.get(d);if(k&&this.isFrameCurrent(d,k))return Promise.resolve({frame:k,replay:!0});this.recent.delete(d);let P=this.captures.get(d);if(!P)P={deviceId:d,run:c,started:!1,waiters:new Set},this.captures.set(d,P),this.queue.push(P);let C=P,M=C.started&&!this.isCaptureCurrent(C),F=new Promise((U,K)=>{let W=()=>{w.removeEventListener("abort",z),C.waiters.delete(V)},V={complete:(J)=>{W(),U(J)},fail:(J)=>{W(),K(J)}},z=()=>{if(V.complete(),!C.started&&C.waiters.size===0)this.captures.delete(d),this.queue.splice(this.queue.indexOf(C),1)};C.waiters.add(V),w.addEventListener("abort",z,{once:!0})});this.drain();let q=()=>this.request(d,c,w,D);return M?F.then(q,(U)=>(e.warn(`[Daemon] Superseded initial observation capture failed for ${d}: ${r(U)}`,U),q())):F}isCaptureCurrent(d){return d.liveFrameGeneration===this.getLiveFrameGeneration(d.deviceId)&&(!this.getDeviceSessionUuid||d.deviceSessionUuid===this.getDeviceSessionUuid(d.deviceId))}isFrameCurrent(d,c){return c.liveFrameGeneration===this.getLiveFrameGeneration(d)&&(!this.getDeviceSessionUuid||c.deviceSessionUuid===this.getDeviceSessionUuid(d))}drain(){while(this.active<this.maxConcurrency&&this.queue.length>0){let d=this.queue.shift();d.started=!0,this.active++,this.capture(d)}}acceptCapturedFrame(d,c,w,D){if(!c)return;if(c.liveFrameGeneration=w,D!==void 0)c.deviceSessionUuid=D;return this.isFrameCurrent(d,c)?c:void 0}async capture(d){let c=this.timer.now(),w=!0,D=!1,k=!1,P=!1,C,M=()=>{if(P)return;if(P=!0,C!==void 0)this.timer.clearTimeout(C),C=void 0;this.active--,this.drain()},F=()=>{if(w=!0,D)M()};try{let q=this.getLiveFrameGeneration(d.deviceId),U=this.getDeviceSessionUuid?.(d.deviceId);d.liveFrameGeneration=q,d.deviceSessionUuid=U;let K=d.run();w=!1,K.then(F,(z)=>{if(k&&!P)e.warn(`[Daemon] Initial observation capture rejected after its deadline for ${d.deviceId}: ${r(z)}`,z);F()});let W=await l(K,{timer:this.timer,timeoutMs:LA,label:`Initial observation frame for ${d.deviceId}`,onTimeout:()=>{k=!0,C=this.timer.setTimeout(()=>{if(!w&&!P)e.warn(`[Daemon] Initial observation capture slot backstop for ${d.deviceId} after ${this.timer.now()-c}ms; releasing its slot`),M()},Math.max(0,$A-(this.timer.now()-c)))}}),V=this.acceptCapturedFrame(d.deviceId,W,q,U);if(V?.screenshot&&d.waiters.size>0)this.recent.set(d.deviceId,V);for(let z of[...d.waiters])z.complete(V?{frame:V,replay:!1}:void 0)}catch(q){if(d.waiters.size===0)e.warn(`[Daemon] Initial observation capture failed for ${d.deviceId}: ${r(q)}`,q);for(let U of[...d.waiters])U.fail(q)}finally{if(this.captures.delete(d.deviceId),D=!0,w)M()}}}function Ad(d){return{deviceId:d.id,name:d.name,platform:d.platform,iosVersion:d.iosVersion}}function HA(d,c){return qc({hostRequestStartMs:d,readAndroidDeviceClockMs:async(w,D)=>(await v.create(Ad(w)).getDeviceTimestampMsWithSource(void 0,D)).timestampMs,observe:(w,{minTimestamp:D,signal:k})=>new xe(Ad(w)).execute({skipWaitForFresh:!1,minTimestamp:D,signal:k}),viewerRead:{applies:c,observe:(w,D)=>new xe(Ad(w),void 0,{deviceReadOnly:!0}).executeDeviceRead(D,"none")}})}function Kh(d,c,w){d.setOnSubscriberConnected((D,k)=>{e.info(`[Daemon] IDE plugin subscribed to observation stream (device: ${D??"all"}), ensuring WebSocket connections...`);let P=w.devicePool().getAllDevices(),C=$h(P,w.passiveWorkPolicy(),(M)=>bt(M.platform,M.id,"connect"));if(Hh(D,C,{streamServer:d,coordinator:c,subscriber:k,isDeviceAllowed:(M)=>{let F=w.devicePool().getAllDevices().find((q)=>q.id===M);return!!F&&w.passiveWorkPolicy().allows(F.platform,"observation-stream",M)},androidClientFactory:(M)=>E.getInstance(M,v),iosClientFactory:(M)=>Xc(M,Et)}).catch((M)=>{e.warn(`[Daemon] Error pushing initial observation frame: ${M}`)}),P.length===0)e.info("[Daemon] No devices in pool to connect")}),d.setOnScreenshotCadenceChanged((D)=>{let k=w.devicePool().getAllDevices().filter((P)=>D===null||P.id===D);for(let P of k)if(P.platform==="android"){if(!w.passiveWorkPolicy().allows("android","observation-stream",P.id)){bt("android",P.id,"screenshot cadence");continue}E.getExistingInstance(P.id)?.refreshObservationStreamScreenshotCadence()}else if(P.platform==="ios"){if(!w.passiveWorkPolicy().allows("ios","observation-stream",P.id)){bt("ios",P.id,"screenshot cadence");continue}x.getExistingInstance(P.id)?.refreshObservationStreamScreenshotCadence()}}),d.setOnHierarchyCadenceChanged((D)=>{let k=w.devicePool().getAllDevices().filter((P)=>D===null||P.id===D);for(let P of k)if(P.platform==="android"){if(!w.passiveWorkPolicy().allows("android","observation-stream",P.id)){bt("android",P.id,"hierarchy cadence");continue}E.getExistingInstance(P.id)?.refreshObservationStreamHierarchyCadence()}else if(P.platform==="ios"){if(!w.passiveWorkPolicy().allows("ios","observation-stream",P.id)){bt("ios",P.id,"hierarchy cadence");continue}let C=x.getExistingInstance(P.id);if(!C)continue;let M=d.getHierarchyIntervalMsForDevice(P.id);C.ensureConnected().then((F)=>{if(F)C.refreshObservationStreamHierarchyCadence(M)}).catch((F)=>{e.warn(`[Daemon] Failed to refresh iOS hierarchy cadence for ${P.id}: ${F}`)})}}),d.setOnStorageSubscriptionRequested((D)=>w.applyStorageSubscriptionRequest(D)),d.setOnObservationRequested(async({deviceId:D,sessionUuid:k,signal:P})=>{let C=An("observationStream",{allowObserverSessions:!0}),M=D?[w.devicePool().getDevice(D)].filter((q)=>q!==null):w.devicePool().getAllDevices().filter((q)=>cr(q.platform));if(M.length===0)throw Error(D?`Device ${D} is not available`:"No devices are available");if(P.aborted)throw Error("Observation request was aborted");let F=w.timer().now();return Kc(M,HA(F,(q)=>zc({sessionManager:w.sessionManager(),devicePool:w.devicePool()},q,k)),{timer:w.timer(),signal:P,assertDeviceActionable:(q)=>{w.devicePool().assertDeviceActionable(q.id,"to observe"),C.authorize({sessionUuid:k,deviceId:q.id,admitViewer:!0})}})},hr+$c)}class Pd{host;initialFrameCoordinators=new WeakMap;constructor(d){this.host=d}onDeviceReadyForSessionRegistry(d){this.host.lifecycle.socketServer()?.evictDeviceInputCache(d);let c=this.host.services.devicePool().getDevice(d);if(!c||!cr(c.platform))return;if(c.platform==="ios")ye.getExistingInstance(d)?.rearmAfterDeviceReappearance().catch((D)=>{e.warn(`[Daemon] Failed to rearm iOS CtrlProxy for ${d}: ${r(D)}`)});if(c.platform==="android")E.noteDeviceOnline(d);this.host.services.deviceSessionRegistry().onDeviceConnected({deviceId:c.id,platform:c.platform,incarnation:c.incarnation})}getDeviceSessionRoutingTargets(){return{deviceDataStream:Et(),performancePush:CD(),failuresPush:Uj(),telemetryPush:uR()}}configureDeviceDataStreamServer(){this.setupDeviceSessionRouting(),this.host.setupDeviceDataStreamCallback()}setupDeviceSessionRouting(){let d=Ane(this.host.services.deviceSessionRegistry(),this.host.services.devicePool()),{deviceDataStream:c,performancePush:w,failuresPush:D,telemetryPush:k}=this.host.getDeviceSessionRoutingTargets();if(this.host.lifecycle.setDeviceDataStreamServer(c),c?.setDeviceSessionResolver(d),w?.setDeviceSessionResolver(d),D?.setDeviceSessionResolver(d),k?.setDeviceSessionResolver(d),c)this.host.services.deviceSessionRegistry().setLifecycleListener({onSessionStarted:(P)=>c.pushDeviceSessionStarted(P),onSessionEnded:(P,C)=>c.pushDeviceSessionEnded(P,C)})}getInitialFrameCoordinator(d){let c=this.initialFrameCoordinators.get(d);if(!c)c=new kd(this.host.services.timer(),void 0,(w)=>d.getLiveFrameGeneration(w),(w)=>d.getDeviceSessionUuid(w)),this.initialFrameCoordinators.set(d,c);return c}setupDeviceDataStreamCallback(){let d=this.host.lifecycle.deviceDataStreamServer()??Et();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 Yc({devicePool:this.host.services.devicePool()},d)}setupNavigationGraphStreamListener(d){this.host.lifecycle.navigationGraphBridge().listen(d)}get testHooks(){return{deviceDataStreamServer:()=>this.host.lifecycle.deviceDataStreamServer(),setupDeviceSessionRouting:()=>this.setupDeviceSessionRouting(),setupDeviceDataStreamCallback:()=>this.host.setupDeviceDataStreamCallback(),setupNavigationGraphStreamListener:(d)=>this.host.setupNavigationGraphStreamListener(d),applyStorageSubscriptionRequest:(d)=>this.applyStorageSubscriptionRequest(d)}}}class Id{timer;intervalMs;previousTick;constructor(d,c){this.timer=d;this.intervalMs=c;this.previousTick=this.readClock()}tick(){let d=this.readClock(),c=this.gap(this.previousTick,d,this.intervalMs);return this.previousTick=d,c}beginProbe(d){let c=this.readClock();return(w,D)=>{if(!(w instanceof Pe))return!1;let k=this.gap(c,this.readClock(),w.timeoutMs,w.startupMs??0),P=[d.lateMs,d.sleptMs,k.lateMs,k.sleptMs].some((C)=>C>lq);if(P)e.warn(`Database health probe timeout inconclusive: tick lateness=${d.lateMs}ms, probe overrun=${k.lateMs}ms, tick host sleep=${d.sleptMs}ms, probe host sleep=${k.sleptMs}ms, timeout=${w.timeoutMs}ms; strike count stays at ${D}`);return P}}readClock(){return{wall:this.timer.now(),monotonic:this.timer.monotonicNow?.()??this.timer.now()}}gap(d,c,w,D=0){return uq({wallElapsedMs:Math.max(0,c.wall-d.wall-D),monotonicElapsedMs:Math.max(0,c.monotonic-d.monotonic-D),scheduledMs:w,monotonicIncludesHostSleep:this.timer.monotonicIncludesHostSleep,maxCredibleStallMs:gA})}}var Td=30000,qA=3,Gh=2*Td,Cd=10;function Wh(d){let c=new Id(d.timer,Td),w=0,D="unknown",k=0,P=(V)=>{if(D!==V)w=0;D=V,w++},C=()=>{w=0,D="unknown"},M=()=>{let V=d.httpServer();if(!V)return e.warn("Health check failed: HTTP server not initialized"),P("http"),!1;if(!V.listening)return e.warn("Health check failed: HTTP server not listening"),P("http"),!1;if(!d.socketServerListening())return e.warn("Health check failed: Socket server not listening"),P("socket"),!1;if(!d.observationStreamHealthy()&&!Fz("observation-stream"))return e.warn("Health check failed: Observation stream socket unavailable"),P("socket"),!1;return!0},F=(V,z)=>{if(!(V instanceof Pe)||!(z||(d.hostIoStalled?.()??!1)))return!1;if(k>=Cd){if(k===Cd)k++,e.error(`Host I/O stall excused ${Cd} consecutive database probe timeouts; counting further timeouts toward recovery`);return!1}return k++,e.warn(`Database health probe timeout inconclusive: host I/O stalled, timeout=${V.timeoutMs}ms; strike count stays at ${w}`),!0},q=async(V)=>{let z=c.beginProbe(V),J=d.hostIoStalled?.()??!1;try{await d.databaseHealthProbe().check(),d.onDatabaseFailureChanged(void 0),C(),k=0,e.debug("Health check passed")}catch(X){if(z(X,w))return!1;if(F(X,J))return!1;d.onDatabaseFailureChanged(r(X)),e.warn(`Health check failed: Database probe failed: ${X}`),P("database")}return!0},U=async()=>{try{if(!await d.onObservationStreamRestored())e.warn("Observation stream restored but daemon identity republish was declined")}catch(V){e.warn("Observation stream restored but daemon identity republish failed",V)}},K=async()=>{if(!Fz("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(!Fz("observation-stream")&&d.observationStreamHealthy())await U()},W=async()=>{let V=c.tick();try{if(M()){let z=await q(V);if(await K(),!z)return}if(w>=qA)e.error(`Health check failed ${w} times, attempting recovery...`),await d.recover(D),C()}catch(z){e.warn(`Health check error: ${z}`),P("unknown")}};return new gl(d.timer,Td,W)}var Vh={"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 KA=5000,GA=LN,WA=20000;function Jh(d,c){return Sf(d,c)}class Ed{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,w,{timer:D=i,...k}={}){this.sessions=d;this.reap=w;this.timer=D,this.checkIntervalMs=k.checkIntervalMs??QC(),this.graceMs=k.graceMs??Jh(f.SESSION_HEARTBEAT_INITIAL_GRACE_MS.name,f.SESSION_HEARTBEAT_INITIAL_GRACE_MS.legacyName)??WA,this.preFirstHeartbeatGraceMs=k.preFirstHeartbeatGraceMs??wS(),this.defaultHeartbeatTimeoutMs=k.heartbeatTimeoutMs??Jh(f.SESSION_HEARTBEAT_TIMEOUT_MS.name,f.SESSION_HEARTBEAT_TIMEOUT_MS.legacyName)??oc(),this.stallThresholdMs=k.stallThresholdMs??lq,this.forceStuckRelease=k.forceStuckRelease,this.maxCredibleStallMs=k.maxCredibleStallMs??gA,this.bunVersionOverride=k.bunVersion,this.executionVeto=new MI(c,D,By,()=>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:KA,label:"Heartbeat monitor release drain"}).catch((w)=>(e.debug(`Heartbeat monitor release drain did not finish: ${w}`),!1))))e.warn("Session heartbeat monitor did not settle before shutdown timeout")}async tick(){let c=(await Promise.allSettled(this.scan())).find((w)=>w.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 w=uq({wallElapsedMs:d-this.lastScanSettledAt,monotonicElapsedMs:c-this.lastScanSettledMonotonic,scheduledMs:this.checkIntervalMs,monotonicIncludesHostSleep:this.timer.monotonicIncludesHostSleep,maxCredibleStallMs:this.maxCredibleStallMs});return this.checkRawWallLead(c),w}checkRawWallLead(d){let c=this.timer.now()-d,w=c-(this.lastRawWallLeadMs??c);if(this.lastRawWallLeadMs=c,this.timer.monotonicIncludesHostSleep===!0&&w>this.stallThresholdMs)this.reportClockSemanticsDisagreement(w)}bunVersion(){return this.bunVersionOverride??process.versions.bun}checkClockSemantics(){if(this.timer.monotonicIncludesHostSleep===void 0)return;let d=hJ(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(),w=this.sinceLastScan(d,c);if(w===void 0)return;let D=w.lateMs>this.stallThresholdMs?w.lateMs:0,k=w.sleptMs>this.stallThresholdMs?w.sleptMs:0;if(D===0&&k===0)return;let P=this.lastScanSettledAt??d;this.lastScanSettledAt=d-this.checkIntervalMs,this.lastScanSettledMonotonic=c-this.checkIntervalMs;let C=this.sessions.forgiveDaemonStall?.(d,D,k,P)??0;e.warn(`Heartbeat monitor tick fired ${D}ms late after the host slept ${k}ms; ${C} session(s) considered for stall forgiveness (host sleep counts toward idle); lease and idle extension counts are logged by the session manager`)}scan(){this.forgiveOwnStall(),this.scanInFlight=!0;try{return this.sessions.cleanupExpiredSessions(),this.forceStuckReleases(),this.reapStaleSessions()}finally{if(this.scanInFlight=!1,this.lastScanSettledAt!==void 0&&this.lastScanSettledMonotonic!==void 0)this.lastScanSettledAt=Math.max(this.lastScanSettledAt,this.now()),this.lastScanSettledMonotonic=Math.max(this.lastScanSettledMonotonic,this.monotonicNow())}}reapStaleSessions(){let d=[];for(let c of this.sessions.getAllSessions()){if(this.reapsInFlight.has(c.sessionId))continue;let w=Math.min(this.now(),this.heartbeatsRefusedSince.get(c)??1/0),D=c.ownership==="awaiting-owner"?this.rehydrationOwnerStaleReason(c,w):this.staleReason(c,w);if(!D){this.executionVeto.forget(c);continue}if(this.isVetoedByActiveExecution(c,D))continue;e.warn(`Session ${c.sessionId} ${Vh[D]}, cancelling (reason=${D})`+(D==="heartbeat-timeout"?`; last heartbeat age=${w-(this.sessions.judgedLeaseHeartbeat?.(c)??Fy(c))}ms, heartbeat timeout=${c.heartbeatTimeoutMs??this.defaultHeartbeatTimeoutMs}ms`:""));try{d.push(this.trackReap(c.sessionId,this.reap(c.sessionId,D)))}catch(k){e.warn(`Failed to reap stale session ${c.sessionId}`,k),d.push(Promise.reject(k))}}return d}trackReap(d,c){let w=c.catch((C)=>{throw e.warn(`Failed to reap stale session ${d}`,C),C}),D=w.then(()=>{return},()=>{return});this.reapsInFlight.set(d,D);let k=this.reapStartedAt.get(d),P=k?.sourceRelease&&this.sessions.isReleaseInProgress?.(d,k.at)===!0?{...k}:{at:this.now(),reported:!1};return this.reapStartedAt.set(d,P),D.then(()=>{if(this.reapsInFlight.get(d)===D)this.reapsInFlight.delete(d);if(this.reapStartedAt.get(d)===P)this.reapStartedAt.delete(d)}),w}forceStuckReleases(){this.trackSourceReleases();for(let d of this.reapStartedAt.keys())this.reportIfStuck(d)}trackSourceReleases(){let d=this.sessions.getNonTerminalReleasesInProgress?.()??[];this.heartbeatsRefusedSince=new Map(d.map((D)=>[D.session,D.startedAtMs]));let c=[d,this.sessions.getIdleReleasesInProgress?.(),this.sessions.getTerminalReleasesInProgress?.()].flatMap((D)=>D??[]),w=new Map(c.map((D)=>[D.sessionId,D.startedAtMs]));for(let[D,k]of this.reapStartedAt)if(k.sourceRelease&&w.get(D)!==k.at&&this.sessions.isReleaseInProgress?.(D,k.at)!==!0)this.reapStartedAt.delete(D);for(let[D,k]of w)if(!this.reapStartedAt.has(D))this.reapStartedAt.set(D,{at:k,reported:!1,sourceRelease:!0})}reportIfStuck(d){let c=this.reapStartedAt.get(d);if(!c||c.reported)return;let w=this.now(),D=w-c.at;if(w<(this.sessions.getReleaseStuckAtMs?.(d)??c.at+GA))return;if(c.reported=!0,!this.forceStuckRelease){e.warn(`Session ${d} release has not settled after ${D}ms; its device stays held until the teardown finishes. Other sessions are still judged on schedule.`);return}e.warn(`Session ${d} release has not settled after ${D}ms; forcing its device back to the pool while the session stays fenced (#10963).`),this.forceStuckRelease(d).catch((k)=>{e.warn(`Forcing the stuck release of session ${d} failed: ${r(k)}`,k)})}isVetoedByActiveExecution(d,c){let w=this.executionVeto.judge(d);if(w.kind!=="expired")return w.kind==="kept";return e.warn(`Session ${d.sessionId} (${Vh[c]}) was kept for ${w.vetoedMs}ms by executions that never settled; releasing it anyway past their ${w.bound} bound (reason=${c})`),!1}staleReason(d,c){if(d.livenessPolicy==="cli-idle")return c>Qf(d)?"cli-idle-timeout":void 0;return this.heartbeatLeaseStaleReason(d,c)}heartbeatLeaseStaleReason(d,c){let w=d.heartbeatTimeoutMs??this.defaultHeartbeatTimeoutMs,D=Fy(d),k=this.sessions.judgedLeaseHeartbeat?.(d)??D;if(!d.hasReceivedHeartbeat&&k===D){if(d.heartbeatTimeoutSource==="default")return c-k>this.preFirstHeartbeatGraceMs?"missing-first-heartbeat":void 0;if(c-d.createdAt<this.graceMs)return}return nq(c,k,w,Ly(d))?"heartbeat-timeout":void 0}rehydrationOwnerStaleReason(d,c){if(d.ownership!=="awaiting-owner")return;let w=d.recoveredFromUncleanDaemonExit?Math.min(d.heartbeatTimeoutMs,this.defaultHeartbeatTimeoutMs):d.heartbeatTimeoutMs,D=d.awaitingOwnerSince??c;return c-D>w+ls?"rehydration-owner-timeout":void 0}}var VA=15000;class Bd{port;idleMs;timer;lastBusyAt=new Map;interval;constructor(d,c,w=i,D=Math.min(Math.max(1,Math.floor(c/4)),VA)){this.port=d;this.idleMs=c;this.timer=w;this.interval=new gl(w,D,async()=>{await this.sweep()})}start(){this.interval.start()}async stop(){await this.interval.stop()}async sweep(){let d=this.timer.now(),c=new Set(this.port.heldDeviceIds());for(let k of[...this.lastBusyAt.keys()])if(!c.has(k))this.lastBusyAt.delete(k);let w=[...c].filter((k)=>this.isIdle(k,d)),D=[];for(let k of w){if(!this.isIdle(k,this.timer.now()))continue;try{e.info(`[CTRL_PROXY] Releasing idle CtrlProxy forwarding lease for ${k} (no session or tool activity for ${this.idleMs}ms)`),this.lastBusyAt.delete(k),await this.port.release(k),D.push(k)}catch(P){e.warn(`[CTRL_PROXY] Failed to release idle forwarding lease for ${k}: ${r(P)}`,P)}}return D}isIdle(d,c){let w=this.port.activity(d);if(c7(w))return this.lastBusyAt.set(d,c),!1;let D=this.lastBusyAt.get(d);if(D===void 0)return this.lastBusyAt.set(d,c),!1;let k=w.idleForMs??Number.POSITIVE_INFINITY;return Math.min(c-D,k)>=this.idleMs}}var JA=900000,jA=30000,zA=1;function zh(d=process.env){return Hu(f.PRIVATE_DAEMON_ORPHAN_IDLE_MS,d)??JA}var YA=f.DAEMON_LAUNCHER_PID.name;function Yh(d,c=process.env){let w=c[YA]?.trim()??"",D=Cb(w);return D!==void 0&&D>1?D:d}var XA=f.HARNESS_PRIVATE_DAEMON.name;function Xh(d,c,w=process.env){let D=w[XA]?.trim();if(D==="1"||D==="0")return D==="1";return jh(w,[f.DAEMON_SOCKET_PATH.name,f.DAEMON_SOCKET_PATH.legacyName])!==""&&d!==c&&jh(w,[f.AUX_SOCKET_DIR.name])!==""}function jh(d,c){return c.map((w)=>d[w]?.trim()??"").find((w)=>w!=="")??""}class Od{orphanIdleSince=null;lastClientActivityCount=null;handle=null;shutdownRequested=!1;launcherToken;port;idleMs;timer;checkIntervalMs;launcherGeneration;constructor(d,c,w=i,{checkIntervalMs:D=Math.min(jA,c),launcherGeneration:k=Ht}={}){this.port=d,this.idleMs=c,this.timer=w,this.checkIntervalMs=D,this.launcherGeneration=k}start(){if(this.handle||this.idleMs<=0)return;this.launcherToken=this.port.launcherIsExplicit()?this.launcherGeneration.current(this.port.launcherPid()):void 0,this.handle=this.timer.setInterval(()=>this.check(),this.checkIntervalMs);let d=this.handle;if(typeof d.unref==="function")d.unref()}stop(){if(this.handle)this.timer.clearInterval(this.handle),this.handle=null}isOrphaned(){let d=this.port.parentPid();if(d===zA)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 w=this.isOrphaned()&&!c&&this.port.clientCount()===0&&this.port.liveSessionCount()===0,D=this.timer.now();if(!w)return this.orphanIdleSince=null,!1;if(this.orphanIdleSince??=D,D-this.orphanIdleSince<this.idleMs)return!1;this.shutdownRequested=!0,this.stop();let k=`private daemon's parent exited and it has had no clients or sessions for ${Math.round((D-this.orphanIdleSince)/1000)}s`;return e.warn(`[Daemon] Shutting down orphaned private daemon: ${k}`),this.port.shutdown(k),!0}}var Qh=86400000,Zh=7*Qh,eg=90*Qh,tg=50000,ig=500000,ng=5000,QA=20,rg=21600000,og=1e4,xd=2147483647;function sg(d){return{screenshotsCleared:0,nodeObservationsDeleted:0,edgeObservationsDeleted:0,suggestionObservationsDeleted:0,buildKeysDeleted:0,edgeTraversalsDeleted:0,prunedAt:d}}function ir(d,c=Number.MAX_SAFE_INTEGER){if(d===void 0)return;return Number.isSafeInteger(d)&&d>0&&d<=c?d:void 0}function ag(d,c=Number.MAX_SAFE_INTEGER){return ir(Sf(d.name,d.legacyName),c)}function _d(d={}){let c=(w,D,k,P=Number.MAX_SAFE_INTEGER)=>ir(w,P)??ag(D,P)??k;return{screenshotTtlMs:c(d.screenshotTtlMs,f.NAV_RETENTION_SCREENSHOT_TTL_MS,Zh),structureTtlMs:c(d.structureTtlMs,f.NAV_RETENTION_STRUCTURE_TTL_MS,eg),perAppMaxObservations:c(d.perAppMaxObservations,f.NAV_RETENTION_PER_APP_MAX_OBSERVATIONS,tg),globalMaxObservations:c(d.globalMaxObservations,f.NAV_RETENTION_GLOBAL_MAX_OBSERVATIONS,ig),evictionChunkSize:Math.min(c(d.evictionChunkSize,f.NAV_RETENTION_EVICTION_CHUNK_SIZE,ng),og),maxEdgeTraversalsPerTransition:ir(d.maxEdgeTraversalsPerTransition)??QA}}function Fd(d){return ir(d,xd)??ag(f.NAV_RETENTION_INTERVAL_MS,xd)??rg}async function nr(d,c){let w=d.selectFrom("navigation_build_keys").select(["id","app_id"]);if(c&&c.length>0)w=w.where("app_id","in",c);return(await w.execute()).map((k)=>({id:k.id,appId:k.app_id}))}async function Ld(d,c,w){let D=c??await nr(d,w);if(D.length===0)return[];let k=await eP(d,w),P=new Map;for(let C of D){let M=k.get(C.id)??Number.NEGATIVE_INFINITY;if(ZA(P.get(C.appId),C.id,M))P.set(C.appId,{id:C.id,seen:M})}return Array.from(P.values(),(C)=>C.id)}function ZA(d,c,w){if(d===void 0)return!0;return w>d.seen||w===d.seen&&c>d.id}function Ii(d,c){if(d.length!==c.length)return!1;let w=new Set(c);return d.every((D)=>w.has(D))}async function eP(d,c){let w=d.selectFrom("navigation_node_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((q)=>["observation.build_key_id",q.fn.max("observation.last_seen_at").as("max_seen")]),D=d.selectFrom("navigation_edge_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((q)=>["observation.build_key_id",q.fn.max("observation.last_seen_at").as("max_seen")]),k=d.selectFrom("navigation_suggestion_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select((q)=>["observation.build_key_id",q.fn.max("observation.last_seen_at").as("max_seen")]);if(c&&c.length>0)w=w.where("buildKey.app_id","in",c),D=D.where("buildKey.app_id","in",c),k=k.where("buildKey.app_id","in",c);let P=await w.groupBy("observation.build_key_id").execute(),C=await D.groupBy("observation.build_key_id").execute(),M=await k.groupBy("observation.build_key_id").execute(),F=new Map;for(let q of[...P,...C,...M]){let U=Number(q.max_seen??0),K=F.get(q.build_key_id);if(K===void 0||U>K)F.set(q.build_key_id,U)}return F}async function $d(d,c){if(c.length===0)return new Map;let w=Array.from(new Set(c));return tP(d,w)}async function tP(d,c){let w=await d.selectFrom("navigation_node_observations").select((C)=>["build_key_id",C.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),D=await d.selectFrom("navigation_edge_observations").select((C)=>["build_key_id",C.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),k=await d.selectFrom("navigation_suggestion_observations").select((C)=>["build_key_id",C.fn.max("last_seen_at").as("max_seen")]).where("build_key_id","in",c).groupBy("build_key_id").execute(),P=new Map;for(let C of[...w,...D,...k]){let M=Number(C.max_seen??0),F=P.get(C.build_key_id);if(F===void 0||M>F)P.set(C.build_key_id,M)}return P}async function ug(d,c,w){if(c.length===0||w.length===0)return[];return(await d.selectFrom("navigation_node_observations").select("node_id").where("node_id","in",c).where("build_key_id","in",w).execute()).map((k)=>k.node_id)}async function or(d,c){return c===null?iP(d):nP(d,c)}async function iP(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 nP(d,c){let w=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(w.c)}async function mg(d,c,w,D){let k=await fg(d,c,w,D).execute(),P=await hg(d,c,w,D).execute(),C=await rP(d,c,w,D).execute(),M=[...k.map((q)=>({kind:"node",id:q.id,buildKeyId:q.build_key_id,lastSeenAt:q.last_seen_at})),...P.map((q)=>({kind:"edge",id:q.id,buildKeyId:q.build_key_id,lastSeenAt:q.last_seen_at})),...C.map((q)=>({kind:"suggestion",id:q.id,buildKeyId:q.build_key_id,lastSeenAt:q.last_seen_at}))],F={node:0,edge:1,suggestion:2};return M.sort((q,U)=>q.lastSeenAt-U.lastSeenAt||F[q.kind]-F[U.kind]||q.id-U.id),M.slice(0,D)}function fg(d,c,w,D){let k=d.selectFrom("navigation_node_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)k=k.where("build_key_id","in",(P)=>P.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(w.length>0)k=k.where((P)=>P.or([P("build_key_id","not in",w),P("last_seen_at","<>",P.selectFrom("navigation_node_observations as t").select((C)=>C.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_node_observations.build_key_id"))]));return k.orderBy("last_seen_at","asc").orderBy("id","asc").limit(D)}function hg(d,c,w,D){let k=d.selectFrom("navigation_edge_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)k=k.where("build_key_id","in",(P)=>P.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(w.length>0)k=k.where((P)=>P.or([P("build_key_id","not in",w),P("last_seen_at","<>",P.selectFrom("navigation_edge_observations as t").select((C)=>C.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_edge_observations.build_key_id"))]));return k.orderBy("last_seen_at","asc").orderBy("id","asc").limit(D)}function rP(d,c,w,D){let k=d.selectFrom("navigation_suggestion_observations").select(["id","build_key_id","last_seen_at"]);if(c!==null)k=k.where("build_key_id","in",(P)=>P.selectFrom("navigation_build_keys").select("id").where("app_id","=",c));if(w.length>0)k=k.where((P)=>P.or([P("build_key_id","not in",w),P("last_seen_at","<>",P.selectFrom("navigation_suggestion_observations as t").select((C)=>C.fn.max("t.last_seen_at").as("m")).whereRef("t.build_key_id","=","navigation_suggestion_observations.build_key_id"))]));return k.orderBy("last_seen_at","asc").orderBy("id","asc").limit(D)}var oP=()=>new Promise((d)=>setImmediate(d)),aP=3;class Hd{db;config;removeScreenshotFile;logger;yieldBetweenBatches;resolveProtectedBuildKeyIds;constructor(d,c={},w={}){this.db=d;this.config=_d(c),this.removeScreenshotFile=w.removeScreenshotFile,this.logger=w.logger??e,this.yieldBetweenBatches=w.yieldBetweenBatches??oP,this.resolveProtectedBuildKeyIds=w.resolveProtectedBuildKeyIds??Ld}async prune(d){let c=sg(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(w){this.logger.debug(`nav retention: failed to unlink screenshot ${c}: ${w}`)}}async retryAfterProtectionChange(d,c){if(c>=aP)return this.logger.debug(`nav retention: ${d} protection kept changing; defer remaining rows`),!1;return await this.yieldBetweenBatches(),!0}async revalidateEmptyProtection(d,c,w){let D=await this.resolveProtectedBuildKeyIds(this.db),k=!Ii(D,d);return{ids:D,retry:k&&await this.retryAfterProtectionChange(c,w)}}async refreshChangedProtection(d,c){return c?this.resolveProtectedBuildKeyIds(this.db):d}async pruneScreenshots(d,c){let w=d-this.config.screenshotTtlMs,D=this.config.evictionChunkSize,k=await this.resolveProtectedBuildKeyIds(this.db),P=0;for(;;){let C=await this.db.transaction().execute(async(F)=>{let q=F.selectFrom("navigation_nodes").select(["id","app_id","screenshot_path"]).where("screenshot_path","is not",null).where("last_seen_at","<",w);if(k.length>0)q=q.where("id","not in",(te)=>te.selectFrom("navigation_node_observations").select("node_id").where("build_key_id","in",k));let U=await q.limit(D).execute();if(U.length===0)return null;let K=Array.from(new Set(U.map((te)=>te.app_id))),W=await this.resolveProtectedBuildKeyIds(F,void 0,K),V=await ug(F,U.map((te)=>te.id),W),z=new Set(V),J=U.filter((te)=>!z.has(te.id)),X=W.some((te)=>!k.includes(te));if(J.length===0)return{clearedCount:0,clearedPaths:[],isFullBatch:U.length===D,activeBuildChanged:X};let ee=J.map((te)=>te.id);await F.updateTable("navigation_nodes").set({screenshot_path:null}).where("id","in",ee).execute();let ne=[];for(let te of J)if(te.screenshot_path!==null)ne.push(te.screenshot_path);return{clearedCount:ee.length,clearedPaths:ne,isFullBatch:U.length===D,activeBuildChanged:X}});if(C===null){let F=await this.revalidateEmptyProtection(k,"screenshots",++P);if(k=F.ids,F.retry)continue;break}if(c.screenshotsCleared+=C.clearedCount,C.clearedCount>0)P=0;if(await this.removeFiles(C.clearedPaths),C.activeBuildChanged)k=await this.resolveProtectedBuildKeyIds(this.db);let M=C.clearedCount===0&&C.activeBuildChanged;if(M&&await this.retryAfterProtectionChange("screenshots",++P))continue;if(M)break;if(!C.isFullBatch||C.clearedCount===0)break;await this.yieldBetweenBatches()}}async pruneExcessEdgeTraversals(d){let c=this.config.maxEdgeTraversalsPerTransition,w=this.config.evictionChunkSize,D=await this.db.selectFrom("navigation_edges").select(["app_id","from_screen","to_screen","tool_name","tool_args"]).groupBy(["app_id","from_screen","to_screen","tool_name","tool_args"]).having((k)=>k.fn.countAll(),">",c).execute();for(let k of D){for(;;){let P=await this.db.transaction().execute((M)=>M.deleteFrom("navigation_edges").where("id","in",(F)=>F.selectFrom("navigation_edges as e").select("e.id").where("e.app_id","=",k.app_id).where("e.from_screen","=",k.from_screen).where("e.to_screen","=",k.to_screen).where(m`e.tool_name is ${k.tool_name}`).where(m`e.tool_args is ${k.tool_args}`).where(m`not exists (select 1 from test_edge_coverage c where c.edge_id = e.id)`).orderBy("e.id","desc").limit(w).offset(c)).executeTakeFirst()),C=Number(P.numDeletedRows??0);if(d.edgeTraversalsDeleted+=C,C<w)break;await this.yieldBetweenBatches()}await this.yieldBetweenBatches()}}async pruneObservationsByTtl(d,c){let w=d-this.config.structureTtlMs;c.nodeObservationsDeleted+=await this.pruneNodeObservationsByTtl(w),c.edgeObservationsDeleted+=await this.pruneEdgeObservationsByTtl(w),c.suggestionObservationsDeleted+=await this.pruneSuggestionObservationsByTtl(w)}async pruneNodeObservationsByTtl(d){let c=0,w=0,D=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let k=await this.db.transaction().execute(async(C)=>{let M=C.selectFrom("navigation_node_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select(["observation.id","observation.build_key_id","buildKey.app_id"]).where("observation.last_seen_at","<",d);if(D.length>0)M=M.where("observation.build_key_id","not in",D);let F=await M.limit(this.config.evictionChunkSize).execute();if(F.length===0)return null;let q=Array.from(new Set(F.map((J)=>J.app_id))),U=await this.resolveProtectedBuildKeyIds(C,void 0,q),K=new Set(U),W=F.filter((J)=>!K.has(J.build_key_id)).map((J)=>J.id),V=U.some((J)=>!D.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V};let z=await C.deleteFrom("navigation_node_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(z.numDeletedRows??0),isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V}});if(k===null){let C=await this.revalidateEmptyProtection(D,"node TTL",++w);if(D=C.ids,C.retry)continue;return c}if(c+=k.deletedCount,k.deletedCount>0)w=0;D=await this.refreshChangedProtection(D,k.protectionChanged);let P=k.protectionChanged&&k.deletedCount===0;if(P&&await this.retryAfterProtectionChange("node TTL",++w))continue;if(P)return c;if(!k.isFullBatch&&!k.protectionChanged||k.deletedCount===0)return c;await this.yieldBetweenBatches()}}async pruneEdgeObservationsByTtl(d){let c=0,w=0,D=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let k=await this.db.transaction().execute(async(C)=>{let M=C.selectFrom("navigation_edge_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select(["observation.id","observation.build_key_id","buildKey.app_id"]).where("observation.last_seen_at","<",d);if(D.length>0)M=M.where("observation.build_key_id","not in",D);let F=await M.limit(this.config.evictionChunkSize).execute();if(F.length===0)return null;let q=Array.from(new Set(F.map((J)=>J.app_id))),U=await this.resolveProtectedBuildKeyIds(C,void 0,q),K=new Set(U),W=F.filter((J)=>!K.has(J.build_key_id)).map((J)=>J.id),V=U.some((J)=>!D.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V};let z=await C.deleteFrom("navigation_edge_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(z.numDeletedRows??0),isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V}});if(k===null){let C=await this.revalidateEmptyProtection(D,"edge TTL",++w);if(D=C.ids,C.retry)continue;return c}if(c+=k.deletedCount,k.deletedCount>0)w=0;D=await this.refreshChangedProtection(D,k.protectionChanged);let P=k.protectionChanged&&k.deletedCount===0;if(P&&await this.retryAfterProtectionChange("edge TTL",++w))continue;if(P)return c;if(!k.isFullBatch&&!k.protectionChanged||k.deletedCount===0)return c;await this.yieldBetweenBatches()}}async pruneSuggestionObservationsByTtl(d){let c=0,w=0,D=await this.resolveProtectedBuildKeyIds(this.db);for(;;){let k=await this.db.transaction().execute(async(C)=>{let M=C.selectFrom("navigation_suggestion_observations as observation").innerJoin("navigation_build_keys as buildKey","buildKey.id","observation.build_key_id").select(["observation.id","observation.build_key_id","buildKey.app_id"]).where("observation.last_seen_at","<",d);if(D.length>0)M=M.where("observation.build_key_id","not in",D);let F=await M.limit(this.config.evictionChunkSize).execute();if(F.length===0)return null;let q=Array.from(new Set(F.map((J)=>J.app_id))),U=await this.resolveProtectedBuildKeyIds(C,void 0,q),K=new Set(U),W=F.filter((J)=>!K.has(J.build_key_id)).map((J)=>J.id),V=U.some((J)=>!D.includes(J));if(W.length===0)return{deletedCount:0,isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V};let z=await C.deleteFrom("navigation_suggestion_observations").where("id","in",W).executeTakeFirst();return{deletedCount:Number(z.numDeletedRows??0),isFullBatch:F.length===this.config.evictionChunkSize,protectionChanged:V}});if(k===null){let C=await this.revalidateEmptyProtection(D,"suggestion TTL",++w);if(D=C.ids,C.retry)continue;return c}if(c+=k.deletedCount,k.deletedCount>0)w=0;D=await this.refreshChangedProtection(D,k.protectionChanged);let P=k.protectionChanged&&k.deletedCount===0;if(P&&await this.retryAfterProtectionChange("suggestion TTL",++w))continue;if(P)return c;if(!k.isFullBatch&&!k.protectionChanged||k.deletedCount===0)return c;await this.yieldBetweenBatches()}}async enforceCaps(d){let c=await nr(this.db),w=Array.from(new Set(c.map((P)=>P.appId)));for(let P of w){let M=await or(this.db,P)-this.config.perAppMaxObservations;if(M>0)await this.evictOldest(P,M,this.config.perAppMaxObservations,d);await this.yieldBetweenBatches()}let k=await or(this.db,null)-this.config.globalMaxObservations;if(k>0)await this.evictOldest(null,k,this.config.globalMaxObservations,d)}async evictOldest(d,c,w,D){let k=c,P=0,C=!1,M=d===null?void 0:[d],F=await this.resolveProtectedBuildKeyIds(this.db,void 0,M);while(k>0){if(C){if(k=Math.max(0,await or(this.db,d)-w),C=!1,k===0)return}let q=Math.min(k,this.config.evictionChunkSize),U=await this.db.transaction().execute(async(K)=>{let W=await mg(K,d,F,q);if(W.length===0){let oe=await this.resolveProtectedBuildKeyIds(K,void 0,M);return{evictedCount:0,protectionChanged:!Ii(oe,F)}}let V=await this.resolveProtectedBuildKeyIds(K,void 0,M);if(!Ii(V,F))return{evictedCount:0,protectionChanged:!0};let z=await $d(K,W.map((oe)=>oe.buildKeyId)),J=new Set(V),X=W.filter((oe)=>!J.has(oe.buildKeyId)||oe.lastSeenAt<(z.get(oe.buildKeyId)??Number.NEGATIVE_INFINITY));if(X.length===0)return{evictedCount:0,protectionChanged:!1};let ee=X.filter((oe)=>oe.kind==="node").map((oe)=>oe.id),ne=X.filter((oe)=>oe.kind==="edge").map((oe)=>oe.id),te=X.filter((oe)=>oe.kind==="suggestion").map((oe)=>oe.id);if(ee.length>0){let oe=await K.deleteFrom("navigation_node_observations").where("id","in",ee).executeTakeFirst();D.nodeObservationsDeleted+=Number(oe.numDeletedRows??0)}if(ne.length>0){let oe=await K.deleteFrom("navigation_edge_observations").where("id","in",ne).executeTakeFirst();D.edgeObservationsDeleted+=Number(oe.numDeletedRows??0)}if(te.length>0){let oe=await K.deleteFrom("navigation_suggestion_observations").where("id","in",te).executeTakeFirst();D.suggestionObservationsDeleted+=Number(oe.numDeletedRows??0)}return{evictedCount:X.length,protectionChanged:!1}});if(U.evictedCount===0){if(U.protectionChanged)F=await this.resolveProtectedBuildKeyIds(this.db,void 0,M);if(U.protectionChanged&&await this.retryAfterProtectionChange("cap eviction",++P)){C=!0;continue}return}if(P=0,k-=U.evictedCount,k>0)await this.yieldBetweenBatches(),C=!0}}async pruneOrphanBuildKeys(d){let c=this.config.evictionChunkSize,w=async(P)=>{let C=await nr(P),M=await this.resolveProtectedBuildKeyIds(P,C),F=new Map(C.map((U)=>[U.id,U.appId])),q=new Map(M.map((U)=>[F.get(U),U]));return{ids:M,byApp:q}},D=await w(this.db),k=0;for(;;){let P=await this.db.transaction().execute(async(M)=>{let F=M.selectFrom("navigation_build_keys").select(["id","app_id"]).where("id","not in",(X)=>X.selectFrom("navigation_node_observations").select("build_key_id")).where("id","not in",(X)=>X.selectFrom("navigation_edge_observations").select("build_key_id")).where("id","not in",(X)=>X.selectFrom("navigation_suggestion_observations").select("build_key_id"));if(D.ids.length>0)F=F.where("id","not in",D.ids);let q=await F.limit(c).execute();if(q.length===0)return{deleted:0,protectionChanged:!1};if(q.some((X)=>!D.byApp.has(X.app_id)))return{deleted:0,protectionChanged:!0,currentProtection:await w(M)};let U=Array.from(new Set(q.map((X)=>D.byApp.get(X.app_id)).filter((X)=>X!==void 0))),K=await M.selectFrom("navigation_build_keys").select("id").where("id","in",U).execute(),W=new Set(K.map((X)=>X.id));if(U.some((X)=>!W.has(X)))return{deleted:0,protectionChanged:!0};let V=Array.from(new Set(q.filter((X)=>X.id>(D.byApp.get(X.app_id)??0)).map((X)=>D.byApp.get(X.app_id)).filter((X)=>X!==void 0))),z=await $d(M,V);if(V.some((X)=>!z.has(X)))return{deleted:0,protectionChanged:!0};let J=await M.deleteFrom("navigation_build_keys").where("id","in",q.map((X)=>X.id)).executeTakeFirst();return{deleted:Number(J.numDeletedRows??0),protectionChanged:!1}});if(d.buildKeysDeleted+=P.deleted,P.deleted>0)k=0;let C=P.protectionChanged;if(C||P.deleted===0){let M=P.currentProtection??await w(this.db);C||=!Ii(M.ids,D.ids),D=M}if(C&&await this.retryAfterProtectionChange("orphan sweep",++k))continue;if(C)return;if(P.deleted<c)return;await this.yieldBetweenBatches()}}}class Kd{retention;timer;timerHandle=null;running=!1;intervalMs;lastSummary=null;constructor(d,c=i,w){this.retention=d;this.timer=c;this.intervalMs=Fd(w)}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 Yt().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 Gd{host;constructor(d){this.host=d}startHealthCheckTimer(){this.host.setHealthCheck(Wh({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?.()??(()=>wJ(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 Ed(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)=>YH(this.host.services.sessionManager(),this.host.services.devicePool(),d)})),this.host.lifecycle.heartbeatMonitor().start()}startNavigationRetentionMonitor(){let d=new Ur,c=new Hd(_e(),{},{removeScreenshotFile:(w)=>d.unlink(w)});this.host.lifecycle.setNavigationRetentionMonitor(new Kd(c,this.host.services.timer())),this.host.lifecycle.navigationRetentionMonitor().start()}startForwardLeaseIdleReleaser(){let d=XH((c)=>this.host.services.sessionManager().getSessionForDevice(c));this.host.lifecycle.setForwardLeaseIdleReleaser(new Bd({heldDeviceIds:()=>E.getForwardLeaseHeldDeviceIds(),activity:(c)=>xN(d,c),release:(c)=>E.releaseIdleForwardLease(c)},lB(),this.host.services.timer())),this.host.lifecycle.forwardLeaseIdleReleaser().start()}startPrivateDaemonOrphanWatchdog(){if(process.platform==="win32"||!Xh(Lt,iB))return;let d=Yh(UW);this.host.lifecycle.setOrphanWatchdog(new Od({parentPid:()=>process.ppid,launcherPid:()=>d,launcherIsExplicit:()=>d!==UW,isProcessRunning:(c)=>at(c),clientCount:()=>(this.host.lifecycle.socketServer()?.getClientConnectionCount()??0)+Rne()+this.host.services.httpIngress().openRequestCount,clientActivityCount:()=>(this.host.lifecycle.socketServer()?.getAcceptedClientConnectionCount()??0)+Pne()+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"))}},zh(),this.host.services.timer())),this.host.lifecycle.orphanWatchdog().start()}async attemptRecovery(d="unknown"){try{if(e.info("Attempting daemon recovery..."),d==="database"){e.error("Database health check failed repeatedly; exiting daemon for a clean restart."),await this.host.recoverFromDatabaseHealthFailure()(1,this.host.lastDatabaseHealthFailure());return}if(this.host.lifecycle.socketServer()&&!this.host.lifecycle.socketServer().isListening()){e.info("Restarting socket server...");try{await this.host.lifecycle.socketServer().close()}catch(c){e.warn(`Error closing socket server during recovery: ${c}`)}this.host.lifecycle.setSocketServer(new Ri(Lt,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:br,sockets:ot(),dbPath:Dp(),processStartedAt:this.host.identityState.processStartedAt(),onRestartAccepted:()=>{setImmediate(()=>process.kill(process.pid,"SIGTERM"))},liveAcceptanceStartupSecret:this.host.identityState.liveAcceptanceStartupSecret(),acceptanceDiscoveryCapability:this.host.identityState.acceptanceDiscoveryCapability(),mcpDispatcher:this.host.services.mcpDispatcher()},this.host.services.idGenerator(),{ownerLiveness:this.host.identityState.incumbentOwnerGuard().asSocketOwnerLiveness()}));try{await this.host.lifecycle.socketServer().start(),this.host.identity.recordControlSocketIdentity(),e.info("Socket server restarted successfully")}catch(c){e.error(`Failed to restart socket server: ${c}`)}}if(!this.host.observationStreamHealth().isHealthy()){e.info("Restarting observation stream socket server...");try{await this.host.observationStreamHealth().recover(),this.host.configureDeviceDataStreamServer();let c=this.host.observationStreamHealth().isHealthy();(c?e.info:e.warn)(c?"Observation stream socket server restarted successfully":"Observation stream socket server remains unavailable after recovery")}catch(c){e.error(`Failed to restart observation stream socket server: ${c}`)}}}catch(c){e.error(`Recovery attempt failed: ${c}`)}}get testHooks(){return{observationStreamHealth:()=>this.host.observationStreamHealth(),setObservationStreamHealth:(d)=>{this.host.setObservationStreamHealth(d)},healthCheck:()=>this.host.healthCheck(),lastDatabaseHealthFailure:()=>this.host.lastDatabaseHealthFailure(),startHealthCheckTimer:()=>this.startHealthCheckTimer(),stopHealthCheckTimer:()=>this.stopHealthCheckTimer()}}}class Ti{sessions;plans;executions;constructor(d,c=N,w=G){this.sessions=d;this.plans=c;this.executions=w}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((w)=>w.executionId?[w.executionId]:[])}bindPlanExecutions(d,c){for(let w of this.leasesForDevice(d,c))if(w.executionId)this.executions.bindDeviceExecution(w.executionId,d,{skipRevoked:!0})}cancelPlanExecutions(d,c,w){return this.bindPlanExecutions(d,c),this.executions.cancelDeviceExecutions(d,w,{onlySessionUuid:c,onlyToolName:"executePlan",includeExecutionIds:this.getPlanExecutionIds(d,c)})}leasesForDevice(d,c){let w=new Set(this.sessions.getAllSessions().filter((D)=>D.assignedDevice===d).map((D)=>D.sessionId));return this.plans.getActivePlanExecutions().filter((D)=>{if(!D.sessionUuid)return c===void 0&&D.deviceId===d;let k=[D.sessionUuid,...D.labelSessionUuids??[]];return(c===void 0||this.ownerSession(D.sessionUuid)===this.ownerSession(c))&&k.some((P)=>w.has(P))})}ownerSession(d){return _B(d,this.sessions)}}var yg=15000,bg=hy,gg=bg-2,dP=60000;function cP(d,c){return c!==void 0&&(d.transitionalSimulators?.length??0)>0}function lP(d,c){if(d!=="either")return{};let w=u$(c.map((D)=>D.platform));return{includeWatchOs:!0,...w.length>0?{includeAppleSimulatorPlatforms:w}:{}}}async function wg(d,c,{isPlanDevice:w=()=>!1,platform:D="either",bypassAndroidDeviceListCache:k=!1,heldDevices:P=[],iosDeviceListMaxAgeMs:C}){let M=[...d.getAllDevices().map((J)=>({platform:J.platform,id:J.id})),...P.map((J)=>({platform:J.platform,id:J.assignedDevice}))],F={bypassAndroidDeviceListCache:k,skipAndroidProfileEnrichment:!0,...lP(D,M),skipPhysicalIosDiscovery:!M.some((J)=>bo(J.platform,J.id)==="ios-physical")},q=async(J)=>{let X=await c.getBootedDevicesDetailed(D,J);return X.devices=await uP(d,X.devices),X},U=await q({...F,...C===void 0?{}:{iosDeviceListMaxAgeMs:C}}),K=cP(U,C),W=new Set(U.devices.map((J)=>J.deviceId)),V=M.filter((J)=>!w(J.id)&&!W.has(J.id));if(K||V.some((J)=>hi(U,J.platform,J.id)&&(J.platform==="ios"||!k)))U=await q({...F,bypassAndroidDeviceListCache:k||V.some((J)=>J.platform==="android"),bypassIosDeviceListCache:K||V.some((J)=>bo(J.platform,J.id)==="ios-simulator"),bypassPhysicalIosDeviceListCache:V.some((J)=>bo(J.platform,J.id)==="ios-physical")});let z=U.devices.filter((J)=>!w(J.deviceId));if(z.length>0||M.some((J)=>!w(J.id)))await d.reconcileDiscoveryObservation(z,"disconnect-monitor",{settleMembership:!0});return U}async function uP(d,c){let w=d.mapAndroidDiscovery(c),D=new Set(w.map((F)=>F.deviceId)),k=d.getAllDevices().filter((F)=>F.platform==="android"),P=new Set(k.map((F)=>F.id));if(!w.some((F)=>F.platform==="android"&&!P.has(F.deviceId)&&Ko(F.deviceId)))return w;if(!k.some((F)=>!D.has(F.id)&&[F.id,...d.getAndroidTransportAliases(F.id)].some(Ko)))return w;return await d.normalizeAndroidDiscovery(c,!1,()=>!0,!1)}function Rg(d,c){return new Map([...c].flatMap((w)=>d.getAndroidTransportAliases(w).map((D)=>[D,w])))}async function Dg(d,c,w){let D=[...w],k=Rg(d,D),P=await c.getAndroidOfflineDeviceIds(new Set([...D,...k.keys()]));return new Set([...P].map((C)=>k.get(C)??C))}function pP(d,c,w){return new Set([...d].filter((D)=>!c.has(D)&&w.get(D)==="android"))}async function kg(d,c,w,{candidateDeviceIds:D,bootedDeviceIds:k,candidatePlatforms:P}){if(w)return{};let C=pP(D,k,P),M=Rg(d,C);try{let F=C.size>0?await c.getAndroidListedDeviceStates(new Set([...C,...M.keys()])):new Map,q=[...F].map(([K,W])=>[M.get(K)??K,W]),U=new Map;for(let[K,W]of F){let V=M.get(K)??K;if(W==="offline"&&C.has(V)){let z=U.get(V)??new Set;z.add(K),U.set(V,z)}}return{offlineTransportIds:U,listedNonDeviceIds:new Set(q.map(([K])=>K)),offlineDeviceIds:new Set(q.filter(([,K])=>K==="offline").map(([K])=>K)),transitionalAdbDeviceIds:new Set(q.filter(([,K])=>Y1(K)).map(([K])=>K))}}catch(F){if(!(F instanceof Ok))throw F;return e.warn(`[DisconnectMonitor] Retaining offline recovery attempts: ${r(F)}`),{}}}function Ag(d,c,w){return TX(w.transitionalAdbDeviceIds,gy({transitional:c.transitionalSimulators,discovered:c.devices,devicePool:d}).map(({device:D})=>D.deviceId))}function Pg(d,c,w){let D=new Set,k=new Map,P=AX(w);for(let C of w)D.add(C.deviceId),k.set(C.deviceId,C.platform);for(let C of d.getAllDevices())D.add(C.id),k.set(C.id,C.platform),P.set(C.id,C.incarnation);for(let C of c.getAllSessions())if(D.add(C.assignedDevice),!k.has(C.assignedDevice))k.set(C.assignedDevice,C.platform);return{candidateDeviceIds:D,candidatePlatforms:k,candidateIncarnations:P}}function Ig(d,c,w){let D=d.length>0,k=new Map(d.map((P)=>[P.id,P]));if(D){e.warn("[DisconnectMonitor] All AutoMobile-owned Android emulators disappeared together; treating this as an ADB server reset and recovering by AVD name");for(let P of d)c.set(P.id,[])}for(let P of w)if(c.has(P.deviceId))c.get(P.deviceId).push(P.recordingId);return k}function Cg(d,c,w,D){for(let{deviceId:k,misses:P,budgetExhausted:C}of c.missed){let M=w.has(k),F=M?Math.min(P,gg):P;if(M)d.set(k,F);let U=`[DisconnectMonitor] Device ${k} not in booted list (${C?"budget exhausted":"absent"}, miss ${F}/${bg}, booted=${D.size})`;if(M&&P>gg)e.debug(U);else e.info(U)}for(let{deviceId:k,transitionalForMs:P}of c.transitional)e.info(`[DisconnectMonitor] Device ${k} listed in a transitional state for ${Math.round(P/1000)}s (budget ${JG/1000}s); keeping session`)}async function Tg(d,c,w){let{timer:D,stoppingRecordings:k}=d;if(k.has(c))return!1;k.add(c);let P=mP(c,w).finally(()=>k.delete(c)),C=Error("recording stop still running");try{return await l(P,{timer:D,timeoutMs:dP,label:"Stop recording after device disconnect",timeoutError:()=>C})}catch(M){if(M!==C)throw M;return e.warn(`[Daemon] Recording ${c} is still finishing after device ${w} disconnected; releasing the device without waiting`),!0}}async function mP(d,c){try{return await C1(d),e.warn(`[Daemon] Stopped recording ${d} after device ${c} disconnected`),!0}catch(w){return e.warn(`[Daemon] Failed to stop recording ${d} after device ${c} disconnected: ${w}`),await fP(d,c)}}async function fP(d,c){try{return await ql(d),e.warn(`[Daemon] Marked recording ${d} interrupted after device ${c} disconnected`),!0}catch(w){return e.warn(`[Daemon] Failed to mark recording ${d} interrupted after device ${c} disconnected: ${w}`),!1}}function Wd(d,c){return d!==null&&d!==void 0&&(!wr(d)||!!O(d))||c}var hP=120000;function gP(d,c){if(c===void 0)return;return{signature:c,unchanged:d?.signature===c?d.unchanged+1:0}}function vP(d,c,w=hP){return Q({initialDelayMs:d,maxDelayMs:w}).delayForAttempt(c+1)}function yP(d,c,w){return JSON.stringify([[...d].sort(),[...c].sort(),[...w].sort()])}function SP(d,c,w,D){if(w===void 0||c-w>=D)return"either";let k=d.filter(cr),P=k[0];return P&&k.every((C)=>C===P)?P:"either"}class Vd{cadence;lastSweepAt;lastEitherSweepAt;idleState;watching=!1;constructor(d,c){this.cadence=d;this.lastSweepAt=c}shouldRun(d,c){let w=this.watching;if(this.watching=d,d){if(this.idleState=void 0,!w)this.lastEitherSweepAt=void 0}if(!d&&c-this.lastSweepAt<vP(this.cadence.idleIntervalMs,this.idleState?.unchanged??0,this.cadence.maxIdleIntervalMs))return!1;return this.lastSweepAt=c,!0}selectPlatform(d,c,w){let D=this.watching&&!w?SP(d,c,this.lastEitherSweepAt,this.cadence.idleIntervalMs):"either";if(D==="either")this.lastEitherSweepAt=c;return D}recordSuccess(d){if(!this.watching)this.idleState=gP(this.idleState,d)}recordFailure(){this.idleState=void 0,this.lastEitherSweepAt=void 0}}function Mg(d,c,w,{bootedDeviceIds:D,pooledDeviceIds:k}){if(d.size===0||c!==0||![...w].every((P)=>D.has(P)))return;return yP(D,k,d)}function ar(d,c,w,D){let k=D.filter((P)=>P.platform==="android"&&P.avdName!==void 0&&P.androidImage!==void 0&&P.id.startsWith("emulator-"));if(!c.has("android")||k.length<2||!k.every((P)=>!d.has(P.id))||!k.some((P)=>w.has(P.id)))return[];return k}function Jd(d,c,w,D){return ar(d,c,w,D).length>0}function Eg(d,c,w){let D=d.services.devicePool().getDevice(c),k=D?.assignmentCount,P=O(D)??d.services.sessionManager().getSessionForDevice(c),C=P?d.services.sessionManager().getSession(P):null,M=d.forceDisconnectedDeviceGenerations().get(c),F=w.get(c);return{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k,sessionIdAtDisconnect:P,sessionAtDisconnect:C,forceGenerationAtDisconnect:M,adbServerResetTarget:F}}function Og(d,c,{pooledDeviceAtDisconnect:w,assignmentCountAtDisconnect:D,sessionIdAtDisconnect:k,sessionAtDisconnect:P}){if(w){if(d.services.devicePool().getDevice(c)!==w||w.assignmentCount!==D)return!1}else if(d.services.devicePool().getDevice(c))return!1;if(!k)return d.services.sessionManager().getSessionForDevice(c)===null;return d.services.sessionManager().getSessionForDevice(c)===k&&d.services.sessionManager().getSession(k)===P}var bP=5000,wP=30000;class Yd{host;constructor(d){this.host=d}hasPlanExecution(d,c){return new Ti(this.host.services.sessionManager()).hasPlanExecution(d,c)}async tryRecoverCapturedDisconnectTarget(d){let{deviceId:c,incidentId:w,pooledDevice:D,sessionId:k,session:P,forceGeneration:C,preparation:M}=d;if(!M){if(k&&await this.host.services.devicePool().waitForSessionPreservingRecovery(k,w))return this.host.retireAdbServerResetDisconnectState(c,C),!0;if(k&&this.host.services.devicePool().isSessionRecoveryInFlight(k))return await this.host.services.devicePool().finishEmulatorLossIncident(w,"not-attempted"),this.host.retireAdbServerResetDisconnectState(c,C),!0}if(!D||!k||!P)return!1;if(this.host.services.devicePool().finishSessionPreservingRecoveryPreparation(M),await this.host.services.devicePool().recoverSessionBoundDeviceAfterLoss(c,w,D)==="not-attempted")return!1;return this.host.retireAdbServerResetDisconnectState(c,C),!0}async recordAndTryRecoverCapturedDisconnect(d,c){let{pooledDeviceAtDisconnect:w,assignmentCountAtDisconnect:D,sessionIdAtDisconnect:k,sessionAtDisconnect:P,forceGenerationAtDisconnect:C}=c;if(await this.host.services.devicePool().isShutdownReservationHeld(d))return await this.host.services.devicePool().removeDisconnectedDevice(d,!0,void 0,w??void 0),{incidentId:void 0,handled:!0};let M=this.host.services.devicePool().prepareSessionPreservingRecovery(d,w??void 0);try{let F=await this.host.services.devicePool().recordEmulatorLossIncident(d,this.host.forceDisconnectedDeviceIds().has(d)?"adb-transport-failure":"device-discovery-miss",void 0,"absent");if(await this.host.shouldSkipStaleDisconnectCleanup(w,d,C)||!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:w,assignmentCountAtDisconnect:D,sessionIdAtDisconnect:k,sessionAtDisconnect:P}))return await this.host.services.devicePool().finishEmulatorLossIncident(F,"not-attempted"),{incidentId:F,handled:!0};let U=await this.tryRecoverCapturedDisconnectTarget({deviceId:d,incidentId:F,pooledDevice:w,sessionId:k,session:P,forceGeneration:C,preparation:M});return{incidentId:F,handled:U}}finally{this.host.services.devicePool().finishSessionPreservingRecoveryPreparation(M)}}startDeviceDisconnectMonitor(d=new si,c=this.host.listActiveVideoRecordings,w=SB,D={activeIntervalMs:bP,idleIntervalMs:wP}){if(this.host.lifecycle.deviceDisconnectMonitor())return;let k=this.createPlanDeviceLossCheck(d,(C)=>this.discoverAndReconcile(d,{platform:C,bypassAndroidDeviceListCache:!0}),w),P=new Vd(D,this.host.services.timer().now());this.host.lifecycle.setDeviceDisconnectMonitor(new gl(this.host.services.timer(),D.activeIntervalMs,async()=>{let C={adbServerResetCohort:[],selectPlatform:(M,F)=>P.selectPlatform(M,this.host.services.timer().now(),F)};try{await this.checkDisconnects(d,c,w,{checkPlanDeviceLoss:k,sweep:C}),P.recordSuccess(C.idleSignature)}catch(M){P.recordFailure(),e.warn(`[Daemon] Device disconnect monitor failed: ${M}`)}finally{if(C.adbServerResetCohort.length>0)await this.host.services.devicePool().releaseAdbServerResetCohortReservations(C.adbServerResetCohort)}},{shouldRun:async()=>{let C=this.host.services.devicePool(),M=this.host.services.sessionManager().getAllSessions().length>0||C.getAllDevices().some(({id:F})=>{let q=C.getDevice(F);return Wd(q,C.isDeviceLeasedForAndroidStartup(F))})||N.isPlanExecutionActive()||(await c()).length>0;return P.shouldRun(M,this.host.services.timer().now())}})),this.host.lifecycle.deviceDisconnectMonitor().start()}discoverAndReconcile(d,c){return wg(this.host.services.devicePool(),d,{...c,isPlanDevice:(w)=>this.hasPlanExecution(w),heldDevices:[...this.host.services.sessionManager().getAllSessions(),...c.heldDevices??[]]})}logDisconnectMisses(...d){Cg(this.host.lifecycle.deviceDisconnectMisses(),...d)}collectDisconnectCandidates(d){return Pg(this.host.services.devicePool(),this.host.services.sessionManager(),d)}createPlanDeviceLossCheck(d,c,w=SB){let D=new G1({timer:this.host.services.timer(),isTransportRestarting:(k)=>w.isRestarting(k),getDevice:(k)=>this.host.services.devicePool().getDevice(k),getPlanSessionUuid:(k)=>st(k,this.host.services.sessionManager())??k,hasPlanExecution:(k,P)=>this.hasPlanExecution(k,P),getPlanExecutionIds:(k,P)=>new Ti(this.host.services.sessionManager()).getPlanExecutionIds(k,P),isStartupLeased:(k)=>this.host.services.devicePool().isDeviceLeasedForAndroidStartup(k),isShutdownReserved:(k)=>this.host.services.devicePool().isShutdownReservationHeld(k),discover:c,getOfflineDeviceIds:(k)=>Dg(this.host.services.devicePool(),d,k),isAdbReset:(k,P)=>Jd(k,P.succeededPlatforms,new Set(this.host.services.devicePool().getAllDevices().filter((C)=>!k.has(C.id)).map((C)=>C.id)),this.host.services.devicePool().getAllDevices()),recordLoss:(k)=>this.host.services.devicePool().recordEmulatorLossIncident(k,this.host.forceDisconnectedDeviceIds().has(k)?"adb-transport-failure":"device-discovery-miss",void 0,"absent"),finishLoss:(k)=>this.host.services.devicePool().finishEmulatorLossIncident(k,"not-attempted"),cancelPlan:(k,P,C)=>new Ti(this.host.services.sessionManager()).cancelPlanExecutions(k,P,C)});return async(k,P)=>{await D.check(k.missed.map(({deviceId:C})=>C),P),e.debug("[DisconnectMonitor] Checked device-scoped plan loss evidence")}}startDeferredSessionRecoverySweep(){this.host.trackDeferredSessionRecoverySweep(this.host.services.devicePool().retryDueDeferredSessionRecoveries((d)=>!this.hasPlanExecution(d)).catch((d)=>{e.warn(`[DisconnectMonitor] Deferred session recovery sweep failed: ${d}`,d)}))}prepareOfflineRecovery(d,c,w){this.host.setOfflineRecoveryAttemptedDeviceIds(EX(this.host.offlineRecoveryAttemptedDeviceIds(),d,c,{attemptedIncarnations:this.host.offlineRecoveryAttemptedIncarnations(),candidateIncarnations:w}));let D=new Set([...c??[]].filter((C)=>!this.hasPlanExecution(C)&&this.host.services.devicePool().isDeviceLeasedForAndroidStartup(C))),k=IX(c??new Set,d,this.host.offlineRecoveryAttemptedDeviceIds(),new Set([...D,...[...c??[]].filter((C)=>this.hasPlanExecution(C))])),P=D.size>0?[]:k;return this.host.setOfflineRecoveryAttemptedDeviceIds(new Set([...this.host.offlineRecoveryAttemptedDeviceIds(),...P])),this.host.setOfflineRecoveryAttemptedIncarnations(new Map([...w].filter(([C])=>this.host.offlineRecoveryAttemptedDeviceIds().has(C)))),{dispatchTargets:P,offlineRecoveryTargets:k}}async recoverOfflineCandidates(d,c,w,D){if([...w].every((M)=>this.hasPlanExecution(M)))return!1;let k=c.offlineDeviceIds&&new Set([...c.offlineDeviceIds,...[...this.host.offlineRecoveryAttemptedDeviceIds()].filter((M)=>this.hasPlanExecution(M))]),{dispatchTargets:P}=this.prepareOfflineRecovery(w,k,D);if(P.length===0)return!1;e.warn(`[DisconnectMonitor] In-session device(s) ADB-offline (${P.join(", ")}); attempting bounded 'adb -s <serial> reconnect' recovery before miss-counting`);let C=P.flatMap((M)=>{let F=c.offlineTransportIds?.get(M);return F?.size?[...F]:[M]});return await d.recoverAndroidOfflineDevices(C),P.filter((M)=>!C.includes(M)).forEach((M)=>Gw(M,"adb_reconnect")),!0}captureDisconnectCleanup(d,c){return this.host.captureDisconnectCleanup(d,c)}confirmDisconnectedDeviceCleanup(d,c){if(this.host.confirmedDisconnectedDeviceIds().add(d),this.host.lifecycle.deviceDisconnectMisses().reset(d),this.host.deviceDisconnectMissIncarnations().delete(d),this.host.offlineRecoveryAttemptedDeviceIds().delete(d),this.host.offlineRecoveryAttemptedIncarnations().delete(d),this.host.offlineEpisodes().delete(d),this.host.forceDisconnectedDeviceGenerations().get(d)===c)this.host.forceDisconnectedDeviceIds().delete(d),this.host.forceDisconnectedDeviceGenerations().delete(d)}async cleanupDisconnectedDevice(d,c,w){let D=this.captureDisconnectCleanup(d,w),{pooledDeviceAtDisconnect:k,forceGenerationAtDisconnect:P,adbServerResetTarget:C}=D;if(!C&&await this.host.shouldSkipStaleDisconnectCleanup(k,d,P))return;let M=!0;xc().stopMonitoring(d);for(let F of c)if(!await this.host.stopRecordingAfterDeviceDisconnect(F,d))M=!1;if(!C&&await this.host.shouldSkipStaleDisconnectCleanup(k,d,P))return;if(C){if(await this.tryRecoverProcessWideAdbServerResetDevice(d,C,P))return}return this.finishDisconnectedDeviceCleanup(d,D,M)}async finishDisconnectedDeviceCleanup(d,c,w){let{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k,sessionIdAtDisconnect:P,sessionAtDisconnect:C,forceGenerationAtDisconnect:M}=c,{incidentId:F,handled:q}=await this.host.recordAndTryRecoverCapturedDisconnect(d,{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k??0,sessionIdAtDisconnect:P,sessionAtDisconnect:C,forceGenerationAtDisconnect:M});if(q)return;if(!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k,sessionIdAtDisconnect:P,sessionAtDisconnect:C})){await this.host.services.devicePool().finishEmulatorLossIncident(F,"not-attempted");return}if(P&&C)e.warn(`[DisconnectMonitor] Device ${d} confirmed disconnected \u2014 cancelling session ${P}`),await this.host.cancelAndReleaseSession(P,Fn(d,F),{expectedSession:C});if(!this.host.isCapturedDisconnectTargetCurrent(d,{pooledDeviceAtDisconnect:D,assignmentCountAtDisconnect:k})){await this.host.services.devicePool().finishEmulatorLossIncident(F,"not-attempted");return}if(await this.host.services.devicePool().removeDisconnectedDevice(d,!0,F,D??void 0),this.host.services.devicePool().getDevice(d))w=!1;else this.host.lifecycle.socketServer()?.evictDeviceInputCache(d);if(w)this.confirmDisconnectedDeviceCleanup(d,M)}trackDeferredSessionRecoverySweep(d){this.host.lifecycle.deferredSessionRecoverySweeps().add(d),d.then(()=>this.host.lifecycle.deferredSessionRecoverySweeps().delete(d),()=>this.host.lifecycle.deferredSessionRecoverySweeps().delete(d))}async tryRecoverProcessWideAdbServerResetDevice(d,c,w){try{return await this.recoverProcessWideAdbServerResetDevice(d,c,w)}catch(D){return e.warn(`[DisconnectMonitor] ADB-reset recovery failed for ${d}; continuing cohort cleanup: ${D}`),!1}}async recoverProcessWideAdbServerResetDevice(d,c,w){if(!await this.host.services.devicePool().recoverSessionBoundAndroidDeviceAfterAdbServerReset(d,c))return this.host.retireAdbServerResetDisconnectState(d,w),!1;return this.host.retireAdbServerResetDisconnectState(d,w),!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 Tg({timer:this.host.services.timer(),stoppingRecordings:this.host.stoppingRecordings()},d,c)}async shouldSkipStaleDisconnectCleanup(d,c,w=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)===w)this.host.forceDisconnectedDeviceIds().delete(c),this.host.forceDisconnectedDeviceGenerations().delete(c);return e.info(`[DisconnectMonitor] Skipping stale disconnect cleanup for recovered device ${c}`),!0}let D=await this.host.services.devicePool().isCurrentDisconnectedDevice(d);if(D==="current")return!1;if(D==="unknown")return e.warn(`[DisconnectMonitor] Retaining disconnect state for ${c}: recovery verification was inconclusive`),!0;if(this.host.lifecycle.deviceDisconnectMisses().reset(c),this.host.deviceDisconnectMissIncarnations().delete(c),this.host.confirmedDisconnectedDeviceIds().delete(c),this.host.forceDisconnectedDeviceGenerations().get(c)===w)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(Lre((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,w,{checkPlanDeviceLoss:D,sweep:k}){this.startDeferredSessionRecoverySweep();let P=await c(),C=P.map(({deviceId:ae,platform:ur})=>({assignedDevice:ae,platform:ur})),M=this.host.services.devicePool().getAllDevices(),F=this.host.services.sessionManager().getAllSessions(),q=[...M.map(({id:ae})=>ae),...F.flatMap(({assignedDevice:ae})=>ae===void 0?[]:[ae]),...P.map(({deviceId:ae})=>ae)].some((ae)=>this.hasPlanExecution(ae)),U=k.selectPlatform([...M.filter((ae)=>Wd(ae,this.host.services.devicePool().isDeviceLeasedForAndroidStartup(ae.id))).map((ae)=>ae.platform),...F.map((ae)=>ae.platform),...P.map((ae)=>ae.platform)],q),K=await this.discoverAndReconcile(d,{iosDeviceListMaxAgeMs:yg,platform:U,heldDevices:C}),W=K.succeededPlatforms,V=new Set(K.devices.map((ae)=>ae.deviceId)),z=new Map,{candidateDeviceIds:J,candidatePlatforms:X,candidateIncarnations:ee}=this.collectDisconnectCandidates(P),ne=new Set([...J].filter((ae)=>this.hasPlanExecution(ae))),te=new Set([...J].filter((ae)=>!ne.has(ae))),oe=U==="ios"?{}:await kg(this.host.services.devicePool(),d,!1,{candidateDeviceIds:te,bootedDeviceIds:V,candidatePlatforms:X});if(await this.recoverOfflineCandidates(d,oe,J,ee))K=await this.discoverAndReconcile(d,{heldDevices:C,platform:U,bypassAndroidDeviceListCache:!0}),W=K.succeededPlatforms,V=new Set(K.devices.map((ae)=>ae.deviceId));let pe=_X({deviceDisconnectMisses:this.host.lifecycle.deviceDisconnectMisses(),confirmedDisconnectedDeviceIds:this.host.confirmedDisconnectedDeviceIds(),bootedDeviceIds:V,candidateDeviceIds:J,succeededPlatforms:W,succeededSources:K.succeededSources,candidatePlatforms:X,candidateIncarnations:ee,deviceDisconnectMissIncarnations:this.host.deviceDisconnectMissIncarnations(),forceDisconnectedDeviceIds:this.host.forceDisconnectedDeviceIds(),transitionalDeviceIds:Ag(this.host.services.devicePool(),K,oe),offlineEpisodes:this.host.offlineEpisodes(),nowMs:this.host.services.timer().monotonicNow?.()??this.host.services.timer().now(),immediateDisconnectDeviceIds:kX(J,X,V,{listedNonDeviceIds:oe.listedNonDeviceIds,transportRestarts:w})});if(pe.skippedAllDiscoveryFailed){e.warn(`[DisconnectMonitor] No platform discovery succeeded but ${J.size} tracked \u2014 skipping miss count`);return}ne=new Set([...ne,...[...J].filter((ae)=>this.hasPlanExecution(ae))]),this.logDisconnectMisses(pe,ne,V),await D(pe,V);for(let ae of pe.disconnected.filter((ur)=>!ne.has(ur)))z.set(ae,[]);k.idleSignature=Mg(K.succeededPlatforms,this.host.lifecycle.deviceDisconnectMisses().size,J,{bootedDeviceIds:V,pooledDeviceIds:this.host.services.devicePool().getAllDevices().map((ae)=>ae.id)}),await this.cleanupDisconnects(V,W,z,{activeRecordings:P,sweep:k})}async cleanupDisconnects(d,c,w,{activeRecordings:D,sweep:k}){let P=ar(d,c,this.host.forceDisconnectedDeviceIds(),this.host.services.devicePool().getAllDevices()),C=P.some((U)=>this.hasPlanExecution(U.id));if(C)for(let U of P)w.delete(U.id);let M=C?[]:P,F=M.length>0?await this.host.services.devicePool().detachAdbServerResetCohort(M):{devices:[],deferred:!1};if(F.deferred){e.info("[DisconnectMonitor] Deferring process-wide ADB reset recovery until matching Android startup completes");return}k.adbServerResetCohort=F.devices;let q=Ig(k.adbServerResetCohort,w,D);for(let[U,K]of w)if(!this.hasPlanExecution(U))await this.host.cleanupDisconnectedDevice(U,K,q)}}async function xg(d){let c=new Pa(jb),w=await G.cancelToolExecutions("provisionDevice",c);if(w===0)return;if(!await G.waitForToolExecutionsToEnd("provisionDevice",d))e.warn(`Timed out after ${d}ms persisting ${w} interrupted provisionDevice operation(s) before daemon shutdown`)}async function Qd(d){if(!await Yt().drain(d))e.warn(`Timed out after ${d}ms draining in-flight DB writes; closing database anyway`)}async function _g(d){if(!await _9(d))e.warn(`Timed out after ${d}ms awaiting in-flight startup migration; closing database anyway`)}async function Fg(d,c,w=sc){let D=w.pendingDeviceIds();if(D.length===0)return;let k=new AbortController,P=d.setTimeout(()=>k.abort(Error(`IME restore exceeded its ${c}ms shutdown bound`)),c);try{let C=await Promise.allSettled(D.map((M)=>w.flush(M,{signal:k.signal})));for(let[M,F]of C.entries())if(F.status==="rejected")e.warn(`[SendKeys] Shutdown IME restoration failed on ${D[M]}`,F.reason)}finally{d.clearTimeout(P)}}function Ng(d){return(c)=>{if(c.type==="uncaughtException"){d.error(`[daemon] uncaughtException in background task; keeping daemon alive: ${Vp(c.error)}`,c.error);return}d.error(`[daemon] unhandledRejection in background task; keeping daemon alive: ${Vp(c.reason)}`,c.reason)}}function se(d,c,w){return H4(U4,d,c,w)}var RP=1000,DP=2000,$g=1000,kP=1000,AP=3000,PP=5000;class Zd{host;shutdownHandlersRegistered=!1;shutdownSessionReleasesDrained=!0;shutdownSessionIds=[];constructor(d){this.host=d}setupShutdownHandlers(){if(this.shutdownHandlersRegistered)return;this.shutdownHandlersRegistered=!0,c0(),z7(),DS(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"),pz(this.host.getDaemonFileCleanupOptions())}),d0(Ng(e))}async stop(){this.host.lifecycle.setShutdownInProgress(!0),e.info("Stopping daemon..."),await c_([...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([E4(),xg(Xd(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",()=>RK()),se("health check timer","the database health probe",async()=>{await this.host.stopHealthCheckTimer(),await this.host.services.databaseHealthProbe().dispose?.()}),se("location routes","nothing (synchronous)",()=>jD.stopAll()),se("prototype preview server","open preview event streams and the preview port close",()=>BJ()),se("shutdown monitors","the heartbeat and disconnect monitors and deferred recovery sweeps",(c)=>this.drainShutdownMonitors(d.navigationRetentionMonitor,d.heartbeatMonitor,d.deviceDisconnectMonitor,Xd(c,$g))),se("ADB missing-device subscription","nothing (synchronous)",()=>this.unsubscribeAdbMissing()),se("session cleanup timer","nothing (synchronous)",()=>this.host.stopSessionTimers())]}shutdownStreamAndTransportStages(){return[se("video recording socket server","its connections closing",()=>kK()),se("device gesture recording socket server","its connections closing",()=>_K()),se("device snapshot socket server","its connections closing",()=>DK()),se("appearance socket server","its connections closing",()=>NK()),se("performance stream socket server","its connections closing",()=>Xf()),se("performance push socket server","its connections closing",()=>jne()),se("device data stream socket server","its connections closing",()=>Vz()),se("failures stream socket server","its connections closing",()=>sh()),se("failures push socket server","its connections closing",()=>Lie()),se("telemetry push socket server","its connections closing",()=>Ene()),se("WebRTC stream socket server","WebRTC stream teardown (encoder stop, adb forward removal)",()=>BK()),se("video stream socket server","capture source stop (encoder stop, adb forward removal)",()=>Ih()),se("iOS simulator capture helper pool","simulator capture helper processes exiting",()=>XO.shutdown()),se("native helper registry","tracked helper processes exiting",async(d)=>{await GT().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 V3({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",()=>UK()),se("performance monitor","an in-flight performance sample",()=>CY()),se("active HTTP sessions","streamable HTTP transports closing",()=>c_([...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=q4({closeDatabase:()=>C9({forShutdown:!0}),refusedAccessCount:()=>x9(),drainWrites:(c)=>Qd(c),keepOpenReason:()=>this.shutdownSessionReleasesDrained?void 0:"a session terminal write is still in flight",warn:(c)=>e.warn(c)});return[se("active device sessions","session release teardown and terminal-row persistence",async(c)=>{await this.releaseActiveSessionsForShutdown(Xd(c,Lv)),await Fg(this.host.services.timer(),Xd(c,kP),this.host.pendingImeRestores)}),se("Unix socket server","release notification writes and in-flight request handlers",async()=>{if(this.host.lifecycle.socketServer())this.publishMissingShutdownReleaseNotifications(),await this.host.lifecycle.socketServer().drainSessionReleaseNotifications(),await this.host.lifecycle.socketServer().close()}),se("pending device cleanups","per-device cleanup registered by released sessions",async(c)=>{await this.host.services.sessionManager().drainPendingDeviceCleanups(Xd(c,DP))}),se("CtrlProxy forwarding leases","adb forward removal",(c)=>this.releaseForwardLeases(Xd(c,AP))),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)=>Qd(Xd(c,RP))),se("in-flight migrations","a cold-start migration still running",(c)=>_g(Xd(c,PP))),se("database","the database connection closing",(c)=>d.close(c)),se("late abandoned stage settle","earlier stages that passed their deadline",(c)=>d.lateSettle(c)),se("logger","the log file flush",async()=>{e.info("Daemon stopped"),await e.closeAfterFlush()}),se("daemon files","pid, socket and token file removal",async()=>{this.host.removeHttpToken(),await this.host.cleanupDaemonFilesForShutdown()})]}unsubscribeAdbMissing(){this.host.lifecycle.unsubscribeAdbMissingDevice()?.(),this.host.lifecycle.setUnsubscribeAdbMissingDevice(null)}releaseForwardLeases(d){return E.releaseForwardLeasesForShutdown(this.host.services.timer(),d)}clearHttpSessionRegistry(){this.host.services.httpIngress().clearSessions()}async drainShutdownMonitors(d,c,w,D){d?.stop(),CJ();let[k,P]=await Promise.all([c?c.stop().then(()=>!0):!0,w?w.stop():!0]);if(!k)e.warn("Session heartbeat monitor did not settle before daemon shutdown");if(!P)e.warn("Device disconnect monitor did not settle before daemon shutdown");let C=Symbol("recovery sweep drain timeout"),M=!0;try{await l(Promise.allSettled(this.host.lifecycle.deferredSessionRecoverySweeps()),{timer:this.host.services.timer(),timeoutMs:D,label:"Recovery sweep drain",timeoutError:()=>C})}catch(F){if(F!==C)throw F;M=!1}if(!M)e.warn(`Timed out after ${D}ms draining deferred session recovery sweeps; continuing daemon shutdown`)}async quiesceProvisioningIngress(){this.host.services.httpIngress().stopAccepting(),this.host.services.mcpDispatcher().stopAccepting(),this.host.services.httpIngress().abortPendingAdmissions(),this.host.services.httpIngress().closeListener().catch((c)=>{e.warn(`Failed to begin HTTP listener shutdown: ${r(c)}`,c)});let d=this.host.lifecycle.socketServer()?.quiesce();this.host.services.sessionManager().stopAcceptingSessionCreations(),await d}async releaseActiveSessionsForShutdown(d){let c=this.host.services.sessionManager().getAllKnownSessionIds();this.shutdownSessionIds=c;let w=c.map(async(C)=>{await this.host.cancelAndReleaseSession(C,"daemon-shutdown",{allowExpired:!0})}),D=(C)=>{for(let[M,F]of C.entries())if(F.status==="rejected")e.warn(`[Daemon] Failed to release session ${c[M]??"unknown"} during shutdown: ${F.reason}`)},k=Promise.allSettled(w);if(await Promise.resolve(),!await this.host.services.sessionManager().drainReleasePromises(d,w)){this.shutdownSessionReleasesDrained=!1,e.warn(`Timed out after ${d}ms draining session releases; database will remain open`),k.then(D);return}D(await k)}publishMissingShutdownReleaseNotifications(){let d=this.host.lifecycle.shutdownReleaseNotifications(),c=this.host.lifecycle.shutdownFallbackReleaseNotifications();if(!(d&&c))return;for(let w of this.shutdownSessionIds){if(d.has(w)||c.has(w))continue;c.add(w),Si.emit(w,"daemon-shutdown")}}get testHooks(){return{markShutdownInProgress:()=>{this.host.lifecycle.setShutdownInProgress(!0)},quiesceProvisioningIngress:()=>this.quiesceProvisioningIngress()}}}function CP(d,c,w){let D=`${new Date(w).toISOString()} [ERROR] [Daemon] exiting with code ${d}: database health check failed repeatedly`;return c===void 0?D:`${D}; last failure: ${c.replace(/[\r\n]/g," ")}`}async function Hg(d,c,w){try{w.writeEmergency(CP(d,c,w.now()))}catch(D){}try{w.writeExitRecord()}catch(D){e.warn(`Failed to record database-health exit: ${r(D)}`,D)}w.cleanupDaemonFiles();try{await w.closeLogger()}finally{w.exit(d)}}class ec{dependencies;constructor(d){this.dependencies=d}isHealthy(){let d=this.dependencies.getServer();return d!==null&&d.isListening()&&d.hasActiveSocketPath()}async recover(){await this.dependencies.stopServer(),await this.dependencies.startServer(),this.dependencies.configureCallbacks()}}function qg(d){return(c,w)=>Hg(c,w,{now:()=>d.timer().now(),writeEmergency:(D)=>Zi(D),writeExitRecord:()=>d.selfExitRecorder().record("database-health"),cleanupDaemonFiles:()=>{pz(d.getDaemonFileCleanupOptions())},closeLogger:()=>e.closeAfterFlush(),exit:(D)=>process.exit(D)})}function Ug(d){return new ec({getServer:Et,stopServer:Vz,startServer:async()=>{await d.startAuxiliarySocket("observation-stream",()=>qz(d.timer()))},configureCallbacks:()=>d.configureDeviceDataStreamServer()})}function Kg(d){return new t4(d,void 0,(c)=>{Fq(c).catch((w)=>{e.warn(`[Appearance] Failed to drop config of observer ${c}`,w)}),tb.emit(c)})}function Gg(d){let c=b5(d);for(let w of c.warnings)e.warn(`[Daemon] ${w}`);return e.info(`[Daemon] Device recovery policy: onLoss=${c.policy.onLoss}, maxAttempts=${c.policy.maxAttempts}`),c}import{Http2ServerRequest as Jg,constants as TP}from"http2";import{Http2ServerRequest as ic}from"http2";import{Readable as Wg}from"stream";import KP from"crypto";var vt=class extends Error{constructor(d,c){super(d,c);this.name="RequestError"}},MP=(d)=>{if(d instanceof vt)return d;return new vt(d.message,{cause:d})},EP=global.Request,Mi=class extends EP{constructor(d,c){if(typeof d==="object"&&Vt in d)d=d[Vt]();if(typeof c?.body?.getReader<"u")c.duplex??="half";super(d,c)}},BP=(d)=>{let c=[],w=d.rawHeaders;for(let D=0;D<w.length;D+=2){let{[D]:k,[D+1]:P}=w;if(k.charCodeAt(0)!==58)c.push([k,P])}return new Headers(c)},jg=Symbol("wrapBodyStream"),OP=(d,c,w,D,k)=>{let P={method:d,headers:w,signal:k.signal};if(d==="TRACE"){P.method="GET";let C=new Mi(c,P);return Object.defineProperty(C,"method",{get(){return"TRACE"}}),C}if(!(d==="GET"||d==="HEAD"))if("rawBody"in D&&D.rawBody instanceof Buffer)P.body=new ReadableStream({start(C){C.enqueue(D.rawBody),C.close()}});else if(D[jg]){let C;P.body=new ReadableStream({async pull(M){try{C||=Wg.toWeb(D).getReader();let{done:F,value:q}=await C.read();if(F)M.close();else M.enqueue(q)}catch(F){M.error(F)}}})}else P.body=Wg.toWeb(D);return new Mi(c,P)},Vt=Symbol("getRequestCache"),zg=Symbol("requestCache"),dr=Symbol("incomingKey"),lr=Symbol("urlKey"),FP=Symbol("headersKey"),Wt=Symbol("abortControllerKey"),LP=Symbol("getAbortController"),Ei={get method(){return this[dr].method||"GET"},get url(){return this[lr]},get headers(){return this[FP]||=BP(this[dr])},[LP](){return this[Vt](),this[Wt]},[Vt](){return this[Wt]||=new AbortController,this[zg]||=OP(this.method,this[lr],this.headers,this[dr],this[Wt])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach((d)=>{Object.defineProperty(Ei,d,{get(){return this[Vt]()[d]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach((d)=>{Object.defineProperty(Ei,d,{value:function(){return this[Vt]()[d]()}})});Object.defineProperty(Ei,Symbol.for("nodejs.util.inspect.custom"),{value:function(d,c,w){let D={method:this.method,url:this.url,headers:this.headers,nativeRequest:this[zg]};return`Request (lightweight) ${w(D,{...c,depth:d==null?null:d-1})}`}});Object.setPrototypeOf(Ei,Mi.prototype);var $P=(d,c)=>{let w=Object.create(Ei);w[dr]=d;let D=d.url||"";if(D[0]!=="/"&&(D.startsWith("http://")||D.startsWith("https://"))){if(d instanceof ic)throw new vt("Absolute URL for :path is not allowed in HTTP/2");try{let M=new URL(D);w[lr]=M.href}catch(M){throw new vt("Invalid absolute URL",{cause:M})}return w}let k=(d instanceof ic?d.authority:d.headers.host)||c;if(!k)throw new vt("Missing host header");let P;if(d instanceof ic){if(P=d.scheme,!(P==="http"||P==="https"))throw new vt("Unsupported scheme")}else P=d.socket&&d.socket.encrypted?"https":"http";let C=new URL(`${P}://${k}${D}`);if(C.hostname.length!==k.length&&C.hostname!==k.replace(/:\d+$/,""))throw new vt("Invalid host header");return w[lr]=C.href,w},hc=Symbol("responseCache"),Kt=Symbol("getResponseCache"),yt=Symbol("cache"),yc=global.Response,Jt=class d{#t;#e;[Kt](){return delete this[yt],this[hc]||=new yc(this.#t,this.#e)}constructor(c,w){let D;if(this.#t=c,w instanceof d){let k=w[hc];if(k){this.#e=k,this[Kt]();return}else this.#e=w.#e,D=new Headers(w.#e.headers)}else this.#e=w;if(typeof c==="string"||typeof c?.getReader<"u"||c instanceof Blob||c instanceof Uint8Array)this[yt]=[w?.status||200,c,D||w?.headers]}get headers(){let c=this[yt];if(c){if(!(c[2]instanceof Headers))c[2]=new Headers(c[2]||{"content-type":"text/plain; charset=UTF-8"});return c[2]}return this[Kt]().headers}get status(){return this[yt]?.[0]??this[Kt]().status}get ok(){let c=this.status;return c>=200&&c<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach((d)=>{Object.defineProperty(Jt.prototype,d,{get(){return this[Kt]()[d]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach((d)=>{Object.defineProperty(Jt.prototype,d,{value:function(){return this[Kt]()[d]()}})});Object.defineProperty(Jt.prototype,Symbol.for("nodejs.util.inspect.custom"),{value:function(d,c,w){let D={status:this.status,headers:this.headers,ok:this.ok,nativeResponse:this[hc]};return`Response (lightweight) ${w(D,{...c,depth:d==null?null:d-1})}`}});Object.setPrototypeOf(Jt,yc);Object.setPrototypeOf(Jt.prototype,yc.prototype);async function HP(d){return Promise.race([d,Promise.resolve().then(()=>Promise.resolve(void 0))])}function Yg(d,c,w){let D=(M)=>{d.cancel(M).catch(()=>{})};return c.on("close",D),c.on("error",D),(w??d.read()).then(C,k),d.closed.finally(()=>{c.off("close",D),c.off("error",D)});function k(M){if(M)c.destroy(M)}function P(){d.read().then(C,k)}function C({done:M,value:F}){try{if(M)c.end();else if(!c.write(F))c.once("drain",P);else return d.read().then(C,k)}catch(q){k(q)}}}function qP(d,c){if(d.locked)throw TypeError("ReadableStream is locked.");else if(c.destroyed)return;return Yg(d.getReader(),c)}var gc=(d)=>{let c={};if(!(d instanceof Headers))d=new Headers(d??void 0);let w=[];for(let[D,k]of d)if(D==="set-cookie")w.push(k);else c[D]=k;if(w.length>0)c["set-cookie"]=w;return c["content-type"]??="text/plain; charset=UTF-8",c},UP="x-hono-already-sent";if(typeof global.crypto>"u")global.crypto=KP;var Sc=Symbol("outgoingEnded"),Vg=Symbol("incomingDraining"),WP=500,VP=67108864,dc=(d)=>{let c=d;if(d.destroyed||c[Vg])return;if(c[Vg]=!0,d instanceof Jg){try{d.stream?.close?.(TP.NGHTTP2_NO_ERROR)}catch{}return}let w=0,D=()=>{clearTimeout(P),d.off("data",C),d.off("end",D),d.off("error",D)},k=()=>{D();let M=d.socket;if(M&&!M.destroyed)M.destroySoon()},P=setTimeout(k,WP);P.unref?.();let C=(M)=>{if(w+=M.length,w>VP)k()};d.on("data",C),d.on("end",D),d.on("error",D),d.resume()},JP=()=>new Response(null,{status:400}),Xg=(d)=>new Response(null,{status:d instanceof Error&&(d.name==="TimeoutError"||d.constructor.name==="TimeoutError")?504:500}),vc=(d,c)=>{let w=d instanceof Error?d:Error("unknown error",{cause:d});if(w.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: ${w.message}`),c.destroy(w)}},Qg=(d)=>{if("flushHeaders"in d&&d.writable)d.flushHeaders()},Zg=async(d,c)=>{let[w,D,k]=d[yt],P=!1;if(!k)k={"content-type":"text/plain; charset=UTF-8"};else if(k instanceof Headers)P=k.has("content-length"),k=gc(k);else if(Array.isArray(k)){let C=new Headers(k);P=C.has("content-length"),k=gc(C)}else for(let C in k)if(C.length===14&&C.toLowerCase()==="content-length"){P=!0;break}if(!P){if(typeof D==="string")k["Content-Length"]=Buffer.byteLength(D);else if(D instanceof Uint8Array)k["Content-Length"]=D.byteLength;else if(D instanceof Blob)k["Content-Length"]=D.size}if(c.writeHead(w,k),typeof D==="string"||D instanceof Uint8Array)c.end(D);else if(D instanceof Blob)c.end(new Uint8Array(await D.arrayBuffer()));else Qg(c),await qP(D,c)?.catch((C)=>vc(C,c));c[Sc]?.()},jP=(d)=>typeof d.then==="function",zP=async(d,c,w={})=>{if(jP(d))if(w.errorHandler)try{d=await d}catch(k){let P=await w.errorHandler(k);if(!P)return;d=P}else d=await d.catch(Xg);if(yt in d)return Zg(d,c);let D=gc(d.headers);if(d.body){let k=d.body.getReader(),P=[],C=!1,M=void 0;if(D["transfer-encoding"]!=="chunked"){let F=2;for(let q=0;q<F;q++){M||=k.read();let U=await HP(M).catch((K)=>{console.error(K),C=!0});if(!U){if(q===1){await new Promise((K)=>setTimeout(K)),F=3;continue}break}if(M=void 0,U.value)P.push(U.value);if(U.done){C=!0;break}}if(C&&!("content-length"in D))D["content-length"]=P.reduce((q,U)=>q+U.length,0)}if(c.writeHead(d.status,D),P.forEach((F)=>{c.write(F)}),C)c.end();else{if(P.length===0)Qg(c);await Yg(k,c,M)}}else if(D[UP]);else c.writeHead(d.status,D),c.end();c[Sc]?.()},bc=(d,c={})=>{let w=c.autoCleanupIncoming??!0;if(c.overrideGlobalObjects!==!1&&global.Request!==Mi)Object.defineProperty(global,"Request",{value:Mi}),Object.defineProperty(global,"Response",{value:Jt});return async(D,k)=>{let P,C;try{C=$P(D,c.hostname);let M=!w||D.method==="GET"||D.method==="HEAD";if(!M){if(D[jg]=!0,D.on("end",()=>{M=!0}),D instanceof Jg)k[Sc]=()=>{if(!M)setTimeout(()=>{if(!M)setTimeout(()=>{dc(D)})})};k.on("finish",()=>{if(!M)dc(D)})}if(k.on("close",()=>{if(C[Wt]){if(D.errored)C[Wt].abort(D.errored.toString());else if(!k.writableFinished)C[Wt].abort("Client connection prematurely closed.")}if(!M)setTimeout(()=>{if(!M)setTimeout(()=>{dc(D)})})}),P=d(C,{incoming:D,outgoing:k}),yt in P)return Zg(P,k)}catch(M){if(!P)if(c.errorHandler){if(P=await c.errorHandler(C?M:MP(M)),!P)return}else if(!C)P=JP();else P=Xg(M);else return vc(M,k)}try{return await zP(P,k,c)}catch(M){return vc(M,k)}}};var ev=class{_webStandardTransport;_requestListener;_requestContext=new WeakMap;constructor(d={}){this._webStandardTransport=new X4(d),this._requestListener=bc(async(c)=>{let w=this._requestContext.get(c);return this._webStandardTransport.handleRequest(c,{authInfo:w?.authInfo,parsedBody:w?.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,w){let D=d.auth;await bc(async(k)=>this._webStandardTransport.handleRequest(k,{authInfo:D,parsedBody:w}),{overrideGlobalObjects:!1})(d,c)}closeSSEStream(d){this._webStandardTransport.closeSSEStream(d)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}};var YP=g({sessionId:y().min(1),livenessOwnerToken:gr().optional()});function iv(d){let c;try{c=JSON.parse(d)}catch(D){return e.debug(`Invalid heartbeat JSON: ${D}`),{ok:!1,response:{status:400,body:{error:"Invalid JSON"}}}}let w=YP.safeParse(c);if(!w.success)return{ok:!1,response:{status:400,body:{error:"Missing sessionId"}}};return{ok:!0,sessionId:w.data.sessionId,livenessOwnerToken:w.data.livenessOwnerToken}}var tv={status:200,body:{status:"ok"}};function QP(d){return typeof d==="string"&&d.trim()?d:void 0}async function nv(d,c,w,D){let k=QP(D),P=d.getSession(w)??d.getReleasingSession?.(w)??null;if(!P||Ki(d,w,P)){let M=await QH(d,c,w,k);if(M.kind==="observer")return tv;return{status:404,body:{error:`Session not found: ${w}`,...wh(M.recorded.releaseReason,M.recorded.idleTimeoutMs)}}}if(k?d.hasLivenessOwnership(w,k)||d.claimUnownedLivenessOwnership(w,k):!ZH(P))d.recordHeartbeat(w);return tv}import{AsyncLocalStorage as tI}from"async_hooks";var ZP={updates:Rw,lists:Er,log:e,maxUrisPerStream:256,maxUriMemberships:4096},eI=s({method:_("subscriptions/listen"),params:s({notifications:s({resourceSubscriptions:S(n()).optional()})})});class wc{bus;uriReferences=new Map;memberships=0;warnedLimit=!1;unsubscribeUpdates;unsubscribeLists;deps;constructor(d,c={}){this.bus=d;this.deps={...ZP,...c},this.unsubscribeUpdates=this.deps.updates.subscribe((w)=>this.publishUpdated(w)),this.unsubscribeLists=this.deps.lists.subscribe((w)=>{this.bus.publish({kind:w==="tools"?"tools_list_changed":"resources_list_changed"})})}track(d){let c=eI.safeParse(d);if(!c.success)return()=>{};let w=new Set(c.data.params.notifications.resourceSubscriptions??[]);if(w.size>this.deps.maxUrisPerStream||this.memberships+w.size>this.deps.maxUriMemberships){if(!this.warnedLimit)this.warnedLimit=!0,this.deps.log.warn("Modern MCP resource subscription URI limit reached; refusing stream");return null}for(let k of w)this.uriReferences.set(k,(this.uriReferences.get(k)??0)+1);this.memberships+=w.size;let D=!1;return()=>{if(!D)D=!0,this.release(w)}}close(){this.unsubscribeUpdates(),this.unsubscribeLists(),this.uriReferences.clear(),this.memberships=0}release(d){for(let c of d){let w=this.uriReferences.get(c);if(w===void 0)continue;if(this.memberships--,w===1)this.uriReferences.delete(c);else this.uriReferences.set(c,w-1)}}publishUpdated(d){if(this.uriReferences.size===0)return;try{let c=new Set(d(new Set(this.uriReferences.keys())));for(let w of c)if(this.uriReferences.has(w))this.publishUri(w)}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 iI=JSON.stringify({jsonrpc:"2.0",error:{code:-32000,message:"Method not allowed."},id:null}),nI=JSON.stringify({error:"Daemon is shutting down"});function Bi(d){return(Array.isArray(d)?d:[d]).filter((w)=>!!w&&typeof w==="object"&&!Array.isArray(w))}function rv(d){return typeof d==="string"||typeof d==="number"}function Oi(d,c){if(!d||typeof d!=="object"||Array.isArray(d))return;return Object.entries(d).find(([w])=>w===c)?.[1]}function rI(d){for(let c of Bi(d)){let w=Oi(Oi(c.params,"arguments"),eD);if(typeof w==="string"&&w.length>0)return w}return}function sv(d){return`\x00${typeof d}:${String(d)}`}function ov(d,c){return`${d}${sv(c)}`}function sI(d,c){let w=new Headers;for(let[D,k]of Object.entries(d.headers)){let P=Array.isArray(k)?k:k===void 0?[]:[k];for(let C of P)w.append(D,C)}return new Request(new URL(Mw,"http://localhost"),{method:"POST",headers:w,signal:c})}async function aI(d,c){if(c.destroyed||c.writableEnded){await d.body?.cancel();return}c.writeHead(d.status,Object.fromEntries(d.headers));let w=new TextDecoder;if(d.body)for await(let D of d.body){if(c.destroyed||c.writableEnded)break;c.write(w.decode(D,{stream:!0}))}if(!c.destroyed&&!c.writableEnded)c.end(w.decode())}var dI="2026-07-28",cI=1024;function lI(d,c){let D=c?.params?._meta?.[ss];return[d,D].some((k)=>typeof k==="string"&&k>=dI)}class Rc{deps;inFlight=new Map;byCancelKey=new Map;accepting=!0;modernBus;modernEvents;modernListenStreams=0;modernScope=new tI;root=ua("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,w,D){if(d.method!=="POST"){c.writeHead(405,{"Content-Type":"application/json",Allow:"POST"}),c.end(iI);return}let k=xU(d.headers);if(await this.cancelNotifiedRequests(k,w),!this.accepting){c.writeHead(503,{"Content-Type":"application/json"}),c.end(nI);return}let P={requestScopeId:this.deps.idGenerator.next(),requestMcpSessionId:k??rI(w)};if(this.isModernRequest(d,w)){await this.handleModern(d,c,w,{scope:P,headerSessionKey:k,sendJsonRpcError:D});return}let C;try{C=this.deps.createServer(d,P)}catch(K){e.error("Failed to create MCP server:",K),D("Server error",K);return}let M=this.deps.createTransport(),F=this.track(P,k,w,{server:C,transport:M}),q=d.socket??void 0,U=()=>{q?.off("close",U),F.close().catch((K)=>{e.warn(`Stateless MCP request close failed: ${r(K)}`,K)})};c.once("close",U),c.once("finish",U),q?.once("close",U);try{await C.connect(M)}catch(K){e.error("MCP server connect failed:",K),D("Server error",K),await F.close();return}await this.dispatch(d,c,M,{parsedBody:w,sendJsonRpcError:D})}isModernRequest(d,c){if(!(this.deps.modern?.enabled()??Be(f.MCP_MODERN_ERA)))return!1;let w=(P)=>{let C=d.headers[P];return typeof C==="string"?C:void 0},D=w("mcp-protocol-version"),k=(this.deps.modern?.classify??wF)({httpMethod:d.method??"POST",protocolVersionHeader:D,mcpMethodHeader:w("mcp-method"),mcpNameHeader:w("mcp-name"),body:c});return k.kind==="modern"||k.kind==="reject"&&lI(D,c)}createModernHandler(d){return(this.deps.modern?.createHandler??MQ)((c)=>{let w=this.modernScope.getStore(),{req:D,scope:k}=w??{};if(!w||!D||!k)throw new t("Modern MCP request scope is missing");w.req=void 0,w.scope=void 0;let P=this.deps.createServer(D,{...k,era:c.era});if(!(P instanceof Fh))throw new t("Modern MCP serving requires an SDK McpServer");return P},{legacy:"reject",responseMode:"sse",keepAliveMs:0,bus:d})}async handleModern(d,c,w,{scope:D,headerSessionKey:k,sendJsonRpcError:P}){let C=this.getModernBus(),M=this.openListenSlot(w,c);if(!M)return;let F=new AbortController,q;try{q=this.createModernHandler(C)}catch(J){throw M.release(),J}let U=this.track(D,k,w,{server:q,transport:{close:async()=>{F.abort(),M.release()}}}),K=d.socket??void 0,W=()=>{K?.off("close",W),U.close().catch((J)=>{e.warn(`Modern MCP request close failed: ${r(J)}`,J)})};c.once("close",W),c.once("finish",W),K?.once("close",W);let V=this.startKeepalive(c),z=Bi(w).map((J)=>Oi(J.params,"_meta")).find((J)=>J!==void 0);try{let J=await this.root.run(()=>this.modernScope.run({req:d,scope:D},()=>gm(ym(z),()=>q.fetch(sI(d,F.signal),{parsedBody:w}))));await aI(J,c)}catch(J){e.error("Modern MCP HTTP request handling failed:",J),P("Server error",J)}finally{V(),K?.off("close",W),await U.close()}}openListenSlot(d,c){if(!Bi(d).some((k)=>k.method==="subscriptions/listen"))return{release:()=>{}};let D=this.modernListenStreams<(this.deps.modern?.maxListenStreams??cI)?this.modernEvents?.track(d):void 0;if(!D)return c.writeHead(429,{"Content-Type":"application/json","Retry-After":"5"}),c.end(JSON.stringify({error:"Subscription stream or resource URI limit reached"})),null;return this.modernListenStreams++,{release:()=>{D(),this.modernListenStreams--}}}getModernBus(){if(!this.modernBus){let d=this.deps.modern?.createEventBus?.()??new PF((c)=>e.warn(`Modern MCP event listener failed: ${r(c)}`,c));this.modernBus=d,this.modernEvents=new wc(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,w,{server:D,transport:k}){let{requestScopeId:P}=d,C=Bi(w).map((q)=>q.id).filter(rv).map((q)=>ov(c??"",q)),M,F={requestScopeId:P,keyless:d.requestMcpSessionId===void 0,cancelKeys:C,close:(q)=>(M??=this.closeRequest(F,D,k,q),M)};this.inFlight.set(P,F);for(let q of C)this.byCancelKey.set(q,[...this.byCancelKey.get(q)??[],P]);return F}async closeRequest(d,c,w,D){try{let k=await this.deps.cancelScopeExecutions(d.requestScopeId,D??this.deps.closeReason());if(k>0)e.info(`Stateless MCP request ${d.requestScopeId} closed (cancelled ${k} executions)`)}finally{this.untrack(d);let k=await Promise.allSettled([w.close(),c.close()]);for(let P of k)if(P.status==="rejected")e.warn(`Stateless MCP request ${d.requestScopeId} teardown failed: ${Vp(P.reason)}`);if(d.keyless)this.deps.forgetScopeBindings(d.requestScopeId)}}untrack(d){if(this.inFlight.get(d.requestScopeId)===d)this.inFlight.delete(d.requestScopeId);for(let c of d.cancelKeys){let w=(this.byCancelKey.get(c)??[]).filter((D)=>D!==d.requestScopeId);if(w.length===0)this.byCancelKey.delete(c);else this.byCancelKey.set(c,w)}this.releaseModernEventsIfIdle()}async cancelNotifiedRequests(d,c){let w=Bi(c).filter((D)=>D.method==="notifications/cancelled");await Promise.all(w.map(async(D)=>{let k=Oi(D.params,"requestId");if(!rv(k))return;let P=this.cancelledScopeId(d,k),C=P===void 0?void 0:this.inFlight.get(P);if(!C){e.debug(`notifications/cancelled for unknown request ${String(k)}`);return}let M=Oi(D.params,"reason");await C.close(typeof M==="string"?M:"notifications/cancelled")}))}cancelledScopeId(d,c){if(d!==void 0)return this.byCancelKey.get(ov(d,c))?.at(-1);let w=sv(c),D=Array.from(this.byCancelKey.entries()).filter(([k])=>k.endsWith(w)).flatMap(([,k])=>k);if(D.length>1)e.warn(`Ignoring header-less notifications/cancelled for ambiguous request id ${String(c)}: ${D.length} in-flight requests share it`);return D.length===1?D[0]:void 0}startKeepalive(d){let c=this.deps.timer.setInterval(()=>{if(d.headersSent&&!d.writableEnded&&!d.destroyed)d.write(`:keepalive
|
|
51
|
+
|
|
52
|
+
`)},this.deps.keepaliveIntervalMs),w=!1,D=()=>{if(!w)w=!0,this.deps.timer.clearInterval(c)};return d.once("close",D),d.once("finish",D),D}async dispatch(d,c,w,{parsedBody:D,sendJsonRpcError:k}){let P=this.startKeepalive(c);try{await w.handleRequest(d,c,D)}catch(C){e.error("Streamable HTTP request handling failed:",C),k("Server error",C)}finally{P()}}}var uI=60000,fI=268435456,av=30000,hI=1,gI=30000;class Dc{deps;httpServer=null;httpServerClosePromise=null;shutdownIngressAbort=new AbortController;httpAllowedHosts=[];mcpHttpTransportFactory=(d)=>new ev({enableDnsRebindingProtection:!0,allowedHosts:d});mcpRequestServerFactory=(d,c)=>this.deps.createRequestMcpServer(d,c);mcpHttpEndpoint=new Rc({timer:{setInterval:(d,c)=>this.deps.timer().setInterval(d,c),clearInterval:(d)=>this.deps.timer().clearInterval(d)},idGenerator:{next:()=>this.deps.idGenerator().next()},keepaliveIntervalMs:gI,createTransport:()=>this.mcpHttpTransportFactory(this.httpAllowedHosts),createServer:(d,c)=>this.mcpRequestServerFactory(d,c),cancelScopeExecutions:(d,c)=>G.cancelSessionExecutions(d,c),forgetScopeBindings:(d)=>SE(d),closeReason:()=>this.deps.isShutdownInProgress()?new Pa(jb):"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(),w=this.deps.httpServerFactory();this.httpServer=w,this.httpServerClosePromise=null,this.acceptingHttpSessions=!0;let D=[`127.0.0.1:${c}`,`localhost:${c}`,`[::1]:${c}`];this.httpAllowedHosts=D,w.requestTimeout=0,w.headersTimeout=0,w.timeout=0;let k=(P,C)=>this.handleHttpRequest(P,C,D);return w.on("request",(P,C)=>{k(P,C).catch((M)=>{if(e.warn(`HTTP request callback failed: ${r(M)}`,M),!C.headersSent)C.writeHead(500,{"Content-Type":"application/json"});C.end()})}),new Promise((P,C)=>{w.listen(c,d,()=>{e.info(`automobile:${d}:${c}${Mw}`),P()}),w.on("error",(M)=>{if(this.deps.strictPort()&&M.code==="EADDRINUSE"){C(new t(`Port ${c} on ${d} is required for this daemon start but is already in use by another process. Refusing to fall back to a different port `+"and risk a split-brain daemon (issue #6260) \u2014 find and stop whatever holds "+`port ${c} and retry.`));return}e.error(`HTTP server error: ${M}`),C(M)})})}closeListener(){let d=this.httpServer;if(!d)return Promise.resolve();return this.httpServerClosePromise??=new Promise((c,w)=>{d.close((D)=>{if(D){w(D);return}e.info("HTTP server stopped"),c()})}),this.httpServerClosePromise}admitHttpRequest(d,c,w){if(!d.headers.host||!w.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 w=d.headers.authorization;delete d.headers.authorization;for(let k=d.rawHeaders.length-2;k>=0;k-=2)if(d.rawHeaders[k]?.toLowerCase()==="authorization")d.rawHeaders.splice(k,2);let D=this.deps.httpToken().value;if(!D||!rl(w,D))return c.writeHead(401,{"Content-Type":"application/json","WWW-Authenticate":"Bearer"}),c.end(JSON.stringify({error:"Unauthorized"})),!1;return!0}async handleHttpRequest(d,c,w){if(!this.admitHttpRequest(d,c,w)||!(this.deps.httpToken().isPublished||await this.awaitHttpTokenPublication(c))||!this.authenticateHttpRequest(d,c))return;if(this.openHttpRequests++,this.httpRequestsSeen++,c.once("close",()=>{this.openHttpRequests--}),d.method==="OPTIONS"){c.writeHead(200),c.end();return}let D=new URL(d.url,`http://${d.headers.host}`);if(D.pathname===L3)return this.handleHeartbeatHttpRequest(d,c);if(D.pathname===Mw)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 w=await this.readHttpBody(d);if(!w.ok){this.respondToBodyReadFailure(c,w);return}let D=iv(w.body);if(!D.ok){c.writeHead(D.response.status,{"Content-Type":"application/json"}),c.end(JSON.stringify(D.response.body));return}let k=await nv(this.deps.sessionManager(),this.deps.observerSessionRegistry(),D.sessionId,D.livenessOwnerToken);c.writeHead(k.status,{"Content-Type":"application/json"}),c.end(JSON.stringify(k.body))}async admitHttpMcpRequest(d){if(!this.acceptingHttpSessions)return d.writeHead(503,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:"Daemon is shutting down"})),!1;return this.awaitStartupAdmission(d)}async awaitStartupAdmission(d){if(this.startupCompleted)return!0;let c=Symbol("HTTP startup admission timeout"),w=this.shutdownIngressAbort.signal;try{return await l(this.deps.startupCompletion(),{timer:this.deps.timer(),timeoutMs:av,signal:w,label:"HTTP MCP startup admission",timeoutError:()=>c}),!0}catch(D){if(w.aborted)return e.info("HTTP MCP request refused: daemon shut down during startup admission"),d.writeHead(503,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:"Daemon is shutting down"})),!1;if(D===c)return e.warn(`HTTP MCP request refused: daemon still starting after ${av}ms`),d.writeHead(503,{"Content-Type":"application/json","Retry-After":String(hI)}),d.end(JSON.stringify({error:"Daemon is still starting"})),!1;return e.warn(`HTTP MCP request refused: daemon startup failed: ${r(D)}`),d.writeHead(503,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:"Daemon startup failed"})),!1}}async handleMcpHttpRequest(d,c){if(!await this.admitHttpMcpRequest(c))return;let w;if(d.method==="POST"){let k=await this.readHttpBody(d);if(!k.ok){this.respondToBodyReadFailure(c,k);return}try{w=JSON.parse(k.body)}catch(P){e.debug(`Invalid MCP JSON: ${P}`),c.writeHead(400,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Invalid JSON"}));return}}let D=(k,P)=>this.sendHttpJsonRpcError(c,w,k,P);if(!this.acceptingHttpSessions){c.writeHead(503,{"Content-Type":"application/json"}),c.end(JSON.stringify({error:"Daemon is shutting down"}));return}return this.mcpHttpEndpoint.handle(d,c,w,D)}sendHttpJsonRpcError(d,c,w,D){if(d.headersSent)return;let k=c&&typeof c==="object"&&"id"in c?c.id:null;d.writeHead(200,{"Content-Type":"application/json"}),d.end(JSON.stringify({jsonrpc:"2.0",id:k,error:{code:-32603,message:w,data:D instanceof Error?D.message:void 0}}))}readHttpBody(d){let c=this.deps.timer();return new Promise((w)=>{let D=[],k=0,P=!1,C=(V)=>{if(P)return;P=!0,c.clearTimeout(W),d.off("data",M),d.off("end",F),d.off("error",q),d.off("aborted",U),d.off("close",K),w(V)},M=(V)=>{let z=Buffer.isBuffer(V)?V:Buffer.from(V);if(k+=z.length,k>fI){C({ok:!1,status:413,error:"Request body too large"}),d.destroy();return}D.push(z)},F=()=>C({ok:!0,body:Buffer.concat(D).toString("utf8")}),q=(V)=>{e.warn("HTTP request body read failed",V),C({ok:!1,status:400,error:"Request body read failed"})},U=()=>C({ok:!1,status:400,error:"Request aborted"}),K=()=>C({ok:!1,status:400,error:"Request closed"}),W=c.setTimeout(()=>{C({ok:!1,status:408,error:"Request body timed out"}),d.destroy()},uI);d.on("data",M),d.on("end",F),d.on("error",q),d.on("aborted",U),d.on("close",K)})}respondToBodyReadFailure(d,c){if(!d.destroyed)d.writeHead(c.status,{"Content-Type":"application/json"}),d.end(JSON.stringify({error:c.error}))}}class kc{host;httpIngress;mcpDispatcher;constructor(d){this.host=d;this.httpIngress=new Dc({...d,createRequestMcpServer:(c,w)=>Cn(this.statelessMcpServerBase(),In({headers:c.headers}),w)}),this.mcpDispatcher=Bn({base:()=>this.statelessMcpServerBase(),idGenerator:{next:()=>d.idGenerator().next()},closeReason:()=>d.isShutdownInProgress()?new Pa(jb):pa})}statelessMcpServerBase(){return{deviceReadiness:this.host.deviceReadiness(),iosDependencies:this.host.iosDoctorDependencies,debug:this.host.debug(),acceptanceDiscoveryCapability:this.host.acceptanceDiscoveryCapability()}}}async function cv(d,c){let w=new Map,D=new Map,k=new Map,P=!1,C=vI(w,c),M=(U,K)=>{let W=c.getDeviceIncarnation(U),V=new Set(c.ownedCaptureIds()),z=(w.get(U)??[]).filter((J)=>J.captureTeardown&&(!K||!V.has(J.recordingId))&&lv(J,W));if(z.length===0||W!==void 0&&k.get(U)===W)return;if(W===void 0&&z.some((J)=>J.captureTeardown?.kind!=="ios-host-recorder")){e.warn(`[RecordingTeardownRedrive] Device ${U} has no pool incarnation; retaining capture descriptors until the device is pooled`);return}for(let J of z)J.hookDriven||=K;if(k.set(U,W),d.getSessionForDevice(U)!==null){if(D.set(U,{records:z,hookDriven:K}),!P)yI(d,D,c),P=!0}else if(W===void 0)d.registerPendingDeviceCleanup(U,pv(d,U,z,{deps:c,hookDriven:K}),Ul);else uv(d,U,z,{deps:c,hookDriven:K})};c.onDeviceIncarnationAssigned?.((U)=>M(U,!0)),c.onDeviceProcessStarted?.(async(U)=>{if(C.list(U).length===0)return;try{await l(()=>C.stop(U,void 0,{mode:"background"}),{timer:c.timer,timeoutMs:Ul,label:`Process-start orphan recorder teardown on ${U}`})}catch(K){e.warn(`[RecordingTeardownRedrive] Process-start teardown unconfirmed on ${U}`,K)}});let F;try{F=await c.recordingRepository.listRecordings({hasCaptureTeardown:!0,excludeLiveDaemonSessionIds:c.liveDaemonSessionIds})}catch(U){return e.warn("[RecordingTeardownRedrive] Could not read unconfirmed capture teardowns; continuing startup",U),!1}let q=new Set(c.ownedCaptureIds());for(let U of F){if(!U.captureTeardown||q.has(U.recordingId))continue;let K=w.get(U.deviceId)??[];K.push({...U}),w.set(U.deviceId,K)}for(let U of w.keys())M(U,!1);return c.onStartupOrphans?.(C),!0}function vI(d,c){let w=(k)=>(d.get(k)??[]).filter((P)=>P.captureTeardown&&!c.ownedCaptureIds().includes(P.recordingId)&&lv(P,c.getDeviceIncarnation(k))),D=(k)=>({recordingId:k.recordingId,deviceId:k.deviceId,ownerSessionUuid:k.ownerSessionUuid});return{list:(k)=>w(k).map(D),find:(k)=>{for(let P of d.keys()){let C=w(P).find((M)=>M.recordingId===k);if(C)return D(C)}return},stop:async(k,P,C)=>{let M=w(k).filter((F)=>!P||F.recordingId===P);try{await Ac(k,M,c,{waitForExpiry:!1,mode:C?.mode??"user"})}finally{let F=new Set(M.map((q)=>q.withdrawRetry));for(let q of F)if(q&&!(d.get(k)??[]).some((U)=>U.withdrawRetry===q&&U.captureTeardown))q()}}}}function lv(d,c){if(c===void 0||d.firstMarkedIncarnation===void 0||d.firstMarkedIncarnation===c||Pc(d.captureTeardown)||Number.isFinite(Cc(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 uv(d,c,w,{deps:D,hookDriven:k=!1}){if(w=w.filter((M)=>M.captureTeardown),w.length===0)return;let P=w.map((M)=>{let F=Cc(M);return Number.isFinite(F)?Math.max(0,F-D.now()):0}),C=d.markDeviceNeedsRecorderTeardown(c,()=>Ac(c,w,D,{waitForExpiry:!0,hookDriven:k}),Math.max(Ul,...P.map((M)=>M+Ul)));for(let M of w)M.withdrawRetry=C,M.firstMarkedIncarnation??=D.getDeviceIncarnation(c)}function yI(d,c,w){let D=(k,P=!1)=>{let C=c.get(k);if(!C)return;let{hookDriven:M}=C,{records:F}=C;if(c.delete(k),P){if(SI(F.filter((q)=>q.captureTeardown?.kind!=="ios-host-recorder"),w),F=F.filter((q)=>q.captureTeardown?.kind==="ios-host-recorder"),F.length===0)return}d.registerPendingDeviceCleanup(k,pv(d,k,F,{deps:w,hookDriven:M}),Ul)};d.onSessionRelease((k,P,C,M)=>{if(!M?.upgradeOnly)D(P,M?.deviceIdentityReplaced)}),d.onSessionDeviceUnbound((k,P,C)=>D(P,C?.deviceIdentityReplaced))}async function SI(d,c){for(let w of d)try{await c.recordingRepository.updateRecording(w.recordingId,{captureTeardown:void 0}),w.captureTeardown=void 0}catch(D){e.warn(`[RecordingTeardownRedrive] Could not clear replaced-device descriptor for ${w.recordingId}`,D)}}async function pv(d,c,w,{deps:D,hookDriven:k}){try{await l(()=>Ac(c,w,D,{waitForExpiry:!1,hookDriven:k}),{timer:D.timer,timeoutMs:Ul,label:`Released orphan recorder teardown on ${c}`})}catch(P){e.warn(`[RecordingTeardownRedrive] Release-time teardown unconfirmed on ${c}`,P),uv(d,c,w,{deps:D,hookDriven:k})}}async function Ac(d,c,w,{waitForExpiry:D,hookDriven:k=!1,mode:P="background"}){let C=[],M=[];for(let F of c){if(!F.captureTeardown||w.ownedCaptureIds().includes(F.recordingId))continue;try{await bI(F,w,D,{hookDriven:k,mode:P})}catch(q){e.warn(`[RecordingTeardownRedrive] Teardown unconfirmed for ${F.recordingId} on ${d}`,q),C.push(F.recordingId),M.push(q)}}if(C.length>0)throw new((M.every((q)=>q instanceof jc))?jc:t)(`Orphan recorder teardown on ${d} is unconfirmed for ${C.join(", ")}. Recover the device if retries fail.`,{cause:M[0]})}async function bI(d,c,w,{hookDriven:D,mode:k}){if(!w&&!Pc(d.captureTeardown)&&d.captureTeardown)await dv(d,c,!1,k);if(d.confirmation)return d.confirmation;let P=(async()=>{if((D||d.hookDriven)&&!await wI(d,c))return;let C=d.captureTeardown;if(!C||c.ownedCaptureIds().includes(d.recordingId))return;if(await dv(d,c,w,k),d.captureTeardown!==C)return;await c.recordingRepository.updateRecording(d.recordingId,{captureTeardown:void 0}),d.captureTeardown=void 0})();d.confirmation=P;try{await P}finally{if(d.confirmation===P)d.confirmation=void 0}}async function wI(d,c){if(c.ownedCaptureIds().includes(d.recordingId))return!1;if((await c.recordingRepository.listRecordings({hasCaptureTeardown:!0,excludeLiveDaemonSessionIds:c.liveDaemonSessionIds,deviceId:d.deviceId})).some((D)=>D.recordingId===d.recordingId))return!c.ownedCaptureIds().includes(d.recordingId);return d.captureTeardown=void 0,!1}function Pc(d){return d?.kind==="ios-host-recorder"?d.hostPid!==void 0:d?.devicePid!==void 0}function Cc(d){if(Pc(d.captureTeardown)||!d.captureTeardown)return NaN;return Date.parse(d.startedAt)+Ci*1000+cq}async function dv(d,c,w,D){let k=d.captureTeardown;if(k.kind==="ios-host-recorder"){await c.forceStopOrphanedCapture(void 0,k,{mode:D});return}if(k.devicePid===void 0){let C=Cc(d);if(!Number.isFinite(C)||!w&&c.now()<C)throw new t(`Orphan recorder ${d.recordingId} on ${d.deviceId} has no pid and its screenrecord hard limit has not elapsed.`);if(c.now()<C)await c.timer.sleep(C-c.now());return}let P=c.getDevice(d.deviceId);if(!P)throw new jc(`Cannot find device ${d.deviceId} to confirm orphan recorder teardown.`);await c.forceStopOrphanedCapture(P,k)}var jt={initializeRecordingTeardownRedriveState:(...d)=>MM(...d),listActiveVideoRecordings:(...d)=>nc(...d),redriveUnconfirmedCaptureTeardowns:(...d)=>cv(...d),setStartupOrphanCaptures:(...d)=>X8(...d),setVideoRecordingManagerDependencies:(...d)=>Z8(...d)};async function mv(d,c){let w=d.services.sessionManager().getSession(c);if(d.lifecycle.shutdownInProgress()||!w||!d.services.sessionManager().isLiveManagedExecutionSession(c))return;let D=w.assignedDevice;if(Zn([{id:D,platform:w.platform}],d.services.passiveWorkPolicy()).length===0||d.services.sessionManager().getSessionForDevice(D)!==c)return;await er([D],{timer:d.services.timer(),perDeviceTimeoutMs:5000,pendingPrefetch:()=>it.pendingPrefetch(),isShuttingDown:()=>d.lifecycle.shutdownInProgress(),verifyIosDevice:async(P,C)=>{if(!d.lifecycle.shutdownInProgress()&&d.services.sessionManager().isLiveManagedExecutionSession(c)&&d.services.sessionManager().getSession(c)?.assignedDevice===P&&d.services.sessionManager().getSessionForDevice(P)===c&&d.lifecycle.managedExecutionReowner()?.ownershipState(c)===void 0)await d.services.iosDeviceVerifier()().verifyIosDevice(P,C)}})}function Tc(d){return{getSession:(c)=>d().getSession(c),getPersistedSession:(c)=>d().getSession(c)}}class fv{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=hn({coreDeviceProbe:vb()});exitRecordFileSystem=lA;startHost;selfExitRecorder=new z6({write:(d)=>this.startHost.writeExitRecord(d),now:()=>this.timer.now(),buildId:()=>Ho().buildId,options:()=>({...ns(this.options),port:this.listen.port}),canRecord:()=>this.runtime.enteredDaemonProcess&&(this.runtime.socketBindCommitted||!this.incumbentOwnerGuard.hasLiveForeignOwner())});startupCompletion=dl();mcpServices=new kc({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 Ar;observerSessionRegistry;sessionManager;devicePool;deviceSessionRegistry;daemonSessionId;installedAppsRepository;deviceSessionRepository;timer;sessionBrokerConfigPath=I(f.SESSION_BROKER_CONFIG)?RI(I(f.SESSION_BROKER_CONFIG)):void 0;processIdentity;passiveWorkPolicy;idGenerator;database;observationStreamHealth;navigationGraphBridge=new kr({server:()=>this.runtime.deviceDataStreamServer,sessionIds:()=>this.sessionManager.getAllSessions().map((d)=>d.sessionId),defaultManager:()=>fe.getInstance(),managerForSession:(d)=>fe.getInstanceForSession(d)});deviceStateChangeNotifier;options;acceptanceDiscoveryCapability=I(f.ACCEPTANCE_DISCOVERY_CAPABILITY);shutdownState=new Pr;runtime=new Tr;daemonState;constructor(d={},c={}){let w=this.createDaemonCoreServices(),D=this.createDaemonIdentityState(),k=this.createDaemonLifecycleState();this.broker=this.createDaemonBroker(w,D,k),this.startup=this.createDaemonStartup(w,D,k),this.identity=this.createDaemonIdentity(w,D),this.streams=this.createDaemonStreams(w,k),this.maintenance=this.createDaemonMaintenance(w,D,k),this.shutdown=this.createDaemonShutdown(w,k);let{timer:P,deviceSessionRepository:C,idGenerator:M,databaseInitializer:F,startupFailureTracker:q,databaseHealthProbe:U,recoveryPolicyEnvironment:K,managedAdbServerShutdown:W,toolSelectionProfileProvenanceLoader:V,processBirthTime:z,processGenerationToken:J,incumbentOwnerGuard:X,installedAppsRepository:ee,recoverFromDatabaseHealthFailure:ne,...te}=al(c);this.deviceReadiness=te.deviceReadiness,this.daemonState=te.daemonState,this.httpToken=new Nr(te.httpTokenStore,c.idGenerator,te.httpToken),this.injected={httpServerFactory:te.httpServerFactory,liveDaemonSessionIdProvider:te.liveDaemonSessionIdProvider,avdManagerFactory:te.avdManagerFactory,iosDeviceVerifier:te.iosDeviceVerifier,bindingExclusionFactory:te.bindingExclusionFactory,foreignCtrlProxyForwardEvidence:te.foreignCtrlProxyForwardEvidence,stopManagedAdbServer:W,hostIoStalled:te.hostIoStalled},zb(),this.startupCompletion.promise.then(()=>{this.httpIngress.markStartupCompleted()},(pe)=>{e.debug(`Daemon startup completion rejected: ${r(pe)}`)}),this.options={...d},this.listen={port:d.port||nd,host:d.host||"127.0.0.1",strictPort:d.strictPort??!1,debug:d.debug||!1},FJ(this.listen.port),this.idGenerator=M,this.daemonSessionId=this.idGenerator.next(),this.timer=P,this.deviceStateChangeNotifier=Vc({timer:P,invalidate:oI,notify:PX}),this.processIdentity={generationStartedAt:this.timer.now(),processStartedAt:z(),processGenerationToken:J(),liveAcceptanceStartupSecret:GH()},this.incumbentOwnerGuard=X,this.passiveWorkPolicy=new yr(Wc(process.env,K6),(pe)=>this.sessionManager.getAllSessions().some((ae)=>ae.assignedDevice===pe)),this.database={databaseInitializer:F,toolSelectionProfileProvenanceLoader:V,databaseHealthProbe:U,startupFailureTracker:q,recoverFromDatabaseHealthFailure:ne??qg({timer:()=>this.timer,selfExitRecorder:()=>this.selfExitRecorder,getDaemonFileCleanupOptions:()=>this.identity.getDaemonFileCleanupOptions()})},this.observationStreamHealth=Ug({timer:()=>this.timer,startAuxiliarySocket:(...pe)=>this.identity.startAuxiliarySocket(...pe),configureDeviceDataStreamServer:()=>this.streams.configureDeviceDataStreamServer()}),this.deviceSessionRepository=C,this.sessionManager=new BI(this.timer,this.deviceSessionRepository,{sessionDeviceReboundEmitter:pq}),this.sessionManager.attachDaemonSessionId(this.daemonSessionId),this.sessionManager.attachLiveDaemonSessionIds(()=>this.incumbentOwnerGuard.withLiveIncumbent(this.injected.liveDaemonSessionIdProvider.collectLiveDaemonSessionIds())),this.observerSessionRegistry=Kg(this.timer),this.sessions.configureSessionLifecycleCallbacks(),this.installedAppsRepository=ee??new bs;let oe=Gg(K);this.deviceSessionRegistry=new JL(this.timer,this.idGenerator),this.devicePool=this.sessions.createDevicePool(oe.policy,K),G.setAutolockSessionResolver({autolockSessionForMcpSession:(pe)=>this.devicePool.captureAutolockSessionForMcpSession(pe)}),this.daemonState.initialize(this.sessionManager,this.devicePool,this.deviceSessionRegistry,this.observerSessionRegistry),this.daemonState.setSessionBrokerMode(this.sessionBrokerConfigPath!==void 0),this.broker.installManagedExecutionRelease(),this.broker.installBrokerDeviceAcquisition(),this.startup.applyRuntimeOptions(d),this.startup.applyAccessibilityOptions(d),this.applyToolOutputOptions(d)}openBindingRegistry(...d){return this.broker.openBindingRegistry(...d)}stopSessionTimers(...d){return this.sessions.stopSessionTimers(...d)}subscribeToolCallEndActivity(...d){return this.sessions.subscribeToolCallEndActivity(...d)}start(...d){return this.startup.start(...d)}startOn(...d){return this.startup.startOn(...d)}stopAfterFailedStartup(...d){return this.startup.stopAfterFailedStartup(...d)}startThroughSocketBind(...d){return this.startup.startThroughSocketBind(...d)}startAfterSocketBind(...d){return this.startup.startAfterSocketBind(...d)}getDeviceSessionRoutingTargets(...d){return this.streams.getDeviceSessionRoutingTargets(...d)}setupDeviceDataStreamCallback(...d){return this.streams.setupDeviceDataStreamCallback(...d)}setupNavigationGraphStreamListener(...d){return this.streams.setupNavigationGraphStreamListener(...d)}startHeartbeatMonitor(...d){return this.maintenance.startHeartbeatMonitor(...d)}recordAndTryRecoverCapturedDisconnect(...d){return this.disconnect.recordAndTryRecoverCapturedDisconnect(...d)}startDeviceDisconnectMonitor(...d){return this.disconnect.startDeviceDisconnectMonitor(...d)}trackDeferredSessionRecoverySweep(...d){return this.disconnect.trackDeferredSessionRecoverySweep(...d)}stopRecordingAfterDeviceDisconnect(...d){return this.disconnect.stopRecordingAfterDeviceDisconnect(...d)}shouldSkipStaleDisconnectCleanup(...d){return this.disconnect.shouldSkipStaleDisconnectCleanup(...d)}isCapturedDisconnectTargetCurrent(...d){return Og({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&&Gc(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,w){let D=this;return new ea({readPersistedSession:Tc(()=>this.deviceSessionRepository).getSession,warmConfirmedManagedExecution:(k)=>mv({services:d,lifecycle:w},k),services:d,identity:c,lifecycle:w,bindingRegistry:()=>D.runtime.bindingRegistry,deviceClaimMirrors:()=>D.runtime.deviceClaimMirrors,setBindingRegistry:(k)=>{D.runtime.bindingRegistry=k},brokerDeviceAcquisition:()=>D.runtime.brokerDeviceAcquisition,setBrokerDeviceAcquisition:(k)=>D.runtime.brokerDeviceAcquisition=k,openBindingRegistry:(...k)=>this.openBindingRegistry(...k),cancelAndReleaseSession:(...k)=>this.cancelAndReleaseSession(...k)})}createDaemonSessions(d,c,w){let D=this;return new oa({services:d,identity:c,lifecycle:w,bindingExclusionFactory:()=>D.injected.bindingExclusionFactory,startBackgroundRegistryUpgrade:()=>this.broker.startBackgroundRegistryUpgrade(),bindingRegistry:()=>D.runtime.bindingRegistry,deviceClaimMirrors:()=>D.runtime.deviceClaimMirrors,foreignCtrlProxyForwardEvidence:()=>D.injected.foreignCtrlProxyForwardEvidence,deviceStateChangeNotifier:()=>D.deviceStateChangeNotifier,observerSessionRegistry:()=>D.observerSessionRegistry,cancelAndReleaseSession:(...k)=>this.cancelAndReleaseSession(...k),onDeviceReadyForSessionRegistry:(...k)=>this.streams.onDeviceReadyForSessionRegistry(...k),reownRehydratedManagedExecutions:(...k)=>this.broker.reownRehydratedManagedExecutions(...k)})}createDaemonStartup(d,c,w){let D=this,k=new bd({initializeRecordingTeardownRedriveState:()=>jt.initializeRecordingTeardownRedriveState(),redriveUnconfirmedCaptureTeardowns:(...P)=>jt.redriveUnconfirmedCaptureTeardowns(...P),setStartupOrphanCaptures:(...P)=>jt.setStartupOrphanCaptures(...P),setVideoRecordingManagerDependencies:(...P)=>jt.setVideoRecordingManagerDependencies(...P),enterDaemonProcess:(...P)=>this.enterDaemonProcess(...P),prepareHttpToken:()=>this.httpToken.prepare(),publishHttpToken:()=>this.httpToken.publish(),startHttpIngress:()=>this.startup.startHttpIngress(),bindControlSocket:(...P)=>this.bindControlSocket(...P),startServicesAfterSocketBind:(...P)=>this.startServicesAfterSocketBind(...P),startMaintenanceMonitors:(...P)=>this.startMaintenanceMonitors(...P),readPersistedSession:Tc(()=>this.deviceSessionRepository).getPersistedSession,start:(...P)=>this.start(...P),services:d,identity:c,lifecycle:w,startHost:()=>D.startHost,setStartHost:(P)=>D.startHost=P,enteredDaemonProcess:()=>D.runtime.enteredDaemonProcess,setEnteredDaemonProcess:(P)=>D.runtime.enteredDaemonProcess=P,resolveStartupCompletion:()=>D.startupCompletion.resolve,rejectStartupCompletion:()=>D.startupCompletion.reject,exitRecordFileSystem:()=>D.exitRecordFileSystem,strictPort:()=>D.listen.strictPort,host:()=>D.listen.host,startupFailureTracker:()=>D.database.startupFailureTracker,avdManagerFactory:()=>D.injected.avdManagerFactory,databaseInitializer:()=>D.database.databaseInitializer,toolSelectionProfileProvenanceLoader:()=>D.database.toolSelectionProfileProvenanceLoader,liveDaemonSessionIdProvider:()=>D.injected.liveDaemonSessionIdProvider,startOn:(...P)=>this.startOn(...P),startThroughSocketBind:(...P)=>this.startThroughSocketBind(...P),startAfterSocketBind:(...P)=>this.startAfterSocketBind(...P),stopAfterFailedStartup:(...P)=>this.stopAfterFailedStartup(...P),stop:(...P)=>this.stop(...P),writeEarlyOwnerRecord:(...P)=>this.writeEarlyOwnerRecord(...P),setupShutdownHandlers:(...P)=>this.setupShutdownHandlers(...P),subscribeToolCallEndActivity:(...P)=>this.subscribeToolCallEndActivity(...P),initializeDatabase:(...P)=>this.initializeDatabase(...P),openBindingRegistry:(...P)=>this.openBindingRegistry(...P),initializeDevicePoolWithTimeout:(...P)=>this.initializeDevicePoolWithTimeout(...P),reownRehydratedManagedExecutions:(...P)=>this.broker.reownRehydratedManagedExecutions(...P),installSessionBroker:(...P)=>this.broker.installSessionBroker(...P),startBackgroundRegistryUpgrade:()=>this.broker.startBackgroundRegistryUpgrade(),initializeIosServices:(...P)=>this.initializeIosServices(...P),restoreIncumbentOwnerRecord:(...P)=>this.identity.restoreIncumbentOwnerRecord(...P),republishIdentity:(...P)=>this.identity.republishIdentity(...P),recordControlSocketIdentity:()=>this.identity.recordControlSocketIdentity(),startAuxiliarySocket:(...P)=>this.startAuxiliarySocket(...P),configureDeviceDataStreamServer:(...P)=>this.streams.configureDeviceDataStreamServer(...P),setupDeviceSessionRouting:(...P)=>this.streams.setupDeviceSessionRouting(...P),getAppearanceSyncTargets:(...P)=>this.sessions.getAppearanceSyncTargets(...P),startAdbMissingDeviceListener:(...P)=>this.startAdbMissingDeviceListener(...P),startDeviceDisconnectMonitor:(...P)=>this.startDeviceDisconnectMonitor(...P),writePidFile:(...P)=>this.writePidFile(...P),startHealthCheckTimer:(...P)=>this.maintenance.startHealthCheckTimer(...P),startNavigationRetentionMonitor:(...P)=>this.maintenance.startNavigationRetentionMonitor(...P),startForwardLeaseIdleReleaser:(...P)=>this.maintenance.startForwardLeaseIdleReleaser(...P),startPrivateDaemonOrphanWatchdog:(...P)=>this.maintenance.startPrivateDaemonOrphanWatchdog(...P),startHeartbeatMonitor:(...P)=>this.startHeartbeatMonitor(...P),initializeDevicePool:(...P)=>this.initializeDevicePool(...P)});return this.startHost=k.processStartHost(),k}createDaemonIdentity(d,c){return new Rd({pidFileWritten:()=>this.runtime.pidFileWritten,setPidFileWritten:(w)=>this.runtime.pidFileWritten=w,persistPidFileData:(...w)=>this.persistPidFileData(...w),writeEarlyOwnerRecord:(...w)=>this.writeEarlyOwnerRecord(...w),cleanupDaemonFilesForShutdown:(...w)=>this.cleanupDaemonFilesForShutdown(...w),services:d,identity:c})}createDaemonStreams(d,c){return new Pd({services:d,lifecycle:c,setupDeviceDataStreamCallback:(...w)=>this.setupDeviceDataStreamCallback(...w),getDeviceSessionRoutingTargets:(...w)=>this.getDeviceSessionRoutingTargets(...w),setupNavigationGraphStreamListener:(...w)=>this.setupNavigationGraphStreamListener(...w)})}createDaemonMaintenance(d,c,w){return new Gd({services:d,identityState:c,identity:this.identity,lifecycle:w,healthCheck:()=>this.runtime.healthCheck,setHealthCheck:(D)=>this.runtime.healthCheck=D,observationStreamHealth:()=>this.observationStreamHealth,setObservationStreamHealth:(D)=>this.observationStreamHealth=D,lastDatabaseHealthFailure:()=>this.runtime.lastDatabaseHealthFailure,setLastDatabaseHealthFailure:(D)=>this.runtime.lastDatabaseHealthFailure=D,recoverFromDatabaseHealthFailure:()=>this.database.recoverFromDatabaseHealthFailure,hostIoStalled:()=>this.injected.hostIoStalled,attemptRecovery:(...D)=>this.attemptRecovery(...D),sessionExecutionProbe:(...D)=>this.sessions.sessionExecutionProbe(...D),cancelAndReleaseSession:(...D)=>this.cancelAndReleaseSession(...D),republishIdentity:(...D)=>this.identity.republishIdentity(...D),configureDeviceDataStreamServer:(...D)=>this.streams.configureDeviceDataStreamServer(...D)})}createDaemonDisconnect(d,c){let w=this;return new Yd({listActiveVideoRecordings:(...D)=>jt.listActiveVideoRecordings(...D),captureDisconnectCleanup:(D,k)=>Eg({services:d,forceDisconnectedDeviceGenerations:()=>w.deviceLoss.forceDisconnectedGenerations},D,k),stoppingRecordings:()=>this.stoppingRecordings,retireAdbServerResetDisconnectState:(...D)=>this.retireAdbServerResetDisconnectState(...D),cleanupDisconnectedDevice:(...D)=>this.cleanupDisconnectedDevice(...D),services:d,lifecycle:c,forceDisconnectedDeviceIds:()=>w.deviceLoss.forceDisconnectedIds,confirmedDisconnectedDeviceIds:()=>w.deviceLoss.confirmedDisconnectedIds,deviceDisconnectMissIncarnations:()=>w.deviceLoss.missIncarnations,offlineEpisodes:()=>w.deviceLoss.offlineEpisodes,offlineRecoveryAttemptedDeviceIds:()=>w.deviceLoss.offlineRecoveryAttemptedIds,setOfflineRecoveryAttemptedDeviceIds:(D)=>w.deviceLoss.offlineRecoveryAttemptedIds=D,offlineRecoveryAttemptedIncarnations:()=>w.deviceLoss.offlineRecoveryAttemptedIncarnations,setOfflineRecoveryAttemptedIncarnations:(D)=>w.deviceLoss.offlineRecoveryAttemptedIncarnations=D,forceDisconnectedDeviceGenerations:()=>w.deviceLoss.forceDisconnectedGenerations,shouldSkipStaleDisconnectCleanup:(...D)=>this.shouldSkipStaleDisconnectCleanup(...D),isCapturedDisconnectTargetCurrent:(...D)=>this.isCapturedDisconnectTargetCurrent(...D),trackDeferredSessionRecoverySweep:(...D)=>this.trackDeferredSessionRecoverySweep(...D),stopRecordingAfterDeviceDisconnect:(...D)=>this.stopRecordingAfterDeviceDisconnect(...D),recordAndTryRecoverCapturedDisconnect:(...D)=>this.recordAndTryRecoverCapturedDisconnect(...D),cancelAndReleaseSession:(...D)=>this.cancelAndReleaseSession(...D)})}createDaemonShutdown(d,c){let w=this;return new Zd({services:d,lifecycle:c,stopManagedAdbServer:()=>w.injected.stopManagedAdbServer,removeHttpToken:()=>this.httpToken.remove(),stop:(...D)=>this.stop(...D),getDaemonFileCleanupOptions:(...D)=>this.identity.getDaemonFileCleanupOptions(...D),closeManagedExecutionRelease:(...D)=>this.broker.closeManagedExecutionRelease(...D),stopHealthCheckTimer:(...D)=>this.maintenance.stopHealthCheckTimer(...D),stopSessionTimers:(...D)=>this.stopSessionTimers(...D),cleanupDaemonFilesForShutdown:(...D)=>this.cleanupDaemonFilesForShutdown(...D),cancelAndReleaseSession:(...D)=>this.cancelAndReleaseSession(...D)})}createDaemonCoreServices(){let d=this;return{deviceReadiness:()=>d.deviceReadiness,iosDeviceVerifier:()=>d.injected.iosDeviceVerifier,httpIngress:()=>d.httpIngress,mcpDispatcher:()=>d.mcpDispatcher,sessionManager:()=>d.sessionManager,devicePool:()=>d.devicePool,deviceSessionRegistry:()=>d.deviceSessionRegistry,installedAppsRepository:()=>d.installedAppsRepository,deviceSessionRepository:()=>d.deviceSessionRepository,timer:()=>d.timer,passiveWorkPolicy:()=>d.passiveWorkPolicy,idGenerator:()=>d.idGenerator,databaseHealthProbe:()=>d.database.databaseHealthProbe,options:()=>d.options,daemonState:()=>d.daemonState}}createDaemonIdentityState(){let d=this;return{port:()=>d.listen.port,setPort:(c)=>d.listen.port=c,completeIdentityPublished:()=>d.runtime.completeIdentityPublished,setCompleteIdentityPublished:(c)=>d.runtime.completeIdentityPublished=c,socketBindCommitted:()=>d.runtime.socketBindCommitted,setSocketBindCommitted:(c)=>d.runtime.socketBindCommitted=c,incumbentOwnerGuard:()=>d.incumbentOwnerGuard,daemonSessionId:()=>d.daemonSessionId,generationStartedAt:()=>d.processIdentity.generationStartedAt,processStartedAt:()=>d.processIdentity.processStartedAt,processGenerationToken:()=>d.processIdentity.processGenerationToken,liveAcceptanceStartupSecret:()=>d.processIdentity.liveAcceptanceStartupSecret,acceptanceDiscoveryCapability:()=>d.acceptanceDiscoveryCapability}}createDaemonLifecycleState(){let d=this;return{socketServer:()=>d.runtime.socketServer,setSocketServer:(c)=>d.runtime.socketServer=c,selfExitRecorder:()=>d.selfExitRecorder,startupCompletion:()=>d.startupCompletion.promise,heartbeatMonitor:()=>d.runtime.heartbeatMonitor,setHeartbeatMonitor:(c)=>d.runtime.heartbeatMonitor=c,navigationRetentionMonitor:()=>d.runtime.navigationRetentionMonitor,setNavigationRetentionMonitor:(c)=>d.runtime.navigationRetentionMonitor=c,forwardLeaseIdleReleaser:()=>d.runtime.forwardLeaseIdleReleaser,setForwardLeaseIdleReleaser:(c)=>d.runtime.forwardLeaseIdleReleaser=c,orphanWatchdog:()=>d.runtime.orphanWatchdog,setOrphanWatchdog:(c)=>d.runtime.orphanWatchdog=c,deviceDisconnectMonitor:()=>d.runtime.deviceDisconnectMonitor,setDeviceDisconnectMonitor:(c)=>d.runtime.deviceDisconnectMonitor=c,deferredSessionRecoverySweeps:()=>d.runtime.deferredSessionRecoverySweeps,deviceDisconnectMisses:()=>d.deviceLoss.misses,sessionBrokerConfigPath:()=>d.sessionBrokerConfigPath,managedExecutionReowner:()=>d.runtime.managedExecutionReowner,setManagedExecutionReowner:(c)=>d.runtime.managedExecutionReowner=c,deviceDataStreamServer:()=>d.runtime.deviceDataStreamServer,setDeviceDataStreamServer:(c)=>d.runtime.deviceDataStreamServer=c,navigationGraphBridge:()=>d.navigationGraphBridge,unsubscribeAdbMissingDevice:()=>d.runtime.unsubscribeAdbMissingDevice,setUnsubscribeAdbMissingDevice:(c)=>d.runtime.unsubscribeAdbMissingDevice=c,shutdownInProgress:()=>d.shutdownState.inProgress,setShutdownInProgress:(c)=>d.shutdownState.inProgress=c,recorderDeviceIncarnationListener:()=>d.runtime.recorderDeviceIncarnationListener,setRecorderDeviceIncarnationListener:(c)=>d.runtime.recorderDeviceIncarnationListener=c,shutdownReleaseNotifications:()=>d.shutdownState.releaseNotifications,setShutdownReleaseNotifications:(c)=>d.shutdownState.releaseNotifications=c,shutdownFallbackReleaseNotifications:()=>d.shutdownState.fallbackReleaseNotifications,setShutdownFallbackReleaseNotifications:(c)=>d.shutdownState.fallbackReleaseNotifications=c,backgroundRegistryUpgrade:()=>d.runtime.backgroundRegistryUpgrade,setBackgroundRegistryUpgrade:(c)=>d.runtime.backgroundRegistryUpgrade=c}}enterDaemonProcess(...d){return this.startup.enterDaemonProcess(...d)}writeEarlyOwnerRecord(...d){return this.identity.writeEarlyOwnerRecord(...d)}writePidFile(...d){return this.identity.writePidFile(...d)}persistPidFileData(...d){return this.identity.persistPidFileData(...d)}bindControlSocket(...d){return this.startup.bindControlSocket(...d)}startServicesAfterSocketBind(...d){return this.startup.startServicesAfterSocketBind(...d)}startAuxiliarySocket(...d){return this.identity.startAuxiliarySocket(...d)}startMaintenanceMonitors(...d){return this.startup.startMaintenanceMonitors(...d)}cleanupDaemonFilesForShutdown(...d){return this.identity.cleanupDaemonFilesForShutdown(...d)}bindingJournalOwner(...d){return this.broker.bindingJournalOwner(...d)}cleanupDisconnectedDevice(...d){return this.disconnect.cleanupDisconnectedDevice(...d)}createPlanDeviceLossCheck(...d){return this.disconnect.createPlanDeviceLossCheck(...d)}getDaemonFileCleanupOptions(...d){return this.identity.getDaemonFileCleanupOptions(...d)}retireAdbServerResetDisconnectState(...d){return this.disconnect.retireAdbServerResetDisconnectState(...d)}applyToolOutputOptions(d){Nh(d,this.options)}}async function mre(d={}){let c=new fv(d,{foreignCtrlProxyForwardEvidence:AB()});Kf().setDeviceReadiness(c.getDeviceReadiness()),await c.start()}export{mre as startDaemon};
|
|
53
|
+
|
|
54
|
+
//# debugId=1B4C62B20BB3104564756E2164756E21
|