@kaeawc/auto-mobile 0.0.93 → 0.0.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-info.json +12 -12
- package/dist/src/ble-peripheral.py +153 -0
- package/dist/src/{chunk-r6z1eztj.js → chunk-026y62r9.js} +11 -11
- package/dist/src/chunk-0jyfg947.js +4 -0
- package/dist/src/{chunk-8g1922rp.js → chunk-0zfpp1wh.js} +4 -4
- package/dist/src/{chunk-qf6nynk6.js → chunk-13qxf7ym.js} +5 -5
- package/dist/src/chunk-1scenrk7.js +4 -0
- package/dist/src/chunk-1vb5ph1k.js +4 -0
- package/dist/src/{chunk-710rxz9y.js → chunk-20g565q7.js} +3 -3
- package/dist/src/chunk-21h6dhdm.js +5 -0
- package/dist/src/chunk-25mfpthk.js +78 -0
- package/dist/src/{chunk-rbpdk7m0.js → chunk-2b39zyxc.js} +3 -3
- package/dist/src/chunk-2gzd6wbd.js +4 -0
- package/dist/src/{chunk-xgan0qqp.js → chunk-3dntffy9.js} +1 -1
- package/dist/src/chunk-3gfczcsn.js +4 -0
- package/dist/src/{chunk-dgrbdpb7.js → chunk-3h5jz1vb.js} +6 -6
- package/dist/src/{chunk-t6c8akcm.js → chunk-41zcy6b3.js} +3 -3
- package/dist/src/chunk-47n9m2de.js +4 -0
- package/dist/src/chunk-4vxeq0vd.js +58 -0
- package/dist/src/chunk-59dx6qaf.js +4 -0
- package/dist/src/chunk-5sdf9y92.js +4 -0
- package/dist/src/{chunk-58wzr3mt.js → chunk-5wk1t46v.js} +3 -3
- package/dist/src/{chunk-vy3bwm1d.js → chunk-661c50hh.js} +5 -5
- package/dist/src/chunk-68n6bjjd.js +21 -0
- package/dist/src/{chunk-v6pya0dm.js → chunk-69pmjdf2.js} +3 -3
- package/dist/src/{chunk-e98dqnc9.js → chunk-6hrj3jt6.js} +20 -20
- package/dist/src/{chunk-wbh8spm5.js → chunk-6myr26wx.js} +8 -8
- package/dist/src/chunk-6n96k09n.js +4 -0
- package/dist/src/chunk-6vwrbkre.js +4 -0
- package/dist/src/chunk-6wk0yrab.js +4 -0
- package/dist/src/chunk-6yhm9een.js +4 -0
- package/dist/src/{chunk-mjrps0ac.js → chunk-7k7gjg2t.js} +5 -5
- package/dist/src/chunk-7n5fz68h.js +4 -0
- package/dist/src/chunk-8cvnpnbp.js +4 -0
- package/dist/src/chunk-8kzv7rk7.js +4 -0
- package/dist/src/chunk-8nj68t1v.js +167 -0
- package/dist/src/{chunk-g7tmjbkt.js → chunk-96r3bpg7.js} +3 -3
- package/dist/src/chunk-97x887te.js +4 -0
- package/dist/src/{chunk-8ph29g99.js → chunk-99a6tbvd.js} +1 -1
- package/dist/src/chunk-9p5d2994.js +5 -0
- package/dist/src/{chunk-aabchzxk.js → chunk-9q265er0.js} +4 -4
- package/dist/src/{chunk-jh6vhqzx.js → chunk-9xgnrv5w.js} +3 -3
- package/dist/src/chunk-9xgsmshb.js +5 -0
- package/dist/src/chunk-a02d1wgv.js +4 -0
- package/dist/src/{chunk-ndt1ccxm.js → chunk-a9ps00a1.js} +10 -10
- package/dist/src/{chunk-5d2hft6c.js → chunk-aewdveet.js} +3 -3
- package/dist/src/{chunk-ycaj2sgf.js → chunk-b3tdtq7r.js} +6 -6
- package/dist/src/chunk-bn7jx7a2.js +4 -0
- package/dist/src/{chunk-3y6eykz9.js → chunk-bnyw27ja.js} +2 -2
- package/dist/src/{chunk-rqc9ap3x.js → chunk-bpwsg76p.js} +2 -2
- package/dist/src/chunk-bvranw3g.js +4 -0
- package/dist/src/chunk-c25a84zb.js +4 -0
- package/dist/src/chunk-c27yv1dx.js +5 -0
- package/dist/src/chunk-c3ewxm4x.js +5 -0
- package/dist/src/{chunk-rvvy1bte.js → chunk-cb1ga9rd.js} +5 -5
- package/dist/src/chunk-cn7fwy7k.js +4 -0
- package/dist/src/chunk-cnvy4a64.js +4 -0
- package/dist/src/{chunk-7rz9898k.js → chunk-cqhw4yr6.js} +3 -3
- package/dist/src/{chunk-g04bwyj3.js → chunk-ctmfshjc.js} +2 -2
- package/dist/src/chunk-ctwmhz13.js +4 -0
- package/dist/src/{chunk-waqwcjyn.js → chunk-d3jx9bz5.js} +2 -2
- package/dist/src/{chunk-ayp07wbb.js → chunk-d6rb08ga.js} +1 -1
- package/dist/src/chunk-ddqhj4eg.js +5 -0
- package/dist/src/{chunk-r7bpkgff.js → chunk-ddrhs1c3.js} +2 -2
- package/dist/src/chunk-dnjnh9p6.js +4 -0
- package/dist/src/{chunk-wyrkw6hw.js → chunk-dw5rwgya.js} +3 -3
- package/dist/src/{chunk-3xkpk44w.js → chunk-e0870khr.js} +3 -3
- package/dist/src/chunk-ea3k10kj.js +4 -0
- package/dist/src/chunk-emv82m1w.js +7 -0
- package/dist/src/chunk-f3m6pdnx.js +4 -0
- package/dist/src/chunk-f84z32cb.js +4 -0
- package/dist/src/chunk-fpczgf0z.js +4 -0
- package/dist/src/{chunk-2tqzq5qh.js → chunk-g2js4c2v.js} +18 -18
- package/dist/src/chunk-g3af2qbk.js +5 -0
- package/dist/src/{chunk-3qwrzxh0.js → chunk-gadtna7s.js} +6 -6
- package/dist/src/{chunk-ybbtagbt.js → chunk-gcyx407v.js} +3 -3
- package/dist/src/{chunk-bfw6125s.js → chunk-gfpntwc1.js} +3 -3
- package/dist/src/chunk-gmnm5e3e.js +4 -0
- package/dist/src/chunk-gp6vb5gf.js +4 -0
- package/dist/src/chunk-gppgy7pa.js +4 -0
- package/dist/src/chunk-hegfz0ae.js +5 -0
- package/dist/src/chunk-hpzxdp1k.js +17 -0
- package/dist/src/{chunk-qcxzr2my.js → chunk-j69g8b50.js} +3 -3
- package/dist/src/chunk-jvstjnqm.js +19 -0
- package/dist/src/chunk-jzqrv78s.js +4 -0
- package/dist/src/chunk-k2948b8d.js +4 -0
- package/dist/src/chunk-k4ftd40d.js +4 -0
- package/dist/src/{chunk-bxmsax22.js → chunk-kd9vfaxh.js} +3 -3
- package/dist/src/{chunk-s3jc6cwp.js → chunk-kdczmgwk.js} +3 -3
- package/dist/src/{chunk-t6bfvfkg.js → chunk-ke3wn14v.js} +1 -1
- package/dist/src/chunk-kh5n7m6w.js +4 -0
- package/dist/src/{chunk-6wt9rgjf.js → chunk-khejfph4.js} +3 -3
- package/dist/src/chunk-kny2xemh.js +4 -0
- package/dist/src/chunk-knyzw9md.js +4 -0
- package/dist/src/chunk-mbzpt2hp.js +4 -0
- package/dist/src/chunk-mm8rcxad.js +4 -0
- package/dist/src/chunk-nc4516tx.js +4 -0
- package/dist/src/{chunk-6bznss4t.js → chunk-ntfrqrqn.js} +5 -5
- package/dist/src/chunk-nz5h2j52.js +4 -0
- package/dist/src/chunk-p22s97qy.js +4 -0
- package/dist/src/chunk-p9kt1sgr.js +6 -0
- package/dist/src/{chunk-yb97j25b.js → chunk-pf282r5g.js} +4 -4
- package/dist/src/chunk-pnd4mrxy.js +4 -0
- package/dist/src/chunk-pqqteyj6.js +4 -0
- package/dist/src/{chunk-6xmss8er.js → chunk-qj1tbnv2.js} +6 -6
- package/dist/src/chunk-qnh9egwr.js +4 -0
- package/dist/src/chunk-qy3khhf8.js +8 -0
- package/dist/src/{chunk-z637nqg8.js → chunk-r0vp315h.js} +6 -6
- package/dist/src/chunk-r4j43b9s.js +237 -0
- package/dist/src/{chunk-1p7xf5kb.js → chunk-r54cxxze.js} +3 -3
- package/dist/src/{chunk-yf7ympyz.js → chunk-r6pvhj33.js} +92 -92
- package/dist/src/chunk-rb7aa5gr.js +54 -0
- package/dist/src/chunk-rdj50kb4.js +4 -0
- package/dist/src/chunk-rnd4vcas.js +4 -0
- package/dist/src/{chunk-w5b2jwk3.js → chunk-s3y3zfcx.js} +8 -8
- package/dist/src/chunk-s4g43k75.js +5 -0
- package/dist/src/chunk-sfqe223f.js +311 -0
- package/dist/src/{chunk-284ptqa4.js → chunk-sqdrxjw5.js} +5 -5
- package/dist/src/{chunk-zgja5f3p.js → chunk-t54k47em.js} +4 -4
- package/dist/src/{chunk-3sy6ahhz.js → chunk-tek4pnvv.js} +10 -10
- package/dist/src/chunk-tn74y7af.js +4 -0
- package/dist/src/{chunk-thbh3jew.js → chunk-tvq0nzam.js} +3 -3
- package/dist/src/{chunk-0jrrsnc9.js → chunk-tx4f0h9c.js} +4 -4
- package/dist/src/chunk-vdqag3fj.js +5 -0
- package/dist/src/chunk-vz5zzs57.js +4 -0
- package/dist/src/chunk-w4s2vfpj.js +4 -0
- package/dist/src/{chunk-4hw3665t.js → chunk-w5yypt53.js} +11 -11
- package/dist/src/{chunk-8037tzzj.js → chunk-w68v64vh.js} +3 -3
- package/dist/src/chunk-whwj0pdk.js +5 -0
- package/dist/src/chunk-wnmqt1dc.js +4 -0
- package/dist/src/{chunk-cyy71ggq.js → chunk-wpe46vsa.js} +3 -3
- package/dist/src/{chunk-w3vs79ex.js → chunk-wxdjeb4k.js} +19 -19
- package/dist/src/chunk-xcqzwf9j.js +247 -0
- package/dist/src/chunk-xezekwwn.js +5 -0
- package/dist/src/chunk-xf19m15s.js +4 -0
- package/dist/src/chunk-xghbxha4.js +4 -0
- package/dist/src/{chunk-00167wan.js → chunk-xn9m3xc2.js} +5 -5
- package/dist/src/{chunk-26k317v5.js → chunk-yqfz4vts.js} +3 -3
- package/dist/src/chunk-z8tvs8nk.js +5 -0
- package/dist/src/chunk-zm2rehqb.js +5 -0
- package/dist/src/chunk-zs6dqm35.js +4 -0
- package/dist/src/daemon/processEntry.js +2 -2
- package/dist/src/index.js +4 -4
- package/dist/src/runtime/bunRuntimeGuard.js +2 -2
- package/dist/src/utils/workers/iosBundleExtractWorker.js +2 -2
- package/package.json +2 -2
- package/dist/src/chunk-0n6swkwg.js +0 -5
- package/dist/src/chunk-0qsy1qsx.js +0 -57
- package/dist/src/chunk-11m8wj8j.js +0 -237
- package/dist/src/chunk-23p5f095.js +0 -4
- package/dist/src/chunk-28re4xrg.js +0 -4
- package/dist/src/chunk-2f9rkmhx.js +0 -5
- package/dist/src/chunk-2fxdh48t.js +0 -4
- package/dist/src/chunk-2tbdrbt6.js +0 -4
- package/dist/src/chunk-32gvv9b4.js +0 -21
- package/dist/src/chunk-3f3t1x97.js +0 -8
- package/dist/src/chunk-3fspkbc7.js +0 -4
- package/dist/src/chunk-3vg455e6.js +0 -4
- package/dist/src/chunk-49bsqdx3.js +0 -4
- package/dist/src/chunk-5snsn9cf.js +0 -4
- package/dist/src/chunk-5tm9mn47.js +0 -54
- package/dist/src/chunk-5zc77a5t.js +0 -4
- package/dist/src/chunk-64j0majr.js +0 -19
- package/dist/src/chunk-65y8v4td.js +0 -17
- package/dist/src/chunk-6awz7vhq.js +0 -5
- package/dist/src/chunk-6ep7f5ge.js +0 -4
- package/dist/src/chunk-7cs2da62.js +0 -5
- package/dist/src/chunk-7g103b54.js +0 -4
- package/dist/src/chunk-7j5vj4pa.js +0 -4
- package/dist/src/chunk-7tw8x05v.js +0 -4
- package/dist/src/chunk-7zy586cb.js +0 -4
- package/dist/src/chunk-84nanf8s.js +0 -5
- package/dist/src/chunk-8gvwcv2p.js +0 -4
- package/dist/src/chunk-8thrmfat.js +0 -4
- package/dist/src/chunk-8zgzzs7k.js +0 -78
- package/dist/src/chunk-97b1zmaq.js +0 -4
- package/dist/src/chunk-9fth9ayh.js +0 -4
- package/dist/src/chunk-9j6anhjr.js +0 -4
- package/dist/src/chunk-bfjwqk8q.js +0 -4
- package/dist/src/chunk-bnhscm2n.js +0 -4
- package/dist/src/chunk-c1vs4g1n.js +0 -4
- package/dist/src/chunk-ct3e7yng.js +0 -4
- package/dist/src/chunk-ddzkz92z.js +0 -4
- package/dist/src/chunk-drdz8hee.js +0 -5
- package/dist/src/chunk-eersndy7.js +0 -5
- package/dist/src/chunk-eggq53ks.js +0 -4
- package/dist/src/chunk-f2dya7cs.js +0 -4
- package/dist/src/chunk-fbakd6cw.js +0 -4
- package/dist/src/chunk-fgb98zjj.js +0 -5
- package/dist/src/chunk-fmpad823.js +0 -5
- package/dist/src/chunk-g0xr8zw0.js +0 -4
- package/dist/src/chunk-g3rjs80x.js +0 -4
- package/dist/src/chunk-g78rtrfv.js +0 -4
- package/dist/src/chunk-gabgv3y5.js +0 -4
- package/dist/src/chunk-gmr45m8f.js +0 -4
- package/dist/src/chunk-gsyfebqj.js +0 -4
- package/dist/src/chunk-h5rpn9wr.js +0 -247
- package/dist/src/chunk-hb1x7v55.js +0 -4
- package/dist/src/chunk-hrfytkxh.js +0 -168
- package/dist/src/chunk-j4yjzbak.js +0 -4
- package/dist/src/chunk-jd6a5v6p.js +0 -5
- package/dist/src/chunk-kn5spq15.js +0 -4
- package/dist/src/chunk-m94qs0f0.js +0 -4
- package/dist/src/chunk-n03dmn5q.js +0 -5
- package/dist/src/chunk-n72qhwd9.js +0 -4
- package/dist/src/chunk-nr6y0n4y.js +0 -5
- package/dist/src/chunk-pcsen2vs.js +0 -4
- package/dist/src/chunk-ppfr0b8h.js +0 -4
- package/dist/src/chunk-q10bdnat.js +0 -4
- package/dist/src/chunk-q9xmq595.js +0 -4
- package/dist/src/chunk-qyqypn28.js +0 -5
- package/dist/src/chunk-r2epb56s.js +0 -4
- package/dist/src/chunk-r5bxavdx.js +0 -311
- package/dist/src/chunk-r8jf3d92.js +0 -4
- package/dist/src/chunk-rc0dbypm.js +0 -4
- package/dist/src/chunk-rhcty4ms.js +0 -4
- package/dist/src/chunk-rpvckv3p.js +0 -4
- package/dist/src/chunk-ry0mz41y.js +0 -4
- package/dist/src/chunk-sfv61xjb.js +0 -6
- package/dist/src/chunk-t7w8rctc.js +0 -4
- package/dist/src/chunk-v2wd4n3e.js +0 -5
- package/dist/src/chunk-w4zga19f.js +0 -4
- package/dist/src/chunk-w7hkv422.js +0 -5
- package/dist/src/chunk-xa73x2cx.js +0 -5
- package/dist/src/chunk-y2vs6jwg.js +0 -4
- package/dist/src/chunk-yattm52s.js +0 -4
- package/dist/src/chunk-yjawdzk8.js +0 -4
- package/dist/src/chunk-zs1sghs9.js +0 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{i,Rr,Q,e}from"./chunk-z637nqg8.js";import{f,I}from"./chunk-58wzr3mt.js";import{_e}from"./chunk-yf7ympyz.js";import{Ea,Q7}from"./chunk-hrfytkxh.js";import{Br,fl,Fs,v,Rn,L,b,kD,dn,ud,vk,LB,jz,yY,N,Qo,MR,oi,Lg,Bg,Lk,E}from"./chunk-r5bxavdx.js";import{n,a,h,S,s,Ne,p}from"./chunk-4hw3665t.js";import{ei}from"./chunk-0qsy1qsx.js";import{Ju,dh,Zd,Gq,Yq,kQ,lh,lm,W4}from"./chunk-26k317v5.js";import{jL}from"./chunk-v6pya0dm.js";import{r,t,u}from"./chunk-rbpdk7m0.js";import{promises as Xe}from"fs";import*as ae from"path";var q=Ne(n(),n()),ee=S(n()),st=s({snapshotName:n(),timestamp:n(),deviceId:n(),deviceName:n(),platform:p(["android","ios"]),deviceType:n().optional(),osVersion:n().optional(),snapshotType:p(["vm","adb","simctl","app_data"]),includeAppData:h(),includeSettings:h(),packages:ee.optional(),foregroundApp:n().optional(),settings:s({global:q.optional(),secure:q.optional(),system:q.optional()}).optional(),iosSettings:s({values:q,ui:s({appearance:p(["light","dark"]).optional(),contentSize:n().optional()}).optional()}).optional(),appDataBackup:s({backupFile:n().optional(),backedUpPackages:ee.optional(),skippedPackages:ee.optional(),failedPackages:ee.optional(),totalPackages:a().optional(),backupTimedOut:h().optional(),backupMethod:p(["root_pull","none","simctl_copy"]).optional(),bundleStatuses:S(s({bundleId:n(),status:p(["captured","skipped-no-container","not-installed","failed"])})).optional()}).optional(),fixture:s({avdName:n(),systemImageId:n(),avdConfigHash:n(),emulatorVersion:n(),userdataGeneration:n()}).optional()});function rt(o,c){let d;try{d=JSON.parse(c)}catch(l){return e.warn(`[DeviceSnapshotRepository] Failed to parse manifest for ${o}: ${r(l)}`),null}let m=st.safeParse(d);if(m.success)return m.data;return e.warn(`[DeviceSnapshotRepository] Manifest for ${o} failed validation: ${m.error.message}`),typeof d==="object"&&d!==null&&!Array.isArray(d)?d:null}function Ie(o){let c=rt(o.snapshot_name,o.manifest_json);if(!c)return null;return{snapshotName:o.snapshot_name,deviceId:o.device_id,deviceName:o.device_name,platform:o.platform,snapshotType:o.snapshot_type,includeAppData:Boolean(o.include_app_data),includeSettings:Boolean(o.include_settings),createdAt:o.created_at,lastAccessedAt:o.last_accessed_at,sizeBytes:o.size_unknown?null:o.size_bytes,pendingReclaim:Boolean(o.pending_reclaim),...o.pending_reclaim_reason===null?{}:{pendingReclaimReason:o.pending_reclaim_reason},manifest:c}}var pt={deviceId:(o,c)=>{o.device_id=c},deviceName:(o,c)=>{o.device_name=c},platform:(o,c)=>{o.platform=c},snapshotType:(o,c)=>{o.snapshot_type=c},includeAppData:(o,c)=>{o.include_app_data=c?1:0},includeSettings:(o,c)=>{o.include_settings=c?1:0},createdAt:(o,c)=>{o.created_at=c},lastAccessedAt:(o,c)=>{o.last_accessed_at=c},pendingReclaim:(o,c)=>{o.pending_reclaim=c?1:0},pendingReclaimReason:(o,c)=>{o.pending_reclaim_reason=c},manifest:(o,c)=>{o.manifest_json=JSON.stringify(c)}};function ct(o){let c={};for(let[d,m]of Object.entries(pt)){let l=o[d];if(l!==void 0)m(c,l)}if(o.sizeBytes!==void 0)c.size_bytes=o.sizeBytes??0,c.size_unknown=o.sizeBytes===null?1:0;return c}class me{db;constructor({db:o}={}){this.db=o??null}getDb(){return this.db??_e()}async insertSnapshot(o){let c=await this.getDb(),d={snapshot_name:o.snapshotName,device_id:o.deviceId,device_name:o.deviceName,platform:o.platform,snapshot_type:o.snapshotType,include_app_data:o.includeAppData?1:0,include_settings:o.includeSettings?1:0,created_at:o.createdAt,last_accessed_at:o.lastAccessedAt,size_bytes:o.sizeBytes??0,size_unknown:o.sizeBytes===null?1:0,pending_reclaim:o.pendingReclaim?1:0,pending_reclaim_reason:o.pendingReclaimReason??null,manifest_json:JSON.stringify(o.manifest)};await c.insertInto("device_snapshots").values(d).onConflict((m)=>m.column("snapshot_name").doUpdateSet({device_id:d.device_id,device_name:d.device_name,platform:d.platform,snapshot_type:d.snapshot_type,include_app_data:d.include_app_data,include_settings:d.include_settings,last_accessed_at:d.last_accessed_at,size_bytes:d.size_bytes,size_unknown:d.size_unknown,pending_reclaim:d.pending_reclaim,pending_reclaim_reason:d.pending_reclaim_reason,manifest_json:d.manifest_json})).execute()}async updateSnapshot(o,c){let d=await this.getDb(),m=ct(c);if(Object.keys(m).length===0)return;await d.updateTable("device_snapshots").set(m).where("snapshot_name","=",o).execute()}async getSnapshot(o){let d=await(await this.getDb()).selectFrom("device_snapshots").selectAll().where("snapshot_name","=",o).executeTakeFirst();return d?Ie(d):null}async listSnapshots(o={}){let d=(await this.getDb()).selectFrom("device_snapshots").selectAll();if(o.deviceId)d=d.where("device_id","=",o.deviceId);if(o.platform)d=d.where("platform","=",o.platform);if(o.snapshotType)d=d.where("snapshot_type","=",o.snapshotType);if(o.pendingReclaim!==void 0)d=d.where("pending_reclaim","=",o.pendingReclaim?1:0);if(o.orderByLastAccessed)d=d.orderBy("last_accessed_at",o.orderByLastAccessed);if(o.orderByCreatedAt)d=d.orderBy("created_at",o.orderByCreatedAt);if(o.limit&&o.limit>0)d=d.limit(o.limit);return(await d.execute()).map((l)=>Ie(l)).filter((l)=>Boolean(l))}async touchSnapshot(o,c){await this.updateSnapshot(o,{lastAccessedAt:c})}async deleteSnapshot(o){let d=await(await this.getDb()).deleteFrom("device_snapshots").where("snapshot_name","=",o).executeTakeFirst();return Number(d.numDeletedRows??0)>0}}function te(o,c){if(typeof o==="boolean")return o;if(typeof o==="string"){let d=o.trim().toLowerCase();if(d==="true")return!0;if(d==="false")return!1}return c}function he(o,c,d){if(o===void 0||o===null||o==="")return c;let m=typeof o==="string"?Number(o):o;if(!Number.isFinite(m)||m<=0)return c;let l=d?m:Math.round(m);return l>0?l:c}function dt(o,c){if(o===void 0||o===null||o==="")return;let d=typeof o==="string"?Number(o):o;if(!Number.isFinite(d)||d<=0)return;let m=c?d:Math.round(d);return m>0?m:void 0}function z(o){let c=o&&typeof o==="object"?o:{};return{includeAppData:te(c.includeAppData,Ea.includeAppData),includeSettings:te(c.includeSettings,Ea.includeSettings),useVmSnapshot:te(c.useVmSnapshot,Ea.useVmSnapshot),strictBackupMode:te(c.strictBackupMode,Ea.strictBackupMode),vmSnapshotTimeoutMs:he(c.vmSnapshotTimeoutMs,Ea.vmSnapshotTimeoutMs,!1),maxVmSnapshotsPerAvd:he(c.maxVmSnapshotsPerAvd,Ea.maxVmSnapshotsPerAvd,!1),maxVmArchiveSizeMb:dt(c.maxVmArchiveSizeMb,!0),maxArchiveSizeMb:he(c.maxArchiveSizeMb,Ea.maxArchiveSizeMb,!0)}}var ZE={ARCHIVE:"automobile:deviceSnapshots/archive"};function be(o,c,d){return jz(c,{simctl:o}).terminateApp(d)}var ut=[{domain:".GlobalPreferences",key:"AppleLocale"}];async function mt(o,c){let d={};try{let m=(await o.executeCommandArgs(["ui",c,"appearance"])).stdout.trim();if(m==="light"||m==="dark")d.appearance=m}catch(m){e.warn(`[iOS] Failed to read appearance: ${m}`)}try{let m=(await o.executeCommandArgs(["ui",c,"content_size"])).stdout.trim();if(m)d.contentSize=m}catch(m){e.warn(`[iOS] Failed to read content_size: ${m}`)}return Object.keys(d).length>0?d:void 0}async function Pe(o,c){let d={};for(let{domain:m,key:l}of ut)try{let y=(await o.executeCommandArgs(["spawn",c,"defaults","read",m,l])).stdout.trim();if(y)d[`${m}/${l}`]=y}catch(g){e.debug(`[iOS] No value for ${m}/${l}: ${g}`)}return{values:d,ui:await mt(o,c)}}async function xe(o,c,d){for(let[m,l]of Object.entries(d.values)){let g=m.indexOf("/");if(g<0)continue;let y=m.slice(0,g),D=m.slice(g+1);try{await o.executeCommandArgs(["spawn",c,"defaults","write",y,D,l])}catch(w){e.warn(`[iOS] Failed to write ${y}/${D}: ${w}`)}}if(d.ui?.appearance)try{await o.executeCommandArgs(["ui",c,"appearance",d.ui.appearance])}catch(m){e.warn(`[iOS] Failed to restore appearance: ${m}`)}if(d.ui?.contentSize)try{await o.executeCommandArgs(["ui",c,"content_size",d.ui.contentSize])}catch(m){e.warn(`[iOS] Failed to restore content_size: ${m}`)}}class Ce{options;kind="simulator";constructor(o){this.options=o}getDeviceInfo(){return this.options.simctl.getDeviceInfo(this.options.deviceId)}getRuntimes(){return this.options.simctl.getRuntimes()}captureSettings(){return Pe(this.options.simctl,this.options.deviceId)}restoreSettings(o){return xe(this.options.simctl,this.options.deviceId,o)}getAppDataContainerPath(o){return LB(this.options.simctl,this.options.deviceId,o,this.options.containerOwnership)}terminateAppIfRunning(o){return be(this.options.simctl,this.options.deviceId,o)}listAppsOrThrow(){return new kD(this.options.deviceId,this.options.simctl).listApps()}listApps(){return yY(this.options.deviceId,this.options).listApps()}}function ne(o,c){return Rn(o)?{kind:"physical"}:new Ce({deviceId:o,simctl:c.simctl,containerOwnership:c.containerOwnership})}import{promises as B}from"fs";import*as ie from"path";var le="isVmSnapshotSaveDispatched";class fe{iosCaptureContainerFiles;consoleBusyRegistry;device;adb;emulator;store;iosSnapshotBackend;constructor(o,c={}){let{adbFactory:d=v,emulator:m,store:l=new lh,simctl:g,consoleBusyRegistry:y=Fs}=c;this.iosCaptureContainerFiles=c.iosCaptureContainerFiles??{mkdir:async(D)=>{await B.mkdir(D,{recursive:!0})},cp:(D,w)=>B.cp(D,w,{recursive:!0}),pathExists:Qo},this.consoleBusyRegistry=y,this.device=o,this.adb=d.create(o),this.emulator=m||new oi,this.store=l,this.iosSnapshotBackend=ne(o.deviceId,{simctl:g||new L(o),containerOwnership:c.containerOwnership})}get simulatorSnapshotBackend(){if(this.iosSnapshotBackend.kind==="physical")throw Error("Snapshot app listing is not supported for physical iOS devices");return this.iosSnapshotBackend}async capture(o){return this.execute(o)}async execute(o){switch(dh(o.snapshotName),this.device.platform){case"android":return this.executeAndroid(o);case"ios":if(this.iosSnapshotBackend.kind==="physical")throw new t(`Device snapshots are not supported on physical iOS devices (${this.device.deviceId}); they require a Simulator (simctl).`);return this.executeIos(o);default:throw new t(`Snapshot capture is not supported for platform '${this.device.platform}'`)}}async executeAndroid(o){let{snapshotName:c,includeAppData:d=!0,includeSettings:m=!0,useVmSnapshot:l=!0,vmSnapshotTimeoutMs:g=30000}=o;e.info(`Capturing snapshot '${c}' for device ${this.device.deviceId}`);let y=this.device.deviceId.startsWith("emulator-"),D=l&&y,w;if(D)w=await this.captureVmSnapshot(c,m,g);else w=await this.captureSettingsSnapshot(c,d,m);return e.info(`Snapshot '${c}' captured successfully (type: ${w.snapshotType})`),{snapshotName:w.snapshotName,timestamp:w.timestamp,snapshotType:w.snapshotType,manifest:w}}async captureVmSnapshot(o,c,d){e.info(`Using VM snapshot for emulator ${this.device.deviceId}`);let m=!1;try{let l=Lg("save",o);e.info(`Executing: adb -s ${this.device.deviceId} ${l}`);let g;try{g=await this.consoleBusyRegistry.runExclusive(this.device.deviceId,()=>this.adb.execute(l.split(" "),{timeoutMs:d,waitForProcessSettlementAfterAbort:!0,beforeDispatch:async()=>{m=!0}}))}catch(R){throw Error(Lk("save",o,R))}let y=Bg("save",o,g);if(!y.ok)throw Error(y.errorMessage);e.info("VM snapshot saved successfully");let D;if(c)D=await this.captureSettings();let w=await this.getForegroundApp();return{snapshotName:o,timestamp:new Date().toISOString(),deviceId:this.device.deviceId,deviceName:this.device.name,platform:"android",snapshotType:"vm",includeAppData:!0,includeSettings:c,foregroundApp:w,settings:D}}catch(l){let g=r(l);e.error(`Failed to capture VM snapshot: ${g}`);let y=new t(`Failed to capture VM snapshot: ${g}`);if(m)Object.assign(y,{[le]:!0});throw y}}async captureSettingsSnapshot(o,c,d){if(e.info(`Using settings-only snapshot for device ${this.device.deviceId}`),c)e.warn("App-data snapshots are not supported on non-VM Android (the adb backup path was removed in #5708); capturing settings only. Use a VM snapshot on an emulator to capture app data.");try{let m=await this.getForegroundApp(),l;if(d)l=await this.captureSettings(),await this.saveSettings(o,l);return{snapshotName:o,timestamp:new Date().toISOString(),deviceId:this.device.deviceId,deviceName:this.device.name,platform:"android",snapshotType:"adb",includeAppData:!1,includeSettings:d,foregroundApp:m,settings:l}}catch(m){throw e.error(`Failed to capture settings snapshot: ${r(m)}`,m),u(m,"Failed to capture settings snapshot")}}async getForegroundApp(){try{return(await this.adb.getForegroundApp())?.packageName}catch(o){e.warn(`Failed to get foreground app: ${o}`);return}}async captureSettings(){e.info("Capturing device settings");let o=["global","secure","system"],c={};for(let d of o)await this.captureSettingsNamespace(d,c);return c}async captureSettingsNamespace(o,c){try{let d=!1;try{let l=await E.getInstance(this.device).requestSettingsList(o);if(l.success&&l.entries)c[o]=l.entries,d=!0}catch(m){e.debug(`[CaptureSnapshot] a11y settings list failed for ${o}: ${m}`)}if(!d){let m=await this.adb.executeCommand(`shell settings list ${o}`);c[o]=this.parseSettings(m.stdout)}e.info(`Captured ${Object.keys(c[o]).length} ${o} settings`)}catch(d){e.warn(`Failed to capture ${o} settings: ${d}`),c[o]={}}}parseSettings(o){let c={};for(let d of o.split(`
|
|
3
|
-
`)){let m=d.trim();if(!m)continue;let l=m.match(/^(.+?)=(.*)$/);if(l)c[l[1]]=l[2]}return c}async saveSettings(o,c){let d=this.getAndroidPathOptions(),m=this.store.getSnapshotPathWithOptions(o,d);await B.mkdir(m,{recursive:!0});let l=this.store.getSettingsPath(o,d);await B.writeFile(l,JSON.stringify(c,null,2),"utf-8"),e.info(`Saved settings to ${l}`)}getAndroidPathOptions(){if(this.device.deviceId.startsWith("emulator-"))return{platform:"android",avdName:this.device.name};return}async executeIos(o){let{snapshotName:c,includeAppData:d=!0,includeSettings:m=!0,useVmSnapshot:l=!0,strictBackupMode:g=!1,appBundleIds:y}=o;if(e.info(`[iOS] Capturing snapshot '${c}' for simulator ${this.device.deviceId}`),l)e.info("[iOS] useVmSnapshot is ignored; using app container backups for portability");let D=await this.getIosDeviceMetadata(),w=this.getIosPathOptions(),A;if(m)A=await this.simulatorSnapshotBackend.captureSettings();let R=d?await this.captureIosAppData(c,y,g,w):void 0,P={snapshotName:c,timestamp:new Date().toISOString(),deviceId:this.device.deviceId,deviceName:this.device.name,platform:"ios",deviceType:D.deviceType,osVersion:D.osVersion,snapshotType:"app_data",includeAppData:d,includeSettings:m,...A?{iosSettings:A}:{},appDataBackup:R};return await this.saveIosMetadata(c,P,w),e.info(`[iOS] Snapshot '${c}' captured successfully (type: ${P.snapshotType})`),{snapshotName:P.snapshotName,timestamp:P.timestamp,snapshotType:P.snapshotType,manifest:P}}getIosPathOptions(){return{platform:"ios",deviceId:this.device.deviceId}}async captureIosAppData(o,c,d,m){let l=Array.from(new Set((c??[]).map((y)=>y.trim()).filter(Boolean)));if(l.length===0)throw new t("No app bundle IDs provided for iOS app-data capture. Pass appBundleIds with at least one installed app, or set includeAppData:false for a settings-only snapshot.");e.info("[iOS] Capturing app data containers");let g=this.store.getAppDataPath(o,m);await B.mkdir(g,{recursive:!0});try{return await this.backupIosAppContainers(l,d,g)}catch(y){throw await this.store.deleteSnapshotData(o,m),y}}async backupIosAppContainers(o,c,d){let m=await this.getInstalledIosBundleIds(),l=[],g=[],y=[],D=[];for(let w of o){if(!m.has(w)){e.warn(`[iOS] ${w} is not installed; skipping app data capture`),D.push(w),l.push({bundleId:w,status:"not-installed"});continue}try{let A=await this.simulatorSnapshotBackend.getAppDataContainerPath(w);if(!A){e.warn(`[iOS] ${w} has no data container; skipping app data capture`),y.push(w),l.push({bundleId:w,status:"skipped-no-container"});continue}e.info(`[iOS] Backing up app data: ${w}`),await this.copyIosAppContainer(A,d,w),g.push(w),l.push({bundleId:w,status:"captured"})}catch(A){if(A instanceof ud)throw A;e.warn(`[iOS] Failed to backup app data for ${w}: ${A}`),D.push(w),l.push({bundleId:w,status:"failed"})}}if(c&&g.length<o.length){let w=new Set(g),A=o.filter((R)=>!w.has(R));throw new t(`Failed to backup app data for ${A.length} of ${o.length} requested app(s) in strictBackupMode (all-or-nothing): ${A.join(", ")}.`)}if(g.length===0){let w=[`iOS app-data capture backed up 0 of ${o.length} requested app(s) (${o.join(", ")}).`];if(D.length>0)w.push(`Failed: ${D.join(", ")}.`);if(y.length>0)w.push(`Skipped (no data container): ${y.join(", ")}.`);throw w.push("Pass appBundleIds for installed apps that have a data container, or set includeAppData:false for a settings-only snapshot."),new t(w.join(" "))}return{backupMethod:"simctl_copy",totalPackages:o.length,backedUpPackages:g,skippedPackages:y,failedPackages:D,bundleStatuses:l}}async getInstalledIosBundleIds(){let o;try{o=await this.simulatorSnapshotBackend.listAppsOrThrow()}catch(d){throw u(d,"Failed to list installed iOS apps to validate appBundleIds")}let c=new Set;for(let d of o){let m=dn(d);if(m)c.add(m)}return c}async copyIosAppContainer(o,c,d){let m=ie.join(c,d);await this.iosCaptureContainerFiles.mkdir(m);for(let l of vk){let g=ie.join(o,l),y=ie.join(m,l);if(await this.iosCaptureContainerFiles.pathExists(g))await this.iosCaptureContainerFiles.cp(g,y)}}async getIosDeviceMetadata(){try{let o=await this.simulatorSnapshotBackend.getDeviceInfo();if(!o)return{};let c=o.deviceTypeIdentifier??o.model,d=o.os_version;if(!d&&o.runtime){let l=(await this.simulatorSnapshotBackend.getRuntimes()).find((g)=>g.identifier===o.runtime);d=l?.version||l?.name}return{deviceType:c,osVersion:d}}catch(o){return e.warn(`[iOS] Failed to read simulator metadata: ${o}`),{}}}async saveIosMetadata(o,c,d){let m=this.store.getSnapshotPathWithOptions(o,d);await B.mkdir(m,{recursive:!0});let l=this.store.getMetadataPath(o,d);await B.writeFile(l,JSON.stringify(c,null,2),"utf-8"),e.info(`[iOS] Wrote metadata to ${l}`)}}import{promises as $e}from"fs";import*as oe from"path";function Oe(o){let c=o.trim(),d=c.match(/^(\d+)(?:\.(\d+))?(?:\.\d+)?$/)??c.match(/^[iI][oO][sS][- _]?(\d+)(?:[.\-_ ](\d+))?(?:[.\-_ ]\d+)?$/)??c.match(/^com\.apple\.CoreSimulator\.SimRuntime\.[iI][oO][sS]-(\d+)(?:-(\d+))?(?:-\d+)?$/);if(!d)return null;let m=Number(d[1]),l=d[2]===void 0?void 0:Number(d[2]);return Number.isFinite(m)&&(l===void 0||Number.isFinite(l))?{major:m,minor:l}:null}var ht=new Set(["global","secure","system"]);function lt(o){return ht.has(o)}function ft(o,c,d,m){let l=o==="vm"&&!c,g=d?"useVmSnapshot is disabled":`device ${m} is not an emulator`;return{snapshotType:c?"vm":"adb",restoreMode:c?"vm":"settings_only",...l?{restoreNote:`VM state was not restored; only captured Android settings were applied because ${g}.`}:{}}}class Se{windowCacheInvalidator=new ei;consoleBusyRegistry;device;adb;emulator;store;timer;iosSnapshotBackend;iosRestoreOperations;constructor(o,c={}){let{adbFactory:d=v,emulator:m,timer:l=i,store:g=new lh,simctl:y,consoleBusyRegistry:D=Fs,iosRestoreOperations:w}=c;this.consoleBusyRegistry=D,this.device=o,this.adb=d.create(o),this.emulator=m||new oi,this.store=g,this.timer=l,this.iosSnapshotBackend=ne(o.deviceId,{simctl:y||new L(o),containerOwnership:c.containerOwnership}),this.iosRestoreOperations=w??{pathExists:Qo,terminateAppIfRunning:(A,R)=>this.simulatorSnapshotBackend.terminateAppIfRunning(R),getAppDataContainerPath:(A,R)=>this.simulatorSnapshotBackend.getAppDataContainerPath(R),rm:(A,R)=>$e.rm(A,R),cp:(A,R,P)=>$e.cp(A,R,P)}}get simulatorSnapshotBackend(){if(this.iosSnapshotBackend.kind==="physical")throw Error("Snapshot app listing is not supported for physical iOS devices");return this.iosSnapshotBackend}async restore(o){return this.execute(o)}async execute(o){switch(dh(o.snapshotName),this.device.platform){case"android":return this.executeAndroid(o);case"ios":if(this.iosSnapshotBackend.kind==="physical")throw new t(`Device snapshots are not supported on physical iOS devices (${this.device.deviceId}); they require a Simulator (simctl).`);return this.executeIos(o);default:throw new t(`Snapshot restore is not supported for platform '${this.device.platform}'`)}}async executeAndroid(o){let{snapshotName:c,manifest:d,useVmSnapshot:m=!0,vmSnapshotTimeoutMs:l=30000,onVmSnapshotLoaded:g,onBeforeVmSnapshotLoad:y}=o;if(e.info(`Restoring snapshot '${c}' (type: ${d.snapshotType}) to device ${this.device.deviceId}`),d.platform!==this.device.platform)throw new t(`Snapshot platform '${d.platform}' does not match device platform '${this.device.platform}'`);let D=this.device.deviceId.startsWith("emulator-"),w=m&&d.snapshotType==="vm"&&D,A=[];if(w)await this.restoreVmSnapshot(c,d,l,{onVmSnapshotLoaded:g,onBeforeVmSnapshotLoad:y});else A=await this.restoreSettingsSnapshot(d);if(A.length===0)e.info(`Snapshot '${c}' restored successfully`);else e.warn(`Snapshot '${c}' partially restored: ${A.length} item(s) failed`);return{...ft(d.snapshotType,w,D,this.device.deviceId),restoredAt:new Date().toISOString(),success:A.length===0,failures:A}}async restoreVmSnapshot(o,c,d,{onVmSnapshotLoaded:m,onBeforeVmSnapshotLoad:l}={}){e.info(`Restoring VM snapshot for emulator ${this.device.deviceId}`);try{let g=Lg("load",o);e.info(`Executing: adb -s ${this.device.deviceId} ${g}`),await l?.();let y;try{y=await this.consoleBusyRegistry.runExclusive(this.device.deviceId,()=>this.adb.execute(g.split(" "),{timeoutMs:d,waitForProcessSettlementAfterAbort:!0}))}catch(w){throw Error(Lk("load",o,w))}let D=Bg("load",o,y);if(!D.ok)throw Object.assign(Error(D.errorMessage),{isDefinitiveVmSnapshotLoadFailure:!0});e.info("VM snapshot restored successfully"),await m?.(),await this.emulator.waitForEmulatorReady(c.deviceName,d,null,{targetDeviceId:this.device.deviceId,options:{skipWakeAndUnlock:!0}}),e.info("VM snapshot restoration complete")}catch(g){let y=r(g);e.error(`Failed to restore VM snapshot: ${y}`);let D=`Failed to restore VM snapshot '${o}' on device ${this.device.deviceId}`,w=g instanceof t?new t(`${D}: ${g.message}`,{cause:g}):u(g,D);if(g instanceof Error&&g.isDefinitiveVmSnapshotLoadFailure===!0)Object.assign(w,{isDefinitiveVmSnapshotLoadFailure:!0});throw w}}async restoreSettingsSnapshot(o){e.info(`Restoring settings-only snapshot for device ${this.device.deviceId}`);try{let c=[];if(o.includeSettings&&o.settings)c=await this.restoreSettings(o.settings);if(o.foregroundApp)await this.restoreForegroundApp(o.foregroundApp);return e.info("Settings snapshot restoration complete"),c}catch(c){throw e.error(`Failed to restore settings snapshot: ${r(c)}`,c),u(c,"Failed to restore settings snapshot")}}async restoreSettings(o){e.info("Restoring device settings");let c=[];for(let[d,m]of Object.entries(o)){if(!m||Object.keys(m).length===0)continue;e.info(`Restoring ${Object.keys(m).length} ${d} settings`);let l=0,g=0;if(!lt(d)){g=Object.keys(m).length,e.warn(`Skipping unsupported settings namespace ${d}`);for(let y of Object.keys(m))c.push({kind:"android_setting",namespace:d,key:y,reason:"unsupported settings namespace"});e.info(`${d} settings restored: ${l} succeeded, ${g} failed`);continue}for(let[y,D]of Object.entries(m)){if(!/^[A-Za-z0-9_.:-]+$/.test(y)){g++,e.warn(`Failed to restore ${d} setting ${y}: invalid settings key`),c.push({kind:"android_setting",namespace:d,key:y,reason:"invalid settings key"});continue}try{await this.applyAndroidSetting(d,y,D),l++}catch(w){g++,e.warn(`Failed to restore ${d} setting ${y}: ${w}`),c.push({kind:"android_setting",namespace:d,key:y,reason:r(w)})}}e.info(`${d} settings restored: ${l} succeeded, ${g} failed`)}return c}async applyAndroidSetting(o,c,d){let m=!1;try{if((await E.getInstance(this.device).requestSettingsPut(o,c,d,{valueType:"string"})).success)m=!0}catch(l){e.debug(`[RestoreSnapshot] a11y settings put failed for ${o}/${c}: ${l}`)}if(!m)await this.adb.executeCommand(`shell settings put ${o} ${b(c)} ${b(d)}`)}async restoreForegroundApp(o){e.info(`Restoring foreground app: ${o}`);try{await this.adb.executeCommand(`shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER ${b(o)}`),e.info(`Launched ${o}`)}catch(c){e.warn(`Failed to restore foreground app: ${c}`)}finally{this.windowCacheInvalidator.invalidate(this.device,!0)}}async executeIos(o){let{snapshotName:c,manifest:d}=o;if(e.info(`[iOS] Restoring snapshot '${c}' (type: ${d.snapshotType})`),d.platform!=="ios")throw new t(`Snapshot platform '${d.platform}' does not match device platform '${this.device.platform}'`);if(d.snapshotType!=="app_data")throw new t(`Unsupported iOS snapshot type '${d.snapshotType}'. Re-capture using app container backups.`);if(await this.validateIosSnapshotCompatibility(d),d.includeSettings&&d.iosSettings)await this.simulatorSnapshotBackend.restoreSettings(d.iosSettings);let m=await this.restoreIosAppData(c,d);if(m.length===0)e.info(`[iOS] Snapshot '${c}' restored successfully`);else e.warn(`[iOS] Snapshot '${c}' partially restored: ${m.length} bundle(s) failed`);return{snapshotType:d.snapshotType,restoredAt:new Date().toISOString(),success:m.length===0,failures:m}}getIosPathOptions(o){return{platform:"ios",deviceId:o??this.device.deviceId}}async restoreIosAppData(o,c){if(!c.includeAppData)return e.info("[iOS] Snapshot does not include app data; skipping restore"),[];let d=await this.resolveIosAppDataPath(o,c);if(!d)return e.warn(`[iOS] App data directory not found for snapshot '${o}'`),[];if(c.appDataBackup?.backupMethod==="none")return e.info("[iOS] Snapshot app data backup method is 'none'; skipping restore"),[];let m=await this.resolveIosSnapshotBundleIds(d,c);if(m.length===0)return e.warn("[iOS] No app bundle IDs found to restore"),[];let l=await this.getInstalledIosBundleIds();if(l.size>0){let y=m.filter((D)=>!l.has(D));if(y.length>0)throw new t(`App(s) not installed on simulator: ${y.join(", ")}. Please reinstall and retry restore.`)}else e.warn("[iOS] Unable to verify installed apps; proceeding with restore");let g=[];for(let y of m)try{await this.restoreIosBundleContainer(y,d)}catch(D){e.warn(`[iOS] Failed to restore app data for ${y}: ${D}`),g.push({kind:"ios_bundle",bundleId:y,reason:r(D)})}return g}async resolveIosAppDataPath(o,c){let d=this.store.getAppDataPath(o,this.getIosPathOptions(c.deviceId));if(await this.iosRestoreOperations.pathExists(d))return d;if(!c.deviceId||c.deviceId===this.device.deviceId)return;let m=this.store.getAppDataPath(o,this.getIosPathOptions(this.device.deviceId));if(!await this.iosRestoreOperations.pathExists(m))return;return e.info(`[iOS] App data not found for '${c.deviceId}', using current device path '${this.device.deviceId}'`),m}async restoreIosBundleContainer(o,c){await this.iosRestoreOperations.terminateAppIfRunning(this.device.deviceId,o);let d=await this.iosRestoreOperations.getAppDataContainerPath(this.device.deviceId,o);if(!d)throw new t(`App data container not found for ${o}`);let m=oe.join(c,o);for(let l of vk){let g=oe.join(m,l);if(!await this.iosRestoreOperations.pathExists(g))continue;let y=oe.join(d,l);await this.iosRestoreOperations.rm(y,{recursive:!0,force:!0});try{await this.iosRestoreOperations.cp(g,y,{recursive:!0})}catch(D){throw new t(`Existing destination data was wiped/deleted and is now gone at '${y}'; restore copy failed: ${r(D)}`,{cause:D})}}}async validateIosSnapshotCompatibility(o){if(!o.osVersion){e.warn("[iOS] Snapshot OS version missing; skipping compatibility check");return}let c=Oe(o.osVersion);if(!c)throw new t(`Snapshot manifest osVersion '${o.osVersion}' is not an iOS version. Expected an iOS version such as '26.5', 'iOS 26.5' or 'com.apple.CoreSimulator.SimRuntime.iOS-26-5'.`);let d=await this.getIosDeviceOsVersion();if(!d){e.warn("[iOS] Unable to read simulator OS version; skipping compatibility check");return}let m=Oe(d);if(!m)throw new t(`Simulator OS version '${d}' is not an iOS version. Expected an iOS version such as '26.5', 'iOS 26.5' or 'com.apple.CoreSimulator.SimRuntime.iOS-26-5'.`);if(c.major!==m.major)throw new t(`Snapshot iOS version '${o.osVersion}' is incompatible with simulator iOS '${d}'. Please restore on an iOS ${c.major}.x simulator.`)}async getIosDeviceOsVersion(){try{let o=await this.simulatorSnapshotBackend.getDeviceInfo();if(!o)return;let c=o.os_version;if(!c&&o.runtime){let m=(await this.simulatorSnapshotBackend.getRuntimes()).find((l)=>l.identifier===o.runtime);c=m?.version||m?.name}return c}catch(o){e.warn(`[iOS] Failed to read simulator OS version: ${o}`);return}}async getInstalledIosBundleIds(){try{let c=(await this.simulatorSnapshotBackend.listApps()).map((d)=>d.bundleId||d.CFBundleIdentifier).filter((d)=>typeof d==="string"&&d.length>0);return new Set(c)}catch(o){return e.warn(`[iOS] Failed to list installed apps: ${o}`),new Set}}async resolveIosSnapshotBundleIds(o,c){let d=c.appDataBackup?.backedUpPackages;if(d&&d.length>0)return d;try{return(await Rr(o)).filter((l)=>l.isDirectory()).map((l)=>l.name)}catch(m){return e.warn(`[iOS] Failed to read app data bundles: ${m}`),[]}}}import{readFile as gt,stat as yt}from"fs/promises";import{isAbsolute as Ve,join as Be,resolve as wt}from"path";import{createHash as St}from"crypto";import{join as vt}from"path";var ve="userdata-qemu.img",Me=(o)=>St("sha256").update(o).digest("hex");class ge{deps;constructor(o){this.deps=o}async currentIdentity(o){let c=await this.deps.avdDirectory.resolveAvdDirectory(o);if(!c)throw new t(`AVD '${o}' is not on this host`);let d=await this.deps.config.readConfig(o);if(!d?.systemImagePackage||!d.systemImagePath)throw new t(`AVD '${o}' lacks system-image metadata in config.ini`);let m=await this.deps.imageMetadata(d.systemImagePath),l=(await this.deps.emulatorVersion()).split(`
|
|
4
|
-
`)[0]?.trim()??"";if(!l)throw new t("Could not read the emulator version for the fixture identity");let g=this.deps.userdataImage?.(c)??vt(c,ve),y=await this.deps.fileIdentity(g);return{avdName:o,systemImageId:`${d.systemImagePackage}:${Me(m)}`,avdConfigHash:Me(JSON.stringify(d.hardware??{})),emulatorVersion:l,userdataGeneration:y?`${y.ino}:${y.birthtimeMs}`:"none"}}}var Dt=1e4;function ke(){let o=new Br,c=new oi;return new ge({config:o,avdDirectory:o,imageMetadata:async(d)=>gt(Rt(d,Ve(d)?void 0:fl()?.androidHome),"utf8"),userdataImage:(d)=>It(d,I(f.EMULATOR_ARGS)),emulatorVersion:async()=>{let d=await c.executeCommand(["-version"],Dt);return d.error?"":d.stdout},fileIdentity:(d)=>At(d)})}async function At(o,c=yt){try{let d=await c(o);return{ino:d.ino,birthtimeMs:d.birthtimeMs}}catch(d){if(d.code!=="ENOENT")throw d;return e.debug(`[DeviceSnapshot] no userdata image at ${o}`),null}}function Rt(o,c){if(Ve(o))return Be(o,"source.properties");if(!c)throw new t("A snapshot fixture needs installed system-image metadata");return wt(c,o,"source.properties")}function It(o,c){let d=c?MR(c):[],m=d.indexOf("-data");if(m===-1)return Be(o,ve);let l=d[m+1];if(!l||l.startsWith("-"))throw new t("AUTOMOBILE_EMULATOR_ARGS passes -data without a path, so a fixture cannot tell which userdata image the emulator runs");return l}async function Ee(o,c){let d=await c.currentIdentity(o.avdName),m=[];if(d.avdName!==o.avdName)m.push("avd-changed");if(d.systemImageId!==o.systemImageId)m.push("system-image-changed");if(d.avdConfigHash!==o.avdConfigHash)m.push("avd-config-changed");if(d.emulatorVersion!==o.emulatorVersion)m.push("emulator-version-changed");if(d.userdataGeneration!==o.userdataGeneration)m.push("userdata-wiped");return m.length===0?{valid:!0}:{valid:!1,reasons:m}}function bt(o,c){return o.platform==="android"&&o.deviceId.startsWith("emulator-")&&c}async function Fe(o,c){let{device:d,snapshotName:m,useVmSnapshot:l,fixture:g}=o;if(!g)return;if(!bt(d,l))throw new Ju("fixture_requires_vm_snapshot",m,`Snapshot '${m}' cannot be a fixture: fixtures are Android emulator VM snapshots only. Capture on an emulator without useVmSnapshot: false.`);let y=await c.currentIdentity(d.name);return{identity:y,confirmUnchanged:async()=>(await Te(y,m,c),y)}}async function Te(o,c,d){let m=await Ee(o,d);if(!m.valid)throw new Ju("fixture_invalidated",c,`Fixture '${c}' no longer matches AVD '${o.avdName}' (${m.reasons.join(", ")}). Capture it again with fixture: true.`,m.reasons)}async function ze(o,c,d,m){let l=o.manifest.fixture;if(c.fixture&&!l)throw new Ju("snapshot_not_a_fixture",o.snapshotName,`Snapshot '${o.snapshotName}' was not captured as a fixture. Capture it again with fixture: true.`);if(!l)return;if(c.fixture&&!d)throw new Ju("fixture_requires_vm_snapshot",o.snapshotName,`Fixture '${o.snapshotName}' reloads its VM snapshot; restore it without useVmSnapshot: false.`);await Te(l,o.snapshotName,m)}function Pt(o,c){if(o.platform!==c.platform)return!1;if(c.platform==="ios")return o.deviceId===c.deviceId;let d=c.deviceId.startsWith("emulator-"),m=o.deviceId.startsWith("emulator-");if(!d)return o.deviceId===c.deviceId;return m&&o.deviceName===c.name||o.deviceId.length===0&&o.deviceName===c.name||o.deviceId===c.deviceId&&o.deviceName.length===0}function B1(o,c,d="restored"){if(Pt(o,c))return;let m=`${o.platform} device '${o.deviceName||"unknown"}' (${o.deviceId||"unknown ID"})`,l=`${c.platform} device '${c.name}' (${c.deviceId})`;throw new t(`Snapshot '${o.snapshotName}' belongs to ${m} and cannot be ${d==="restored"?"restored to":"deleted on"} ${l}. `+(d==="restored"?"Restore it on its original device or capture a snapshot for the target device.":"Delete it on its original device."))}function Le(o,c){return`${o}\x00${c}`}async function je(o,c){let d=new Set(o.filter((l)=>l.platform==="android"&&l.snapshotType==="vm").map((l)=>Le(l.deviceName,l.snapshotName))),m=[];try{for(let l of await c.listKnownAvdNames()){let g=await c.listAvdSnapshotDirectories(l);m.push(...g.filter((y)=>y.snapshotName!==lm&&!d.has(Le(l,y.snapshotName))).map((y)=>({avdName:l,...y})))}}catch(l){e.warn(`[DeviceSnapshot] Failed to scan for orphaned in-AVD snapshots: ${l}`,l)}return{count:m.length,totalSizeBytes:m.reduce((l,g)=>l+(g.sizeBytes??0),0),unsizedCount:m.filter((l)=>l.sizeBytes===null).length,entries:m}}var j={prepareForIncarnationChange:async()=>{},invalidate:async()=>{},settleIncarnationChange:async()=>{}};function mX(o){let c=j;return j=o,()=>{j=c}}var $1={prepareForIncarnationChange:(...o)=>j.prepareForIncarnationChange(...o),invalidate:(...o)=>j.invalidate(...o),settleIncarnationChange:(...o)=>j.settleIncarnationChange(...o)};var ye=null,xt="manifest.json",Ct=500,$t=50,Ot=64,Ue=!1,We=0;function re(o){if(Ue)return;Ue=!0;let c=We;o.timer.sleep(Ct).then(()=>{if(c!==We)return;Nt().catch((d)=>{e.warn("[DeviceSnapshot] Startup snapshot journal sweep failed",d)})}).catch((d)=>{e.warn("[DeviceSnapshot] Startup snapshot journal sweep delay failed",d)})}async function Nt(){let{snapshotStore:o}=await Ei(),{entries:c,truncated:d}=await o.listLeftoverSnapshotJournals({maxEntries:$t,maxScopeDirectories:Ot}),m={recovered:0,failed:0,skippedLocked:0,truncated:d};for(let{snapshotName:l,options:g}of c){if(J.has(l)){m.skippedLocked++;continue}try{await G(l,()=>o.recoverSnapshotData(l,g)),m.recovered++}catch(y){e.warn(`[DeviceSnapshot] Failed to recover snapshot '${l}' in scope ${JSON.stringify(g??"flat")}`,y),m.failed++}}if(d)e.warn("[DeviceSnapshot] Snapshot journal sweep truncated; remaining artifacts are left to lazy recovery");if(m.recovered||m.failed||m.skippedLocked)e.info(`[DeviceSnapshot] Snapshot journal sweep: ${m.recovered} recovered, ${m.failed} failed, ${m.skippedLocked} locked`);return m}var J=new Map,Mt=new Map,Vt="archive-budget",Bt=new Map,kt="config-update",Et=new Map,H=new Map,we=new Map;function _t(o,c){let d=H.get(o)??new Map;d.set(c,(d.get(c)??0)+1),H.set(o,d)}function Ft(o,c){let d=H.get(o);if(!d)return;let m=d.get(c);if(m===void 0)return;if(m===1)d.delete(c);else d.set(c,m-1);if(d.size===0)H.delete(o)}function Tt(o){let c=H.get(o);return new Set([...c??new Map].filter(([,d])=>d>0).map(([d])=>d))}function zt(o,c){let d=Tt(o);if(c!==void 0)d.add(c);return d}async function Lt(o,c,d,m){if(!Ze(o,d))return m();_t(o.name,c);try{return await m()}finally{Ft(o.name,c)}}function Ze(o,c){return o.platform==="android"&&o.deviceId.startsWith("emulator-")&&c}function pe(o,c,d){let l=(o.get(c)??Promise.resolve()).then(d,d),g=l.then(()=>{return},()=>{return});return o.set(c,g),g.finally(()=>{if(o.get(c)===g)o.delete(c)}),l}function G(o,c){return pe(J,o,c)}function jt(o){return pe(Mt,Vt,o)}function Ut(o){return pe(Bt,kt,o)}function Wt(o,c){return pe(Et,o,c)}function ce(o){if(o.platform==="ios")return{platform:"ios",deviceId:o.deviceId};if(o.platform==="android"&&o.deviceId?.startsWith("emulator-")&&o.avdName)return{platform:"android",avdName:o.avdName};return}async function Ei(){if(!ye)ye={snapshotRepository:new me,configRepository:Q7(),snapshotStore:new lh,avdSnapshots:new W4(new lh),timer:i,vmRetentionRetryBackoff:Q({initialDelayMs:100,maxDelayMs:5000}),now:()=>new Date,createCaptureProvider:(o,c,d)=>new fe(o,{timer:c,store:d}),createRestoreProvider:(o,c,d)=>new Se(o,{timer:c,store:d}),deviceIncarnationInvalidator:$1,fixtureIdentityProbe:ke()};return ye}function Ht(o){return{includeAppData:o.includeAppData,includeSettings:o.includeSettings,useVmSnapshot:o.useVmSnapshot,strictBackupMode:o.strictBackupMode,vmSnapshotTimeoutMs:o.vmSnapshotTimeoutMs,maxVmSnapshotsPerAvd:o.maxVmSnapshotsPerAvd,maxVmArchiveSizeMb:o.maxVmArchiveSizeMb,maxArchiveSizeMb:o.maxArchiveSizeMb}}function Jt(o,c){return{includeAppData:c.includeAppData??o.includeAppData,includeSettings:c.includeSettings??o.includeSettings,useVmSnapshot:c.useVmSnapshot??o.useVmSnapshot,strictBackupMode:c.strictBackupMode??o.strictBackupMode,vmSnapshotTimeoutMs:c.vmSnapshotTimeoutMs??o.vmSnapshotTimeoutMs,maxVmSnapshotsPerAvd:c.maxVmSnapshotsPerAvd??o.maxVmSnapshotsPerAvd,maxVmArchiveSizeMb:c.maxVmArchiveSizeMb??o.maxVmArchiveSizeMb,maxArchiveSizeMb:c.maxArchiveSizeMb??o.maxArchiveSizeMb}}function Gt(o){if(o===null)return"unknown";if(o<=0)return"0 B";let c=["B","KB","MB","GB"],d=Math.min(Math.floor(Math.log(o)/Math.log(1024)),c.length-1);return`${(o/Math.pow(1024,d)).toFixed(2)} ${c[d]}`}function Kt(o){return{snapshotName:o.snapshotName,restorable:!o.pendingReclaim,deviceId:o.deviceId,deviceName:o.deviceName,platform:o.platform,snapshotType:o.snapshotType,includeAppData:o.includeAppData,includeSettings:o.includeSettings,createdAt:o.createdAt,lastAccessedAt:o.lastAccessedAt,sizeBytes:o.sizeBytes,sizeLabel:Gt(o.sizeBytes),...o.pendingReclaim?{pendingReclaim:!0,...o.pendingReclaimReason===void 0?{}:{pendingReclaimReason:o.pendingReclaimReason}}:{}}}function k(o){return o.platform==="android"&&o.snapshotType==="vm"}async function qe(o,c,d,{avdSnapshots:m,pathOptions:l}){if(!k(c))return d.getSnapshotSizeBytes(o,l);let g=await m.measureVmSnapshotBytes(c.deviceName,o);if(g===null)e.warn(`[DeviceSnapshot] Could not measure the in-AVD payload of VM snapshot '${o}' for AVD '${c.deviceName}'; recording its size as unknown`);return g}function Yt(o){return typeof o==="object"&&o!==null&&o[le]===!0}async function He(o,c,d,{vmSnapshotTimeoutMs:m,context:l}){try{let g=await d.findLiveEmulatorSerial(o.name);if(!g){e.warn(`[DeviceSnapshot] Skipping cleanup of ${l} VM snapshot '${c}' because AVD '${o.name}' is not live`);return}let y=await d.deleteVmSnapshot(g,c,m,o.name);if(!y.reclaimed)e.warn(`[DeviceSnapshot] Could not clean up ${l} VM snapshot '${c}' on AVD '${o.name}': ${y.reason??"unknown reason"}`)}catch(g){e.warn(`[DeviceSnapshot] Failed to clean up ${l} VM snapshot '${c}' on AVD '${o.name}': ${r(g)}`,g)}}async function Qt({device:o,snapshotName:c,includeSettings:d,snapshotRepository:m,avdSnapshots:l,vmSnapshotTimeoutMs:g,now:y,error:D}){let w=`VM snapshot save was dispatched but capture failed: ${r(D)}`,A=null;try{A=await l.measureVmSnapshotBytes(o.name,c)}catch(P){e.warn(`[DeviceSnapshot] Failed to measure orphaned VM snapshot '${c}' on AVD '${o.name}': ${r(P)}`,P)}let R=y().toISOString();try{let P=await m.getSnapshot(c);if(P&&(!k(P)||P.deviceName!==o.name)){let C=k(P)?`it belongs to AVD '${P.deviceName}' (${P.deviceId})`:"it is a non-VM snapshot record";return e.warn(`[DeviceSnapshot] Same-named capture '${c}' failed on AVD '${o.name}' (${o.deviceId}); preserving the existing row because ${C}: ${w}`),await He(o,c,l,{vmSnapshotTimeoutMs:g,context:"failed same-named"}),!1}return await m.insertSnapshot({snapshotName:c,deviceId:o.deviceId,deviceName:o.name,platform:"android",snapshotType:"vm",includeAppData:!0,includeSettings:d,createdAt:R,lastAccessedAt:R,sizeBytes:A,pendingReclaim:!0,pendingReclaimReason:w,manifest:{snapshotName:c,timestamp:R,deviceId:o.deviceId,deviceName:o.name,platform:"android",snapshotType:"vm",includeAppData:!0,includeSettings:d}}),e.warn(`[DeviceSnapshot] Recorded pending reclaim for orphaned VM snapshot '${c}' on AVD '${o.name}': ${w}`),!0}catch(P){return e.warn(`[DeviceSnapshot] Failed to record pending reclaim for orphaned VM snapshot '${c}' on AVD '${o.name}': ${r(P)}`,P),await He(o,c,l,{vmSnapshotTimeoutMs:g,context:"unrecordable"}),!1}}function Xt(o){if(!o||typeof o!=="object")return!1;let c=o;return typeof c.snapshotName==="string"&&typeof c.timestamp==="string"&&typeof c.deviceId==="string"&&typeof c.deviceName==="string"&&(c.platform==="android"||c.platform==="ios")&&Zt(c.snapshotType)&&typeof c.includeAppData==="boolean"&&typeof c.includeSettings==="boolean"}function Zt(o){return o==="adb"||o==="vm"||o==="simctl"||o==="app_data"}function qt(o){if(!o||typeof o!=="object"||Array.isArray(o))return!1;let c=o;return["global","secure","system"].every((d)=>{let m=c[d];return m===void 0||typeof m==="object"&&m!==null&&!Array.isArray(m)})}function Je(o,c){if(c.snapshotName===o)return c;return{...c,snapshotName:o}}function en(o,c){return Number.isNaN(Date.parse(o))?c:o}async function Ge(o){try{let c=await Xe.readFile(o,"utf-8"),d=JSON.parse(c);if(!Xt(d))return e.warn(`[DeviceSnapshot] Manifest at '${o}' has an unexpected shape`),null;return d}catch(c){if(c.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to read manifest at '${o}': ${c}`);return null}}async function tn(o,c,d){let m=await Ge(c.getMetadataPath(o,d));if(m)return Je(o,m);let l=ae.join(c.getSnapshotPathWithOptions(o,d),xt),g=await Ge(l);if(g)return Je(o,g);return null}async function nn(o,c,d,m){let l=c.getSettingsPath(o,d),g;try{g=await Xe.readFile(l,"utf-8")}catch(D){if(D.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to read settings for '${o}': ${D}`);return null}let y;try{y=JSON.parse(g)}catch(D){return e.warn(`[DeviceSnapshot] Settings file for '${o}' is not valid JSON: ${D}`),null}if(!qt(y))return e.warn(`[DeviceSnapshot] Settings file for '${o}' has an unexpected shape`),null;return{snapshotName:o,timestamp:m().toISOString(),deviceId:"",deviceName:d?.avdName??"",platform:"android",snapshotType:"adb",includeAppData:!1,includeSettings:!0,settings:y}}async function de(o,c,d,m){let l=await tn(o,c,d);if(l)return l;if(d?.platform==="ios")return null;return nn(o,c,d,m)}async function se(o,c,d,{snapshotRepository:m,now:l,pathOptions:g}){let{avdSnapshots:y}=await Ei(),D=await qe(o,c,d,{avdSnapshots:y,pathOptions:g}),w=l().toISOString(),A=en(c.timestamp,w),R={snapshotName:o,deviceId:c.deviceId,deviceName:c.deviceName,platform:c.platform,snapshotType:c.snapshotType,includeAppData:c.includeAppData,includeSettings:c.includeSettings,createdAt:A,lastAccessedAt:A,sizeBytes:D,manifest:c};try{return await m.insertSnapshot(R),R}catch(P){return e.warn(`[DeviceSnapshot] Failed to import legacy snapshot '${o}': ${P}`),m.getSnapshot(o)}}async function $G(o,c,d,m){let l=await de(o,c,void 0,m);if(l)return se(o,l,c,{snapshotRepository:d,now:m});let g=await on(o,c,m);if(!g)return null;return se(o,g.manifest,c,{snapshotRepository:d,now:m,pathOptions:g.pathOptions})}async function*et(o){for(let c of["android","ios"]){let d=ae.join(o.getBasePath(),c),m;try{m=await Rr(d)}catch(l){if(l.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to scan ${c} snapshot scope: ${l}`);continue}for(let l of m){if(!l.isDirectory())continue;yield{pathOptions:c==="ios"?{platform:"ios",deviceId:l.name}:{platform:"android",avdName:l.name},scopedDirPath:ae.join(d,l.name)}}}}async function on(o,c,d){for await(let{pathOptions:m}of et(c)){if(!await c.snapshotDirectoryExists(o,m))continue;let g=await de(o,c,m,d);if(g)return{manifest:g,pathOptions:m}}return null}async function an(o,c,d,m){let l;try{l=await Rr(c.getBasePath())}catch(y){if(y.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to scan legacy snapshots: ${y}`);return!1}let g=!1;for(let y of l){if(!y.isDirectory())continue;let D=y.name;if(D.endsWith(Zd))continue;if(Ae(D))continue;if(m.has(D)||J.has(D))continue;let w=await de(D,c,void 0,d);if(!w)continue;if(await se(D,w,c,{snapshotRepository:o,now:d}))m.add(D),g=!0}return g}async function sn(o,c,d,m){let l=!1;for await(let{pathOptions:g,scopedDirPath:y}of et(c)){let D;try{D=await Rr(y)}catch(w){if(w.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to scan snapshots under ${y}: ${w}`);continue}for(let w of D){if(!w.isDirectory())continue;let A=w.name;if(A.endsWith(Zd))continue;if(m.has(A)||J.has(A))continue;let R=await de(A,c,g,d);if(!R)continue;if(await se(A,R,c,{snapshotRepository:o,now:d,pathOptions:g}))m.add(A),l=!0}}return l}async function rn(o,c,d,m){let l=await an(o,c,d,m),g=await sn(o,c,d,m);return l||g}async function Yp(){await jL([ZE.ARCHIVE])}function pn(o){let c=kQ(o);if(c?.kind==="scope-root")throw new t(`Snapshot name '${o}' is reserved. Please choose a different name.`);if(c?.kind==="suffix")throw new t(`Snapshot name '${o}' ends with the reserved '${Zd}' suffix (case-insensitively). Please choose a different name.`)}function cn(o){if(o.trim().toLowerCase()===lm.toLowerCase())throw new t(`Snapshot name '${lm}' is reserved for the emulator's own quick-boot snapshot and cannot be used as an AutoMobile capture name.`)}async function tt(o,c){let{snapshotRepository:d,avdSnapshots:m}=await Ei(),l=o.deviceName,g=await m.findLiveEmulatorSerial(l);if(g)await d.updateSnapshot(o.snapshotName,{pendingReclaim:!0,pendingReclaimReason:`reclaiming the in-AVD payload on AVD '${l}'`});let y=g?await m.deleteVmSnapshot(g,o.snapshotName,c,l):{reclaimed:!1,reason:`emulator for AVD '${l}' is not running; in-AVD snapshot left in place`};if(y.reclaimed)return!0;return e.warn(`[DeviceSnapshot] Could not reclaim the in-AVD payload of VM snapshot '${o.snapshotName}': ${y.reason}. Keeping the record so the reclaim can be completed when that emulator is next seen live.`),await d.updateSnapshot(o.snapshotName,{pendingReclaim:!0,pendingReclaimReason:y.reason}),!1}var Ke=Symbol("snapshot-record-superseded");function nt(o,c){return o.deviceId===c.deviceId&&o.deviceName===c.deviceName&&o.snapshotType===c.snapshotType&&o.createdAt===c.createdAt&&o.sizeBytes===c.sizeBytes&&o.manifest.timestamp===c.manifest.timestamp}async function U1(o,c){if(J.has(o.snapshotName))return e.debug(`[DeviceSnapshot] Skipping reclaim of '${o.snapshotName}': a capture or restore of that name is in flight`),Ke;return G(o.snapshotName,async()=>{let{snapshotRepository:d}=await Ei(),m=await d.getSnapshot(o.snapshotName);if(!m||!nt(m,o))return e.debug(`[DeviceSnapshot] Skipping reclaim of '${o.snapshotName}': the record was replaced after it was selected`),Ke;return c()})}async function un(o,c,d){if(!(d instanceof Ju)||d.code!=="fixture_invalidated")throw d;let m=(!k(o)||await tt(o,c))&&await HM(o);throw new Ju(d.code,d.snapshotName,`${d.message} ${m?"It was removed.":"Its in-AVD snapshot could not be reclaimed now and is pending."}`,d.reasons)}async function UM(o,c){return await U1(o,async()=>{if(k(o)&&!await tt(o,c))return!1;return HM(o)})===!0}async function HM(o){let{snapshotStore:c}=await Ei(),d=ce({platform:o.platform,deviceId:o.deviceId,avdName:o.deviceName}),m=[d];if(d?.platform==="android"&&!Ae(o.snapshotName))m.push(void 0);for(let l of m)try{await c.recoverSnapshotData(o.snapshotName,l)}catch(g){e.warn(`[DeviceSnapshot] Recovery before deletion failed for '${o.snapshotName}' in scope ${JSON.stringify(l??"flat")}`,g);let y=await c.discardSnapshotArtifacts(o.snapshotName,l);if(y.length>0)e.warn(`[DeviceSnapshot] Snapshot artifacts left behind after deletion: ${y.join(", ")}`)}return mn(o)}async function mn(o){let{snapshotRepository:c}=await Ei();return await it(o),c.deleteSnapshot(o.snapshotName)}async function it(o,c={}){let{snapshotStore:d}=await Ei(),m=ce({platform:o.platform,deviceId:o.deviceId,avdName:o.deviceName});if(d.getSnapshotPathWithOptions(o.snapshotName,m)===c.preserveSnapshotPath)return;if(await d.deleteSnapshotData(o.snapshotName,m),m?.platform==="android"&&!Ae(o.snapshotName)&&d.getSnapshotPath(o.snapshotName)!==c.preserveSnapshotPath)await d.deleteSnapshotData(o.snapshotName)}function Ae(o){return o===Yq||o===Gq}async function hn(o){let{snapshotRepository:c,avdSnapshots:d}=await Ei(),m=[];for(let l of o){if(l.sizeBytes!==null||!k(l)){m.push(l);continue}let g=await G(l.snapshotName,async()=>{let y=await d.measureVmSnapshotBytes(l.deviceName,l.snapshotName),D=await c.getSnapshot(l.snapshotName);if(!D||!nt(D,l)){e.warn(`[DeviceSnapshot] Concurrent replacement detected while re-measuring VM snapshot '${l.snapshotName}'; skipping stale size update.`);return}if(y===null)return D;try{return await c.updateSnapshot(l.snapshotName,{sizeBytes:y}),{...D,sizeBytes:y}}catch(w){return e.warn(`[DeviceSnapshot] Failed to record the re-measured size of VM snapshot '${l.snapshotName}': ${r(w)}`,w),D}});if(g)m.push(g)}return m}async function De(o){return jt(async()=>{let c=Math.max(0,Math.floor(o*1024*1024)),{snapshotRepository:d}=await Ei(),{vmSnapshotTimeoutMs:m}=await Fc(),l=(await d.listSnapshots({orderByLastAccessed:"asc"})).filter((w)=>w.snapshotType!=="vm"),g=l.reduce((w,A)=>w+(A.sizeBytes??0),0),y=l.filter((w)=>w.sizeBytes===null).length;if(y>0)e.warn(`[DeviceSnapshot] ${y} snapshot record(s) have an unknown size and are excluded from the non-VM archive budget`);if(c===0||g<=c)return{evictedSnapshotNames:[],currentSizeBytes:g,maxSizeBytes:c,unsizedCount:y};let D=[];for(let w of l){if(g<=c)break;try{if(await UM(w,m))D.push(w.snapshotName),g-=w.sizeBytes??0}catch(A){e.warn(`[DeviceSnapshot] Failed to evict snapshot ${w.snapshotName}: ${A}`)}}if(g>c)e.warn(`[DeviceSnapshot] Non-VM archive size ${g} bytes still exceeds limit ${c} bytes after eviction`);if(D.length>0)e.warn(`[DeviceSnapshot] Evicted ${D.length} snapshot(s) under the app_data byte budget (maxArchiveSizeMb=${o}): ${D.join(", ")}`),await Yp();return{evictedSnapshotNames:D,currentSizeBytes:g,maxSizeBytes:c,unsizedCount:y}})}function ln(o){if(o.maxVmArchiveSizeMb===void 0)return Number.POSITIVE_INFINITY;return Math.max(0,Math.floor(o.maxVmArchiveSizeMb*1024*1024))}function ot(o){return o.snapshots.reduce((c,d)=>c+(d.sizeBytes??0),0)}function fn(o,c,d){return o!==void 0&&c.maxVmArchiveSizeMb!==void 0&&(o.sizeBytes??0)>d}function Sn(o,c){return o.snapshots.find((d)=>!c.has(d.snapshotName)&&!o.failedNames.has(d.snapshotName))}async function Ye(o,c,d,m){let l=Sn(o,d);if(!l)return"no-candidate";try{if(!await UM(l,c.vmSnapshotTimeoutMs)){let{snapshotRepository:g}=await Ei(),y=await g.getSnapshot(l.snapshotName);if(y?.pendingReclaim)return"deferred";if(!y||y.deviceName!==l.deviceName)return o.snapshots=o.snapshots.filter((D)=>D.snapshotName!==l.snapshotName),"removed-concurrently";return o.failedNames.add(l.snapshotName),"failed"}return o.snapshots=o.snapshots.filter((g)=>g.snapshotName!==l.snapshotName),o.evictedSnapshotNames.push(l.snapshotName),(m==="count"?o.countEvictedSnapshotNames:o.byteEvictedSnapshotNames).push(l.snapshotName),"evicted"}catch(g){return e.warn(`[DeviceSnapshot] Failed to evict snapshot ${l.snapshotName}: ${g}`),o.failedNames.add(l.snapshotName),"failed"}}async function vn(o){let{snapshotRepository:c}=await Ei(),d=await hn((await c.listSnapshots({snapshotType:"vm"})).filter((m)=>m.deviceName===o&&!m.pendingReclaim&&!m.manifest.fixture));return d.sort((m,l)=>m.lastAccessedAt.localeCompare(l.lastAccessedAt)),{snapshots:d,evictedSnapshotNames:[],countEvictedSnapshotNames:[],byteEvictedSnapshotNames:[],failedNames:new Set}}async function gn(o,c,d,m){while(o.snapshots.length>c.maxVmSnapshotsPerAvd){let l=await Ye(o,c,d,"count");if(l==="deferred"||l==="no-candidate")return}while(ot(o)>m){let l=await Ye(o,c,d,"byte");if(l==="deferred"||l==="no-candidate")return}}function yn(o,c,d){if(o.evictedSnapshotNames.length===0)return;e.warn(`[DeviceSnapshot] Evicted ${o.evictedSnapshotNames.length} VM snapshot(s) for AVD '${c}': ${o.countEvictedSnapshotNames.length} by the per-AVD count retention (maxVmSnapshotsPerAvd=${d.maxVmSnapshotsPerAvd}), ${o.byteEvictedSnapshotNames.length} by the VM byte budget (maxVmArchiveSizeMb=${d.maxVmArchiveSizeMb??"unlimited"}): `+o.evictedSnapshotNames.join(", "))}async function wn(o,c,d,{currentSizeBytes:m,maxSizeBytes:l,excludeFromEviction:g}){let y=d.snapshots.length>c.maxVmSnapshotsPerAvd||c.maxVmArchiveSizeMb!==void 0&&m>l;if(d.failedNames.size===0||!y){we.delete(o);return}let{timer:D,vmRetentionRetryBackoff:w}=await Ei(),A=(we.get(o)??0)+1;we.set(o,A),D.setTimeout(()=>{Fc().then((R)=>Re(o,R,{excludeFromEviction:g})).catch((R)=>{e.warn(`[DeviceSnapshot] Deferred VM retention retry for AVD '${o}' failed: `+r(R),R)})},w.delayForAttempt(A))}async function Re(o,c,d={}){return Wt(o,async()=>{let m=await vn(o),l=zt(o,d.excludeFromEviction),g=ln(c),y=m.snapshots.filter((C)=>C.sizeBytes===null).length;if(y>0)e.warn(`[DeviceSnapshot] ${y} VM snapshot record(s) have an unknown size and are excluded from the VM retention byte budget`);let D=d.excludeFromEviction?m.snapshots.find((C)=>C.snapshotName===d.excludeFromEviction):void 0,w=fn(D,c,g);if(!w)await gn(m,c,l,g);let A=d.excludeFromEviction?m.snapshots.find((C)=>C.snapshotName===d.excludeFromEviction):void 0,R=d.excludeFromEviction!==void 0&&A===void 0,P=ot(m);if(c.maxVmArchiveSizeMb!==void 0&&P>g)e.warn(`[DeviceSnapshot] VM snapshots for AVD '${o}' total ${P} bytes still exceed limit ${g} bytes after retention`);if(yn(m,o,c),m.evictedSnapshotNames.length>0)await Yp();return await wn(o,c,m,{currentSizeBytes:P,maxSizeBytes:g,excludeFromEviction:d.excludeFromEviction}),{evictedSnapshotNames:m.evictedSnapshotNames,currentSizeBytes:P,maxSizeBytes:g,unsizedCount:y,cannotFitExcluded:w,excludedSnapshotMissing:R,excludedSnapshotRecord:A??null,excludedSnapshotSizeBytes:A?.sizeBytes??null,countEvictedSnapshotNames:m.countEvictedSnapshotNames,byteEvictedSnapshotNames:m.byteEvictedSnapshotNames}})}async function Qe(o){let{snapshotRepository:c}=await Ei(),d=await c.listSnapshots({snapshotType:"vm"}),m=[...new Set(d.map((g)=>g.deviceName))],l=await Promise.all(m.map((g)=>Re(g,o)));return{evictedSnapshotNames:l.flatMap((g)=>g.evictedSnapshotNames),currentSizeBytes:l.reduce((g,y)=>g+y.currentSizeBytes,0),maxSizeBytes:o.maxVmArchiveSizeMb===void 0?0:o.maxVmArchiveSizeMb*1024*1024,unsizedCount:l.reduce((g,y)=>g+y.unsizedCount,0)}}async function Dn(o){if(o.platform!=="android"||!o.deviceId.startsWith("emulator-")||!o.name)return[];let{snapshotRepository:c,avdSnapshots:d}=await Ei(),m;try{m=await c.listSnapshots({pendingReclaim:!0,snapshotType:"vm"})}catch(y){return e.warn(`[DeviceSnapshot] Failed to read pending VM snapshot reclaims: ${y}`,y),[]}let l=[],{vmSnapshotTimeoutMs:g}=await Fc();for(let y of m.filter((D)=>D.deviceName===o.name))if(await U1(y,async()=>{let w=await d.deleteVmSnapshot(o.deviceId,y.snapshotName,g,y.deviceName);if(!w.reclaimed)return e.warn(`[DeviceSnapshot] Pending reclaim of VM snapshot '${y.snapshotName}' still incomplete: ${w.reason}`),!1;return HM(y)})===!0)l.push(y.snapshotName);if(l.length>0)e.info(`[DeviceSnapshot] Completed ${l.length} pending VM snapshot reclaim(s) for AVD '${o.name}'`),await Yp();return l}async function An(o,c,d){let{snapshotRepository:m,avdSnapshots:l}=await Ei(),g=await m.getSnapshot(o);if(!g?.pendingReclaim||!k(g)||g.deviceName===c)return;let y=await l.findLiveEmulatorSerial(g.deviceName),D=y?await l.deleteVmSnapshot(y,o,d,g.deviceName):{reclaimed:!1,reason:`emulator for AVD '${g.deviceName}' is not running`};if(D.reclaimed){e.info(`[DeviceSnapshot] Reclaimed the pending in-AVD payload of '${o}' on AVD '${g.deviceName}' before reusing that name on AVD '${c}'`);return}e.warn(`[DeviceSnapshot] Capturing '${o}' on AVD '${c}' overwrites the only record of a pending reclaim for AVD '${g.deviceName}' (${D.reason}). Its in-AVD payload stays on disk and is reported as an orphan until it is removed manually (see docs/using/test-prep-tools.md).`)}async function Fc(){let{configRepository:o}=await Ei(),c=await o.getConfig();if(c)return z(c);return z(N.getDeviceSnapshotDefaults())}async function fX(o){return Ut(async()=>{let{configRepository:c,timer:d}=await Ei();if(re({timer:d}),o===null){await c.clearConfig();let w=z(N.getDeviceSnapshotDefaults()),[A,R]=await Promise.all([De(w.maxArchiveSizeMb),Qe(w)]);return{config:w,evictedSnapshotNames:[...A.evictedSnapshotNames,...R.evictedSnapshotNames]}}let m=await Fc(),l=Jt(Ht(m),o),g=z(l);await c.setConfig(g);let[y,D]=await Promise.all([De(g.maxArchiveSizeMb),Qe(g)]);return{config:g,evictedSnapshotNames:[...y.evictedSnapshotNames,...D.evictedSnapshotNames]}})}async function In(o,c,d,m){let l=await De(d.maxArchiveSizeMb);if(o.manifest.snapshotType!=="vm")return l.evictedSnapshotNames;let g=await Re(c.name,d,o.manifest.fixture?{}:{excludeFromEviction:o.snapshotName});if(g.excludedSnapshotMissing)throw new t(`Snapshot '${o.snapshotName}' was removed by a concurrent VM retention sweep before capture could complete; capture did not succeed`);if(!g.cannotFitExcluded)return[...l.evictedSnapshotNames,...g.evictedSnapshotNames];if(m)throw await Yp(),new t(`Snapshot '${o.snapshotName}' recapture exceeds the configured maxVmArchiveSizeMb budget for AVD '${c.name}'. The emulator's destructive snapshot save already irreversibly overwrote the prior payload under this name, so the new oversized capture was kept rather than deleting the only remaining usable snapshot.`);let y=g.excludedSnapshotRecord;if(y){if(!await UM(y,d.vmSnapshotTimeoutMs))throw await Yp(),new t(`Snapshot '${o.snapshotName}' exceeds maxVmArchiveSizeMb but its VM payload could not be reclaimed; it remains tracked for a later reclaim`)}let D=Math.floor((d.maxVmArchiveSizeMb??0)*1024*1024);throw new t(`Snapshot '${o.snapshotName}' could not be captured because its VM payload (${g.excludedSnapshotSizeBytes??"unknown"} bytes) exceeds the configured maxVmArchiveSizeMb budget for AVD '${c.name}' (${D} bytes)`)}async function bn(o,c,d,m){if(dh(c),pn(c),Ze(o,d))cn(c);let{fixtureIdentityProbe:l}=await Ei();return Fe({device:o,snapshotName:c,useVmSnapshot:d,fixture:m.fixture},l)}async function hX(o,c){let{snapshotRepository:d,snapshotStore:m,avdSnapshots:l,timer:g,now:y,createCaptureProvider:D}=await Ei();re({timer:g});let w=await Fc(),A=c.useVmSnapshot??w.useVmSnapshot,R=c.snapshotName??m.generateSnapshotName(o.name),P=await bn(o,R,A,c);await Dn(o);let C=ce({platform:o.platform,deviceId:o.deviceId,avdName:o.name}),M={...w,includeAppData:c.includeAppData??w.includeAppData,includeSettings:c.includeSettings??w.includeSettings,useVmSnapshot:A,strictBackupMode:c.strictBackupMode??w.strictBackupMode,vmSnapshotTimeoutMs:c.vmSnapshotTimeoutMs??w.vmSnapshotTimeoutMs};return Lt(o,R,M.useVmSnapshot,async()=>{let _=!1,U=await G(R,async()=>{let V=await d.getSnapshot(R);_=V!==null&&V.deviceName===o.name,await An(R,o.name,M.vmSnapshotTimeoutMs);let ue=D(o,g,m),T,X=!1;try{T=await m.replaceSnapshotData(R,C,async()=>{let x=await ue.capture({snapshotName:R,includeAppData:M.includeAppData,includeSettings:M.includeSettings,useVmSnapshot:M.useVmSnapshot,strictBackupMode:M.strictBackupMode,vmSnapshotTimeoutMs:M.vmSnapshotTimeoutMs,appBundleIds:c.appBundleIds});X=x.manifest.snapshotType==="vm",x.manifest.fixture??=await P?.confirmUnchanged();let W=await qe(R,x.manifest,m,{avdSnapshots:l,pathOptions:C}),Z=x.manifest.timestamp;return await d.insertSnapshot({snapshotName:x.snapshotName,deviceId:x.manifest.deviceId,deviceName:x.manifest.deviceName,platform:x.manifest.platform,snapshotType:x.manifest.snapshotType,includeAppData:x.manifest.includeAppData,includeSettings:x.manifest.includeSettings,createdAt:Z,lastAccessedAt:Z,sizeBytes:W,manifest:x.manifest}),x})}catch(x){if(o.platform==="android"&&o.deviceId.startsWith("emulator-")&&(Yt(x)||X)){if(await Qt({device:o,snapshotName:R,includeSettings:M.includeSettings,snapshotRepository:d,avdSnapshots:l,vmSnapshotTimeoutMs:M.vmSnapshotTimeoutMs,now:y,error:x}))await Yp()}throw x}if(V)try{await it(V,{preserveSnapshotPath:m.getSnapshotPathWithOptions(R,C)})}catch(x){e.warn(`[DeviceSnapshot] Failed to retire prior archive data for '${R}': ${r(x)}`,x)}return T}),F=await Fc(),K={...M,maxVmSnapshotsPerAvd:F.maxVmSnapshotsPerAvd,maxArchiveSizeMb:F.maxArchiveSizeMb,maxVmArchiveSizeMb:F.maxVmArchiveSizeMb},Y=await In(U,o,K,_);return await Yp(),{result:U,evictedSnapshotNames:Y}})}async function gX(o,c){let{snapshotRepository:d,snapshotStore:m,timer:l,now:g,createRestoreProvider:y,deviceIncarnationInvalidator:D,fixtureIdentityProbe:w}=await Ei();return re({timer:l}),dh(c.snapshotName),G(c.snapshotName,async()=>{let A=await d.getSnapshot(c.snapshotName);if(!A)A=await $G(c.snapshotName,m,d,g);if(!A)throw new t(`Snapshot '${c.snapshotName}' not found`);if(B1(A,o),A.pendingReclaim){let O=A.pendingReclaimReason?`: ${A.pendingReclaimReason}`:"";throw new t(`Snapshot '${A.snapshotName}' is awaiting reclaim after a failed capture${O}`)}let R=await Fc(),P=c.useVmSnapshot??R.useVmSnapshot,C=c.vmSnapshotTimeoutMs??R.vmSnapshotTimeoutMs;await ze(A,c,P,w).catch((O)=>un(A,C,O));try{await m.recoverSnapshotData(A.snapshotName,ce({platform:A.platform,deviceId:A.deviceId,avdName:A.deviceName}))}catch(O){throw e.warn(`[DeviceSnapshot] Failed to recover snapshot '${A.snapshotName}' before restore: ${r(O)}`,O),u(O,`Failed to recover snapshot '${A.snapshotName}' before restore`)}let M=y(o,l,m),_=!1,U=!1,F=!1,K=!1,Y=!1,V={},ue=async()=>{if(_||o.platform!=="android"||!o.deviceId.startsWith("emulator-")||A.manifest.snapshotType!=="vm"||!P)return;_=!0,await D.prepareForIncarnationChange(o)},T=async()=>{if(U||o.platform!=="android"||!o.deviceId.startsWith("emulator-")||A.manifest.snapshotType!=="vm"||!P)return;U=!0;let O=await D.invalidate(o);if(typeof O==="string")V={deviceSessionUuid:O}},X=async()=>{F=!0,await T()},x=async()=>{if(!_||K)return;K=!0,await D.settleIncarnationChange(o,{ready:Y})},W;try{W=await M.restore({snapshotName:A.snapshotName,manifest:A.manifest,useVmSnapshot:P,vmSnapshotTimeoutMs:C,onBeforeVmSnapshotLoad:ue,onVmSnapshotLoaded:X}),Y=!0,await T()}catch(O){let at=O instanceof Error&&O.isDefinitiveVmSnapshotLoadFailure===!0;if(F||!at)await T();throw u(O,`Failed to restore snapshot '${A.snapshotName}'`)}finally{await x()}let Z=g().toISOString();return await d.touchSnapshot(A.snapshotName,Z),await Yp(),{result:W,manifest:A.manifest,...V}})}async function yX(){let{snapshotRepository:o,snapshotStore:c,now:d,timer:m}=await Ei();re({timer:m});let l=await o.listSnapshots({orderByCreatedAt:"desc"}),g=new Set(l.map((P)=>P.snapshotName)),D=await rn(o,c,d,g)?await o.listSnapshots({orderByCreatedAt:"desc"}):l,w=D.map(Kt),A=D.reduce((P,C)=>P+(C.sizeBytes??0),0),R=await je(D,(await Ei()).avdSnapshots);return{snapshots:w,count:w.length,totalSizeBytes:A,unsizedCount:D.filter((P)=>P.sizeBytes===null).length,pendingReclaimCount:D.filter((P)=>P.pendingReclaim).length,orphanedAvdSnapshots:R}}
|
|
5
|
-
export{
|
|
2
|
+
import{i,Tr,Q,e}from"./chunk-r0vp315h.js";import{h,I}from"./chunk-5wk1t46v.js";import{_e}from"./chunk-r6pvhj33.js";import{Ca,fQ}from"./chunk-8nj68t1v.js";import{Nr,Pl,qs,v,En,L,b,VD,pn,bd,Mk,t$,fj,$Y,N,rs,QR,pi,ry,ny,eE,E}from"./chunk-sfqe223f.js";import{n,a,m,S,s,Ne,p}from"./chunk-w5yypt53.js";import{ai}from"./chunk-4vxeq0vd.js";import{lp,wh,sl,oV,sV,HQ,Rh,Am,o5}from"./chunk-yqfz4vts.js";import{lB}from"./chunk-69pmjdf2.js";import{r,t,u}from"./chunk-2b39zyxc.js";import{promises as Xe}from"fs";import*as ae from"path";var q=Ne(n(),n()),ee=S(n()),st=s({snapshotName:n(),timestamp:n(),deviceId:n(),deviceName:n(),platform:p(["android","ios"]),deviceType:n().optional(),osVersion:n().optional(),snapshotType:p(["vm","adb","simctl","app_data"]),includeAppData:m(),includeSettings:m(),packages:ee.optional(),foregroundApp:n().optional(),settings:s({global:q.optional(),secure:q.optional(),system:q.optional()}).optional(),iosSettings:s({values:q,ui:s({appearance:p(["light","dark"]).optional(),contentSize:n().optional()}).optional()}).optional(),appDataBackup:s({backupFile:n().optional(),backedUpPackages:ee.optional(),skippedPackages:ee.optional(),failedPackages:ee.optional(),totalPackages:a().optional(),backupTimedOut:m().optional(),backupMethod:p(["root_pull","none","simctl_copy"]).optional(),bundleStatuses:S(s({bundleId:n(),status:p(["captured","skipped-no-container","not-installed","failed"])})).optional()}).optional(),fixture:s({avdName:n(),systemImageId:n(),avdConfigHash:n(),emulatorVersion:n(),userdataGeneration:n()}).optional()});function rt(o,c){let d;try{d=JSON.parse(c)}catch(f){return e.warn(`[DeviceSnapshotRepository] Failed to parse manifest for ${o}: ${r(f)}`),null}let l=st.safeParse(d);if(l.success)return l.data;return e.warn(`[DeviceSnapshotRepository] Manifest for ${o} failed validation: ${l.error.message}`),typeof d==="object"&&d!==null&&!Array.isArray(d)?d:null}function Ie(o){let c=rt(o.snapshot_name,o.manifest_json);if(!c)return null;return{snapshotName:o.snapshot_name,deviceId:o.device_id,deviceName:o.device_name,platform:o.platform,snapshotType:o.snapshot_type,includeAppData:Boolean(o.include_app_data),includeSettings:Boolean(o.include_settings),createdAt:o.created_at,lastAccessedAt:o.last_accessed_at,sizeBytes:o.size_unknown?null:o.size_bytes,pendingReclaim:Boolean(o.pending_reclaim),...o.pending_reclaim_reason===null?{}:{pendingReclaimReason:o.pending_reclaim_reason},manifest:c}}var pt={deviceId:(o,c)=>{o.device_id=c},deviceName:(o,c)=>{o.device_name=c},platform:(o,c)=>{o.platform=c},snapshotType:(o,c)=>{o.snapshot_type=c},includeAppData:(o,c)=>{o.include_app_data=c?1:0},includeSettings:(o,c)=>{o.include_settings=c?1:0},createdAt:(o,c)=>{o.created_at=c},lastAccessedAt:(o,c)=>{o.last_accessed_at=c},pendingReclaim:(o,c)=>{o.pending_reclaim=c?1:0},pendingReclaimReason:(o,c)=>{o.pending_reclaim_reason=c},manifest:(o,c)=>{o.manifest_json=JSON.stringify(c)}};function ct(o){let c={};for(let[d,l]of Object.entries(pt)){let f=o[d];if(f!==void 0)l(c,f)}if(o.sizeBytes!==void 0)c.size_bytes=o.sizeBytes??0,c.size_unknown=o.sizeBytes===null?1:0;return c}class me{db;constructor({db:o}={}){this.db=o??null}getDb(){return this.db??_e()}async insertSnapshot(o){let c=await this.getDb(),d={snapshot_name:o.snapshotName,device_id:o.deviceId,device_name:o.deviceName,platform:o.platform,snapshot_type:o.snapshotType,include_app_data:o.includeAppData?1:0,include_settings:o.includeSettings?1:0,created_at:o.createdAt,last_accessed_at:o.lastAccessedAt,size_bytes:o.sizeBytes??0,size_unknown:o.sizeBytes===null?1:0,pending_reclaim:o.pendingReclaim?1:0,pending_reclaim_reason:o.pendingReclaimReason??null,manifest_json:JSON.stringify(o.manifest)};await c.insertInto("device_snapshots").values(d).onConflict((l)=>l.column("snapshot_name").doUpdateSet({device_id:d.device_id,device_name:d.device_name,platform:d.platform,snapshot_type:d.snapshot_type,include_app_data:d.include_app_data,include_settings:d.include_settings,last_accessed_at:d.last_accessed_at,size_bytes:d.size_bytes,size_unknown:d.size_unknown,pending_reclaim:d.pending_reclaim,pending_reclaim_reason:d.pending_reclaim_reason,manifest_json:d.manifest_json})).execute()}async updateSnapshot(o,c){let d=await this.getDb(),l=ct(c);if(Object.keys(l).length===0)return;await d.updateTable("device_snapshots").set(l).where("snapshot_name","=",o).execute()}async getSnapshot(o){let d=await(await this.getDb()).selectFrom("device_snapshots").selectAll().where("snapshot_name","=",o).executeTakeFirst();return d?Ie(d):null}async listSnapshots(o={}){let d=(await this.getDb()).selectFrom("device_snapshots").selectAll();if(o.deviceId)d=d.where("device_id","=",o.deviceId);if(o.platform)d=d.where("platform","=",o.platform);if(o.snapshotType)d=d.where("snapshot_type","=",o.snapshotType);if(o.pendingReclaim!==void 0)d=d.where("pending_reclaim","=",o.pendingReclaim?1:0);if(o.orderByLastAccessed)d=d.orderBy("last_accessed_at",o.orderByLastAccessed);if(o.orderByCreatedAt)d=d.orderBy("created_at",o.orderByCreatedAt);if(o.limit&&o.limit>0)d=d.limit(o.limit);return(await d.execute()).map((f)=>Ie(f)).filter((f)=>Boolean(f))}async touchSnapshot(o,c){await this.updateSnapshot(o,{lastAccessedAt:c})}async deleteSnapshot(o){let d=await(await this.getDb()).deleteFrom("device_snapshots").where("snapshot_name","=",o).executeTakeFirst();return Number(d.numDeletedRows??0)>0}}function te(o,c){if(typeof o==="boolean")return o;if(typeof o==="string"){let d=o.trim().toLowerCase();if(d==="true")return!0;if(d==="false")return!1}return c}function he(o,c,d){if(o===void 0||o===null||o==="")return c;let l=typeof o==="string"?Number(o):o;if(!Number.isFinite(l)||l<=0)return c;let f=d?l:Math.round(l);return f>0?f:c}function dt(o,c){if(o===void 0||o===null||o==="")return;let d=typeof o==="string"?Number(o):o;if(!Number.isFinite(d)||d<=0)return;let l=c?d:Math.round(d);return l>0?l:void 0}function z(o){let c=o&&typeof o==="object"?o:{};return{includeAppData:te(c.includeAppData,Ca.includeAppData),includeSettings:te(c.includeSettings,Ca.includeSettings),useVmSnapshot:te(c.useVmSnapshot,Ca.useVmSnapshot),strictBackupMode:te(c.strictBackupMode,Ca.strictBackupMode),vmSnapshotTimeoutMs:he(c.vmSnapshotTimeoutMs,Ca.vmSnapshotTimeoutMs,!1),maxVmSnapshotsPerAvd:he(c.maxVmSnapshotsPerAvd,Ca.maxVmSnapshotsPerAvd,!1),maxVmArchiveSizeMb:dt(c.maxVmArchiveSizeMb,!0),maxArchiveSizeMb:he(c.maxArchiveSizeMb,Ca.maxArchiveSizeMb,!0)}}var fI={ARCHIVE:"automobile:deviceSnapshots/archive"};function be(o,c,d){return fj(c,{simctl:o}).terminateApp(d)}var ut=[{domain:".GlobalPreferences",key:"AppleLocale"}];async function mt(o,c){let d={};try{let l=(await o.executeCommandArgs(["ui",c,"appearance"])).stdout.trim();if(l==="light"||l==="dark")d.appearance=l}catch(l){e.warn(`[iOS] Failed to read appearance: ${l}`)}try{let l=(await o.executeCommandArgs(["ui",c,"content_size"])).stdout.trim();if(l)d.contentSize=l}catch(l){e.warn(`[iOS] Failed to read content_size: ${l}`)}return Object.keys(d).length>0?d:void 0}async function Pe(o,c){let d={};for(let{domain:l,key:f}of ut)try{let y=(await o.executeCommandArgs(["spawn",c,"defaults","read",l,f])).stdout.trim();if(y)d[`${l}/${f}`]=y}catch(g){e.debug(`[iOS] No value for ${l}/${f}: ${g}`)}return{values:d,ui:await mt(o,c)}}async function xe(o,c,d){for(let[l,f]of Object.entries(d.values)){let g=l.indexOf("/");if(g<0)continue;let y=l.slice(0,g),D=l.slice(g+1);try{await o.executeCommandArgs(["spawn",c,"defaults","write",y,D,f])}catch(w){e.warn(`[iOS] Failed to write ${y}/${D}: ${w}`)}}if(d.ui?.appearance)try{await o.executeCommandArgs(["ui",c,"appearance",d.ui.appearance])}catch(l){e.warn(`[iOS] Failed to restore appearance: ${l}`)}if(d.ui?.contentSize)try{await o.executeCommandArgs(["ui",c,"content_size",d.ui.contentSize])}catch(l){e.warn(`[iOS] Failed to restore content_size: ${l}`)}}class Ce{options;kind="simulator";constructor(o){this.options=o}getDeviceInfo(){return this.options.simctl.getDeviceInfo(this.options.deviceId)}getRuntimes(){return this.options.simctl.getRuntimes()}captureSettings(){return Pe(this.options.simctl,this.options.deviceId)}restoreSettings(o){return xe(this.options.simctl,this.options.deviceId,o)}getAppDataContainerPath(o){return t$(this.options.simctl,this.options.deviceId,o,this.options.containerOwnership)}terminateAppIfRunning(o){return be(this.options.simctl,this.options.deviceId,o)}listAppsOrThrow(){return new VD(this.options.deviceId,this.options.simctl).listApps()}listApps(){return $Y(this.options.deviceId,this.options).listApps()}}function ne(o,c){return En(o)?{kind:"physical"}:new Ce({deviceId:o,simctl:c.simctl,containerOwnership:c.containerOwnership})}import{promises as B}from"fs";import*as ie from"path";var le="isVmSnapshotSaveDispatched";class fe{iosCaptureContainerFiles;consoleBusyRegistry;device;adb;emulator;store;iosSnapshotBackend;constructor(o,c={}){let{adbFactory:d=v,emulator:l,store:f=new Rh,simctl:g,consoleBusyRegistry:y=qs}=c;this.iosCaptureContainerFiles=c.iosCaptureContainerFiles??{mkdir:async(D)=>{await B.mkdir(D,{recursive:!0})},cp:(D,w)=>B.cp(D,w,{recursive:!0}),pathExists:rs},this.consoleBusyRegistry=y,this.device=o,this.adb=d.create(o),this.emulator=l||new pi,this.store=f,this.iosSnapshotBackend=ne(o.deviceId,{simctl:g||new L(o),containerOwnership:c.containerOwnership})}get simulatorSnapshotBackend(){if(this.iosSnapshotBackend.kind==="physical")throw Error("Snapshot app listing is not supported for physical iOS devices");return this.iosSnapshotBackend}async capture(o){return this.execute(o)}async execute(o){switch(wh(o.snapshotName),this.device.platform){case"android":return this.executeAndroid(o);case"ios":if(this.iosSnapshotBackend.kind==="physical")throw new t(`Device snapshots are not supported on physical iOS devices (${this.device.deviceId}); they require a Simulator (simctl).`);return this.executeIos(o);default:throw new t(`Snapshot capture is not supported for platform '${this.device.platform}'`)}}async executeAndroid(o){let{snapshotName:c,includeAppData:d=!0,includeSettings:l=!0,useVmSnapshot:f=!0,vmSnapshotTimeoutMs:g=30000}=o;e.info(`Capturing snapshot '${c}' for device ${this.device.deviceId}`);let y=this.device.deviceId.startsWith("emulator-"),D=f&&y,w;if(D)w=await this.captureVmSnapshot(c,l,g);else w=await this.captureSettingsSnapshot(c,d,l);return e.info(`Snapshot '${c}' captured successfully (type: ${w.snapshotType})`),{snapshotName:w.snapshotName,timestamp:w.timestamp,snapshotType:w.snapshotType,manifest:w}}async captureVmSnapshot(o,c,d){e.info(`Using VM snapshot for emulator ${this.device.deviceId}`);let l=!1;try{let f=ry("save",o);e.info(`Executing: adb -s ${this.device.deviceId} ${f}`);let g;try{g=await this.consoleBusyRegistry.runExclusive(this.device.deviceId,()=>this.adb.execute(f.split(" "),{timeoutMs:d,waitForProcessSettlementAfterAbort:!0,beforeDispatch:async()=>{l=!0}}))}catch(R){throw Error(eE("save",o,R))}let y=ny("save",o,g);if(!y.ok)throw Error(y.errorMessage);e.info("VM snapshot saved successfully");let D;if(c)D=await this.captureSettings();let w=await this.getForegroundApp();return{snapshotName:o,timestamp:new Date().toISOString(),deviceId:this.device.deviceId,deviceName:this.device.name,platform:"android",snapshotType:"vm",includeAppData:!0,includeSettings:c,foregroundApp:w,settings:D}}catch(f){let g=r(f);e.error(`Failed to capture VM snapshot: ${g}`);let y=new t(`Failed to capture VM snapshot: ${g}`);if(l)Object.assign(y,{[le]:!0});throw y}}async captureSettingsSnapshot(o,c,d){if(e.info(`Using settings-only snapshot for device ${this.device.deviceId}`),c)e.warn("App-data snapshots are not supported on non-VM Android (the adb backup path was removed in #5708); capturing settings only. Use a VM snapshot on an emulator to capture app data.");try{let l=await this.getForegroundApp(),f;if(d)f=await this.captureSettings(),await this.saveSettings(o,f);return{snapshotName:o,timestamp:new Date().toISOString(),deviceId:this.device.deviceId,deviceName:this.device.name,platform:"android",snapshotType:"adb",includeAppData:!1,includeSettings:d,foregroundApp:l,settings:f}}catch(l){throw e.error(`Failed to capture settings snapshot: ${r(l)}`,l),u(l,"Failed to capture settings snapshot")}}async getForegroundApp(){try{return(await this.adb.getForegroundApp())?.packageName}catch(o){e.warn(`Failed to get foreground app: ${o}`);return}}async captureSettings(){e.info("Capturing device settings");let o=["global","secure","system"],c={};for(let d of o)await this.captureSettingsNamespace(d,c);return c}async captureSettingsNamespace(o,c){try{let d=!1;try{let f=await E.getInstance(this.device).requestSettingsList(o);if(f.success&&f.entries)c[o]=f.entries,d=!0}catch(l){e.debug(`[CaptureSnapshot] a11y settings list failed for ${o}: ${l}`)}if(!d){let l=await this.adb.executeCommand(`shell settings list ${o}`);c[o]=this.parseSettings(l.stdout)}e.info(`Captured ${Object.keys(c[o]).length} ${o} settings`)}catch(d){e.warn(`Failed to capture ${o} settings: ${d}`),c[o]={}}}parseSettings(o){let c={};for(let d of o.split(`
|
|
3
|
+
`)){let l=d.trim();if(!l)continue;let f=l.match(/^(.+?)=(.*)$/);if(f)c[f[1]]=f[2]}return c}async saveSettings(o,c){let d=this.getAndroidPathOptions(),l=this.store.getSnapshotPathWithOptions(o,d);await B.mkdir(l,{recursive:!0});let f=this.store.getSettingsPath(o,d);await B.writeFile(f,JSON.stringify(c,null,2),"utf-8"),e.info(`Saved settings to ${f}`)}getAndroidPathOptions(){if(this.device.deviceId.startsWith("emulator-"))return{platform:"android",avdName:this.device.name};return}async executeIos(o){let{snapshotName:c,includeAppData:d=!0,includeSettings:l=!0,useVmSnapshot:f=!0,strictBackupMode:g=!1,appBundleIds:y}=o;if(e.info(`[iOS] Capturing snapshot '${c}' for simulator ${this.device.deviceId}`),f)e.info("[iOS] useVmSnapshot is ignored; using app container backups for portability");let D=await this.getIosDeviceMetadata(),w=this.getIosPathOptions(),A;if(l)A=await this.simulatorSnapshotBackend.captureSettings();let R=d?await this.captureIosAppData(c,y,g,w):void 0,P={snapshotName:c,timestamp:new Date().toISOString(),deviceId:this.device.deviceId,deviceName:this.device.name,platform:"ios",deviceType:D.deviceType,osVersion:D.osVersion,snapshotType:"app_data",includeAppData:d,includeSettings:l,...A?{iosSettings:A}:{},appDataBackup:R};return await this.saveIosMetadata(c,P,w),e.info(`[iOS] Snapshot '${c}' captured successfully (type: ${P.snapshotType})`),{snapshotName:P.snapshotName,timestamp:P.timestamp,snapshotType:P.snapshotType,manifest:P}}getIosPathOptions(){return{platform:"ios",deviceId:this.device.deviceId}}async captureIosAppData(o,c,d,l){let f=Array.from(new Set((c??[]).map((y)=>y.trim()).filter(Boolean)));if(f.length===0)throw new t("No app bundle IDs provided for iOS app-data capture. Pass appBundleIds with at least one installed app, or set includeAppData:false for a settings-only snapshot.");e.info("[iOS] Capturing app data containers");let g=this.store.getAppDataPath(o,l);await B.mkdir(g,{recursive:!0});try{return await this.backupIosAppContainers(f,d,g)}catch(y){throw await this.store.deleteSnapshotData(o,l),y}}async backupIosAppContainers(o,c,d){let l=await this.getInstalledIosBundleIds(),f=[],g=[],y=[],D=[];for(let w of o){if(!l.has(w)){e.warn(`[iOS] ${w} is not installed; skipping app data capture`),D.push(w),f.push({bundleId:w,status:"not-installed"});continue}try{let A=await this.simulatorSnapshotBackend.getAppDataContainerPath(w);if(!A){e.warn(`[iOS] ${w} has no data container; skipping app data capture`),y.push(w),f.push({bundleId:w,status:"skipped-no-container"});continue}e.info(`[iOS] Backing up app data: ${w}`),await this.copyIosAppContainer(A,d,w),g.push(w),f.push({bundleId:w,status:"captured"})}catch(A){if(A instanceof bd)throw A;e.warn(`[iOS] Failed to backup app data for ${w}: ${A}`),D.push(w),f.push({bundleId:w,status:"failed"})}}if(c&&g.length<o.length){let w=new Set(g),A=o.filter((R)=>!w.has(R));throw new t(`Failed to backup app data for ${A.length} of ${o.length} requested app(s) in strictBackupMode (all-or-nothing): ${A.join(", ")}.`)}if(g.length===0){let w=[`iOS app-data capture backed up 0 of ${o.length} requested app(s) (${o.join(", ")}).`];if(D.length>0)w.push(`Failed: ${D.join(", ")}.`);if(y.length>0)w.push(`Skipped (no data container): ${y.join(", ")}.`);throw w.push("Pass appBundleIds for installed apps that have a data container, or set includeAppData:false for a settings-only snapshot."),new t(w.join(" "))}return{backupMethod:"simctl_copy",totalPackages:o.length,backedUpPackages:g,skippedPackages:y,failedPackages:D,bundleStatuses:f}}async getInstalledIosBundleIds(){let o;try{o=await this.simulatorSnapshotBackend.listAppsOrThrow()}catch(d){throw u(d,"Failed to list installed iOS apps to validate appBundleIds")}let c=new Set;for(let d of o){let l=pn(d);if(l)c.add(l)}return c}async copyIosAppContainer(o,c,d){let l=ie.join(c,d);await this.iosCaptureContainerFiles.mkdir(l);for(let f of Mk){let g=ie.join(o,f),y=ie.join(l,f);if(await this.iosCaptureContainerFiles.pathExists(g))await this.iosCaptureContainerFiles.cp(g,y)}}async getIosDeviceMetadata(){try{let o=await this.simulatorSnapshotBackend.getDeviceInfo();if(!o)return{};let c=o.deviceTypeIdentifier??o.model,d=o.os_version;if(!d&&o.runtime){let f=(await this.simulatorSnapshotBackend.getRuntimes()).find((g)=>g.identifier===o.runtime);d=f?.version||f?.name}return{deviceType:c,osVersion:d}}catch(o){return e.warn(`[iOS] Failed to read simulator metadata: ${o}`),{}}}async saveIosMetadata(o,c,d){let l=this.store.getSnapshotPathWithOptions(o,d);await B.mkdir(l,{recursive:!0});let f=this.store.getMetadataPath(o,d);await B.writeFile(f,JSON.stringify(c,null,2),"utf-8"),e.info(`[iOS] Wrote metadata to ${f}`)}}import{promises as $e}from"fs";import*as oe from"path";function Oe(o){let c=o.trim(),d=c.match(/^(\d+)(?:\.(\d+))?(?:\.\d+)?$/)??c.match(/^[iI][oO][sS][- _]?(\d+)(?:[.\-_ ](\d+))?(?:[.\-_ ]\d+)?$/)??c.match(/^com\.apple\.CoreSimulator\.SimRuntime\.[iI][oO][sS]-(\d+)(?:-(\d+))?(?:-\d+)?$/);if(!d)return null;let l=Number(d[1]),f=d[2]===void 0?void 0:Number(d[2]);return Number.isFinite(l)&&(f===void 0||Number.isFinite(f))?{major:l,minor:f}:null}var ht=new Set(["global","secure","system"]);function lt(o){return ht.has(o)}function ft(o,c,d,l){let f=o==="vm"&&!c,g=d?"useVmSnapshot is disabled":`device ${l} is not an emulator`;return{snapshotType:c?"vm":"adb",restoreMode:c?"vm":"settings_only",...f?{restoreNote:`VM state was not restored; only captured Android settings were applied because ${g}.`}:{}}}class Se{windowCacheInvalidator=new ai;consoleBusyRegistry;device;adb;emulator;store;timer;iosSnapshotBackend;iosRestoreOperations;constructor(o,c={}){let{adbFactory:d=v,emulator:l,timer:f=i,store:g=new Rh,simctl:y,consoleBusyRegistry:D=qs,iosRestoreOperations:w}=c;this.consoleBusyRegistry=D,this.device=o,this.adb=d.create(o),this.emulator=l||new pi,this.store=g,this.timer=f,this.iosSnapshotBackend=ne(o.deviceId,{simctl:y||new L(o),containerOwnership:c.containerOwnership}),this.iosRestoreOperations=w??{pathExists:rs,terminateAppIfRunning:(A,R)=>this.simulatorSnapshotBackend.terminateAppIfRunning(R),getAppDataContainerPath:(A,R)=>this.simulatorSnapshotBackend.getAppDataContainerPath(R),rm:(A,R)=>$e.rm(A,R),cp:(A,R,P)=>$e.cp(A,R,P)}}get simulatorSnapshotBackend(){if(this.iosSnapshotBackend.kind==="physical")throw Error("Snapshot app listing is not supported for physical iOS devices");return this.iosSnapshotBackend}async restore(o){return this.execute(o)}async execute(o){switch(wh(o.snapshotName),this.device.platform){case"android":return this.executeAndroid(o);case"ios":if(this.iosSnapshotBackend.kind==="physical")throw new t(`Device snapshots are not supported on physical iOS devices (${this.device.deviceId}); they require a Simulator (simctl).`);return this.executeIos(o);default:throw new t(`Snapshot restore is not supported for platform '${this.device.platform}'`)}}async executeAndroid(o){let{snapshotName:c,manifest:d,useVmSnapshot:l=!0,vmSnapshotTimeoutMs:f=30000,onVmSnapshotLoaded:g,onBeforeVmSnapshotLoad:y}=o;if(e.info(`Restoring snapshot '${c}' (type: ${d.snapshotType}) to device ${this.device.deviceId}`),d.platform!==this.device.platform)throw new t(`Snapshot platform '${d.platform}' does not match device platform '${this.device.platform}'`);let D=this.device.deviceId.startsWith("emulator-"),w=l&&d.snapshotType==="vm"&&D,A=[];if(w)await this.restoreVmSnapshot(c,d,f,{onVmSnapshotLoaded:g,onBeforeVmSnapshotLoad:y});else A=await this.restoreSettingsSnapshot(d);if(A.length===0)e.info(`Snapshot '${c}' restored successfully`);else e.warn(`Snapshot '${c}' partially restored: ${A.length} item(s) failed`);return{...ft(d.snapshotType,w,D,this.device.deviceId),restoredAt:new Date().toISOString(),success:A.length===0,failures:A}}async restoreVmSnapshot(o,c,d,{onVmSnapshotLoaded:l,onBeforeVmSnapshotLoad:f}={}){e.info(`Restoring VM snapshot for emulator ${this.device.deviceId}`);try{let g=ry("load",o);e.info(`Executing: adb -s ${this.device.deviceId} ${g}`),await f?.();let y;try{y=await this.consoleBusyRegistry.runExclusive(this.device.deviceId,()=>this.adb.execute(g.split(" "),{timeoutMs:d,waitForProcessSettlementAfterAbort:!0}))}catch(w){throw Error(eE("load",o,w))}let D=ny("load",o,y);if(!D.ok)throw Object.assign(Error(D.errorMessage),{isDefinitiveVmSnapshotLoadFailure:!0});e.info("VM snapshot restored successfully"),await l?.(),await this.emulator.waitForEmulatorReady(c.deviceName,d,null,{targetDeviceId:this.device.deviceId,options:{skipWakeAndUnlock:!0}}),e.info("VM snapshot restoration complete")}catch(g){let y=r(g);e.error(`Failed to restore VM snapshot: ${y}`);let D=`Failed to restore VM snapshot '${o}' on device ${this.device.deviceId}`,w=g instanceof t?new t(`${D}: ${g.message}`,{cause:g}):u(g,D);if(g instanceof Error&&g.isDefinitiveVmSnapshotLoadFailure===!0)Object.assign(w,{isDefinitiveVmSnapshotLoadFailure:!0});throw w}}async restoreSettingsSnapshot(o){e.info(`Restoring settings-only snapshot for device ${this.device.deviceId}`);try{let c=[];if(o.includeSettings&&o.settings)c=await this.restoreSettings(o.settings);if(o.foregroundApp)await this.restoreForegroundApp(o.foregroundApp);return e.info("Settings snapshot restoration complete"),c}catch(c){throw e.error(`Failed to restore settings snapshot: ${r(c)}`,c),u(c,"Failed to restore settings snapshot")}}async restoreSettings(o){e.info("Restoring device settings");let c=[];for(let[d,l]of Object.entries(o)){if(!l||Object.keys(l).length===0)continue;e.info(`Restoring ${Object.keys(l).length} ${d} settings`);let f=0,g=0;if(!lt(d)){g=Object.keys(l).length,e.warn(`Skipping unsupported settings namespace ${d}`);for(let y of Object.keys(l))c.push({kind:"android_setting",namespace:d,key:y,reason:"unsupported settings namespace"});e.info(`${d} settings restored: ${f} succeeded, ${g} failed`);continue}for(let[y,D]of Object.entries(l)){if(!/^[A-Za-z0-9_.:-]+$/.test(y)){g++,e.warn(`Failed to restore ${d} setting ${y}: invalid settings key`),c.push({kind:"android_setting",namespace:d,key:y,reason:"invalid settings key"});continue}try{await this.applyAndroidSetting(d,y,D),f++}catch(w){g++,e.warn(`Failed to restore ${d} setting ${y}: ${w}`),c.push({kind:"android_setting",namespace:d,key:y,reason:r(w)})}}e.info(`${d} settings restored: ${f} succeeded, ${g} failed`)}return c}async applyAndroidSetting(o,c,d){let l=!1;try{if((await E.getInstance(this.device).requestSettingsPut(o,c,d,{valueType:"string"})).success)l=!0}catch(f){e.debug(`[RestoreSnapshot] a11y settings put failed for ${o}/${c}: ${f}`)}if(!l)await this.adb.executeCommand(`shell settings put ${o} ${b(c)} ${b(d)}`)}async restoreForegroundApp(o){e.info(`Restoring foreground app: ${o}`);try{await this.adb.executeCommand(`shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER ${b(o)}`),e.info(`Launched ${o}`)}catch(c){e.warn(`Failed to restore foreground app: ${c}`)}finally{this.windowCacheInvalidator.invalidate(this.device,!0)}}async executeIos(o){let{snapshotName:c,manifest:d}=o;if(e.info(`[iOS] Restoring snapshot '${c}' (type: ${d.snapshotType})`),d.platform!=="ios")throw new t(`Snapshot platform '${d.platform}' does not match device platform '${this.device.platform}'`);if(d.snapshotType!=="app_data")throw new t(`Unsupported iOS snapshot type '${d.snapshotType}'. Re-capture using app container backups.`);if(await this.validateIosSnapshotCompatibility(d),d.includeSettings&&d.iosSettings)await this.simulatorSnapshotBackend.restoreSettings(d.iosSettings);let l=await this.restoreIosAppData(c,d);if(l.length===0)e.info(`[iOS] Snapshot '${c}' restored successfully`);else e.warn(`[iOS] Snapshot '${c}' partially restored: ${l.length} bundle(s) failed`);return{snapshotType:d.snapshotType,restoredAt:new Date().toISOString(),success:l.length===0,failures:l}}getIosPathOptions(o){return{platform:"ios",deviceId:o??this.device.deviceId}}async restoreIosAppData(o,c){if(!c.includeAppData)return e.info("[iOS] Snapshot does not include app data; skipping restore"),[];let d=await this.resolveIosAppDataPath(o,c);if(!d)return e.warn(`[iOS] App data directory not found for snapshot '${o}'`),[];if(c.appDataBackup?.backupMethod==="none")return e.info("[iOS] Snapshot app data backup method is 'none'; skipping restore"),[];let l=await this.resolveIosSnapshotBundleIds(d,c);if(l.length===0)return e.warn("[iOS] No app bundle IDs found to restore"),[];let f=await this.getInstalledIosBundleIds();if(f.size>0){let y=l.filter((D)=>!f.has(D));if(y.length>0)throw new t(`App(s) not installed on simulator: ${y.join(", ")}. Please reinstall and retry restore.`)}else e.warn("[iOS] Unable to verify installed apps; proceeding with restore");let g=[];for(let y of l)try{await this.restoreIosBundleContainer(y,d)}catch(D){e.warn(`[iOS] Failed to restore app data for ${y}: ${D}`),g.push({kind:"ios_bundle",bundleId:y,reason:r(D)})}return g}async resolveIosAppDataPath(o,c){let d=this.store.getAppDataPath(o,this.getIosPathOptions(c.deviceId));if(await this.iosRestoreOperations.pathExists(d))return d;if(!c.deviceId||c.deviceId===this.device.deviceId)return;let l=this.store.getAppDataPath(o,this.getIosPathOptions(this.device.deviceId));if(!await this.iosRestoreOperations.pathExists(l))return;return e.info(`[iOS] App data not found for '${c.deviceId}', using current device path '${this.device.deviceId}'`),l}async restoreIosBundleContainer(o,c){await this.iosRestoreOperations.terminateAppIfRunning(this.device.deviceId,o);let d=await this.iosRestoreOperations.getAppDataContainerPath(this.device.deviceId,o);if(!d)throw new t(`App data container not found for ${o}`);let l=oe.join(c,o);for(let f of Mk){let g=oe.join(l,f);if(!await this.iosRestoreOperations.pathExists(g))continue;let y=oe.join(d,f);await this.iosRestoreOperations.rm(y,{recursive:!0,force:!0});try{await this.iosRestoreOperations.cp(g,y,{recursive:!0})}catch(D){throw new t(`Existing destination data was wiped/deleted and is now gone at '${y}'; restore copy failed: ${r(D)}`,{cause:D})}}}async validateIosSnapshotCompatibility(o){if(!o.osVersion){e.warn("[iOS] Snapshot OS version missing; skipping compatibility check");return}let c=Oe(o.osVersion);if(!c)throw new t(`Snapshot manifest osVersion '${o.osVersion}' is not an iOS version. Expected an iOS version such as '26.5', 'iOS 26.5' or 'com.apple.CoreSimulator.SimRuntime.iOS-26-5'.`);let d=await this.getIosDeviceOsVersion();if(!d){e.warn("[iOS] Unable to read simulator OS version; skipping compatibility check");return}let l=Oe(d);if(!l)throw new t(`Simulator OS version '${d}' is not an iOS version. Expected an iOS version such as '26.5', 'iOS 26.5' or 'com.apple.CoreSimulator.SimRuntime.iOS-26-5'.`);if(c.major!==l.major)throw new t(`Snapshot iOS version '${o.osVersion}' is incompatible with simulator iOS '${d}'. Please restore on an iOS ${c.major}.x simulator.`)}async getIosDeviceOsVersion(){try{let o=await this.simulatorSnapshotBackend.getDeviceInfo();if(!o)return;let c=o.os_version;if(!c&&o.runtime){let l=(await this.simulatorSnapshotBackend.getRuntimes()).find((f)=>f.identifier===o.runtime);c=l?.version||l?.name}return c}catch(o){e.warn(`[iOS] Failed to read simulator OS version: ${o}`);return}}async getInstalledIosBundleIds(){try{let c=(await this.simulatorSnapshotBackend.listApps()).map((d)=>d.bundleId||d.CFBundleIdentifier).filter((d)=>typeof d==="string"&&d.length>0);return new Set(c)}catch(o){return e.warn(`[iOS] Failed to list installed apps: ${o}`),new Set}}async resolveIosSnapshotBundleIds(o,c){let d=c.appDataBackup?.backedUpPackages;if(d&&d.length>0)return d;try{return(await Tr(o)).filter((f)=>f.isDirectory()).map((f)=>f.name)}catch(l){return e.warn(`[iOS] Failed to read app data bundles: ${l}`),[]}}}import{readFile as gt,stat as yt}from"fs/promises";import{isAbsolute as Ve,join as Be,resolve as wt}from"path";import{createHash as St}from"crypto";import{join as vt}from"path";var ve="userdata-qemu.img",Me=(o)=>St("sha256").update(o).digest("hex");class ge{deps;constructor(o){this.deps=o}async currentIdentity(o){let c=await this.deps.avdDirectory.resolveAvdDirectory(o);if(!c)throw new t(`AVD '${o}' is not on this host`);let d=await this.deps.config.readConfig(o);if(!d?.systemImagePackage||!d.systemImagePath)throw new t(`AVD '${o}' lacks system-image metadata in config.ini`);let l=await this.deps.imageMetadata(d.systemImagePath),f=(await this.deps.emulatorVersion()).split(`
|
|
4
|
+
`)[0]?.trim()??"";if(!f)throw new t("Could not read the emulator version for the fixture identity");let g=this.deps.userdataImage?.(c)??vt(c,ve),y=await this.deps.fileIdentity(g);return{avdName:o,systemImageId:`${d.systemImagePackage}:${Me(l)}`,avdConfigHash:Me(JSON.stringify(d.hardware??{})),emulatorVersion:f,userdataGeneration:y?`${y.ino}:${y.birthtimeMs}`:"none"}}}var Dt=1e4;function ke(){let o=new Nr,c=new pi;return new ge({config:o,avdDirectory:o,imageMetadata:async(d)=>gt(Rt(d,Ve(d)?void 0:Pl()?.androidHome),"utf8"),userdataImage:(d)=>It(d,I(h.EMULATOR_ARGS)),emulatorVersion:async()=>{let d=await c.executeCommand(["-version"],Dt);return d.error?"":d.stdout},fileIdentity:(d)=>At(d)})}async function At(o,c=yt){try{let d=await c(o);return{ino:d.ino,birthtimeMs:d.birthtimeMs}}catch(d){if(d.code!=="ENOENT")throw d;return e.debug(`[DeviceSnapshot] no userdata image at ${o}`),null}}function Rt(o,c){if(Ve(o))return Be(o,"source.properties");if(!c)throw new t("A snapshot fixture needs installed system-image metadata");return wt(c,o,"source.properties")}function It(o,c){let d=c?QR(c):[],l=d.indexOf("-data");if(l===-1)return Be(o,ve);let f=d[l+1];if(!f||f.startsWith("-"))throw new t("AUTOMOBILE_EMULATOR_ARGS passes -data without a path, so a fixture cannot tell which userdata image the emulator runs");return f}async function Ee(o,c){let d=await c.currentIdentity(o.avdName),l=[];if(d.avdName!==o.avdName)l.push("avd-changed");if(d.systemImageId!==o.systemImageId)l.push("system-image-changed");if(d.avdConfigHash!==o.avdConfigHash)l.push("avd-config-changed");if(d.emulatorVersion!==o.emulatorVersion)l.push("emulator-version-changed");if(d.userdataGeneration!==o.userdataGeneration)l.push("userdata-wiped");return l.length===0?{valid:!0}:{valid:!1,reasons:l}}function bt(o,c){return o.platform==="android"&&o.deviceId.startsWith("emulator-")&&c}async function Fe(o,c){let{device:d,snapshotName:l,useVmSnapshot:f,fixture:g}=o;if(!g)return;if(!bt(d,f))throw new lp("fixture_requires_vm_snapshot",l,`Snapshot '${l}' cannot be a fixture: fixtures are Android emulator VM snapshots only. Capture on an emulator without useVmSnapshot: false.`);let y=await c.currentIdentity(d.name);return{identity:y,confirmUnchanged:async()=>(await Te(y,l,c),y)}}async function Te(o,c,d){let l=await Ee(o,d);if(!l.valid)throw new lp("fixture_invalidated",c,`Fixture '${c}' no longer matches AVD '${o.avdName}' (${l.reasons.join(", ")}). Capture it again with fixture: true.`,l.reasons)}async function ze(o,c,d,l){let f=o.manifest.fixture;if(c.fixture&&!f)throw new lp("snapshot_not_a_fixture",o.snapshotName,`Snapshot '${o.snapshotName}' was not captured as a fixture. Capture it again with fixture: true.`);if(!f)return;if(c.fixture&&!d)throw new lp("fixture_requires_vm_snapshot",o.snapshotName,`Fixture '${o.snapshotName}' reloads its VM snapshot; restore it without useVmSnapshot: false.`);await Te(f,o.snapshotName,l)}function Pt(o,c){if(o.platform!==c.platform)return!1;if(c.platform==="ios")return o.deviceId===c.deviceId;let d=c.deviceId.startsWith("emulator-"),l=o.deviceId.startsWith("emulator-");if(!d)return o.deviceId===c.deviceId;return l&&o.deviceName===c.name||o.deviceId.length===0&&o.deviceName===c.name||o.deviceId===c.deviceId&&o.deviceName.length===0}function tH(o,c,d="restored"){if(Pt(o,c))return;let l=`${o.platform} device '${o.deviceName||"unknown"}' (${o.deviceId||"unknown ID"})`,f=`${c.platform} device '${c.name}' (${c.deviceId})`;throw new t(`Snapshot '${o.snapshotName}' belongs to ${l} and cannot be ${d==="restored"?"restored to":"deleted on"} ${f}. `+(d==="restored"?"Restore it on its original device or capture a snapshot for the target device.":"Delete it on its original device."))}function Le(o,c){return`${o}\x00${c}`}async function je(o,c){let d=new Set(o.filter((f)=>f.platform==="android"&&f.snapshotType==="vm").map((f)=>Le(f.deviceName,f.snapshotName))),l=[];try{for(let f of await c.listKnownAvdNames()){let g=await c.listAvdSnapshotDirectories(f);l.push(...g.filter((y)=>y.snapshotName!==Am&&!d.has(Le(f,y.snapshotName))).map((y)=>({avdName:f,...y})))}}catch(f){e.warn(`[DeviceSnapshot] Failed to scan for orphaned in-AVD snapshots: ${f}`,f)}return{count:l.length,totalSizeBytes:l.reduce((f,g)=>f+(g.sizeBytes??0),0),unsizedCount:l.filter((f)=>f.sizeBytes===null).length,entries:l}}var j={prepareForIncarnationChange:async()=>{},invalidate:async()=>{},settleIncarnationChange:async()=>{}};function LX(o){let c=j;return j=o,()=>{j=c}}var rH={prepareForIncarnationChange:(...o)=>j.prepareForIncarnationChange(...o),invalidate:(...o)=>j.invalidate(...o),settleIncarnationChange:(...o)=>j.settleIncarnationChange(...o)};var ye=null,xt="manifest.json",Ct=500,$t=50,Ot=64,Ue=!1,We=0;function re(o){if(Ue)return;Ue=!0;let c=We;o.timer.sleep(Ct).then(()=>{if(c!==We)return;Nt().catch((d)=>{e.warn("[DeviceSnapshot] Startup snapshot journal sweep failed",d)})}).catch((d)=>{e.warn("[DeviceSnapshot] Startup snapshot journal sweep delay failed",d)})}async function Nt(){let{snapshotStore:o}=await _i(),{entries:c,truncated:d}=await o.listLeftoverSnapshotJournals({maxEntries:$t,maxScopeDirectories:Ot}),l={recovered:0,failed:0,skippedLocked:0,truncated:d};for(let{snapshotName:f,options:g}of c){if(J.has(f)){l.skippedLocked++;continue}try{await G(f,()=>o.recoverSnapshotData(f,g)),l.recovered++}catch(y){e.warn(`[DeviceSnapshot] Failed to recover snapshot '${f}' in scope ${JSON.stringify(g??"flat")}`,y),l.failed++}}if(d)e.warn("[DeviceSnapshot] Snapshot journal sweep truncated; remaining artifacts are left to lazy recovery");if(l.recovered||l.failed||l.skippedLocked)e.info(`[DeviceSnapshot] Snapshot journal sweep: ${l.recovered} recovered, ${l.failed} failed, ${l.skippedLocked} locked`);return l}var J=new Map,Mt=new Map,Vt="archive-budget",Bt=new Map,kt="config-update",Et=new Map,H=new Map,we=new Map;function _t(o,c){let d=H.get(o)??new Map;d.set(c,(d.get(c)??0)+1),H.set(o,d)}function Ft(o,c){let d=H.get(o);if(!d)return;let l=d.get(c);if(l===void 0)return;if(l===1)d.delete(c);else d.set(c,l-1);if(d.size===0)H.delete(o)}function Tt(o){let c=H.get(o);return new Set([...c??new Map].filter(([,d])=>d>0).map(([d])=>d))}function zt(o,c){let d=Tt(o);if(c!==void 0)d.add(c);return d}async function Lt(o,c,d,l){if(!Ze(o,d))return l();_t(o.name,c);try{return await l()}finally{Ft(o.name,c)}}function Ze(o,c){return o.platform==="android"&&o.deviceId.startsWith("emulator-")&&c}function pe(o,c,d){let f=(o.get(c)??Promise.resolve()).then(d,d),g=f.then(()=>{return},()=>{return});return o.set(c,g),g.finally(()=>{if(o.get(c)===g)o.delete(c)}),f}function G(o,c){return pe(J,o,c)}function jt(o){return pe(Mt,Vt,o)}function Ut(o){return pe(Bt,kt,o)}function Wt(o,c){return pe(Et,o,c)}function ce(o){if(o.platform==="ios")return{platform:"ios",deviceId:o.deviceId};if(o.platform==="android"&&o.deviceId?.startsWith("emulator-")&&o.avdName)return{platform:"android",avdName:o.avdName};return}async function _i(){if(!ye)ye={snapshotRepository:new me,configRepository:fQ(),snapshotStore:new Rh,avdSnapshots:new o5(new Rh),timer:i,vmRetentionRetryBackoff:Q({initialDelayMs:100,maxDelayMs:5000}),now:()=>new Date,createCaptureProvider:(o,c,d)=>new fe(o,{timer:c,store:d}),createRestoreProvider:(o,c,d)=>new Se(o,{timer:c,store:d}),deviceIncarnationInvalidator:rH,fixtureIdentityProbe:ke()};return ye}function Ht(o){return{includeAppData:o.includeAppData,includeSettings:o.includeSettings,useVmSnapshot:o.useVmSnapshot,strictBackupMode:o.strictBackupMode,vmSnapshotTimeoutMs:o.vmSnapshotTimeoutMs,maxVmSnapshotsPerAvd:o.maxVmSnapshotsPerAvd,maxVmArchiveSizeMb:o.maxVmArchiveSizeMb,maxArchiveSizeMb:o.maxArchiveSizeMb}}function Jt(o,c){return{includeAppData:c.includeAppData??o.includeAppData,includeSettings:c.includeSettings??o.includeSettings,useVmSnapshot:c.useVmSnapshot??o.useVmSnapshot,strictBackupMode:c.strictBackupMode??o.strictBackupMode,vmSnapshotTimeoutMs:c.vmSnapshotTimeoutMs??o.vmSnapshotTimeoutMs,maxVmSnapshotsPerAvd:c.maxVmSnapshotsPerAvd??o.maxVmSnapshotsPerAvd,maxVmArchiveSizeMb:c.maxVmArchiveSizeMb??o.maxVmArchiveSizeMb,maxArchiveSizeMb:c.maxArchiveSizeMb??o.maxArchiveSizeMb}}function Gt(o){if(o===null)return"unknown";if(o<=0)return"0 B";let c=["B","KB","MB","GB"],d=Math.min(Math.floor(Math.log(o)/Math.log(1024)),c.length-1);return`${(o/Math.pow(1024,d)).toFixed(2)} ${c[d]}`}function Kt(o){return{snapshotName:o.snapshotName,restorable:!o.pendingReclaim,deviceId:o.deviceId,deviceName:o.deviceName,platform:o.platform,snapshotType:o.snapshotType,includeAppData:o.includeAppData,includeSettings:o.includeSettings,createdAt:o.createdAt,lastAccessedAt:o.lastAccessedAt,sizeBytes:o.sizeBytes,sizeLabel:Gt(o.sizeBytes),...o.pendingReclaim?{pendingReclaim:!0,...o.pendingReclaimReason===void 0?{}:{pendingReclaimReason:o.pendingReclaimReason}}:{}}}function k(o){return o.platform==="android"&&o.snapshotType==="vm"}async function qe(o,c,d,{avdSnapshots:l,pathOptions:f}){if(!k(c))return d.getSnapshotSizeBytes(o,f);let g=await l.measureVmSnapshotBytes(c.deviceName,o);if(g===null)e.warn(`[DeviceSnapshot] Could not measure the in-AVD payload of VM snapshot '${o}' for AVD '${c.deviceName}'; recording its size as unknown`);return g}function Yt(o){return typeof o==="object"&&o!==null&&o[le]===!0}async function He(o,c,d,{vmSnapshotTimeoutMs:l,context:f}){try{let g=await d.findLiveEmulatorSerial(o.name);if(!g){e.warn(`[DeviceSnapshot] Skipping cleanup of ${f} VM snapshot '${c}' because AVD '${o.name}' is not live`);return}let y=await d.deleteVmSnapshot(g,c,l,o.name);if(!y.reclaimed)e.warn(`[DeviceSnapshot] Could not clean up ${f} VM snapshot '${c}' on AVD '${o.name}': ${y.reason??"unknown reason"}`)}catch(g){e.warn(`[DeviceSnapshot] Failed to clean up ${f} VM snapshot '${c}' on AVD '${o.name}': ${r(g)}`,g)}}async function Qt({device:o,snapshotName:c,includeSettings:d,snapshotRepository:l,avdSnapshots:f,vmSnapshotTimeoutMs:g,now:y,error:D}){let w=`VM snapshot save was dispatched but capture failed: ${r(D)}`,A=null;try{A=await f.measureVmSnapshotBytes(o.name,c)}catch(P){e.warn(`[DeviceSnapshot] Failed to measure orphaned VM snapshot '${c}' on AVD '${o.name}': ${r(P)}`,P)}let R=y().toISOString();try{let P=await l.getSnapshot(c);if(P&&(!k(P)||P.deviceName!==o.name)){let C=k(P)?`it belongs to AVD '${P.deviceName}' (${P.deviceId})`:"it is a non-VM snapshot record";return e.warn(`[DeviceSnapshot] Same-named capture '${c}' failed on AVD '${o.name}' (${o.deviceId}); preserving the existing row because ${C}: ${w}`),await He(o,c,f,{vmSnapshotTimeoutMs:g,context:"failed same-named"}),!1}return await l.insertSnapshot({snapshotName:c,deviceId:o.deviceId,deviceName:o.name,platform:"android",snapshotType:"vm",includeAppData:!0,includeSettings:d,createdAt:R,lastAccessedAt:R,sizeBytes:A,pendingReclaim:!0,pendingReclaimReason:w,manifest:{snapshotName:c,timestamp:R,deviceId:o.deviceId,deviceName:o.name,platform:"android",snapshotType:"vm",includeAppData:!0,includeSettings:d}}),e.warn(`[DeviceSnapshot] Recorded pending reclaim for orphaned VM snapshot '${c}' on AVD '${o.name}': ${w}`),!0}catch(P){return e.warn(`[DeviceSnapshot] Failed to record pending reclaim for orphaned VM snapshot '${c}' on AVD '${o.name}': ${r(P)}`,P),await He(o,c,f,{vmSnapshotTimeoutMs:g,context:"unrecordable"}),!1}}function Xt(o){if(!o||typeof o!=="object")return!1;let c=o;return typeof c.snapshotName==="string"&&typeof c.timestamp==="string"&&typeof c.deviceId==="string"&&typeof c.deviceName==="string"&&(c.platform==="android"||c.platform==="ios")&&Zt(c.snapshotType)&&typeof c.includeAppData==="boolean"&&typeof c.includeSettings==="boolean"}function Zt(o){return o==="adb"||o==="vm"||o==="simctl"||o==="app_data"}function qt(o){if(!o||typeof o!=="object"||Array.isArray(o))return!1;let c=o;return["global","secure","system"].every((d)=>{let l=c[d];return l===void 0||typeof l==="object"&&l!==null&&!Array.isArray(l)})}function Je(o,c){if(c.snapshotName===o)return c;return{...c,snapshotName:o}}function en(o,c){return Number.isNaN(Date.parse(o))?c:o}async function Ge(o){try{let c=await Xe.readFile(o,"utf-8"),d=JSON.parse(c);if(!Xt(d))return e.warn(`[DeviceSnapshot] Manifest at '${o}' has an unexpected shape`),null;return d}catch(c){if(c.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to read manifest at '${o}': ${c}`);return null}}async function tn(o,c,d){let l=await Ge(c.getMetadataPath(o,d));if(l)return Je(o,l);let f=ae.join(c.getSnapshotPathWithOptions(o,d),xt),g=await Ge(f);if(g)return Je(o,g);return null}async function nn(o,c,d,l){let f=c.getSettingsPath(o,d),g;try{g=await Xe.readFile(f,"utf-8")}catch(D){if(D.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to read settings for '${o}': ${D}`);return null}let y;try{y=JSON.parse(g)}catch(D){return e.warn(`[DeviceSnapshot] Settings file for '${o}' is not valid JSON: ${D}`),null}if(!qt(y))return e.warn(`[DeviceSnapshot] Settings file for '${o}' has an unexpected shape`),null;return{snapshotName:o,timestamp:l().toISOString(),deviceId:"",deviceName:d?.avdName??"",platform:"android",snapshotType:"adb",includeAppData:!1,includeSettings:!0,settings:y}}async function de(o,c,d,l){let f=await tn(o,c,d);if(f)return f;if(d?.platform==="ios")return null;return nn(o,c,d,l)}async function se(o,c,d,{snapshotRepository:l,now:f,pathOptions:g}){let{avdSnapshots:y}=await _i(),D=await qe(o,c,d,{avdSnapshots:y,pathOptions:g}),w=f().toISOString(),A=en(c.timestamp,w),R={snapshotName:o,deviceId:c.deviceId,deviceName:c.deviceName,platform:c.platform,snapshotType:c.snapshotType,includeAppData:c.includeAppData,includeSettings:c.includeSettings,createdAt:A,lastAccessedAt:A,sizeBytes:D,manifest:c};try{return await l.insertSnapshot(R),R}catch(P){return e.warn(`[DeviceSnapshot] Failed to import legacy snapshot '${o}': ${P}`),l.getSnapshot(o)}}async function s6(o,c,d,l){let f=await de(o,c,void 0,l);if(f)return se(o,f,c,{snapshotRepository:d,now:l});let g=await on(o,c,l);if(!g)return null;return se(o,g.manifest,c,{snapshotRepository:d,now:l,pathOptions:g.pathOptions})}async function*et(o){for(let c of["android","ios"]){let d=ae.join(o.getBasePath(),c),l;try{l=await Tr(d)}catch(f){if(f.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to scan ${c} snapshot scope: ${f}`);continue}for(let f of l){if(!f.isDirectory())continue;yield{pathOptions:c==="ios"?{platform:"ios",deviceId:f.name}:{platform:"android",avdName:f.name},scopedDirPath:ae.join(d,f.name)}}}}async function on(o,c,d){for await(let{pathOptions:l}of et(c)){if(!await c.snapshotDirectoryExists(o,l))continue;let g=await de(o,c,l,d);if(g)return{manifest:g,pathOptions:l}}return null}async function an(o,c,d,l){let f;try{f=await Tr(c.getBasePath())}catch(y){if(y.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to scan legacy snapshots: ${y}`);return!1}let g=!1;for(let y of f){if(!y.isDirectory())continue;let D=y.name;if(D.endsWith(sl))continue;if(Ae(D))continue;if(l.has(D)||J.has(D))continue;let w=await de(D,c,void 0,d);if(!w)continue;if(await se(D,w,c,{snapshotRepository:o,now:d}))l.add(D),g=!0}return g}async function sn(o,c,d,l){let f=!1;for await(let{pathOptions:g,scopedDirPath:y}of et(c)){let D;try{D=await Tr(y)}catch(w){if(w.code!=="ENOENT")e.warn(`[DeviceSnapshot] Failed to scan snapshots under ${y}: ${w}`);continue}for(let w of D){if(!w.isDirectory())continue;let A=w.name;if(A.endsWith(sl))continue;if(l.has(A)||J.has(A))continue;let R=await de(A,c,g,d);if(!R)continue;if(await se(A,R,c,{snapshotRepository:o,now:d,pathOptions:g}))l.add(A),f=!0}}return f}async function rn(o,c,d,l){let f=await an(o,c,d,l),g=await sn(o,c,d,l);return f||g}async function lm(){await lB([fI.ARCHIVE])}function cn(o){let c=HQ(o);if(c?.kind==="scope-root")throw new t(`Snapshot name '${o}' is reserved. Please choose a different name.`);if(c?.kind==="suffix")throw new t(`Snapshot name '${o}' ends with the reserved '${sl}' suffix (case-insensitively). Please choose a different name.`)}function dn(o){if(o.trim().toLowerCase()===Am.toLowerCase())throw new t(`Snapshot name '${Am}' is reserved for the emulator's own quick-boot snapshot and cannot be used as an AutoMobile capture name.`)}async function tt(o,c){let{snapshotRepository:d,avdSnapshots:l}=await _i(),f=o.deviceName,g=await l.findLiveEmulatorSerial(f);if(g)await d.updateSnapshot(o.snapshotName,{pendingReclaim:!0,pendingReclaimReason:`reclaiming the in-AVD payload on AVD '${f}'`});let y=g?await l.deleteVmSnapshot(g,o.snapshotName,c,f):{reclaimed:!1,reason:`emulator for AVD '${f}' is not running; in-AVD snapshot left in place`};if(y.reclaimed)return!0;return e.warn(`[DeviceSnapshot] Could not reclaim the in-AVD payload of VM snapshot '${o.snapshotName}': ${y.reason}. Keeping the record so the reclaim can be completed when that emulator is next seen live.`),await d.updateSnapshot(o.snapshotName,{pendingReclaim:!0,pendingReclaimReason:y.reason}),!1}var Ke=Symbol("snapshot-record-superseded");function nt(o,c){return o.deviceId===c.deviceId&&o.deviceName===c.deviceName&&o.snapshotType===c.snapshotType&&o.createdAt===c.createdAt&&o.sizeBytes===c.sizeBytes&&o.manifest.timestamp===c.manifest.timestamp}async function nH(o,c){if(J.has(o.snapshotName))return e.debug(`[DeviceSnapshot] Skipping reclaim of '${o.snapshotName}': a capture or restore of that name is in flight`),Ke;return G(o.snapshotName,async()=>{let{snapshotRepository:d}=await _i(),l=await d.getSnapshot(o.snapshotName);if(!l||!nt(l,o))return e.debug(`[DeviceSnapshot] Skipping reclaim of '${o.snapshotName}': the record was replaced after it was selected`),Ke;return c()})}async function un(o,c,d){if(!(d instanceof lp)||d.code!=="fixture_invalidated")throw d;let l=(!k(o)||await tt(o,c))&&await aN(o);throw new lp(d.code,d.snapshotName,`${d.message} ${l?"It was removed.":"Its in-AVD snapshot could not be reclaimed now and is pending."}`,d.reasons)}async function sN(o,c){return await nH(o,async()=>{if(k(o)&&!await tt(o,c))return!1;return aN(o)})===!0}async function aN(o){let{snapshotStore:c}=await _i(),d=ce({platform:o.platform,deviceId:o.deviceId,avdName:o.deviceName}),l=[d];if(d?.platform==="android"&&!Ae(o.snapshotName))l.push(void 0);for(let f of l)try{await c.recoverSnapshotData(o.snapshotName,f)}catch(g){e.warn(`[DeviceSnapshot] Recovery before deletion failed for '${o.snapshotName}' in scope ${JSON.stringify(f??"flat")}`,g);let y=await c.discardSnapshotArtifacts(o.snapshotName,f);if(y.length>0)e.warn(`[DeviceSnapshot] Snapshot artifacts left behind after deletion: ${y.join(", ")}`)}return mn(o)}async function mn(o){let{snapshotRepository:c}=await _i();return await it(o),c.deleteSnapshot(o.snapshotName)}async function it(o,c={}){let{snapshotStore:d}=await _i(),l=ce({platform:o.platform,deviceId:o.deviceId,avdName:o.deviceName});if(d.getSnapshotPathWithOptions(o.snapshotName,l)===c.preserveSnapshotPath)return;if(await d.deleteSnapshotData(o.snapshotName,l),l?.platform==="android"&&!Ae(o.snapshotName)&&d.getSnapshotPath(o.snapshotName)!==c.preserveSnapshotPath)await d.deleteSnapshotData(o.snapshotName)}function Ae(o){return o===sV||o===oV}async function hn(o){let{snapshotRepository:c,avdSnapshots:d}=await _i(),l=[];for(let f of o){if(f.sizeBytes!==null||!k(f)){l.push(f);continue}let g=await G(f.snapshotName,async()=>{let y=await d.measureVmSnapshotBytes(f.deviceName,f.snapshotName),D=await c.getSnapshot(f.snapshotName);if(!D||!nt(D,f)){e.warn(`[DeviceSnapshot] Concurrent replacement detected while re-measuring VM snapshot '${f.snapshotName}'; skipping stale size update.`);return}if(y===null)return D;try{return await c.updateSnapshot(f.snapshotName,{sizeBytes:y}),{...D,sizeBytes:y}}catch(w){return e.warn(`[DeviceSnapshot] Failed to record the re-measured size of VM snapshot '${f.snapshotName}': ${r(w)}`,w),D}});if(g)l.push(g)}return l}async function De(o){return jt(async()=>{let c=Math.max(0,Math.floor(o*1024*1024)),{snapshotRepository:d}=await _i(),{vmSnapshotTimeoutMs:l}=await qc(),f=(await d.listSnapshots({orderByLastAccessed:"asc"})).filter((w)=>w.snapshotType!=="vm"),g=f.reduce((w,A)=>w+(A.sizeBytes??0),0),y=f.filter((w)=>w.sizeBytes===null).length;if(y>0)e.warn(`[DeviceSnapshot] ${y} snapshot record(s) have an unknown size and are excluded from the non-VM archive budget`);if(c===0||g<=c)return{evictedSnapshotNames:[],currentSizeBytes:g,maxSizeBytes:c,unsizedCount:y};let D=[];for(let w of f){if(g<=c)break;try{if(await sN(w,l))D.push(w.snapshotName),g-=w.sizeBytes??0}catch(A){e.warn(`[DeviceSnapshot] Failed to evict snapshot ${w.snapshotName}: ${A}`)}}if(g>c)e.warn(`[DeviceSnapshot] Non-VM archive size ${g} bytes still exceeds limit ${c} bytes after eviction`);if(D.length>0)e.warn(`[DeviceSnapshot] Evicted ${D.length} snapshot(s) under the app_data byte budget (maxArchiveSizeMb=${o}): ${D.join(", ")}`),await lm();return{evictedSnapshotNames:D,currentSizeBytes:g,maxSizeBytes:c,unsizedCount:y}})}function ln(o){if(o.maxVmArchiveSizeMb===void 0)return Number.POSITIVE_INFINITY;return Math.max(0,Math.floor(o.maxVmArchiveSizeMb*1024*1024))}function ot(o){return o.snapshots.reduce((c,d)=>c+(d.sizeBytes??0),0)}function fn(o,c,d){return o!==void 0&&c.maxVmArchiveSizeMb!==void 0&&(o.sizeBytes??0)>d}function Sn(o,c){return o.snapshots.find((d)=>!c.has(d.snapshotName)&&!o.failedNames.has(d.snapshotName))}async function Ye(o,c,d,l){let f=Sn(o,d);if(!f)return"no-candidate";try{if(!await sN(f,c.vmSnapshotTimeoutMs)){let{snapshotRepository:g}=await _i(),y=await g.getSnapshot(f.snapshotName);if(y?.pendingReclaim)return"deferred";if(!y||y.deviceName!==f.deviceName)return o.snapshots=o.snapshots.filter((D)=>D.snapshotName!==f.snapshotName),"removed-concurrently";return o.failedNames.add(f.snapshotName),"failed"}return o.snapshots=o.snapshots.filter((g)=>g.snapshotName!==f.snapshotName),o.evictedSnapshotNames.push(f.snapshotName),(l==="count"?o.countEvictedSnapshotNames:o.byteEvictedSnapshotNames).push(f.snapshotName),"evicted"}catch(g){return e.warn(`[DeviceSnapshot] Failed to evict snapshot ${f.snapshotName}: ${g}`),o.failedNames.add(f.snapshotName),"failed"}}async function vn(o){let{snapshotRepository:c}=await _i(),d=await hn((await c.listSnapshots({snapshotType:"vm"})).filter((l)=>l.deviceName===o&&!l.pendingReclaim&&!l.manifest.fixture));return d.sort((l,f)=>l.lastAccessedAt.localeCompare(f.lastAccessedAt)),{snapshots:d,evictedSnapshotNames:[],countEvictedSnapshotNames:[],byteEvictedSnapshotNames:[],failedNames:new Set}}async function gn(o,c,d,l){while(o.snapshots.length>c.maxVmSnapshotsPerAvd){let f=await Ye(o,c,d,"count");if(f==="deferred"||f==="no-candidate")return}while(ot(o)>l){let f=await Ye(o,c,d,"byte");if(f==="deferred"||f==="no-candidate")return}}function yn(o,c,d){if(o.evictedSnapshotNames.length===0)return;e.warn(`[DeviceSnapshot] Evicted ${o.evictedSnapshotNames.length} VM snapshot(s) for AVD '${c}': ${o.countEvictedSnapshotNames.length} by the per-AVD count retention (maxVmSnapshotsPerAvd=${d.maxVmSnapshotsPerAvd}), ${o.byteEvictedSnapshotNames.length} by the VM byte budget (maxVmArchiveSizeMb=${d.maxVmArchiveSizeMb??"unlimited"}): `+o.evictedSnapshotNames.join(", "))}async function wn(o,c,d,{currentSizeBytes:l,maxSizeBytes:f,excludeFromEviction:g}){let y=d.snapshots.length>c.maxVmSnapshotsPerAvd||c.maxVmArchiveSizeMb!==void 0&&l>f;if(d.failedNames.size===0||!y){we.delete(o);return}let{timer:D,vmRetentionRetryBackoff:w}=await _i(),A=(we.get(o)??0)+1;we.set(o,A),D.setTimeout(()=>{qc().then((R)=>Re(o,R,{excludeFromEviction:g})).catch((R)=>{e.warn(`[DeviceSnapshot] Deferred VM retention retry for AVD '${o}' failed: `+r(R),R)})},w.delayForAttempt(A))}async function Re(o,c,d={}){return Wt(o,async()=>{let l=await vn(o),f=zt(o,d.excludeFromEviction),g=ln(c),y=l.snapshots.filter((C)=>C.sizeBytes===null).length;if(y>0)e.warn(`[DeviceSnapshot] ${y} VM snapshot record(s) have an unknown size and are excluded from the VM retention byte budget`);let D=d.excludeFromEviction?l.snapshots.find((C)=>C.snapshotName===d.excludeFromEviction):void 0,w=fn(D,c,g);if(!w)await gn(l,c,f,g);let A=d.excludeFromEviction?l.snapshots.find((C)=>C.snapshotName===d.excludeFromEviction):void 0,R=d.excludeFromEviction!==void 0&&A===void 0,P=ot(l);if(c.maxVmArchiveSizeMb!==void 0&&P>g)e.warn(`[DeviceSnapshot] VM snapshots for AVD '${o}' total ${P} bytes still exceed limit ${g} bytes after retention`);if(yn(l,o,c),l.evictedSnapshotNames.length>0)await lm();return await wn(o,c,l,{currentSizeBytes:P,maxSizeBytes:g,excludeFromEviction:d.excludeFromEviction}),{evictedSnapshotNames:l.evictedSnapshotNames,currentSizeBytes:P,maxSizeBytes:g,unsizedCount:y,cannotFitExcluded:w,excludedSnapshotMissing:R,excludedSnapshotRecord:A??null,excludedSnapshotSizeBytes:A?.sizeBytes??null,countEvictedSnapshotNames:l.countEvictedSnapshotNames,byteEvictedSnapshotNames:l.byteEvictedSnapshotNames}})}async function Qe(o){let{snapshotRepository:c}=await _i(),d=await c.listSnapshots({snapshotType:"vm"}),l=[...new Set(d.map((g)=>g.deviceName))],f=await Promise.all(l.map((g)=>Re(g,o)));return{evictedSnapshotNames:f.flatMap((g)=>g.evictedSnapshotNames),currentSizeBytes:f.reduce((g,y)=>g+y.currentSizeBytes,0),maxSizeBytes:o.maxVmArchiveSizeMb===void 0?0:o.maxVmArchiveSizeMb*1024*1024,unsizedCount:f.reduce((g,y)=>g+y.unsizedCount,0)}}async function Dn(o){if(o.platform!=="android"||!o.deviceId.startsWith("emulator-")||!o.name)return[];let{snapshotRepository:c,avdSnapshots:d}=await _i(),l;try{l=await c.listSnapshots({pendingReclaim:!0,snapshotType:"vm"})}catch(y){return e.warn(`[DeviceSnapshot] Failed to read pending VM snapshot reclaims: ${y}`,y),[]}let f=[],{vmSnapshotTimeoutMs:g}=await qc();for(let y of l.filter((D)=>D.deviceName===o.name))if(await nH(y,async()=>{let w=await d.deleteVmSnapshot(o.deviceId,y.snapshotName,g,y.deviceName);if(!w.reclaimed)return e.warn(`[DeviceSnapshot] Pending reclaim of VM snapshot '${y.snapshotName}' still incomplete: ${w.reason}`),!1;return aN(y)})===!0)f.push(y.snapshotName);if(f.length>0)e.info(`[DeviceSnapshot] Completed ${f.length} pending VM snapshot reclaim(s) for AVD '${o.name}'`),await lm();return f}async function An(o,c,d){let{snapshotRepository:l,avdSnapshots:f}=await _i(),g=await l.getSnapshot(o);if(!g?.pendingReclaim||!k(g)||g.deviceName===c)return;let y=await f.findLiveEmulatorSerial(g.deviceName),D=y?await f.deleteVmSnapshot(y,o,d,g.deviceName):{reclaimed:!1,reason:`emulator for AVD '${g.deviceName}' is not running`};if(D.reclaimed){e.info(`[DeviceSnapshot] Reclaimed the pending in-AVD payload of '${o}' on AVD '${g.deviceName}' before reusing that name on AVD '${c}'`);return}e.warn(`[DeviceSnapshot] Capturing '${o}' on AVD '${c}' overwrites the only record of a pending reclaim for AVD '${g.deviceName}' (${D.reason}). Its in-AVD payload stays on disk and is reported as an orphan until it is removed manually (see docs/using/test-prep-tools.md).`)}async function qc(){let{configRepository:o}=await _i(),c=await o.getConfig();if(c)return z(c);return z(N.getDeviceSnapshotDefaults())}async function BX(o){return Ut(async()=>{let{configRepository:c,timer:d}=await _i();if(re({timer:d}),o===null){await c.clearConfig();let w=z(N.getDeviceSnapshotDefaults()),[A,R]=await Promise.all([De(w.maxArchiveSizeMb),Qe(w)]);return{config:w,evictedSnapshotNames:[...A.evictedSnapshotNames,...R.evictedSnapshotNames]}}let l=await qc(),f=Jt(Ht(l),o),g=z(f);await c.setConfig(g);let[y,D]=await Promise.all([De(g.maxArchiveSizeMb),Qe(g)]);return{config:g,evictedSnapshotNames:[...y.evictedSnapshotNames,...D.evictedSnapshotNames]}})}async function Rn(o,c,d,l){let f=await De(d.maxArchiveSizeMb);if(o.manifest.snapshotType!=="vm")return f.evictedSnapshotNames;let g=await Re(c.name,d,o.manifest.fixture?{}:{excludeFromEviction:o.snapshotName});if(g.excludedSnapshotMissing)throw new t(`Snapshot '${o.snapshotName}' was removed by a concurrent VM retention sweep before capture could complete; capture did not succeed`);if(!g.cannotFitExcluded)return[...f.evictedSnapshotNames,...g.evictedSnapshotNames];if(l)throw await lm(),new t(`Snapshot '${o.snapshotName}' recapture exceeds the configured maxVmArchiveSizeMb budget for AVD '${c.name}'. The emulator's destructive snapshot save already irreversibly overwrote the prior payload under this name, so the new oversized capture was kept rather than deleting the only remaining usable snapshot.`);let y=g.excludedSnapshotRecord;if(y){if(!await sN(y,d.vmSnapshotTimeoutMs))throw await lm(),new t(`Snapshot '${o.snapshotName}' exceeds maxVmArchiveSizeMb but its VM payload could not be reclaimed; it remains tracked for a later reclaim`)}let D=Math.floor((d.maxVmArchiveSizeMb??0)*1024*1024);throw new t(`Snapshot '${o.snapshotName}' could not be captured because its VM payload (${g.excludedSnapshotSizeBytes??"unknown"} bytes) exceeds the configured maxVmArchiveSizeMb budget for AVD '${c.name}' (${D} bytes)`)}async function In(o,c,d,l){if(wh(c),cn(c),Ze(o,d))dn(c);let{fixtureIdentityProbe:f}=await _i();return Fe({device:o,snapshotName:c,useVmSnapshot:d,fixture:l.fixture},f)}async function $X(o,c){let{snapshotRepository:d,snapshotStore:l,avdSnapshots:f,timer:g,now:y,createCaptureProvider:D}=await _i();re({timer:g});let w=await qc(),A=c.useVmSnapshot??w.useVmSnapshot,R=c.snapshotName??l.generateSnapshotName(o.name),P=await In(o,R,A,c);await Dn(o);let C=ce({platform:o.platform,deviceId:o.deviceId,avdName:o.name}),M={...w,includeAppData:c.includeAppData??w.includeAppData,includeSettings:c.includeSettings??w.includeSettings,useVmSnapshot:A,strictBackupMode:c.strictBackupMode??w.strictBackupMode,vmSnapshotTimeoutMs:c.vmSnapshotTimeoutMs??w.vmSnapshotTimeoutMs};return Lt(o,R,M.useVmSnapshot,async()=>{let _=!1,U=await G(R,async()=>{let V=await d.getSnapshot(R);_=V!==null&&V.deviceName===o.name,await An(R,o.name,M.vmSnapshotTimeoutMs);let ue=D(o,g,l),T,X=!1;try{T=await l.replaceSnapshotData(R,C,async()=>{let x=await ue.capture({snapshotName:R,includeAppData:M.includeAppData,includeSettings:M.includeSettings,useVmSnapshot:M.useVmSnapshot,strictBackupMode:M.strictBackupMode,vmSnapshotTimeoutMs:M.vmSnapshotTimeoutMs,appBundleIds:c.appBundleIds});X=x.manifest.snapshotType==="vm",x.manifest.fixture??=await P?.confirmUnchanged();let W=await qe(R,x.manifest,l,{avdSnapshots:f,pathOptions:C}),Z=x.manifest.timestamp;return await d.insertSnapshot({snapshotName:x.snapshotName,deviceId:x.manifest.deviceId,deviceName:x.manifest.deviceName,platform:x.manifest.platform,snapshotType:x.manifest.snapshotType,includeAppData:x.manifest.includeAppData,includeSettings:x.manifest.includeSettings,createdAt:Z,lastAccessedAt:Z,sizeBytes:W,manifest:x.manifest}),x})}catch(x){if(o.platform==="android"&&o.deviceId.startsWith("emulator-")&&(Yt(x)||X)){if(await Qt({device:o,snapshotName:R,includeSettings:M.includeSettings,snapshotRepository:d,avdSnapshots:f,vmSnapshotTimeoutMs:M.vmSnapshotTimeoutMs,now:y,error:x}))await lm()}throw x}if(V)try{await it(V,{preserveSnapshotPath:l.getSnapshotPathWithOptions(R,C)})}catch(x){e.warn(`[DeviceSnapshot] Failed to retire prior archive data for '${R}': ${r(x)}`,x)}return T}),F=await qc(),K={...M,maxVmSnapshotsPerAvd:F.maxVmSnapshotsPerAvd,maxArchiveSizeMb:F.maxArchiveSizeMb,maxVmArchiveSizeMb:F.maxVmArchiveSizeMb},Y=await Rn(U,o,K,_);return await lm(),{result:U,evictedSnapshotNames:Y}})}async function UX(o,c){let{snapshotRepository:d,snapshotStore:l,timer:f,now:g,createRestoreProvider:y,deviceIncarnationInvalidator:D,fixtureIdentityProbe:w}=await _i();return re({timer:f}),wh(c.snapshotName),G(c.snapshotName,async()=>{let A=await d.getSnapshot(c.snapshotName);if(!A)A=await s6(c.snapshotName,l,d,g);if(!A)throw new t(`Snapshot '${c.snapshotName}' not found`);if(tH(A,o),A.pendingReclaim){let O=A.pendingReclaimReason?`: ${A.pendingReclaimReason}`:"";throw new t(`Snapshot '${A.snapshotName}' is awaiting reclaim after a failed capture${O}`)}let R=await qc(),P=c.useVmSnapshot??R.useVmSnapshot,C=c.vmSnapshotTimeoutMs??R.vmSnapshotTimeoutMs;await ze(A,c,P,w).catch((O)=>un(A,C,O));try{await l.recoverSnapshotData(A.snapshotName,ce({platform:A.platform,deviceId:A.deviceId,avdName:A.deviceName}))}catch(O){throw e.warn(`[DeviceSnapshot] Failed to recover snapshot '${A.snapshotName}' before restore: ${r(O)}`,O),u(O,`Failed to recover snapshot '${A.snapshotName}' before restore`)}let M=y(o,f,l),_=!1,U=!1,F=!1,K=!1,Y=!1,V={},ue=async()=>{if(_||o.platform!=="android"||!o.deviceId.startsWith("emulator-")||A.manifest.snapshotType!=="vm"||!P)return;_=!0,await D.prepareForIncarnationChange(o)},T=async()=>{if(U||o.platform!=="android"||!o.deviceId.startsWith("emulator-")||A.manifest.snapshotType!=="vm"||!P)return;U=!0;let O=await D.invalidate(o);if(typeof O==="string")V={deviceSessionUuid:O}},X=async()=>{F=!0,await T()},x=async()=>{if(!_||K)return;K=!0,await D.settleIncarnationChange(o,{ready:Y})},W;try{W=await M.restore({snapshotName:A.snapshotName,manifest:A.manifest,useVmSnapshot:P,vmSnapshotTimeoutMs:C,onBeforeVmSnapshotLoad:ue,onVmSnapshotLoaded:X}),Y=!0,await T()}catch(O){let at=O instanceof Error&&O.isDefinitiveVmSnapshotLoadFailure===!0;if(F||!at)await T();throw u(O,`Failed to restore snapshot '${A.snapshotName}'`)}finally{await x()}let Z=g().toISOString();return await d.touchSnapshot(A.snapshotName,Z),await lm(),{result:W,manifest:A.manifest,...V}})}async function HX(){let{snapshotRepository:o,snapshotStore:c,now:d,timer:l}=await _i();re({timer:l});let f=await o.listSnapshots({orderByCreatedAt:"desc"}),g=new Set(f.map((P)=>P.snapshotName)),D=await rn(o,c,d,g)?await o.listSnapshots({orderByCreatedAt:"desc"}):f,w=D.map(Kt),A=D.reduce((P,C)=>P+(C.sizeBytes??0),0),R=await je(D,(await _i()).avdSnapshots);return{snapshots:w,count:w.length,totalSizeBytes:A,unsizedCount:D.filter((P)=>P.sizeBytes===null).length,pendingReclaimCount:D.filter((P)=>P.pendingReclaim).length,orphanedAvdSnapshots:R}}
|
|
5
|
+
export{fI,tH,LX,rH,_i,s6,lm,nH,sN,aN,qc,BX,$X,UX,HX};
|
|
6
6
|
|
|
7
|
-
//# debugId=
|
|
7
|
+
//# debugId=66D5837E885EA02F64756E2164756E21
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{_2,G9,dU,Za,py,Ace,my,Mf,Ta}from"./chunk-r6pvhj33.js";import"./chunk-r0vp315h.js";import"./chunk-5wk1t46v.js";export{_2 as DARWIN_PS_LSTART_ENV,Za as compareProcessGenerationTokens,Mf as currentDaemonProcessGenerationToken,G9 as daemonGenerationMatches,dU as darwinProcessGenerationToken,Ace as processGenerationReadIsCheap,my as readDarwinProcessGenerationToken,py as readLinuxProcessGenerationToken,Ta as readProcessGenerationTokenForPid};
|
|
3
|
+
|
|
4
|
+
//# debugId=2DAA040CBF9CA0C764756E2164756E21
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{qv,Eo}from"./chunk-t54k47em.js";import"./chunk-cb1ga9rd.js";import"./chunk-sfqe223f.js";import"./chunk-r6pvhj33.js";import"./chunk-w5yypt53.js";import"./chunk-aewdveet.js";import"./chunk-r0vp315h.js";import"./chunk-5wk1t46v.js";export{Eo as Keyboard,qv as KeyboardOpenIndeterminateError};
|
|
3
|
+
|
|
4
|
+
//# debugId=2AEE9D091100E37B64756E2164756E21
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{i,Q,e}from"./chunk-
|
|
3
|
-
export{
|
|
2
|
+
import{i,Q,e}from"./chunk-r0vp315h.js";import{on}from"./chunk-sfqe223f.js";import{aD}from"./chunk-4vxeq0vd.js";import{Y9,Kb,WO,O2}from"./chunk-r6pvhj33.js";import{im,u}from"./chunk-2b39zyxc.js";var p=300000;class SM{store;windowMs;constructor(r=new aD,t=p){this.store=r,this.windowMs=t}recordFailure(r,t){let a=this.read().filter((o)=>t-o.at<=this.windowMs);a.push({at:t,kind:r});try{this.store.write(JSON.stringify(a))}catch(o){return e.debug(`Failed to persist startup failure tracker: ${o}`),Math.max(a.length,2)}return a.length}reset(){this.store.clear()}read(){let r=this.store.read();if(r===null)return[];try{let t=JSON.parse(r);if(!Array.isArray(t))return[];return t.filter((a)=>typeof a?.at==="number"&&(a.kind==="transient"||a.kind==="permanent"))}catch(t){return e.debug(`Failed to parse startup failure tracker contents: ${t}`),[]}}}var d=Math.max(1000,on-2000);async function UU(r,t,a=i){let o=Y9(r),n=t.recordFailure(o,a.now()),c=O2(r)?`${o}/${Kb}`:o;if(e.error(`Fatal: database initialization failed (${c}; ${n} recent failure(s)); daemon cannot serve queries and will exit for a clean restart: ${im(r)}`),o==="permanent"&&n>1){let l=Q({initialDelayMs:1000,multiplier:2,maxDelayMs:d}).delayForAttempt(n-1);e.error(`Database initialization has failed ${n} times; backing off ${l}ms before exit to avoid a restart hot-loop.`),await a.sleep(l)}let s=u(r,"Database initialization failed at daemon startup");if(O2(r))s.code=Kb;throw s}function bce(r){return O2(r)?WO:1}async function Sce(r,t=new SM,a=i){try{await r()}catch(o){await UU(o,t,a)}}
|
|
3
|
+
export{SM,UU,bce,Sce};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=50C3DDB444388E7064756E2164756E21
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Ir,gt,ct,pe,ye,IV,kee,Gh}from"./chunk-6hrj3jt6.js";import{h,$e,nce}from"./chunk-5wk1t46v.js";import{i,e}from"./chunk-r0vp315h.js";import{Fr,N}from"./chunk-sfqe223f.js";import{RS,to}from"./chunk-xcqzwf9j.js";import{YS}from"./chunk-8nj68t1v.js";import{JQ,mv,m5,fv,f5,Ah,j0,P_,ZQ}from"./chunk-jvstjnqm.js";import{n,a,Me,S,s,kP,Ne,_}from"./chunk-w5yypt53.js";import{r,t}from"./chunk-2b39zyxc.js";var H="Invalid tools/call request: ",X="Invalid tools/call result: ",Z="AutoMobile drives Android and iOS devices. Start with listDevices, getAndroid or getApple, then bind your session. Call observe before acting and again after each action; element ids are only valid for the observation that returned them. Prefer tapOn/sendKeys on observed elements over raw coordinates. Large artifacts (screenshots, logs) are resources, not inline output. Read the automobile usage skill (skill://auto-mobile-usage/SKILL.md) for the full workflow before your first device call.";function ee(o=process.env){return $e(h.SERVER_INSTRUCTIONS,o)?Z:void 0}function RM(o,c,l={}){let{cacheHints:d,requestState:u,instructions:m=ee()}=l,p=new Gh(o,{capabilities:{...c,prompts:void 0},...d&&{cacheHints:d},...u&&{requestState:u},...m!==void 0&&{instructions:m}});if(c.prompts)p.server.registerCapabilities({prompts:c.prompts});return te(p.server),p}class q{result;constructor(o){this.result=o}}function te(o){let c=o._wrapHandler.bind(o);o._wrapHandler=(l,d)=>{if(l!=="tools/call")return c(l,(m,p)=>d(m,L(p)));let u=c(l,async(m,p)=>{let f=await d(m,L(p));if(Ah(f))throw new q(f);return f});return async(m,p)=>{try{return await u(m,p)}catch(f){if(f instanceof q)return f.result;throw re(f)}}}}function re(o){if(!(o instanceof ye)||o instanceof to||o.code!==pe.InvalidParams)return o;if(o.message.startsWith(H))return new ye(RS.InternalError,o.message.slice(H.length),o.data);if(o.message.startsWith(X))return new to(RS.InvalidParams,o.message,o.data);return o}function L(o){return{...o,mcpReq:{...o.mcpReq,signal:oe(o.mcpReq.signal)}}}function oe(o){let c=new AbortController,l=()=>{c.abort(ne(o.reason)?void 0:o.reason)};if(o.aborted)l();else o.addEventListener("abort",l,{once:!0});return c.signal}function ne(o){return o instanceof ct&&o.code===gt.ConnectionClosed}var D="x-auto-mobile-mcp-session-id";function KU(o){let c=o["x-auto-mobile-mcp-session-id"],l=Array.isArray(c)?c[0]:c;return typeof l==="string"&&l.length>0?l:void 0}var w=s({version:_(1),toolName:n(),argumentsHash:n(),deviceIds:S(n())}),ie={createSecret:()=>crypto.getRandomValues(new Uint8Array(32))},z=600000,ae=w.extend({expiresAt:a().finite()});function se(o){let c=KU({[D]:o.http?.req?.headers.get(D)??void 0});return JSON.stringify(["ambiguous-device",c??null])}function ce(o={}){let c=o.timer??i,l,d=()=>(l??=JQ({key:(o.secretProvider??ie).createSecret(),ttlSeconds:z/1000,bind:se}),l);return{mint:(u,m)=>d().mint({...u,expiresAt:c.now()+z},m),verify:async(u,m)=>{let p=ae.parse(await d().verify(u,m));if(c.now()>=p.expiresAt)throw Error("expired");return w.parse(p)}}}var GU=ce();import{createHash as Se}from"crypto";function $E(o=process.env){return nce(h.ELICITATION,o)!=="off"}class T{declined=new Set;static key(o){return[...new Set(o)].sort().join("\x00")}remembers(o){return this.declined.has(T.key(o))}remember(o){this.declined.add(T.key(o))}}function j(o){return typeof o==="object"&&o!==null&&!Array.isArray(o)}function zP(o){let c=j(o)?o.elicitation:void 0;if(!j(c))return"none";if(c.form!==void 0)return"form";return c.url!==void 0?"url":"bare"}function le(o){return`[elicitation] ${o.toolName} era=${o.era} declared=${o.declared} outcome=${o.outcome} candidates=${o.candidateCount}`+(o.latencyMs===void 0?"":` latencyMs=${o.latencyMs}`)}var B={record:(o)=>e.info(le(o))};function tJ(o){return{record(c){B.record(c),o.recordElicitationEvent(c)}}}var K=B;function rJ(o){K=o}var UE={record:(o)=>K.record(o)};var de=20000;function U(o){return typeof o==="object"&&o!==null&&!Array.isArray(o)}function PM(o){let c=U(o)?o.elicitation:void 0;if(!U(c))return!1;return c.form!==void 0||c.url===void 0}function V(o,c){return{declaresElicitation:()=>c.mcpReq.envelope===void 0&&PM(o.server.getClientCapabilities()),declaration:()=>c.mcpReq.envelope===void 0?zP(o.server.getClientCapabilities()):"none",elicit:(l,d)=>o.server.request({method:"elicitation/create",params:l},{signal:d})}}var ue=s({isError:_(!0),content:S(kP({type:n()})).min(1)}),me=s({code:_(YS),candidates:S(s({deviceId:n(),platform:n().default("unknown")}))}),fe=s({type:_("text"),text:n()});function ve(o){let c=ue.safeParse(o),l=c.success?fe.safeParse(c.data.content[0]):void 0;if(!l?.success||!l.data.text.includes(YS))return;try{let d=me.safeParse(JSON.parse(l.data.text));return d.success?d.data:void 0}catch(d){e.debug(`ambiguous device result is not JSON: ${r(d)}`);return}}function b(o){let c=new Map((ve(o)?.candidates??[]).map((l)=>[l.deviceId,l]));return c.size>1?[...c.values()]:void 0}function I(o,c){return{mode:"form",message:`${o} matched ${c.length} devices. Which device should it use?`,requestedSchema:{type:"object",properties:{deviceId:{type:"string",title:"Device",description:"The device this call should run on.",oneOf:c.map(({deviceId:l,platform:d})=>({const:l,title:`${l} (${d})`}))}},required:["deviceId"]}}}function ge(o,c){if(o.action!=="accept")return;let l=o.content?.deviceId;return typeof l==="string"&&c.some(({deviceId:d})=>d===l)?l:void 0}function Re(o,c){if(o.action!=="accept")return{outcome:o.action};let l=ge(o,c);return l===void 0?{outcome:"invalid"}:{outcome:"accept",deviceId:l}}async function Ce(o,c,l,d){let u=new AbortController,m=!1,p=()=>u.abort();d.callSignal.addEventListener("abort",p,{once:!0});let f=d.timer.setTimeout(()=>{m=!0,p()},d.timeoutMs);try{let v=await o.elicit(I(c,l),u.signal);return Re(v,l)}catch(v){if(u.signal.aborted)return e.debug(`device choice for ${c} not answered: ${r(v)}`),{outcome:m?"timeout":"cancel"};return e.warn(`device choice elicitation for ${c} failed: ${r(v)}`,v),{outcome:"error"}}finally{d.timer.clearTimeout(f),d.callSignal.removeEventListener("abort",p)}}function F(o,c,l={}){let d=l.timer??i,u=l.timeoutMs??de,m=l.recorder??UE,p=()=>c.declaration?.()??(c.declaresElicitation()?"form":"none"),f=l.enabled??(()=>$E()),v=(y,R,C)=>m.record({toolName:y.name,era:"legacy",declared:p(),outcome:C,candidateCount:R,atMs:d.now()}),g=(y)=>{if(!f())return"disabled";if(!c.declaresElicitation())return"not_offered";return l.declines?.remembers(y)?"remembered":void 0};return{...o,execute:async(y)=>{let R=await o.execute(y),C=y.args.deviceId===void 0?b(R):void 0;if(!C)return R;let E=C.map(({deviceId:Y})=>Y),A=g(E);if(A)return v(y,C.length,A),R;let Q=d.now(),x=await Ce(c,y.name,C,{timer:d,timeoutMs:u,callSignal:y.extra.signal}),O=d.now();if(m.record({toolName:y.name,era:"legacy",declared:p(),outcome:x.outcome,candidateCount:C.length,atMs:O,latencyMs:O-Q}),x.outcome==="decline"||x.outcome==="cancel")l.declines?.remember(E);return x.deviceId===void 0?R:o.execute({...y,args:{...y.args,deviceId:x.deviceId}})}}}async function YU(o,c,l,d){let u=await c(o),m=b(u);if(!m)return u;let p=d?.timer??i,f=p.now(),v=(R,C)=>{let E=p.now();d?.recorder.record({toolName:o.name,era:"modern",declared:d.declared,outcome:R,candidateCount:m.length,atMs:E,...C?{latencyMs:E-f}:{}})},g=await l({candidates:m,inputRequests:{deviceChoice:IV.elicit(I(o.name,m))}});if(!g)return v("not_offered",!1),u;if("pending"in g)return v("asked",!1),g.pending;let y=kee(g.responses,"deviceChoice",s({deviceId:n().refine((R)=>m.some(({deviceId:C})=>C===R)&&(g.offeredDeviceIds===void 0||g.offeredDeviceIds.includes(R)))}));return v(y?"accept":Ee(g.responses),!0),y?c({...o,args:{...o.args,deviceId:y.deviceId}}):u}function Ee(o){let c=o.deviceChoice,l=typeof c==="object"&&c!==null&&"action"in c?c.action:void 0;return l==="decline"||l==="cancel"?l:"invalid"}function W(o,c=UE,l=()=>$E()){return{...o,execute:async(d)=>{let u=!l();if(d.args.deviceId!==void 0||u||!PM(d.extra.envelope?.[Ir])){let f=await o.execute(d),v=d.args.deviceId===void 0&&b(f);if(v)xe(c,d,v.length,u?"disabled":"not_offered");return f}let m={...d.args};delete m.deviceId;let p=Se("sha256").update(Fr(m)).digest("hex");return YU(d,(f)=>o.execute(f),async({candidates:f,inputRequests:v})=>{if(d.extra.inputResponses!==void 0){let g=w.safeParse(d.extra.deviceChoiceState?.verified);if(!g.success||g.data.toolName!==d.name||g.data.argumentsHash!==p)return;return{responses:d.extra.inputResponses,offeredDeviceIds:g.data.deviceIds}}if(!d.extra.deviceChoiceState)return;return{pending:IV({requestState:await d.extra.deviceChoiceState.mint({version:1,toolName:d.name,argumentsHash:p,deviceIds:f.map(({deviceId:g})=>g)}),inputRequests:v})}},{recorder:c,declared:zP(d.extra.envelope?.[Ir])})}}}function xe(o,c,l,d){o.record({toolName:c.name,era:"modern",declared:zP(c.extra.envelope?.[Ir]),outcome:d,candidateCount:l,atMs:i.now()})}function Te(o,c){let l=o._meta?.progressToken;if(l===void 0)return;return async(d,u,m)=>{try{await o.sendNotification({method:"notifications/progress",params:{progressToken:l,progress:d,total:u,...m&&{message:m}}})}catch(p){e.warn(`${c}: ${p}`)}}}async function he(o,c,l){l.prepare?.(o);let d=o.params.name,u=o.params.arguments||{};if(!d)throw new t("Tool name is missing in the request");return l.execute({name:d,args:u,progressToken:c._meta?.progressToken,progress:Te(c,l.progressFailureMessage),extra:c})}function be(o,c){return{signal:o.mcpReq.signal,_meta:o.mcpReq._meta,...o.mcpReq.envelope!==void 0&&{envelope:o.mcpReq.envelope},...o.mcpReq.inputResponses!==void 0&&{inputResponses:o.mcpReq.inputResponses},...c&&{deviceChoiceState:{verified:o.mcpReq.requestState(),mint:(l)=>c.mint(l,o)}},sendNotification:(l)=>o.mcpReq.notify(l)}}function AM(o,c,l={}){let d=new T,u=l.era==="modern"?W(c):c,m=l.era==="modern"?l.deviceChoiceRequestState??GU:void 0;o.server.setRequestHandler("tools/call",async(p,f)=>await he(p,be(f,m),l.era!=="modern"&&l.ambiguousDeviceElicitation?F(c,V(o,f),{declines:d,...l.ambiguousDeviceElicitation}):u))}function iS(o,c=N.isToolResultsNoStructuredContentEnabled()){if(!o)return"no-schema";if(c)return"flag";return null}function mG(o){return o!==null&&typeof o==="object"&&"structuredContent"in o}function oS(o,c){if(c!==null&&mG(o))delete o.structuredContent;return o}var J=kP({taskId:n()}),we=kP({taskId:n(),inputResponses:Ne(n(),Me()).optional()});function fG(o){let c=o._oninitialize.bind(o);o.setRequestHandler("initialize",async(l,d)=>{let u=await c(l);if(!(f5(l.params.capabilities)||G(d)))return u;return{...u,capabilities:{...u.capabilities,extensions:{...u.capabilities.extensions,[mv]:{}}}}})}function G(o){return fv({envelope:o.mcpReq.envelope,meta:o.mcpReq._meta})}function M(o){if(!G(o))throw j0()}function P(o){if(!o.ownerKey)throw P_("not_found");return o.ownerKey}function nJ(o,c){let l=o.server;fG(l),l.setRequestHandler("tasks/get",{params:J},async(d,u)=>{M(u);let m=await c.taskManager.get(P(c),d.taskId);return ZQ(m)}),l.setRequestHandler("tasks/update",{params:we},async(d,u)=>{M(u);let m=u.mcpReq.inputResponses??d.inputResponses??{};return await c.taskManager.update(P(c),d.taskId,m),m5}),l.setRequestHandler("tasks/cancel",{params:J},async(d,u)=>(M(u),await c.taskManager.cancel(P(c),d.taskId),m5))}
|
|
3
|
+
export{RM,KU,GU,$E,zP,tJ,rJ,UE,PM,YU,AM,iS,mG,oS,fG,nJ};
|
|
4
|
+
|
|
5
|
+
//# debugId=282D5FB670E9D05F64756E2164756E21
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Ho,YS,At,bh,Sh}from"./chunk-8nj68t1v.js";import{i,hi,e}from"./chunk-r0vp315h.js";import{h}from"./chunk-5wk1t46v.js";import{kB,oR,Zz,hd,Du,Mp,RR,Np,Lg,zs,N,ki}from"./chunk-sfqe223f.js";import"./chunk-z8tvs8nk.js";import{LI,Hr}from"./chunk-s3y3zfcx.js";import{B,kt,ti,Wn}from"./chunk-r6pvhj33.js";import"./chunk-aewdveet.js";import"./chunk-4vxeq0vd.js";import"./chunk-w5yypt53.js";import"./chunk-9xgnrv5w.js";import"./chunk-e0870khr.js";import{gS,iA,bN,AH,F,gA,Hy,qy,Vy,FI}from"./chunk-xcqzwf9j.js";import"./chunk-c3ewxm4x.js";import{ge}from"./chunk-jvstjnqm.js";import"./chunk-6hrj3jt6.js";import"./chunk-xn9m3xc2.js";import{pee}from"./chunk-xezekwwn.js";import"./chunk-cqhw4yr6.js";import"./chunk-tx4f0h9c.js";import"./chunk-qy3khhf8.js";import"./chunk-661c50hh.js";import"./chunk-b3tdtq7r.js";import"./chunk-gadtna7s.js";import"./chunk-tvq0nzam.js";import{sS,KM}from"./chunk-r4j43b9s.js";import"./chunk-8cvnpnbp.js";import"./chunk-t54k47em.js";import"./chunk-emv82m1w.js";import"./chunk-9q265er0.js";import"./chunk-hpzxdp1k.js";import"./chunk-wxdjeb4k.js";import"./chunk-g3af2qbk.js";import"./chunk-96r3bpg7.js";import"./chunk-13qxf7ym.js";import"./chunk-gfpntwc1.js";import"./chunk-qj1tbnv2.js";import"./chunk-pf282r5g.js";import"./chunk-3h5jz1vb.js";import"./chunk-gcyx407v.js";import"./chunk-yqfz4vts.js";import"./chunk-sqdrxjw5.js";import"./chunk-c27yv1dx.js";import"./chunk-vdqag3fj.js";import"./chunk-cb1ga9rd.js";import"./chunk-69pmjdf2.js";import{r,t}from"./chunk-2b39zyxc.js";function x(n,o,s={}){let a=iA(n);if(a&&/Unknown tool\b/i.test(o))return a;let l=o.replace(/[.]+$/,""),c=s.buildSkew?" Try: auto-mobile --daemon restart":"";return`Error calling daemon: ${l}.${c}`}function T(){sS(),KM({daemonMode:!0,includeDoctor:!0,includeToolSelection:!1})}function E(n){try{return{parsed:!0,value:JSON.parse(n)}}catch(o){return e.debug(`[cli] value is not JSON, treating as a raw token: ${n} (${o})`),{parsed:!1,value:n}}}function _(n,o){let s=()=>E(n).value;if(o?.nullable&&n==="null")return null;switch(o?.type){case"string":case"enum":return ie(n);case"number":case"bigint":return se(n);case"boolean":if(n==="true")return!0;if(n==="false")return!1;return s();default:return s()}}function ie(n){let{parsed:o,value:s}=E(n);return o&&typeof s==="string"?s:n}function se(n){let{parsed:o,value:s}=E(n);return o&&typeof s==="number"&&Number.isFinite(s)?s:n}var k=new Set(["optional","nullable","default","readonly","catch","branded","lazy"]);function A(n){let o=n?._def?.typeName??n?._def?.type??"unknown";return String(o).replace(/^Zod/,"").toLowerCase()}function L(n){let o=n?._def;return o?.innerType??o?.type??o?.schema??null}function ae(n){let o=n?._def?.options;if(!Array.isArray(o))return!1;let s=o.map((d)=>U(d).type),a=s.some((d)=>d==="number"||d==="bigint"),c=o.filter((d,u)=>s[u]==="string").every((d)=>{let u=d;for(let f=0;f<10&&u;f++){let m=A(u);if(m==="literal")return typeof(u._def?.value??u._def?.values?.[0])==="string";if(!k.has(m))return!1;u=L(u)}return!1});if(a&&c)return!1;return s.includes("string")&&s.every((d)=>["string","number","boolean","bigint"].includes(d))}function U(n){let o=n,s=!1;for(let a=0;a<10&&o;a++){let l=A(o);if(l==="nullable")s=!0;if(l==="literal")return{type:typeof(o._def?.value??o._def?.values?.[0]),nullable:s};if(l==="union"&&ae(o))return{type:"string",nullable:s};if(!k.has(l))return{type:l,nullable:s};o=L(o)}return{type:"unknown",nullable:s}}function C(n){let o=n?._def;if(!o)return[];if(o.shape)return[o.shape];let s=o.options??o.out?._def?.options;if(Array.isArray(s))return s.flatMap((a)=>C(a));return o.out?C(o.out):[]}function M(n){T();let o=F.getRegisteredTool(n);if(!o)return null;let s=C(o.schema);if(s.length===0)return null;let a=new Map;for(let l of s)for(let[c,d]of Object.entries(l)){let u=U(d),f=a.get(c)??{types:new Set,nullable:!1};f.types.add(u.type),f.nullable=f.nullable||u.nullable,a.set(c,f)}return Object.fromEntries([...a.entries()].filter(([,l])=>l.types.size===1).map(([l,c])=>[l,{type:[...c.types][0],nullable:c.nullable}]))}import le from"fs";var ce=65536,ue="CliToolResult";function R(n,o){let s=o.maxBytes??ce,a;try{a=JSON.stringify(n,null,2)}catch(c){return v(o.tool,0,`result is not JSON-serializable: ${r(c)}`)}if(a===void 0)return v(o.tool,0,"tool returned a value with no JSON representation");let l=Buffer.byteLength(a,"utf8");if(l<=s)return a;if(!o.artifactWriter)return v(o.tool,l,"no tool-output directory is available to spill the payload to");try{let c=o.artifactWriter.writeJsonArtifact({tool:o.tool,payload:ue,data:n,serialized:a});return JSON.stringify({truncated:!1,bytes:l,artifact:{...c.artifact,resourceUri:void 0},note:`Tool output was ${l} bytes, over the ${s}-byte CLI inline limit. The complete JSON result is in artifact.path.`},null,2)}catch(c){return e.debug(`[cli] failed to spill oversized tool output: ${r(c)}`),v(o.tool,l,r(c))}}function v(n,o,s){return JSON.stringify({truncated:!0,tool:n,bytes:o,reason:s,recovery:"Re-run with AUTOMOBILE_TOOL_OUTPUTS_DIR set to a writable directory, or narrow the request (for example observe with a scope) so the result fits inline."},null,2)}var H={write:(n)=>W(1,n)},j={write:(n)=>W(2,n)},de={writeSync:(n,o,s,a)=>le.writeSync(n,o,s,a),sleepSync:(n)=>{Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,n)}},fe=1000;function pe(n,o,s){let a=o+1;if(s.sleepSync(1),a>=fe)throw Error(`Zero-progress write to fd ${n} after ${a} attempts; refusing to spin`);return a}function W(n,o,s=de){let a=Buffer.from(o,"utf8"),l=0,c=0;while(l<a.length)try{let d=s.writeSync(n,a,l,a.length-l);if(d===0){c=pe(n,c,s);continue}c=0,l+=d}catch(d){let u=d.code;if(u==="EAGAIN"){s.sleepSync(1);continue}if(u==="EPIPE"){e.debug(`[cli] output stream closed before the write completed (fd ${n})`);return}throw d}}function me(n){if(!n||typeof n!=="object")return;let o=n,s=o.failure;if(s&&typeof s==="object")return s.code;let a=o.error;return o.code??(a&&typeof a==="object"?a.code:void 0)}function g(n){return n&&typeof n==="object"?n:void 0}function ye(n){return g(g(n)?.error)?.reason}function P(n){if(n<60000){let s=Math.round(n/1000*10)/10;return`${s} ${s===1?"second":"seconds"}`}let o=Math.round(n/60000*10)/10;return`${o} ${o===1?"minute":"minutes"}`}function he(n){let o=g(g(n)?.error)?.idleTimeoutMs;return typeof o==="number"&&Number.isFinite(o)&&o>0?o:void 0}var Se=`(reads do not count), so its session UUID cannot be used again. Acquire a new session with getAndroid, getApple or startDevice. To keep a session across longer gaps, set ${h.CLI_SESSION_IDLE_TIMEOUT_MS.name} (milliseconds, at most ${P(oR)}) in the environment of every --cli call.`;function be(n){let o=he(n);return`Hint: this --cli session went longer than ${o===void 0?`its idle timeout (${P(kB)} by default)`:`its idle timeout of ${P(o)} (${o} ms)`} without a control call ${Se}`}function we(n){let o=g(n)?.candidates;if(!Array.isArray(o))return[];return o.flatMap((s)=>{let a=g(s);if(typeof a?.deviceId!=="string")return[];return[typeof a.platform==="string"?`${a.deviceId} (${a.platform})`:a.deviceId]})}function Te(n){let o=we(n);return`Hint: more than one device matches this call. Re-run with --deviceId <id> to pick one, or with --session-uuid <uuid> to use a device your session holds.${o.length>0?` Candidates: ${o.join(", ")}.`:""}`}var ve=new Map([[hd,"Hint: the device's previous session is still finishing its cleanup. Re-run the command after the retryAfterMs in the error has passed; nothing else needs to change."],[Mp,"Hint: the device is being shut down. Re-run the command after the retryAfterMs in the error has passed, once the shutdown has finished."],[Np,"Hint: this session is being released because its device is being shut down, so its session UUID cannot be used again. Retrying with the same --session-uuid will not succeed; acquire the device again under a new session instead."],[Lg,"Hint: the device's session is moving to another device. Re-run the command after the retryAfterMs in the error has passed, once the rebind has settled."],[RR,"Hint: the session no longer holds this device; it was rebound or released. Check who holds the device now with --daemon active-sessions before re-running the command."],[Du,"Hint: another AutoMobile daemon on this host is using the device. Re-run after it releases the device, or pass another deviceId."]]);function J(n,o){let s=me(n);if(s===Ho&&ye(n)==="cli-idle-timeout")return be(n);if(s===YS)return Te(n);let a=typeof s==="string"?ve.get(s):void 0;if(a!==void 0)return a;if(s!==Zz)return;if(Hr(o))return`Hint: another session holds the device, and ${o} cannot join it: acquisition tools mint their own session and the CLI ignores --session-uuid for them. If that session is yours, skip re-acquiring and pass --session-uuid <uuid> to your follow-up calls; to see who holds the device, run --daemon active-sessions (releasing a session that is not yours can break another agent's work); otherwise wait for the holder to release it.`;return`Hint: a device a session holds takes calls only from that session. Re-run with --session-uuid <uuid>, the sessionUuid that getAndroid, getApple or startDevice returned when the device was acquired, or wait for the holder to release it.${pee(o,"force")?" To stop it anyway, pass --force true.":""}`}import p from"fs";import q from"path";var Oe="tool-selection-profile",Ce=3000,Ee=50,_e=B.next(),Pe;function O(n){return q.join(hi("cli",n),Oe)}function Ie(n){return`${O(n)}.lock`}async function I(n,o=process.env){let s=De(o,Pe??{});if(!await s.acquire())return!1;try{await n()}finally{s.release()}return!0}function De(n,o){let s=o.timer??i,a=Math.max(1,o.pollIntervalMs??Ee),l=o.timeoutMs??Ce,c=Ie(n),d=o.pid??process.pid,u=o.ownerToken??_e,f=s.now()+l;return{acquire:async()=>{try{for(;;){if(ti(c,{pid:d,isProcessRunning:o.isProcessRunning,ownerGeneration:o.ownerGeneration??kt,reclaimOwnPid:!0,ownerToken:u}))return!0;if(s.now()>=f)return!1;await s.sleep(Math.min(a,f-s.now()))}}catch(m){return e.debug(`Unable to acquire CLI tool-selection profile lock: ${r(m)}`),!1}},release:()=>{Wn(c,d,u)}}}function y(n=process.env){try{let o=p.readFileSync(O(n),"utf8").trim();if(o.length===0)return;if(!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o)){e.debug("Ignoring persisted CLI tool-selection profile because the file content is not a valid UUID");return}return o}catch(o){e.debug(`Unable to load the persisted CLI tool-selection profile: ${r(o)}`);return}}function V(n=process.env){let o=O(n),s=q.dirname(o);try{if(p.accessSync(s,p.constants.W_OK),p.existsSync(o)){if(!p.statSync(o).isFile())throw Error("profile path is not a regular file");p.accessSync(o,p.constants.W_OK)}}catch(a){throw new t(`CLI tool-selection profile store is not writable: ${o}. Fix its permissions or set AUTOMOBILE_DATA_DIR/AUTO_MOBILE_DATA_DIR to a writable directory so the CLI can persist a stable tool-selection profile across invocations.`,{cause:a})}}function G(n,o=process.env){let s=n.trim();if(s.length===0)return;let a;try{let l=O(o);if(a=`${l}.${process.pid}.${B.next()}.tmp`,p.writeFileSync(a,s,{encoding:"utf8",mode:384}),process.platform!=="win32")p.chmodSync(a,384);if(p.renameSync(a,l),a=void 0,process.platform!=="win32")p.chmodSync(l,384)}catch(l){if(e.debug(`Unable to persist the CLI tool-selection profile: ${r(l)}`),a)try{p.unlinkSync(a)}catch(c){e.debug(`Unable to remove incomplete CLI tool-selection profile: ${r(c)}`)}}}function xe(n){let o=n/60000;return`${o} ${o===1?"minute":"minutes"}`}function Z(n){if(typeof n==="string"&&n.trim()==="")throw new t("--session-uuid requires a non-empty value")}function ke(n){let o=ki(n[0]);if(o.flag!=="--session-uuid")return{sessionUuid:void 0,toolNameIndex:0};let s=o.inlineValue!==void 0,a=s?o.inlineValue:n[1],l=s?1:2;if(n.length<=l)throw new t("--session-uuid requires a value and a tool name");return Z(a),{sessionUuid:a,toolNameIndex:l}}function Ae(n){return K(n,M)}function z(n,o){return n&&Object.hasOwn(n,o)?n[o]:void 0}function K(n,o){if(n.length===0)throw new t("No tool name provided. Usage: --cli [--session-uuid <uuid>] <tool-name> [--param value ...]");let{sessionUuid:s,toolNameIndex:a}=ke(n),l=n[a],c=new Map,d=o(l);for(let u=a+1;u<n.length;u++){let f=n[u];if(!f.startsWith("--"))throw new t(`Invalid parameter format: ${f}. Parameters must start with --`);let{flag:m,inlineValue:D}=ki(f),b=m.slice(2).replace(/-([a-z])/g,(Qe,re)=>re.toUpperCase());if(D!==void 0){c.set(b,_(D,z(d,b)));continue}let w=n[u+1],oe=w!==void 0&&/^---(?:\s|$)/.test(w);if(w===void 0||w.startsWith("--")&&!oe)c.set(b,!0);else u++,c.set(b,_(w,z(d,b)))}return Z(c.get("sessionUuid")),{toolName:l,sessionUuid:s,params:Object.fromEntries(c)}}var Le=(n)=>new FI(n);async function $e(n,o){if(o===At)return;if(F.getTool(o)?.hidden)return;let s=y();if(!s){await Me(n,o);return}await Ue(n,o,s)}async function Ue(n,o,s){let a;try{n.setToolSelectionProfileUuid?.(s),a=await n.callTool(At,{toolName:o,enabled:!0,sessionUuid:s})}catch(f){e.debug(`CLI pre-enable of ${o} did not apply: ${r(f)}`);return}let l=bh(a);if(!(a?.isError===!0||l===void 0||l!==s))return;if(n.setToolSelectionProfileUuid?.(void 0),e.debug(`CLI tool-selection profile ${s} is stale; re-minting a profile`),await I(async()=>{let f=y();if(f&&f!==s){if(await X(n,o,f))return;n.setToolSelectionProfileUuid?.(void 0)}await Q(n,o)}))return;let u=y();e.debug(`CLI pre-enable of ${o} skipped after a contended profile-lock timeout; ${u?"a profile is now persisted for the next invocation":"the next invocation will retry"}, and the tool call will surface any gate error.`)}async function Me(n,o){if(!await I(async()=>{let a=y();if(a){if(await X(n,o,a))return;n.setToolSelectionProfileUuid?.(void 0)}await Q(n,o)})){let a=y();e.debug(`CLI pre-enable of ${o} skipped after a contended profile-lock timeout; ${a?"a profile is now persisted for the next invocation":"the next invocation will retry"}, and the tool call will surface any gate error.`)}}async function X(n,o,s){try{n.setToolSelectionProfileUuid?.(s);let a=await n.callTool(At,{toolName:o,enabled:!0,sessionUuid:s}),l=bh(a);return a?.isError!==!0&&l!==void 0&&l===s}catch(a){return e.debug(`CLI pre-enable of ${o} did not apply: ${r(a)}`),!0}}async function Q(n,o){V();try{let s=await n.callTool(At,{toolName:o,enabled:!0}),a=bh(s);G(a??"")}catch(s){e.debug(`CLI pre-enable of ${o} did not apply: ${r(s)}`)}}async function Ne(n,o,s){let a=Le({daemonOptions:s,oneShotCli:!0,lifecycleNamespaceEnv:process.env});try{await $e(a,n);let l=await a.callTool(n,o);if(l===null)throw new t(`Daemon returned null result. This may indicate a daemon connectivity issue. Try: bunx ${zs()} --daemon restart`);return l}catch(l){if(l instanceof Hy||l instanceof qy||l instanceof Vy)throw new t(`Daemon preflight failed; no device operation started. ${l.message}`);if(l instanceof ge)throw new t(`Daemon became unavailable during tool execution: ${l.message}. Try: auto-mobile --daemon restart`);if(l instanceof t)throw l;let c=r(l);throw new t(x(n,c,{buildSkew:l instanceof gA&&l.buildMismatch}))}finally{if(n!=="listDevices")await a.adoptCliSessionLiveness();await a.close()}}function Re(){return`Usage: auto-mobile --cli doctor [options]
|
|
3
|
+
|
|
4
|
+
Status: status-only and read-only diagnostics.
|
|
5
|
+
|
|
6
|
+
Options:
|
|
7
|
+
--android Filter to Android checks
|
|
8
|
+
--ios Filter to iOS checks
|
|
9
|
+
--json Machine-readable JSON output
|
|
10
|
+
--help Print this help
|
|
11
|
+
|
|
12
|
+
The universal --session-uuid option is accepted and ignored.`}function ee(n){if(Object.hasOwn(n,"repair")||Object.hasOwn(n,"timeoutMs"))return"doctor is status-only; --repair and --timeout-ms were removed. Use --daemon restart to recover the daemon; --daemon diagnose only gathers further diagnostics.";let o=["android","ios","json","help","sessionUuid"],s=Object.keys(n).filter((a)=>!o.includes(a)).map((a)=>`--${a.replace(/[A-Z]/g,(l)=>`-${l.toLowerCase()}`)}`);if(s.length>0)return`Unknown doctor flags: ${s.join(", ")}. Supported flags: --android, --ios, --json, --help (the universal --session-uuid option is accepted and ignored).`;return}function Fe(n){let o=ee(n);if(o!==void 0)throw new t(o)}function rn(n){let o;try{o=K(n,()=>null)}catch(s){return e.debug(`CLI bootstrap routing kept the normal path: ${r(s)}`),!1}if(o.toolName!=="doctor")return!1;return ee(o.params)!==void 0||Boolean(o.params.help)}async function Be(n,o={}){if(Fe(n),n.help){(o.writeOutput??console.log)(Re());return}let s=await import("./chunk-nc4516tx.js"),a=await(o.runDoctor??s.runDoctor)({android:n.android,ios:n.ios});if(n.json===!0)ne(a,"doctor");else(o.writeOutput??console.log)((o.formatConsoleOutput??s.formatConsoleOutput)(a,process.stdout.isTTY??!0));if(a.summary.failed>0)(o.exit??process.exit)(1);return}function te(n){let o=n;if(n&&typeof n==="object"&&"content"in n&&Array.isArray(n.content)){if(n.content.length>0&&n.content[0].type==="text")try{o=JSON.parse(n.content[0].text)}catch(s){e.debug(`CLI tool result is not JSON: ${r(s)}`),o=n}}return o}function He(n){return n?.isError===!0||te(n)?.success===!1}var je={stdout:H,stderr:j};function We(){try{return new bN({outputDirectory:N.getToolOutputsDir()??Sh(),retention:AH})}catch(n){e.debug(`[cli] no tool-output artifact writer available: ${r(n)}`);return}}function ne(n,o){je.stdout.write(R(n,{tool:o,artifactWriter:We()})+`
|
|
13
|
+
`)}function Je(n){if(!n||typeof n!=="object")return n;let{message:o,nextAction:s}=n;if(typeof o!=="string")return n;return typeof s==="string"?`${o}
|
|
14
|
+
Next: ${s}`:o}function qe(n,o){ne(n,o);let s=te(n);if(He(n)){if(s&&typeof s==="object"&&s.error)console.error(Je(s.error));else if(n?.isError===!0&&Array.isArray(n.content)&&n.content[0]?.type==="text")console.error(n.content[0].text);Ve(s,o);let a=J(s,o);if(a)console.error(a);process.exit(1)}}function Ve(n,o){if(o==="executePlan"&&n&&typeof n==="object"&&typeof n.executedSteps==="number"&&typeof n.totalSteps==="number"){if(console.error(`Executed ${n.executedSteps} of ${n.totalSteps} steps`),n.failedStep)console.error(`Failed at step ${n.failedStep.stepIndex+1}: ${n.failedStep.tool}`),console.error(`Step error: ${n.failedStep.error}`)}}async function sn(n,o,s=console){try{if(n.length===0){T(),Y(s);return}if(n[0]==="help"||n[0]==="--help"||n[0]==="-h"){if(T(),n.length>1)Ge(n[1],s);else Y(s);return}let{toolName:a,sessionUuid:l,params:c}=Ae(n);if(l)if(Hr(a))e.debug(`Ignoring session UUID for acquisition tool ${a}: it mints its own`);else c.sessionUuid=l,e.debug(`Using session UUID: ${l}`);if(a==="doctor")return await Be(c);e.debug(`Executing tool via daemon: ${a}`);let d=await Ne(a,c,o);qe(d,a)}catch(a){if(a instanceof t)e.error(`CLI Error: ${a.message}`),console.error(`Error: ${a.message}`);else e.error(`Unexpected CLI Error: ${a}`),console.error(`Unexpected error: ${a}`);process.exit(1)}}function Y(n){let o=F.getAllTools(),s=zs();n.log(`
|
|
15
|
+
AutoMobile CLI - Android Device Automation
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
bunx ${s} --cli [--session-uuid <uuid>] <tool-name> [--param value ...]
|
|
19
|
+
bunx ${s} --cli help [tool-name]
|
|
20
|
+
bunx ${s} --ios-templates build --runtime <identifier> --device-type <identifier>
|
|
21
|
+
bunx ${s} --ios-templates clean (--all | --stale | --runtime <identifier> [--device-type <identifier>]) [--force]
|
|
22
|
+
|
|
23
|
+
Examples:
|
|
24
|
+
bunx ${s} --cli listDeviceImages
|
|
25
|
+
bunx ${s} --cli observe
|
|
26
|
+
bunx ${s} --cli tapOn --selector '{"text":"Submit"}'
|
|
27
|
+
bunx ${s} --cli getAndroid --avd-name "pixel_7_api_34"
|
|
28
|
+
bunx ${s} --cli getApple --udid "SIMULATOR-UDID"
|
|
29
|
+
bunx ${s} --cli --session-uuid abc-123-uuid observe
|
|
30
|
+
bunx ${s} --cli --session-uuid $SESSION_UUID tapOn --selector '{"text":"Submit"}'
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
help [tool-name] Show help for a specific tool
|
|
34
|
+
--session-uuid <uuid> Associate tool execution with a session (optional).
|
|
35
|
+
The CLI omits it for acquisition tools
|
|
36
|
+
(${LI.join(", ")}), which mint
|
|
37
|
+
their own session. For other tools, an undeclared
|
|
38
|
+
sessionUuid is removed before strict validation.
|
|
39
|
+
|
|
40
|
+
Parameters:
|
|
41
|
+
Parameters are passed as --key value pairs
|
|
42
|
+
Values are converted using the tool's declared parameter type
|
|
43
|
+
Strings: --text 12345 stays the string "12345"
|
|
44
|
+
Boolean values: --flag true or --flag false
|
|
45
|
+
Numbers: --count 5
|
|
46
|
+
Objects: --options '{"key": "value"}'
|
|
47
|
+
Unknown tools or parameters fall back to JSON-if-possible, otherwise string
|
|
48
|
+
|
|
49
|
+
Session-based Execution:
|
|
50
|
+
When using --session-uuid, the tool will be executed on the device assigned to that session.
|
|
51
|
+
This allows multiple tool calls to target the same device in parallel.
|
|
52
|
+
A session acquired or used from the CLI is held on a wall-clock idle timeout
|
|
53
|
+
(${xe(kB)} by default; override with
|
|
54
|
+
AUTOMOBILE_CLI_SESSION_IDLE_TIMEOUT_MS) rather than the
|
|
55
|
+
heartbeat contract a long-running MCP connection keeps, so it survives the gap
|
|
56
|
+
between one-shot invocations. Every control call refreshes it; reads do not.
|
|
57
|
+
|
|
58
|
+
Device ownership:
|
|
59
|
+
A device a session holds takes control calls only from that session. A control
|
|
60
|
+
call without --session-uuid (or with another session's) on a held device is
|
|
61
|
+
refused with code device_owned_by_other_session. Pass the sessionUuid that
|
|
62
|
+
getAndroid, getApple or startDevice returned, or wait for the holder to release
|
|
63
|
+
the device. Reads need no session and are allowed on any device: observe, hitTest,
|
|
64
|
+
identifyInteractions, listApps, getDeviceState, a read-only sqlQuery, and the read
|
|
65
|
+
forms of keyboard, clipboard, displayConfig, accessibility and prototype. A read
|
|
66
|
+
never counts as use. killDevice and deleteDevice also accept --force true to stop
|
|
67
|
+
a held device.
|
|
68
|
+
`);let a=new Map,l=["setActiveDevice","listDevices","listDeviceImages","getAndroid","getApple","killDevice","checkRunningDevices"],c=["changeLocalization"];o.forEach((d)=>{let u="General";if(c.includes(d.name))u="System Configuration";else if(l.includes(d.name))u="Device Management";else if(d.name.includes("App")||d.name.includes("app"))u="App Management";else if(d.name.startsWith("assert"))u="Assertions";else if(d.name.includes("observe"))u="Observation";else if(d.name.includes("Plan")||d.name.includes("plan"))u="Plan Management";else u="Interactions";if(!a.has(u))a.set(u,[]);a.get(u).push(d)}),n.log(`
|
|
69
|
+
Available Tools:`),n.log("================"),a.forEach((d,u)=>{n.log(`
|
|
70
|
+
${u}:`),d.forEach((f)=>{n.log(` ${f.name.padEnd(25)} - ${f.description}`)})}),n.log(`
|
|
71
|
+
Total: ${o.length} tools available`),n.log(`
|
|
72
|
+
Use 'bunx ${s} --cli help <tool-name>' for detailed information about a specific tool.`)}function Ge(n,o){let s=zs(),a=F.getTool(n);if(!a){o.error(`Unknown tool: ${n}`),o.log(`
|
|
73
|
+
Use 'bunx ${s} --cli help' to see available tools.`);return}if(o.log(`
|
|
74
|
+
Tool: ${a.name}`),o.log("=".repeat(a.name.length+6)),o.log(`Description: ${a.description}`),a.supportsProgress)o.log("Supports: Progress notifications");o.log(`
|
|
75
|
+
Parameters:`),o.log(` Pass objects and arrays as JSON, e.g. --selector '{"text":"Submit"}'.`);try{let l=ze(a.schema);if(l)Object.entries(l).forEach(([c,d])=>{let u=Ye(d);if(o.log(` --${c} ${u.isOptional?"(optional)":"(required)"}`),o.log(` Type: ${u.typeName}`),u.description)o.log(` Description: ${u.description}`)});else o.log(" No parameters required")}catch(l){e.debug(`CLI parameter schema help unavailable: ${r(l)}`),o.log(" Could not parse parameter schema")}o.log(`
|
|
76
|
+
Example usage:`),o.log(` bunx ${s} --cli ${n} [parameters...]`)}function ze(n){let o=n?._def;if(!o)return;if(o.shape)return o.shape;if(o.type==="pipe"&&o.out?._def?.shape)return o.out._def.shape;return}function Ye(n){let o=Ze(n),s=o?n?._def?.innerType??n:n,a=s?._def?.typeName??s?._def?.type??"unknown",l=String(a).replace(/^Zod/,"").toLowerCase(),c=["union","intersection","object","record","array","enum","literal","nullable"].includes(l)?S(gS(s,{io:"input"})):l;return{isOptional:o,typeName:c,description:Ke(n,s)}}function Ze(n){return typeof n?.isOptional==="function"?n.isOptional():n?._def?.typeName==="ZodOptional"}function Ke(n,o){return n?.description??o?.description??o?._def?.description}function S(n){if(n.not&&Object.keys(n.not).length===0)return"never";if(n.allOf)return n.allOf.map((s)=>"("+S(s)+")").join(" & ");let o=n.anyOf??n.oneOf;if(o)return o.map((s)=>S(s)).join(" | ");if("const"in n)return JSON.stringify(n.const);if(n.enum)return n.enum.map((s)=>JSON.stringify(s)).join(" | ");if(n.type==="object")return Xe(n);if(n.type==="array")return"("+S(n.items??{})+")[] (JSON)";return n.type??"any"}function Xe(n){let o=Object.entries(n.properties??{}).map(([s,a])=>JSON.stringify(s)+(n.required?.includes(s)?"":"?")+": "+S(a));if(n.additionalProperties){let s=n.additionalProperties===!0?"any":S(n.additionalProperties);o.push("[key: string]: "+s)}return"JSON { "+o.join(", ")+" }"}export{rn as cliCommandSkipsServerBootstrap,sn as runCliCommand};
|
|
77
|
+
|
|
78
|
+
//# debugId=080445F42826ACA664756E2164756E21
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{
|
|
3
|
-
`).slice(0,3).join(" \u2190 "),i="cause"in n&&n.cause!==void 0?
|
|
2
|
+
import{Kl}from"./chunk-j69g8b50.js";function im(n){if(n instanceof Error){let e=[n.name,n.message].filter(Boolean).join(": "),o=n.stack?.split(`
|
|
3
|
+
`).slice(0,3).join(" \u2190 "),i="cause"in n&&n.cause!==void 0?im(n.cause):"";return[e||"Error",o,i?`cause=${i}`:""].filter(Boolean).join(" | ")}if(n===null||n===void 0)return String(n);if(typeof n==="object"){if(Object.keys(n).length===0)return`${Object.prototype.toString.call(n)} (no enumerable keys)`;return Kl(()=>JSON.stringify(n),()=>Object.prototype.toString.call(n))}return String(n)}function r(n){return Kl(()=>{if(n instanceof Error)return n.message;return String(n)},()=>Kl(()=>Object.prototype.toString.call(n),()=>"Unknown error"))}class t extends Error{constructor(n,e){super(n,e);let o=e?.containerFailure??(e?.cause instanceof t?e.cause.containerFailure:void 0);if(o)this.containerFailure=o}}function u(n,e){if(n instanceof t)return n;let o=r(n);return new t(`${e}: ${o}`,{cause:n})}function Rt(n,e){return new t(`${e} is not supported on platform '${n}'. Supported platforms: android, ios.`)}export{im,r,t,u,Rt};
|
|
4
4
|
|
|
5
|
-
//# debugId=
|
|
5
|
+
//# debugId=41BED146C6790E8864756E2164756E21
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{vce,eG,tG,rG}from"./chunk-kd9vfaxh.js";import"./chunk-r54cxxze.js";import"./chunk-gadtna7s.js";import"./chunk-jvstjnqm.js";import"./chunk-xezekwwn.js";import"./chunk-z8tvs8nk.js";import"./chunk-xn9m3xc2.js";import"./chunk-6hrj3jt6.js";import"./chunk-c27yv1dx.js";import"./chunk-cqhw4yr6.js";import"./chunk-vdqag3fj.js";import"./chunk-e0870khr.js";import"./chunk-4vxeq0vd.js";import"./chunk-9xgnrv5w.js";import"./chunk-cb1ga9rd.js";import"./chunk-sfqe223f.js";import"./chunk-r6pvhj33.js";import"./chunk-w5yypt53.js";import"./chunk-aewdveet.js";import"./chunk-r0vp315h.js";import"./chunk-5wk1t46v.js";export{vce as createDirectModeAppearanceDeviceSource,eG as getAppearanceSocketPath,tG as startAppearanceSocketServer,rG as stopAppearanceSocketServer};
|
|
3
|
+
|
|
4
|
+
//# debugId=184C1E7D51901F5964756E2164756E21
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{e}from"./chunk-
|
|
2
|
+
import{e}from"./chunk-r0vp315h.js";import"./chunk-5wk1t46v.js";class i{inner;log;stoppedReason;answersOnlyReason;receivedRequestIds=new Set;pendingAnswerWrites=0;messageCallback;answerWait;constructor(s,n=(r)=>e.debug(r)){this.inner=s;this.log=n}stopSending(s){this.stoppedReason??=s,this.answerWait?.resolve()}answerReceivedThenStop(s){if(!this.answerWait)this.answerWait=Promise.withResolvers(),this.answersOnlyReason=s,this.stopIfAnswered();return this.answerWait.promise}stopIfAnswered(){if(this.stoppedReason!==void 0)this.answerWait?.resolve();else if(this.answersOnlyReason!==void 0&&this.receivedRequestIds.size===0&&this.pendingAnswerWrites===0)this.stopSending(this.answersOnlyReason)}async send(s,n){let r=!("method"in s)&&"id"in s?s.id:void 0,t=this.stoppedReason??(this.answersOnlyReason!==void 0&&(r===void 0||!this.receivedRequestIds.has(r))?this.answersOnlyReason:void 0);if(t!==void 0){this.log(`[OutputGatedTransport] Dropped ${"method"in s?s.method:"response"}: ${t}`);return}if(r===void 0)return this.inner.send(s,n);this.pendingAnswerWrites++;try{await this.inner.send(s,n)}finally{this.receivedRequestIds.delete(r),this.pendingAnswerWrites--,this.stopIfAnswered()}}start(){return this.inner.start()}close(){return this.inner.close()}get sessionId(){return this.inner.sessionId}setProtocolVersion(s){this.inner.setProtocolVersion?.(s)}get onmessage(){return this.messageCallback}set onmessage(s){this.messageCallback=s,this.inner.onmessage=(n,r)=>{if("method"in n&&"id"in n)this.receivedRequestIds.add(n.id);else if("method"in n&&n.method==="notifications/cancelled"){let t=n.params?.requestId;if(typeof t==="string"||typeof t==="number")this.receivedRequestIds.delete(t),this.stopIfAnswered()}s?.(n,r)}}get onclose(){return this.inner.onclose}set onclose(s){this.inner.onclose=s}get onerror(){return this.inner.onerror}set onerror(s){this.inner.onerror=s}}export{i as OutputGatedTransport};
|
|
3
3
|
|
|
4
4
|
//# debugId=F996DBF661FB7D4564756E2164756E21
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import{Rce,cv,W4}from"./chunk-8nj68t1v.js";import"./chunk-aewdveet.js";import"./chunk-r0vp315h.js";import"./chunk-5wk1t46v.js";export{Rce as createTemplateMaintenance,cv as getDefaultSimulatorCreationService,W4 as stopTemplateBuilds};
|
|
3
|
+
|
|
4
|
+
//# debugId=C26C85BD92DE286664756E2164756E21
|