agent-device 0.20.7 → 0.20.8
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/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.apk → agent-device-android-ime-helper-0.20.8.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.8.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.manifest.json → agent-device-android-ime-helper-0.20.8.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.apk → agent-device-android-snapshot-helper-0.20.8.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.8.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.manifest.json → agent-device-android-snapshot-helper-0.20.8.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +5 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +4 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +7 -7
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/apps.js +5 -5
- package/dist/src/auth-session.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/client-metro.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/debug-symbols.js +3 -3
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device-ready.js +1 -0
- package/dist/src/dispatch.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/handler-utils.js +1 -0
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -0
- package/dist/src/helper.js +1 -1
- package/dist/src/host-process.js +3 -2
- package/dist/src/ime-lifecycle.js +5 -5
- package/dist/src/index.d.ts +21 -21
- package/dist/src/input-actions.js +4 -4
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact.js +1 -1
- package/dist/src/interaction-runtime.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction-touch-reference-frame.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +1 -1
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +7 -29
- package/dist/src/inventory2.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/output-path.js +1 -0
- package/dist/src/owner-identity.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-network-web-transport.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-output-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -0
- package/dist/src/platform-runtime-toolchain-host.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/prepare-kind.js +13 -13
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -0
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-telemetry.js +1 -0
- package/dist/src/registry.js +4 -4
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay.js +2 -2
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +3 -3
- package/dist/src/runtime3.js +3 -3
- package/dist/src/runtime4.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +5 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +10 -10
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-session.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +2 -2
- package/dist/src/src3.js +1 -1
- package/dist/src/text-surface.js +1 -1
- package/dist/src/tool-provider.js +3 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -1
- package/dist/src/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +23 -0
- package/dist/src/web.js +1 -1
- package/package.json +2 -4
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +0 -1
- package/dist/src/context.js +0 -1
- package/dist/src/provider.js +0 -1
- package/dist/src/runner-client.js +0 -1
- package/dist/src/runner-provider.js +0 -1
- package/skills/agent-device/SKILL.md +0 -20
- package/skills/dogfood/SKILL.md +0 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./png-worker-contract.js";import{_ as t,v as n}from"./sdk-contracts.js";import{t as r}from"./version.js";import{Wn as i}from"./sdk-batch-runner.js";import{c as a,l as o}from"./sdk-device.js";import{A as s,m as c,x as l}from"./sdk-android-adb.js";import{c as u,n as d,r as f,s as p}from"./host-process.js";import{a as ee,i as m,n as h,o as te,t as g}from"./boot-diagnostics.js";import{n as _}from"./entities.js";import{t as v}from"./parser.js";import{t as ne}from"./process-lock.js";import{A as re,D as ie,E as ae,F as oe,L as se,N as ce,O as le,S as ue,T as de,V as fe,b as pe,j as me,k as he,t as ge,w as _e,x as ve,y as ye}from"./physical-device-control.js";import{a as be,i as y,n as b}from"./tool-provider.js";import{t as xe}from"./plist-xml.js";import{i as Se,s as Ce}from"./runner-lease.js";import x from"node:path";import we from"node:crypto";import{AsyncLocalStorage as Te}from"node:async_hooks";import S from"node:fs";import C from"node:os";import Ee from"node:net";import De from"node:http";const w=new Set,T=new Map,Oe=`request_canceled`,ke=`request canceled`;function Ae(e,t){if(typeof e==`string`&&e.length>0)return e;let n=(typeof t==`string`?t:typeof t==`number`&&Number.isFinite(t)?String(t):`generated`).trim().replace(/[^a-zA-Z0-9_-]/g,`_`).slice(0,32)||`generated`,r=Math.random().toString(36).slice(2,10);return`req:${n}:${process.pid}:${Date.now()}:${r}`}const je=5e4,Me=1e4;function Ne(e){if(e.size<=je)return;let t=0;for(let n of e.keys()){if(t>=Me)break;e.delete(n),t++}}function Pe(e){if(e.size<=je)return;let t=0;for(let n of e){if(t>=Me)break;e.delete(n),t++}}function Fe(e){if(!e)return;if(T.has(e))throw new t(`INVALID_ARGS`,`Request ID is already in flight: ${e}`,{requestId:e,reason:`duplicate_request_id`});Ne(T);let n=new AbortController;return T.set(e,n),w.has(e)&&n.abort(),{requestId:e,controller:n}}function Ie(e){e&&(Pe(w),w.add(e),T.get(e)?.abort())}function Le(e,t){e&&(t&&(t.requestId!==e||T.get(e)!==t.controller)||(w.delete(e),T.delete(e)))}function Re(e){e&&Le(e.requestId,e)}function E(e){return e?w.has(e):!1}function ze(e){if(e)return T.get(e)?.signal}function D(){return new t(`COMMAND_FAILED`,ke,{reason:Oe,hint:`The request was canceled intentionally (explicit cancel or client disconnect) — no retry is needed unless the cancellation was unintended.`})}function Be(e){if(E(e))throw D()}function O(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`?!1:e.details?.reason===Oe?!0:e.message===ke}const Ve=new Te;async function He(e,t){return await Ve.run(e,t)}function Ue(e){Ve.getStore()?.(e)}const We=new Te;async function Ge(e,t,n){let r=We.getStore()??[];if(r.some(n=>n.locks===e&&n.key===t))return await n();let i=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>We.run([...r,{locks:e,key:t}],n));return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)})}const k=new Map;function Ke(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return A(e,t,null,!1);let o=ge(e);if(o.backend===`xctest`||!r)return Je(e,t);if(!a){let r=Ye(e.id);if(r)return A(e,t,r,!0);if(n!==void 0)return A(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&Xe(e.id,s),A(e,t,s,!1)}}}function qe(e){k.delete(e)}function Je(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function A(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function Ye(e){let t=k.get(e);return t?t.expiresAt<=Date.now()?(k.delete(e),null):t.ip:null}function Xe(e,t){k.set(e,{ip:t,expiresAt:Date.now()+3e4})}const Ze="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function Qe(e){let t=ze(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}const $e=[{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:`usbmux-device-unattached`},verdicts:{connectRetry:!1}},{reason:`flagged_retriable`,match:{code:`COMMAND_FAILED`,details:`retriable`},verdicts:{retryable:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`xcodebuild exited early`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`runner did not accept connection`]},verdicts:{retryable:!0,restartBeforeSend:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:`RUNNER_WEDGED`},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}}];function et(e,t){return t.code!==void 0&&e.code!==t.code||!tt(e,t.details)?!1:nt(e,t.messageIncludesAll)}function tt(e,t){return t===void 0?!0:t===`retriable`?e.details?.retriable===!0:M(e)}function nt(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function j(e,n){if(e instanceof t){for(let t of $e)if(t.verdicts[n]!==void 0&&et(e,t.match))return t.verdicts[n]}}function rt(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`?!1:j(e,`retryable`)??!1}function M(e){return!(e instanceof t)||e.code!==`DEVICE_NOT_FOUND`?!1:e.details?.usbmuxDeviceAttached===!1}function N(e){return j(e,`connectRetry`)??!0}function it(e){return j(e,`sessionFatalReason`)}function at(e){return(j(e,`restartBeforeSend`)??!1)&&N(e)}function ot(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?g(a):`${g(a)} ${Ze}`}function st(e){let{port:n,endpoints:r,logPath:i,lastError:a}=e,o=`Runner did not accept connection`;return new t(`COMMAND_FAILED`,o,{port:n,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:h({error:a,message:o,context:{platform:`ios`,phase:`connect`}}),hint:g(`IOS_RUNNER_CONNECT_TIMEOUT`)})}async function ct(e){let{session:n,port:r,logPath:i}=e,a=await n.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=h({message:o,stdout:a.stdout,stderr:a.stderr,context:{platform:`ios`,phase:`connect`}});return new t(`COMMAND_FAILED`,o,{port:r,logPath:i,xcodebuild:{exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr},reason:s,hint:ot(o,a.stdout,a.stderr,s)})}function lt(e){let t=e.details?JSON.stringify(e.details):``,n=`${e.message}\n${t}`.toLowerCase();if(n.includes(`failed registering bundle identifier`)||n.includes(`app identifier`)&&n.includes(`not available`))return`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`;if(n.includes(`requires a development team`))return`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`;if(n.includes(`no profiles for`)||n.includes(`provisioning profile`))return`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`;if(n.includes(`code signing`))return`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}function ut(e){return lt(e)??Ze}function dt(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:ft()}}function ft(){return`runner-${we.randomUUID()}`}function pt(e){if(E(e))throw D()}const mt=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function ht(e,t,n,r,i){let a=m.fromTimeoutMs(r);return await _t(e,t,await gt(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function gt(e,n,r,i){let a=await vt(e,r,i);try{await yt(a,1,xt(`ListDevices`));let e=St((await bt(a,r,i)).payload.toString(`utf8`),n);if(e!==void 0)return e;throw new t(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:n,backend:`xctest`,usbmuxDeviceAttached:!1,hint:mt})}finally{a.destroy()}}async function _t(e,t,n,r,i,a){let o=await vt(e,i,a);try{await yt(o,2,xt(`Connect`,{DeviceID:n,PortNumber:Et(r)}));let e=wt((await bt(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw Tt({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function vt(e,n,r){if(Dt(n,`connect to usbmuxd`),r?.aborted)throw D();return await new Promise((i,a)=>{let o=Ee.createConnection(e),s=!1,c=setTimeout(()=>{f(new t(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:n}))},n),l=()=>f(),u=e=>f(e),d=()=>f(D()),f=e=>{s||(s=!0,clearTimeout(c),o.off(`connect`,l),o.off(`error`,u),r?.removeEventListener(`abort`,d),e?(o.destroy(),a(e)):i(o))};o.once(`connect`,l),o.once(`error`,u),r?.addEventListener(`abort`,d,{once:!0})})}async function yt(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function bt(e,n,r){if(Dt(n,`read usbmuxd response`),r?.aborted)throw D();return await new Promise((i,a)=>{let o=Buffer.alloc(0),s=!1,c=setTimeout(()=>p(new t(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:n})),n),l=e=>{if(o=Buffer.concat([o,e]),o.length<16)return;let n=o.readUInt32LE(0);if(n<16||n>4194304){p(new t(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}o.length<n||p(void 0,{payload:o.subarray(16,n)})},u=e=>p(e),d=()=>p(new t(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),f=()=>p(D()),p=(t,n)=>{s||(s=!0,clearTimeout(c),e.off(`data`,l),e.off(`error`,u),e.off(`close`,d),r?.removeEventListener(`abort`,f),e.pause(),t?a(t):i(n))};e.on(`data`,l),e.once(`error`,u),e.once(`close`,d),r?.addEventListener(`abort`,f,{once:!0}),e.resume()})}function xt(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${_(e)}</key><integer>${t}</integer>`:`<key>${_(e)}</key><string>${_(t)}</string>`).join(``)}</dict></plist>`}function St(e,t){for(let n of F(v(e))){let e=Ct(n);if(e?.udid===t)return e.id}}function Ct(e){if(e.name!==`dict`)return;let t=P(e,`Properties`);if(t?.name!==`dict`)return;let n=P(t,`SerialNumber`)?.text,r=Number(P(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function wt(e,t){for(let n of F(v(e))){if(n.name!==`dict`)continue;let e=P(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function P(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*F(e){for(let t of e)yield t,yield*F(t.children)}function Tt(e){let{result:n,udid:r,deviceId:i,port:a}=e;return n===2?new t(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:n,hint:mt}):n===3?new t(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:n,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new t(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:n,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Et(e){return(e&255)<<8|e>>>8&255}function Dt(e,n){if(!(e>0))throw new t(`COMMAND_FAILED`,`No time remaining to ${n}`,{backend:`xctest`,timeoutMs:e})}function Ot(e){return{postCommand:async(t,n,r,i,a)=>{let o=m.fromTimeoutMs(i),s=await ht(e,t,n,o.remainingMs(),a);try{return await At(s,r,o.remainingMs(),a)}catch(e){throw s.destroy(),e}}}}const kt=Ot(`/var/run/usbmuxd`);async function At(e,n,r,i){if(Nt(r),i?.aborted)throw D();let a=Buffer.from(JSON.stringify(n),`utf8`),o=AbortSignal.timeout(r),s=i?AbortSignal.any([i,o]):o,c=new De.Agent;c.createConnection=(t,n)=>(n?.(null,e),e);try{let t=await jt(c,e,a,s);return new Response((await Mt(t)).toString(`utf8`),{status:t.statusCode??500})}catch(e){throw i?.aborted?D():o.aborted?new t(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:r}):e}finally{c.destroy(),e.destroy()}}async function jt(e,t,n,r){return await new Promise((i,a)=>{let o=De.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function Mt(e){let n=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new t(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);n.push(e)}return Buffer.concat(n)}function Nt(e){if(!(e>0))throw new t(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}async function Pt(){return await new Promise((e,n)=>{let r=Ee.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>n(new t(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,n)})}function I(e,t,n,r){t&&Ft(t,e),n&&Ft(n,e),r&&process.stderr.write(e)}const L=new Map;function Ft(e,t){let n=(L.get(e)??Promise.resolve()).catch(()=>{}).then(async()=>{await S.promises.mkdir(x.dirname(e),{recursive:!0}),await S.promises.appendFile(e,t)}).catch(()=>{}).finally(()=>{L.get(e)===n&&L.delete(e)});L.set(e,n)}function R(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}const It=45e3,Lt=45e3,Rt=2e4;async function zt(e,t,n,r,i=It,a,o){let s=m.fromTimeoutMs(i),{resolveRoute:c,markUsbmuxUnattached:l}=Ke(e,t),u=await c(s.remainingMs()),d=null,f=Math.max(1,Math.ceil(i/250));try{return await te(async({deadline:s})=>{let f=await Bt({device:e,port:t,command:n,timeoutMs:i,logPath:r,session:a,route:u,resolveRoute:c,markUsbmuxUnattached:l,signal:o,attemptDeadline:s,setRoute:e=>{u=e},setLastError:e=>{d=e}});if(f)return f;throw Gt({port:t,endpoints:u.endpoints,lastError:d,signal:o})},{maxAttempts:f,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:N},{deadline:s,phase:`ios_runner_connect`,signal:o})}catch(e){if(o?.aborted||O(e))throw D();if(M(e))throw e;d||=e}if(o?.aborted)throw D();if(e.kind===`simulator`){let i=s.remainingMs();if(i<=0)throw st({port:t,endpoints:u.endpoints,logPath:r,lastError:d});let a=await $t(e,t,n,i,o);return new Response(a.body,{status:a.status})}throw st({port:t,endpoints:u.endpoints,logPath:r,lastError:d})}async function Bt(e){await Vt(e);let t=await Ht(e);return t.response?t.response:await Ut(e)||await Wt(e,t.usedCachedTunnelIp)}async function Vt(e){if(e.attemptDeadline?.isExpired())throw new t(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await ct({session:e.session,port:e.port,logPath:e.logPath})}async function Ht(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await Yt(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&qe(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Ut(e){return e.device.kind!==`simulator`||!e.session?.ready?null:await Zt(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Wt(e,t){if(e.device.kind!==`device`||!t)return null;qe(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await Yt(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function Gt(e){if(e.signal?.aborted)throw D();return new t(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,endpoints:e.endpoints,lastError:e.lastError?String(e.lastError):void 0})}async function Kt(e,n,r,i=Lt,a){if(a?.aborted)throw D();let o=m.fromTimeoutMs(i),s=Ke(e,n),c=await s.resolveRoute(o.remainingMs());if(c.kind===`usbmux`)try{return await qt(e,n,r,o,a)}catch(t){if(!Jt(e,t))throw t;s.markUsbmuxUnattached(),c=await s.resolveRoute(o.remainingMs())}let l=o.remainingMs();if(l<=0)throw new t(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:i});let u=c.endpoints[0];if(!u)throw new t(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:n,endpoints:c.endpoints});return await Qt(u,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)},l,a)}async function qt(e,n,r,i,a){let o=i.remainingMs();if(o<=0)throw new t(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:n,timeoutMs:o});return await kt.postCommand(e.id,n,r,o,a)}function Jt(e,t){return M(t)?ge(e).backend!==`xctest`:!1}async function Yt(e,n,r){if(n.kind===`network`)return await Xt(n.endpoints,r);let i=n.endpoints[0];try{let n=r.attemptDeadline?.remainingMs()??r.timeoutMs;if(n<=0)throw new t(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:r.port,timeoutMs:r.timeoutMs});return await kt.postCommand(e.id,r.port,r.command,Math.min(Rt,n),r.signal)}catch(t){if(r.signal?.aborted||O(t))throw D();if(M(t)){if(!Jt(e,t))throw t;return r.onUsbmuxUnattached?.(),null}return r.onError(i,t),null}}async function Xt(e,n){let{command:r,port:i,timeoutMs:a,signal:o,attemptDeadline:s,onError:c}=n;for(let n of e)try{let e=s?.remainingMs()??a;if(e<=0)throw new t(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:i,timeoutMs:a});return await Qt(n,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)},Math.min(Rt,e),o)}catch(e){if(o?.aborted||O(e))throw D();c(n,e)}return null}async function Zt(e,t,n,r){let{signal:i,attemptDeadline:a,onError:o}=r,s=a?.remainingMs()??45e3;if(s<=0)return null;try{let r=await $t(e,t,n,s,i);return new Response(r.body,{status:r.status})}catch(e){if(i?.aborted||O(e))throw D();return o(e),null}}async function Qt(e,t,n,r){let i=AbortSignal.timeout(n),a=r?AbortSignal.any([r,i]):i;return await fetch(e,{...t,signal:a})}async function $t(e,t,n,r,i){let a=JSON.stringify(n);return{status:200,body:c(await be(se(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]),{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=h({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:g(n)}}).stdout}}const en=`XCTestDevices`,tn=`.agent-device-backup`,nn=`.agent-device-xctestdevices-backup-`;function rn(e=C.homedir()){return x.join(e,`Library`,`Developer`,`XCTestDevices`)}function an(e=C.homedir()){return x.join(e,`.agent-device`,`xctest-device-set.lock`)}function on(e=rn()){return`${e}${tn}`}async function sn(e,n={}){if(!a(e)||e.kind!==`simulator`)return null;let r=fe(e.simulatorSetPath);if(!r)return null;let i=x.resolve(r),o=x.resolve(n.xctestDeviceSetPath??rn()),s=x.resolve(n.backupPath??on(o)),c=x.resolve(n.lockDirPath??an()),l=n.ownerStartTime??p(process.pid),u=await fn({lockDirPath:c,owner:{pid:n.ownerPid??process.pid,startTime:l,acquiredAtMs:n.nowMs??Date.now()}});try{if(z({xctestDeviceSetPath:o,backupPath:s}),dn(i,o))return await u(),null;S.mkdirSync(i,{recursive:!0}),S.existsSync(o)&&S.renameSync(o,s),ln({requestedSetPath:i,xctestDeviceSetPath:o})}catch(e){throw z({xctestDeviceSetPath:o,backupPath:s}),await u(),new t(`COMMAND_FAILED`,`Failed to redirect XCTest device set path`,{requestedSetPath:i,xctestDeviceSetPath:o,backupPath:s,error:String(e)})}let d=!1;return{release:async()=>{if(!d){d=!0;try{z({xctestDeviceSetPath:o,backupPath:s})}finally{await u()}}}}}function z(e){let{xctestDeviceSetPath:t,backupPath:n}=e,r=[n,...cn(n)],i=r.find(e=>S.existsSync(e)),a=un(t);if(i){if(a&&B(t),!S.existsSync(t))S.mkdirSync(x.dirname(t),{recursive:!0}),S.renameSync(i,t);else if(a)i===n?S.rmSync(n,{recursive:!0,force:!0}):S.rmSync(i,{recursive:!0,force:!0});else{s({level:`warn`,phase:`ios_runner_xctest_device_set_restore_collision`,data:{xctestDeviceSetPath:t,activeBackupPath:i}});return}for(let e of r)e!==i&&S.existsSync(e)&&S.rmSync(e,{recursive:!0,force:!0});return}a&&(s({level:`warn`,phase:`ios_runner_xctest_device_set_orphaned_symlink`,data:{xctestDeviceSetPath:t}}),B(t))}function cn(e){let t=x.dirname(e),n=x.basename(e).replace(tn,``),r=n===en?nn:`${n}${nn}`;try{return S.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>x.join(t,e))}catch{return[]}}function ln(e){let{requestedSetPath:t,xctestDeviceSetPath:n}=e,r=x.dirname(n),i=x.join(r,`${en}.agent-device-link-${process.pid}-${Date.now()}`);S.mkdirSync(r,{recursive:!0});try{S.symlinkSync(t,i,`dir`),S.renameSync(i,n)}catch(e){throw B(i),e}}function un(e){return S.lstatSync(e,{throwIfNoEntry:!1})?.isSymbolicLink()??!1}function B(e){un(e)&&S.unlinkSync(e)}function dn(e,t){if(x.resolve(e)===x.resolve(t))return!0;try{return S.realpathSync.native(e)===S.realpathSync.native(t)}catch{return!1}}async function fn(e){return await ne({lockDirPath:e.lockDirPath,owner:e.owner,timeoutMs:e.timeoutMs??3e4,pollMs:e.pollMs??100,ownerGraceMs:5e3,description:e.description??`XCTest device set lock`})}const V=new Set;function pn(e){return x.join(e,pe)}function mn(e,t){S.mkdirSync(e,{recursive:!0}),S.writeFileSync(pn(e),`${JSON.stringify(t,null,2)}\n`)}async function hn(e,t){if(e.cache===`external`){G(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}V.add(e.derived);let n=await gn(e.derived);try{G(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),W(e.derived),H(e.derived)}finally{await n()}}async function gn(e){return await _n({lockDirPath:vn(e),owner:{pid:process.pid,startTime:p(process.pid),acquiredAtMs:Date.now()},description:`iOS runner cache lock`})}async function _n(e){return await ne({lockDirPath:e.lockDirPath,owner:e.owner,timeoutMs:e.timeoutMs??6e5,pollMs:100,ownerGraceMs:5e3,description:e.description??`iOS runner cache lock`})}function vn(e){return x.join(x.dirname(e),`${x.basename(e)}.lock`)}function yn(e,t){!Mn()&&!t&&!V.has(e)||(G(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),W(e),H(e),V.delete(e))}function bn(e,t,n,r){mn(e,Tn(t,n,r))}function H(e){try{if(!S.existsSync(e))return;if(x.basename(e)!==`derived`){S.rmSync(e,{recursive:!0,force:!0});return}for(let t of S.readdirSync(e,{withFileTypes:!0}))Sn(t.name)&&S.rmSync(x.join(e,t.name),{recursive:!0,force:!0})}catch{}}const xn=new Set([pe,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Sn(e){return xn.has(e)}function Cn(e){try{let t=JSON.parse(S.readFileSync(pn(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function wn(e,t){let n=Cn(e);return n?re(ve(n))===re(ve(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`}:{ok:!1,reason:`cache_metadata_missing`}}function Tn(e,t,n){let r=En(t,n);return r?{...e,artifacts:r}:e}function En(e,t){let n=U(e);if(n===null||t.length===0)return null;let r=[];for(let e of t){let t=U(e);if(t===null)return null;r.push({path:e,...t})}return{xctestrunPath:e,xctestrunMtimeMs:n.mtimeMs,xctestrunSize:n.size,productPaths:r}}function Dn(e,t){let n=t?.artifacts;if(!On(n)||!jn(n.xctestrunPath,e)||!An(n.xctestrunPath,{mtimeMs:n.xctestrunMtimeMs,size:n.xctestrunSize}))return null;let r=[];for(let t of n.productPaths){if(!jn(t.path,e)||!An(t.path,t))return null;r.push(t.path)}return{xctestrunPath:n.xctestrunPath,productPaths:r}}function On(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.xctestrunPath==`string`&&Number.isInteger(t.xctestrunMtimeMs)&&Number.isInteger(t.xctestrunSize)&&Array.isArray(t.productPaths)&&t.productPaths.length>0&&t.productPaths.every(kn)}function kn(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.path==`string`&&Number.isInteger(t.mtimeMs)&&Number.isInteger(t.size)}function U(e){try{let t=S.statSync(e);return{mtimeMs:Math.trunc(t.mtimeMs),size:t.size}}catch{return null}}function An(e,t){let n=U(e);return n?.mtimeMs===t.mtimeMs&&n.size===t.size}function jn(e,t){let n=x.relative(x.resolve(t),x.resolve(e));return n!==``&&!n.startsWith(`..`)&&!x.isAbsolute(n)}function Mn(){return ee(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function W(e,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!Nn(e))throw new t(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:e,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${x.join(r(),`.tmp`)}.`})}function Nn(e){let t=x.resolve(r(),`.tmp`),n=x.relative(t,x.resolve(e));return n!==``&&!n.startsWith(`..`)&&!x.isAbsolute(n)}async function Pn(e){let t=wn(e.derived,e.expectedCacheMetadata),n=t.ok?Dn(e.derived,t.metadata):null,r=n?.xctestrunPath??e.findXctestrun(e.derived);if(!r)return{reason:`missing_xctestrun`,xctestrunPath:null};let i=n?.xctestrunPath===r,a=i?`manifest`:`scan`,o=i?n.productPaths:await e.resolveExistingXctestrunProductPaths(r);return o?!e.xctestrunReferencesProjectRoot(r,e.projectRoot)&&!i?{reason:`project_root_mismatch`,xctestrunPath:r,productPaths:o,source:a}:t.ok?{reason:`reuse_ready`,xctestrunPath:r,productPaths:o,source:a}:{reason:t.reason,xctestrunPath:r,productPaths:o,source:a}:{reason:`missing_products`,xctestrunPath:r,productPaths:[],source:a}}function G(e,t,n){s({level:e===`rebuild`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const Fn=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]);async function In(e,r,i){if(!o(e))return;if(r.length===0)throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:i});let a=Array.from(new Set(r)).sort((e,t)=>t.length-e.length);for(let e of a)if(!S.existsSync(e))throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:i});for(let e of a)if(!await Rn(e)){await y(`codesign`,[`--remove-signature`,e],{allowFailure:!0});try{await y(`codesign`,[`--force`,`--sign`,`-`,e])}catch(r){let a=n(r,`COMMAND_FAILED`);throw new t(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:i,error:a.message,details:a.details})}}}function Ln(e){if(!(e instanceof t))return!1;let n=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof n==`string`&&Fn.has(n)}async function Rn(e){return(await y(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const zn=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function Bn(e){let t=await Un(e);if(!t||t.length===0)return null;let n=x.dirname(e),r=new Set,i=Vn(t,n);for(let e of i.testRootPaths){if(!S.existsSync(e))return null;r.add(e)}for(let e of Hn(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Vn(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(x.join(t,e));let o=Xn(e);o&&r.add(x.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function Hn(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>S.existsSync(x.join(e,t)));return n?x.join(n,t):null})}async function Un(e){let t=await b(e);if(t)return Wn(t);if(process.platform===`darwin`)return null;try{return Jn(S.readFileSync(e,`utf8`))}catch{return null}}function Wn(e){let t=new Set;for(let n of[e,...Gn(e),...Kn(e)])for(let e of qn(n))t.add(e);return Array.from(t)}function Gn(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!i(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(i))}return n}function Kn(e){return Object.values(e).filter(e=>i(e)&&`TestBundlePath`in e)}function qn(e){let t=new Set;for(let[n,r]of Object.entries(e))if(zn.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function Jn(e){return Yn(v(e))}function Yn(e){let t=new Set;return xe(e,(e,n)=>{if(zn.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function Xn(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const Zn=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function Qn(e){let t=e.filter(lr);if(t.length===0)return;let n=e.filter(e=>dr(e)&&!ur(e));for(let e of t){let t=cr(e,n);t&&await $n(t,e)}}async function $n(e,t){let n=er(e,t),r=await tr(e,t);(n||r)&&(await ir(t),sr(t))}function er(e,t){let n=!1;for(let r of S.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!or(r.name)||ar(x.join(e,r.name),x.join(t,r.name))&&(n=!0);return n}async function tr(e,t){let n=x.join(e,`Info.plist`),r=x.join(t,`Info.plist`),i=await b(n),a=await b(r);if(!i||!a)return!1;let o=nr(i,a);if(o.length===0)return!1;for(let e of o)await rr(r,e.key,e.value,e.shouldInsert);return!0}function nr(e,t){return Zn.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function rr(e,t,n,r){c(await y(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function ir(e){c(await y(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function ar(e,t){if(S.existsSync(t)){let n=S.readFileSync(e),r=S.readFileSync(t);return n.equals(r)?!1:(S.copyFileSync(e,t),!0)}return S.copyFileSync(e,t),!0}function or(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function sr(e){let t=new Date;S.utimesSync(e,t,t)}function cr(e,t){let n=x.dirname(e);return t.find(e=>x.dirname(e)===n&&x.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>x.dirname(t)===n&&t!==e)??null}function lr(e){return dr(e)&&ur(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function ur(e){return x.basename(e).endsWith(`-Runner.app`)}function dr(e){return x.basename(e).endsWith(`.app`)}const fr={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function pr(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?x.resolve(i):x.dirname(e);S.mkdirSync(a,{recursive:!0});let o=n.replace(/[^a-zA-Z0-9._-]/g,`_`),s=x.join(a,`AgentDeviceRunner.env.${o}.json`),c=x.join(a,`AgentDeviceRunner.env.${o}.xctestrun`),l=await mr(e);return vr(l,e=>gr(e,t)),_r(l),await hr(l,s,c),{xctestrunPath:c,jsonPath:s}}async function mr(e){let n=await y(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(n.exitCode!==0||!n.stdout.trim())throw new t(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:n.stderr});try{let e=JSON.parse(n.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(n){throw new t(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(n)})}}async function hr(e,t,n){S.writeFileSync(t,JSON.stringify(e,null,2)),c(await y(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function gr(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function _r(e){vr(e,e=>Object.assign(e,fr),{requireTestBundlePath:!0})}function vr(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||yr(e.TestTargets,t,n);for(let n of Object.values(e)){let e=br(n,{requireTestBundlePath:!0});e&&t(e)}}function yr(e,t,n){if(Array.isArray(e))for(let r of e){let e=br(r,n);e&&t(e)}}function br(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const xr=new Map,K=new Set;async function Sr(e,t){let n=Cr(t);if(n)return n;let i=r(),a=ue(e,i),o=de(e,a);return await Ge(xr,o,async()=>{let n=await gn(o);try{return await Tr({device:e,options:t,projectRoot:i,expectedCacheMetadata:a,derived:o,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}finally{await n()}})}function Cr(e){let n=e.iosXctestrunFile?.trim();if(!n)return null;let r=x.resolve(n);if(!S.existsSync(r))throw new t(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:r});let i=e.iosXctestDerivedDataPath?.trim(),a=i?x.resolve(i):wr(r);return G(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:r}),{xctestrunPath:r,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function wr(e){let t=we.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return x.join(C.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function Tr(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;yn(a,e.forceRebuild);let o=await Ar({device:t,derived:a,projectRoot:r,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:o.xctestrunPath?`restore-key`:`miss`;return o.reason!==`reuse_ready`&&G(`rebuild`,o.reason,{derived:a,xctestrunPath:o.xctestrunPath}),await Er({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.xctestrunPath&&(W(a),H(a)),await Dr({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function Er(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await Or(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,artifact:`valid`,buildMs:0,xctestrunPathSource:i.source}:null}async function Dr(e){let{device:n,options:r,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=me(i);if(!S.existsSync(l))throw new t(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=Date.now();Ue({type:`command`,status:`progress`,message:`Building Apple runner...`}),await Ir(n,l,o,r);let d=Math.max(0,Date.now()-u),f=jr(o,n);if(!f)throw new t(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let p=await Bn(f);if(!p)throw new t(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:f});return await In(n,p,f),await Qn(p),bn(o,a,f,p),G(`build`,`built_new`,{derived:o,xctestrunPath:f}),{xctestrunPath:f,derived:o,cache:s,artifact:`rebuilt`,buildMs:d,xctestrunPathSource:`build`,reason:c}}async function Or(e,t,n,r){try{return await In(e,r.productPaths,r.xctestrunPath),G(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),bn(t,n,r.xctestrunPath,r.productPaths),r.xctestrunPath}catch(e){if(!Ln(e))throw e;return G(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function kr(e){try{let t=r(),n=ue(e,t);return(await Ar({device:e,derived:de(e,n),projectRoot:t,expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function Ar(e){let{device:t,derived:n,projectRoot:r,expectedCacheMetadata:i}=e;return Pn({derived:n,projectRoot:r,expectedCacheMetadata:i,findXctestrun:e=>jr(e,t),xctestrunReferencesProjectRoot:Fr,resolveExistingXctestrunProductPaths:Bn})}function jr(e,t){let n=Mr(e);return n.length===0?null:(n.sort((e,n)=>Nr(e,n,t)),n[0]?.path??null)}function Mr(e){if(!S.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=S.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=x.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=S.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function Nr(e,t,n){if(n){let r=Pr(t.path,n)-Pr(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function Pr(e,t){let n=0,r=e.toLowerCase();x.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${x.sep}macos${x.sep}`)&&(n-=5e3);let i=oe(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}function Fr(e,t){try{let n=S.readFileSync(e,`utf8`),r=new Set([t]);try{r.add(S.realpathSync(t))}catch{}for(let e of r)if(n.includes(e))return!0;return!1}catch{return!1}}async function Ir(e,n,r,i){let a=_e(process.env),o=he(process.env,e.kind===`device`,e),s=e.kind===`device`?[`-allowProvisioningUpdates`]:[],c=ie(),u=le(),d=await sn(e);try{await l(`xcodebuild`,[`build-for-testing`,`-project`,n,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,ae(e),`1`,`-destination`,ce(e),`-derivedDataPath`,r,...c,...u,...a,...s,...o],{detached:!0,timeoutMs:i.buildTimeoutMs,signal:i.signal,onSpawn:e=>{K.add(e),e.on(`close`,()=>{K.delete(e)})},onStdoutChunk:e=>{I(e,i.logPath,i.traceLogPath,i.verbose)},onStderrChunk:e=>{I(e,i.logPath,i.traceLogPath,i.verbose)}})}catch(e){if(O(e))throw e;let n=e instanceof t?e:new t(`COMMAND_FAILED`,String(e)),r=ut(n);throw new t(`COMMAND_FAILED`,`xcodebuild build-for-testing failed`,{error:n.message,details:n.details,logPath:i.logPath,hint:r})}finally{await d?.release()}}var Lr=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>Rr,abortRunnerSessionsAndPrepProcesses:()=>Hr,cleanupOwnedIosRunnerLease:()=>Vr,disposeRunnerSession:()=>Br,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>q,stopRunnerPrepProcesses:()=>Ur});const Rr=1e3,zr=2e3,q={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Yr,cleanupTempFile:R};async function Br(e,t={}){let n=!1;if(t.graceful!==!1)n=await Wr(e);else if(o(e.device)){await J([e]),await Y(e);return}else await $(e.child.pid,`SIGTERM`);n||(await Gr(e,t.waitTimeoutMs??1e4),Jr(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Y(e)}async function Vr(e){await Se(e,q)}async function Hr(e){let t=Array.from(K),n=e.filter(e=>o(e.device)),r=e.filter(e=>!o(e.device));await Z(r,`SIGINT`),await Q(t,`SIGINT`),await Z(r,`SIGTERM`),await Q(t,`SIGTERM`),await Z(r,`SIGKILL`),await Q(t,`SIGKILL`),await J(n),await Promise.allSettled(e.map(async e=>{await Y(e)}))}async function Ur(){let e=Array.from(K);await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{K.delete(e)}}))}async function Wr(e){try{return await zt(e.device,e.port,dt({command:`shutdown`}),void 0,15e3),!1}catch{return o(e.device)?(await J([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function Gr(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!Jr(e.child.pid)}finally{n&&clearTimeout(n)}}async function J(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await Kr(e,5e3);await Z(t,`SIGTERM`),await Z(await Kr(t,2e3),`SIGKILL`)}async function Kr(e,t){let n=await Promise.all(e.map(async e=>await Gr(e,t)));return e.filter((e,t)=>!n[t])}async function Y(e){await qr(e.device),R(e.xctestrunPath),R(e.jsonPath);try{await e.simulatorSetRedirect?.release()}finally{Ce(e.lease)}}async function qr(e){e.kind===`simulator`&&await Promise.allSettled(ye.map(async t=>{try{await be(se(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:zr})}catch(n){s({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:zr,error:n instanceof Error?n.message:String(n)}})}}))}function Jr(e){return e?X(e)||f(e):!1}function X(e){return e?d(e):!1}async function Z(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&K.delete(e)}))}async function $(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}u([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await y(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Yr(e,t){let n=t?`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${Xr(e)}-${Xr(t)}-`:`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${Xr(e)}-[0-9]`;for(let t of[`TERM`,`KILL`])try{await y(`pkill`,[`-${t}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){s({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:e,signal:t,error:n instanceof Error?n.message:String(n)}})}}function Xr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}export{Re as A,Qe as C,Ge as D,dt as E,O as F,Ie as I,Fe as L,D as M,ze as N,Ue as O,E as P,Ae as R,it as S,N as T,zt as _,X as a,pt as b,Ur as c,pr as d,hn as f,Kt as g,It as h,Br as i,Le as j,He as k,Sr as l,Lt as m,Hr as n,q as o,sn as p,Vr as r,Lr as s,Rr as t,kr as u,Pt as v,at as w,rt as x,I as y,Be as z};
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t,v as n}from"./sdk-contracts.js";import{t as r}from"./version.js";import{Gn as i}from"./sdk-batch-runner.js";import{c as a,l as o}from"./sdk-device.js";import{S as s,h as c,j as l}from"./sdk-android-adb.js";import{c as u,l as d,n as f,r as p}from"./host-process.js";import{a as ee,i as m,n as h,o as te,t as g}from"./boot-diagnostics.js";import{n as _}from"./entities.js";import{t as v}from"./parser.js";import{t as ne}from"./process-lock.js";import{A as re,C as ie,D as ae,E as oe,I as se,M as ce,O as le,P as ue,R as de,S as fe,T as pe,U as me,b as he,j as ge,k as _e,n as ve,x as ye}from"./physical-device-control.js";import{a as be,i as y,n as b}from"./tool-provider.js";import{t as xe}from"./plist-xml.js";import{i as Se,s as Ce}from"./runner-lease.js";import x from"node:path";import we from"node:crypto";import{AsyncLocalStorage as Te}from"node:async_hooks";import S from"node:fs";import C from"node:os";import Ee from"node:net";import De from"node:http";const w=new Set,T=new Map,Oe=`request_canceled`,ke=`request canceled`;function Ae(e,t){if(typeof e==`string`&&e.length>0)return e;let n=(typeof t==`string`?t:typeof t==`number`&&Number.isFinite(t)?String(t):`generated`).trim().replace(/[^a-zA-Z0-9_-]/g,`_`).slice(0,32)||`generated`,r=Math.random().toString(36).slice(2,10);return`req:${n}:${process.pid}:${Date.now()}:${r}`}const je=5e4,Me=1e4;function Ne(e){if(e.size<=je)return;let t=0;for(let n of e.keys()){if(t>=Me)break;e.delete(n),t++}}function Pe(e){if(e.size<=je)return;let t=0;for(let n of e){if(t>=Me)break;e.delete(n),t++}}function Fe(e){if(!e)return;if(T.has(e))throw new t(`INVALID_ARGS`,`Request ID is already in flight: ${e}`,{requestId:e,reason:`duplicate_request_id`});Ne(T);let n=new AbortController;return T.set(e,n),w.has(e)&&n.abort(),{requestId:e,controller:n}}function Ie(e){e&&(Pe(w),w.add(e),T.get(e)?.abort())}function Le(e,t){e&&(t&&(t.requestId!==e||T.get(e)!==t.controller)||(w.delete(e),T.delete(e)))}function Re(e){e&&Le(e.requestId,e)}function E(e){return e?w.has(e):!1}function ze(e){if(e)return T.get(e)?.signal}function D(){return new t(`COMMAND_FAILED`,ke,{reason:Oe,hint:`The request was canceled intentionally (explicit cancel or client disconnect) — no retry is needed unless the cancellation was unintended.`})}function Be(e){if(E(e))throw D()}function O(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`?!1:e.details?.reason===Oe?!0:e.message===ke}const Ve=new Te;async function He(e,t){return await Ve.run(e,t)}function Ue(e){Ve.getStore()?.(e)}const We=new Te;async function Ge(e,t,n){let r=We.getStore()??[];if(r.some(n=>n.locks===e&&n.key===t))return await n();let i=(e.get(t)??Promise.resolve()).catch(()=>{}).then(()=>We.run([...r,{locks:e,key:t}],n));return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)})}const k=new Map;function Ke(e,t){let n,r=!1;return{markUsbmuxUnattached:()=>{r=!0},resolveRoute:async(i,a=!1)=>{if(e.kind!==`device`)return A(e,t,null,!1);let o=ve(e);if(o.backend===`xctest`||!r)return Je(e,t);if(!a){let r=Ye(e.id);if(r)return A(e,t,r,!0);if(n!==void 0)return A(e,t,n,!1)}let{tunnelIp:s}=await o.resolveTunnel(e,i);return n=s,s&&Xe(e.id,s),A(e,t,s,!1)}}}function qe(e){k.delete(e)}function Je(e,t){return{kind:`usbmux`,endpoints:[`usbmux://${e.id}:${t}/command`],cachedTunnelIp:!1}}function A(e,t,n,r){let i=[`http://127.0.0.1:${t}/command`];return e.kind===`device`&&n&&i.unshift(`http://[${n}]:${t}/command`),{kind:`network`,endpoints:i,cachedTunnelIp:r}}function Ye(e){let t=k.get(e);return t?t.expiresAt<=Date.now()?(k.delete(e),null):t.ip:null}function Xe(e,t){k.set(e,{ip:t,expiresAt:Date.now()+3e4})}const Ze="If runner build products look stale or corrupted, run `pnpm clean:xcuitest` in a local checkout, or remove ~/.agent-device/apple-runner/derived, then retry.";function Qe(e){let t=ze(e.requestId);return e.signal?!t||t===e.signal?e.signal:AbortSignal.any([t,e.signal]):t}const $e=[{reason:`usbmux_device_unattached`,match:{code:`DEVICE_NOT_FOUND`,details:`usbmux-device-unattached`},verdicts:{connectRetry:!1}},{reason:`flagged_retriable`,match:{code:`COMMAND_FAILED`,details:`retriable`},verdicts:{retryable:!0}},{reason:`xcodebuild_exited_early`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`xcodebuild exited early`]},verdicts:{retryable:!1,connectRetry:!1}},{reason:`device_busy_connecting`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`device is busy`,`connecting`]},verdicts:{retryable:!1}},{reason:`runner_connect_refused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`runner did not accept connection`]},verdicts:{retryable:!0,restartBeforeSend:!0}},{reason:`fetch_failed`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`fetch failed`]},verdicts:{retryable:!0}},{reason:`econnrefused`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`econnrefused`]},verdicts:{retryable:!0}},{reason:`socket_hang_up`,match:{code:`COMMAND_FAILED`,messageIncludesAll:[`socket hang up`]},verdicts:{retryable:!0}},{reason:`ax_snapshot_failure`,match:{code:`IOS_AX_SNAPSHOT_FAILED`},verdicts:{sessionFatalReason:`ax_snapshot_failure`}},{reason:`xctest_recorded_failure`,match:{code:`XCTEST_RECORDED_FAILURE`},verdicts:{sessionFatalReason:`xctest_recorded_failure`}},{reason:`runner_main_thread_wedged`,match:{code:`RUNNER_WEDGED`},verdicts:{sessionFatalReason:`runner_main_thread_wedged`}}];function et(e,t){return t.code!==void 0&&e.code!==t.code||!tt(e,t.details)?!1:nt(e,t.messageIncludesAll)}function tt(e,t){return t===void 0?!0:t===`retriable`?e.details?.retriable===!0:M(e)}function nt(e,t){if(!t)return!0;let n=`${e.message??``}`.toLowerCase();return t.every(e=>n.includes(e))}function j(e,n){if(e instanceof t){for(let t of $e)if(t.verdicts[n]!==void 0&&et(e,t.match))return t.verdicts[n]}}function rt(e){return!(e instanceof t)||e.code!==`COMMAND_FAILED`?!1:j(e,`retryable`)??!1}function M(e){return!(e instanceof t)||e.code!==`DEVICE_NOT_FOUND`?!1:e.details?.usbmuxDeviceAttached===!1}function N(e){return j(e,`connectRetry`)??!0}function it(e){return j(e,`sessionFatalReason`)}function at(e){return(j(e,`restartBeforeSend`)??!1)&&N(e)}function ot(e,t,n,r){let i=`${e}\n${t}\n${n}`.toLowerCase();if(i.includes(`device is busy`)&&i.includes(`connecting`))return`Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.`;let a=r??`IOS_RUNNER_CONNECT_TIMEOUT`;return a===`IOS_RUNNER_DEVICE_NOT_PROVISIONED`?g(a):`${g(a)} ${Ze}`}function st(e){let{port:n,endpoints:r,logPath:i,lastError:a}=e,o=`Runner did not accept connection`;return new t(`COMMAND_FAILED`,o,{port:n,endpoints:r,logPath:i,lastError:a?String(a):void 0,reason:h({error:a,message:o,context:{platform:`ios`,phase:`connect`}}),hint:g(`IOS_RUNNER_CONNECT_TIMEOUT`)})}async function ct(e){let{session:n,port:r,logPath:i}=e,a=await n.testPromise,o=`Runner did not accept connection (xcodebuild exited early)`,s=h({message:o,stdout:a.stdout,stderr:a.stderr,context:{platform:`ios`,phase:`connect`}});return new t(`COMMAND_FAILED`,o,{port:r,logPath:i,xcodebuild:{exitCode:a.exitCode,stdout:a.stdout,stderr:a.stderr},reason:s,hint:ot(o,a.stdout,a.stderr,s)})}function lt(e){let t=e.details?JSON.stringify(e.details):``,n=`${e.message}\n${t}`.toLowerCase();if(n.includes(`failed registering bundle identifier`)||n.includes(`app identifier`)&&n.includes(`not available`))return`Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.`;if(n.includes(`requires a development team`))return`Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.`;if(n.includes(`no profiles for`)||n.includes(`provisioning profile`))return`Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.`;if(n.includes(`code signing`))return`Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.`}function ut(e){return lt(e)??Ze}function dt(e){return e.command===`status`||e.commandId?.trim()?e:{...e,commandId:ft()}}function ft(){return`runner-${we.randomUUID()}`}function pt(e){if(E(e))throw D()}const mt=`Connect the device by cable, trust this Mac, keep it unlocked, and retry.`;async function ht(e,t,n,r,i){let a=m.fromTimeoutMs(r);return await _t(e,t,await gt(e,t,a.remainingMs(),i),n,a.remainingMs(),i)}async function gt(e,n,r,i){let a=await vt(e,r,i);try{await yt(a,1,xt(`ListDevices`));let e=St((await bt(a,r,i)).payload.toString(`utf8`),n);if(e!==void 0)return e;throw new t(`DEVICE_NOT_FOUND`,`iOS device is not available through usbmux`,{deviceId:n,backend:`xctest`,usbmuxDeviceAttached:!1,hint:mt})}finally{a.destroy()}}async function _t(e,t,n,r,i,a){let o=await vt(e,i,a);try{await yt(o,2,xt(`Connect`,{DeviceID:n,PortNumber:Et(r)}));let e=wt((await bt(o,i,a)).payload.toString(`utf8`),`Number`);if(e!==0)throw Tt({result:e,udid:t,deviceId:n,port:r});return o}catch(e){throw o.destroy(),e}}async function vt(e,n,r){if(Dt(n,`connect to usbmuxd`),r?.aborted)throw D();return await new Promise((i,a)=>{let o=Ee.createConnection(e),s=!1,c=setTimeout(()=>{f(new t(`COMMAND_FAILED`,`Timed out connecting to usbmuxd`,{backend:`xctest`,socketPath:e,timeoutMs:n}))},n),l=()=>f(),u=e=>f(e),d=()=>f(D()),f=e=>{s||(s=!0,clearTimeout(c),o.off(`connect`,l),o.off(`error`,u),r?.removeEventListener(`abort`,d),e?(o.destroy(),a(e)):i(o))};o.once(`connect`,l),o.once(`error`,u),r?.addEventListener(`abort`,d,{once:!0})})}async function yt(e,t,n){let r=Buffer.from(n,`utf8`),i=Buffer.alloc(16+r.length);i.writeUInt32LE(i.length,0),i.writeUInt32LE(1,4),i.writeUInt32LE(8,8),i.writeUInt32LE(t,12),r.copy(i,16),!e.write(i)&&await new Promise((t,n)=>{e.once(`drain`,t),e.once(`error`,n)})}async function bt(e,n,r){if(Dt(n,`read usbmuxd response`),r?.aborted)throw D();return await new Promise((i,a)=>{let o=Buffer.alloc(0),s=!1,c=setTimeout(()=>p(new t(`COMMAND_FAILED`,`Timed out reading usbmuxd response`,{backend:`xctest`,timeoutMs:n})),n),l=e=>{if(o=Buffer.concat([o,e]),o.length<16)return;let n=o.readUInt32LE(0);if(n<16||n>4194304){p(new t(`COMMAND_FAILED`,`Invalid usbmuxd response length`));return}o.length<n||p(void 0,{payload:o.subarray(16,n)})},u=e=>p(e),d=()=>p(new t(`COMMAND_FAILED`,`usbmuxd closed the connection unexpectedly`)),f=()=>p(D()),p=(t,n)=>{s||(s=!0,clearTimeout(c),e.off(`data`,l),e.off(`error`,u),e.off(`close`,d),r?.removeEventListener(`abort`,f),e.pause(),t?a(t):i(n))};e.on(`data`,l),e.once(`error`,u),e.once(`close`,d),r?.addEventListener(`abort`,f,{once:!0}),e.resume()})}function xt(e,t={}){return`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>${[[`BundleID`,`com.callstack.agent-device`],[`ClientVersionString`,`agent-device`],[`MessageType`,e],[`ProgName`,`agent-device`],[`kLibUSBMuxVersion`,3],...Object.entries(t)].map(([e,t])=>typeof t==`number`?`<key>${_(e)}</key><integer>${t}</integer>`:`<key>${_(e)}</key><string>${_(t)}</string>`).join(``)}</dict></plist>`}function St(e,t){for(let n of F(v(e))){let e=Ct(n);if(e?.udid===t)return e.id}}function Ct(e){if(e.name!==`dict`)return;let t=P(e,`Properties`);if(t?.name!==`dict`)return;let n=P(t,`SerialNumber`)?.text,r=Number(P(e,`DeviceID`)?.text);if(!(!n||!Number.isSafeInteger(r)||r<=0))return{udid:n,id:r}}function wt(e,t){for(let n of F(v(e))){if(n.name!==`dict`)continue;let e=P(n,t);if(e?.name!==`integer`)continue;let r=Number(e.text);if(Number.isSafeInteger(r))return r}}function P(e,t){for(let n=0;n<e.children.length-1;n+=1){let r=e.children[n];if(r?.name===`key`&&r.text===t)return e.children[n+1]}}function*F(e){for(let t of e)yield t,yield*F(t.children)}function Tt(e){let{result:n,udid:r,deviceId:i,port:a}=e;return n===2?new t(`DEVICE_NOT_FOUND`,`iOS device is no longer available through usbmux`,{deviceId:r,backend:`xctest`,usbmuxDeviceAttached:!1,usbmuxResult:n,hint:mt}):n===3?new t(`COMMAND_FAILED`,`XCTest runner is not listening on the device port`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:n,hint:`The device is reachable but nothing is bound to the runner port yet; this resolves once the runner finishes starting.`}):new t(`COMMAND_FAILED`,`Failed to connect to XCTest runner through usbmux`,{backend:`xctest`,deviceId:i,port:a,usbmuxResult:n,hint:`Keep the device connected by cable and unlocked, then retry.`})}function Et(e){return(e&255)<<8|e>>>8&255}function Dt(e,n){if(!(e>0))throw new t(`COMMAND_FAILED`,`No time remaining to ${n}`,{backend:`xctest`,timeoutMs:e})}function Ot(e){return{postCommand:async(t,n,r,i,a)=>{let o=m.fromTimeoutMs(i),s=await ht(e,t,n,o.remainingMs(),a);try{return await At(s,r,o.remainingMs(),a)}catch(e){throw s.destroy(),e}}}}const kt=Ot(`/var/run/usbmuxd`);async function At(e,n,r,i){if(Nt(r),i?.aborted)throw D();let a=Buffer.from(JSON.stringify(n),`utf8`),o=AbortSignal.timeout(r),s=i?AbortSignal.any([i,o]):o,c=new De.Agent;c.createConnection=(t,n)=>(n?.(null,e),e);try{let t=await jt(c,e,a,s);return new Response((await Mt(t)).toString(`utf8`),{status:t.statusCode??500})}catch(e){throw i?.aborted?D():o.aborted?new t(`COMMAND_FAILED`,`Timed out waiting for XCTest runner over usbmux`,{backend:`xctest`,timeoutMs:r}):e}finally{c.destroy(),e.destroy()}}async function jt(e,t,n,r){return await new Promise((i,a)=>{let o=De.request({method:`POST`,host:`127.0.0.1`,path:`/command`,headers:{"Content-Type":`application/json`,"Content-Length":n.length,Connection:`close`},agent:e,signal:r},i);o.once(`error`,a),t.resume(),o.end(n)})}async function Mt(e){let n=[],r=0;for await(let i of e){let e=Buffer.isBuffer(i)?i:Buffer.from(i);if(r+=e.length,r>67108864)throw new t(`COMMAND_FAILED`,`XCTest runner response exceeded size limit`);n.push(e)}return Buffer.concat(n)}function Nt(e){if(!(e>0))throw new t(`COMMAND_FAILED`,`No time remaining to send XCTest runner command`,{backend:`xctest`,timeoutMs:e})}async function Pt(){return await new Promise((e,n)=>{let r=Ee.createServer();r.listen(0,`127.0.0.1`,()=>{let i=r.address();if(typeof i==`object`&&i?.port){let t=i.port;r.close(()=>e(t))}else r.close(()=>n(new t(`COMMAND_FAILED`,`Failed to allocate port`)))}),r.on(`error`,n)})}function I(e,t,n,r){t&&Ft(t,e),n&&Ft(n,e),r&&process.stderr.write(e)}const L=new Map;function Ft(e,t){let n=(L.get(e)??Promise.resolve()).catch(()=>{}).then(async()=>{await S.promises.mkdir(x.dirname(e),{recursive:!0}),await S.promises.appendFile(e,t)}).catch(()=>{}).finally(()=>{L.get(e)===n&&L.delete(e)});L.set(e,n)}function R(e){try{S.existsSync(e)&&S.unlinkSync(e)}catch{}}const It=45e3,Lt=45e3,Rt=2e4;async function zt(e,t,n,r,i=It,a,o){let s=m.fromTimeoutMs(i),{resolveRoute:c,markUsbmuxUnattached:l}=Ke(e,t),u=await c(s.remainingMs()),d=null,f=Math.max(1,Math.ceil(i/250));try{return await te(async({deadline:s})=>{let f=await Bt({device:e,port:t,command:n,timeoutMs:i,logPath:r,session:a,route:u,resolveRoute:c,markUsbmuxUnattached:l,signal:o,attemptDeadline:s,setRoute:e=>{u=e},setLastError:e=>{d=e}});if(f)return f;throw Gt({port:t,endpoints:u.endpoints,lastError:d,signal:o})},{maxAttempts:f,baseDelayMs:300,maxDelayMs:2e3,jitter:.2,shouldRetry:N},{deadline:s,phase:`ios_runner_connect`,signal:o})}catch(e){if(o?.aborted||O(e))throw D();if(M(e))throw e;d||=e}if(o?.aborted)throw D();if(e.kind===`simulator`){let i=s.remainingMs();if(i<=0)throw st({port:t,endpoints:u.endpoints,logPath:r,lastError:d});let a=await $t(e,t,n,i,o);return new Response(a.body,{status:a.status})}throw st({port:t,endpoints:u.endpoints,logPath:r,lastError:d})}async function Bt(e){await Vt(e);let t=await Ht(e);return t.response?t.response:await Ut(e)||await Wt(e,t.usedCachedTunnelIp)}async function Vt(e){if(e.attemptDeadline?.isExpired())throw new t(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:e.port,timeoutMs:e.timeoutMs});if(e.session?.child.exitCode!==null&&e.session?.child.exitCode!==void 0)throw await ct({session:e.session,port:e.port,logPath:e.logPath})}async function Ht(e){let t=e.route,n=!1;e.device.kind===`device`&&(t=await e.resolveRoute(e.attemptDeadline?.remainingMs()),n=t.cachedTunnelIp,e.setRoute(t));let r=async t=>{let n=t.cachedTunnelIp?t.endpoints[0]:null;return await Yt(e.device,t,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onUsbmuxUnattached:e.markUsbmuxUnattached,onError:(t,r)=>{e.setLastError(r),e.device.kind===`device`&&t===n&&qe(e.device.id)}})},i=await r(t);if(i||t.kind!==`usbmux`)return{response:i,usedCachedTunnelIp:n};let a=await e.resolveRoute(e.attemptDeadline?.remainingMs());return a.kind===`usbmux`?{response:null,usedCachedTunnelIp:n}:(e.setRoute(a),{response:await r(a),usedCachedTunnelIp:a.cachedTunnelIp})}async function Ut(e){return e.device.kind!==`simulator`||!e.session?.ready?null:await Zt(e.device,e.port,e.command,{signal:e.signal,attemptDeadline:e.attemptDeadline,onError:e.setLastError})}async function Wt(e,t){if(e.device.kind!==`device`||!t)return null;qe(e.device.id);let n=await e.resolveRoute(e.attemptDeadline?.remainingMs(),!0);return e.setRoute(n),await Yt(e.device,n,{command:e.command,port:e.port,timeoutMs:e.timeoutMs,signal:e.signal,attemptDeadline:e.attemptDeadline,onError:(t,n)=>{e.setLastError(n)}})}function Gt(e){if(e.signal?.aborted)throw D();return new t(`COMMAND_FAILED`,`Runner endpoint probe failed`,{port:e.port,endpoints:e.endpoints,lastError:e.lastError?String(e.lastError):void 0})}async function Kt(e,n,r,i=Lt,a){if(a?.aborted)throw D();let o=m.fromTimeoutMs(i),s=Ke(e,n),c=await s.resolveRoute(o.remainingMs());if(c.kind===`usbmux`)try{return await qt(e,n,r,o,a)}catch(t){if(!Jt(e,t))throw t;s.markUsbmuxUnattached(),c=await s.resolveRoute(o.remainingMs())}let l=o.remainingMs();if(l<=0)throw new t(`COMMAND_FAILED`,`Runner command deadline exceeded`,{timeoutMs:i});let u=c.endpoints[0];if(!u)throw new t(`COMMAND_FAILED`,`Runner command endpoint not available`,{port:n,endpoints:c.endpoints});return await Qt(u,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)},l,a)}async function qt(e,n,r,i,a){let o=i.remainingMs();if(o<=0)throw new t(`COMMAND_FAILED`,`Runner command deadline exceeded`,{port:n,timeoutMs:o});return await kt.postCommand(e.id,n,r,o,a)}function Jt(e,t){return M(t)?ve(e).backend!==`xctest`:!1}async function Yt(e,n,r){if(n.kind===`network`)return await Xt(n.endpoints,r);let i=n.endpoints[0];try{let n=r.attemptDeadline?.remainingMs()??r.timeoutMs;if(n<=0)throw new t(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:r.port,timeoutMs:r.timeoutMs});return await kt.postCommand(e.id,r.port,r.command,Math.min(Rt,n),r.signal)}catch(t){if(r.signal?.aborted||O(t))throw D();if(M(t)){if(!Jt(e,t))throw t;return r.onUsbmuxUnattached?.(),null}return r.onError(i,t),null}}async function Xt(e,n){let{command:r,port:i,timeoutMs:a,signal:o,attemptDeadline:s,onError:c}=n;for(let n of e)try{let e=s?.remainingMs()??a;if(e<=0)throw new t(`COMMAND_FAILED`,`Runner connection deadline exceeded`,{port:i,timeoutMs:a});return await Qt(n,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)},Math.min(Rt,e),o)}catch(e){if(o?.aborted||O(e))throw D();c(n,e)}return null}async function Zt(e,t,n,r){let{signal:i,attemptDeadline:a,onError:o}=r,s=a?.remainingMs()??45e3;if(s<=0)return null;try{let r=await $t(e,t,n,s,i);return new Response(r.body,{status:r.status})}catch(e){if(i?.aborted||O(e))throw D();return o(e),null}}async function Qt(e,t,n,r){let i=AbortSignal.timeout(n),a=r?AbortSignal.any([r,i]):i;return await fetch(e,{...t,signal:a})}async function $t(e,t,n,r,i){let a=JSON.stringify(n);return{status:200,body:c(await be(de(e,[`spawn`,e.id,`/usr/bin/curl`,`-s`,`-X`,`POST`,`-H`,`Content-Type: application/json`,`--data`,a,`http://127.0.0.1:${t}/command`]),{allowFailure:!0,timeoutMs:r,signal:i}),`Runner did not accept connection (simctl spawn)`,e=>{let n=h({message:`Runner did not accept connection (simctl spawn)`,stdout:e.stdout,stderr:e.stderr,context:{platform:`ios`,phase:`connect`}});return{port:t,reason:n,hint:g(n)}}).stdout}}const en=`XCTestDevices`,tn=`.agent-device-backup`,nn=`.agent-device-xctestdevices-backup-`;function rn(e=C.homedir()){return x.join(e,`Library`,`Developer`,`XCTestDevices`)}function an(e=C.homedir()){return x.join(e,`.agent-device`,`xctest-device-set.lock`)}function on(e=rn()){return`${e}${tn}`}async function sn(e,n={}){if(!a(e)||e.kind!==`simulator`)return null;let r=me(e.simulatorSetPath);if(!r)return null;let i=x.resolve(r),o=x.resolve(n.xctestDeviceSetPath??rn()),s=x.resolve(n.backupPath??on(o)),c=x.resolve(n.lockDirPath??an()),l=n.ownerStartTime??u(process.pid),d=await fn({lockDirPath:c,owner:{pid:n.ownerPid??process.pid,startTime:l,acquiredAtMs:n.nowMs??Date.now()}});try{if(z({xctestDeviceSetPath:o,backupPath:s}),dn(i,o))return await d(),null;S.mkdirSync(i,{recursive:!0}),S.existsSync(o)&&S.renameSync(o,s),ln({requestedSetPath:i,xctestDeviceSetPath:o})}catch(e){throw z({xctestDeviceSetPath:o,backupPath:s}),await d(),new t(`COMMAND_FAILED`,`Failed to redirect XCTest device set path`,{requestedSetPath:i,xctestDeviceSetPath:o,backupPath:s,error:String(e)})}let f=!1;return{release:async()=>{if(!f){f=!0;try{z({xctestDeviceSetPath:o,backupPath:s})}finally{await d()}}}}}function z(e){let{xctestDeviceSetPath:t,backupPath:n}=e,r=[n,...cn(n)],i=r.find(e=>S.existsSync(e)),a=un(t);if(i){if(a&&B(t),!S.existsSync(t))S.mkdirSync(x.dirname(t),{recursive:!0}),S.renameSync(i,t);else if(a)i===n?S.rmSync(n,{recursive:!0,force:!0}):S.rmSync(i,{recursive:!0,force:!0});else{l({level:`warn`,phase:`ios_runner_xctest_device_set_restore_collision`,data:{xctestDeviceSetPath:t,activeBackupPath:i}});return}for(let e of r)e!==i&&S.existsSync(e)&&S.rmSync(e,{recursive:!0,force:!0});return}a&&(l({level:`warn`,phase:`ios_runner_xctest_device_set_orphaned_symlink`,data:{xctestDeviceSetPath:t}}),B(t))}function cn(e){let t=x.dirname(e),n=x.basename(e).replace(tn,``),r=n===en?nn:`${n}${nn}`;try{return S.readdirSync(t).filter(e=>e.startsWith(r)).sort().map(e=>x.join(t,e))}catch{return[]}}function ln(e){let{requestedSetPath:t,xctestDeviceSetPath:n}=e,r=x.dirname(n),i=x.join(r,`${en}.agent-device-link-${process.pid}-${Date.now()}`);S.mkdirSync(r,{recursive:!0});try{S.symlinkSync(t,i,`dir`),S.renameSync(i,n)}catch(e){throw B(i),e}}function un(e){return S.lstatSync(e,{throwIfNoEntry:!1})?.isSymbolicLink()??!1}function B(e){un(e)&&S.unlinkSync(e)}function dn(e,t){if(x.resolve(e)===x.resolve(t))return!0;try{return S.realpathSync.native(e)===S.realpathSync.native(t)}catch{return!1}}async function fn(e){return await ne({lockDirPath:e.lockDirPath,owner:e.owner,timeoutMs:e.timeoutMs??3e4,pollMs:e.pollMs??100,ownerGraceMs:5e3,description:e.description??`XCTest device set lock`})}const V=new Set;function pn(e){return x.join(e,ye)}function mn(e,t){S.mkdirSync(e,{recursive:!0}),S.writeFileSync(pn(e),`${JSON.stringify(t,null,2)}\n`)}async function hn(e,t){if(e.cache===`external`){G(`preserve`,`external_bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t});return}V.add(e.derived);let n=await gn(e.derived);try{G(`clean`,`bad_artifact`,{derived:e.derived,xctestrunPath:e.xctestrunPath,reason:t}),W(e.derived),H(e.derived)}finally{await n()}}async function gn(e){return await _n({lockDirPath:vn(e),owner:{pid:process.pid,startTime:u(process.pid),acquiredAtMs:Date.now()},description:`iOS runner cache lock`})}async function _n(e){return await ne({lockDirPath:e.lockDirPath,owner:e.owner,timeoutMs:e.timeoutMs??6e5,pollMs:100,ownerGraceMs:5e3,description:e.description??`iOS runner cache lock`})}function vn(e){return x.join(x.dirname(e),`${x.basename(e)}.lock`)}function yn(e,t){!Mn()&&!t&&!V.has(e)||(G(`clean`,t?`forced_rebuild`:`forced_clean`,{derived:e}),W(e),H(e),V.delete(e))}function bn(e,t,n,r){mn(e,Tn(t,n,r))}function H(e){try{if(!S.existsSync(e))return;if(x.basename(e)!==`derived`){S.rmSync(e,{recursive:!0,force:!0});return}for(let t of S.readdirSync(e,{withFileTypes:!0}))Sn(t.name)&&S.rmSync(x.join(e,t.name),{recursive:!0,force:!0})}catch{}}const xn=new Set([ye,`Build`,`BuildCache.noindex`,`Index.noindex`,`Logs`,`ModuleCache.noindex`,`SDKStatCaches.noindex`,`SourcePackages`,`TextBasedInstallAPI`,`info.plist`]);function Sn(e){return xn.has(e)}function Cn(e){try{let t=JSON.parse(S.readFileSync(pn(e),`utf8`));return!t||typeof t!=`object`||Array.isArray(t)?null:t}catch{return null}}function wn(e,t){let n=Cn(e);return n?ge(fe(n))===ge(fe(t))?{ok:!0,metadata:n}:{ok:!1,reason:`cache_metadata_mismatch`}:{ok:!1,reason:`cache_metadata_missing`}}function Tn(e,t,n){let r=En(t,n);return r?{...e,artifacts:r}:e}function En(e,t){let n=U(e);if(n===null||t.length===0)return null;let r=[];for(let e of t){let t=U(e);if(t===null)return null;r.push({path:e,...t})}return{xctestrunPath:e,xctestrunMtimeMs:n.mtimeMs,xctestrunSize:n.size,productPaths:r}}function Dn(e,t){let n=t?.artifacts;if(!On(n)||!jn(n.xctestrunPath,e)||!An(n.xctestrunPath,{mtimeMs:n.xctestrunMtimeMs,size:n.xctestrunSize}))return null;let r=[];for(let t of n.productPaths){if(!jn(t.path,e)||!An(t.path,t))return null;r.push(t.path)}return{xctestrunPath:n.xctestrunPath,productPaths:r}}function On(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.xctestrunPath==`string`&&Number.isInteger(t.xctestrunMtimeMs)&&Number.isInteger(t.xctestrunSize)&&Array.isArray(t.productPaths)&&t.productPaths.length>0&&t.productPaths.every(kn)}function kn(e){if(!e||typeof e!=`object`||Array.isArray(e))return!1;let t=e;return typeof t.path==`string`&&Number.isInteger(t.mtimeMs)&&Number.isInteger(t.size)}function U(e){try{let t=S.statSync(e);return{mtimeMs:Math.trunc(t.mtimeMs),size:t.size}}catch{return null}}function An(e,t){let n=U(e);return n?.mtimeMs===t.mtimeMs&&n.size===t.size}function jn(e,t){let n=x.relative(x.resolve(t),x.resolve(e));return n!==``&&!n.startsWith(`..`)&&!x.isAbsolute(n)}function Mn(){return ee(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)}function W(e,n=process.env){if(n.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!Nn(e))throw new t(`COMMAND_FAILED`,`Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically`,{derivedPath:e,hint:`Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or move AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH under a subdirectory of ${x.join(r(),`.tmp`)}.`})}function Nn(e){let t=x.resolve(r(),`.tmp`),n=x.relative(t,x.resolve(e));return n!==``&&!n.startsWith(`..`)&&!x.isAbsolute(n)}async function Pn(e){let t=wn(e.derived,e.expectedCacheMetadata),n=t.ok?Dn(e.derived,t.metadata):null,r=n?.xctestrunPath??e.findXctestrun(e.derived);if(!r)return{reason:`missing_xctestrun`,xctestrunPath:null};let i=n?.xctestrunPath===r,a=i?`manifest`:`scan`,o=i?n.productPaths:await e.resolveExistingXctestrunProductPaths(r);return o?!e.xctestrunReferencesProjectRoot(r,e.projectRoot)&&!i?{reason:`project_root_mismatch`,xctestrunPath:r,productPaths:o,source:a}:t.ok?{reason:`reuse_ready`,xctestrunPath:r,productPaths:o,source:a}:{reason:t.reason,xctestrunPath:r,productPaths:o,source:a}:{reason:`missing_products`,xctestrunPath:r,productPaths:[],source:a}}function G(e,t,n){l({level:e===`rebuild`?`warn`:`info`,phase:`runner_xctestrun_cache`,data:{action:e,reason:t,...n}})}const Fn=new Set([`RUNNER_PRODUCT_MISSING`,`RUNNER_PRODUCT_REPAIR_FAILED`]);async function In(e,r,i){if(!o(e))return;if(r.length===0)throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,xctestrunPath:i});let a=Array.from(new Set(r)).sort((e,t)=>t.length-e.length);for(let e of a)if(!S.existsSync(e))throw new t(`COMMAND_FAILED`,`Missing macOS runner product`,{reason:`RUNNER_PRODUCT_MISSING`,productPath:e,xctestrunPath:i});for(let e of a)if(!await Rn(e)){await y(`codesign`,[`--remove-signature`,e],{allowFailure:!0});try{await y(`codesign`,[`--force`,`--sign`,`-`,e])}catch(r){let a=n(r,`COMMAND_FAILED`);throw new t(`COMMAND_FAILED`,`Failed to repair macOS runner product signature`,{reason:`RUNNER_PRODUCT_REPAIR_FAILED`,productPath:e,xctestrunPath:i,error:a.message,details:a.details})}}}function Ln(e){if(!(e instanceof t))return!1;let n=e.details&&typeof e.details==`object`?e.details.reason:void 0;return typeof n==`string`&&Fn.has(n)}async function Rn(e){return(await y(`codesign`,[`--verify`,`--deep`,`--strict`,e],{allowFailure:!0})).exitCode===0}const zn=new Set([`ProductPaths`,`DependentProductPaths`,`TestHostPath`,`TestBundlePath`,`UITargetAppPath`]);async function Bn(e){let t=await Un(e);if(!t||t.length===0)return null;let n=x.dirname(e),r=new Set,i=Vn(t,n);for(let e of i.testRootPaths){if(!S.existsSync(e))return null;r.add(e)}for(let e of Hn(i)){if(!e)return null;r.add(e)}return Array.from(r)}function Vn(e,t){let n=[],r=new Set,i=[];for(let a of e){if(a.startsWith(`__TESTHOST__/`)){i.push(a.slice(13));continue}if(!a.startsWith(`__TESTROOT__/`))continue;let e=a.slice(13);n.push(x.join(t,e));let o=Xn(e);o&&r.add(x.join(t,o))}return{testRootPaths:n,hostRoots:Array.from(r),hostRelativePaths:i}}function Hn(e){return e.hostRelativePaths.map(t=>{let n=e.hostRoots.find(e=>S.existsSync(x.join(e,t)));return n?x.join(n,t):null})}async function Un(e){let t=await b(e);if(t)return Wn(t);if(process.platform===`darwin`)return null;try{return Jn(S.readFileSync(e,`utf8`))}catch{return null}}function Wn(e){let t=new Set;for(let n of[e,...Gn(e),...Kn(e)])for(let e of qn(n))t.add(e);return Array.from(t)}function Gn(e){let t=e.TestConfigurations;if(!Array.isArray(t))return[];let n=[];for(let e of t){if(!i(e))continue;let t=e.TestTargets;Array.isArray(t)&&n.push(...t.filter(i))}return n}function Kn(e){return Object.values(e).filter(e=>i(e)&&`TestBundlePath`in e)}function qn(e){let t=new Set;for(let[n,r]of Object.entries(e))if(zn.has(n)){if(typeof r==`string`){t.add(r);continue}if(Array.isArray(r))for(let e of r)typeof e==`string`&&t.add(e)}return Array.from(t)}function Jn(e){return Yn(v(e))}function Yn(e){let t=new Set;return xe(e,(e,n)=>{if(zn.has(e)){if(n.name===`string`&&n.text){t.add(n.text);return}if(n.name===`array`)for(let e of n.children)e.name===`string`&&e.text&&t.add(e.text)}}),Array.from(t)}function Xn(e){let t=/\.app(?:\/|$)/.exec(e);return!t||t.index===void 0?null:e.slice(0,t.index+4)}const Zn=[`CFBundleIcons`,`CFBundleIcons~ipad`];async function Qn(e){let t=e.filter(lr);if(t.length===0)return;let n=e.filter(e=>dr(e)&&!ur(e));for(let e of t){let t=cr(e,n);t&&await $n(t,e)}}async function $n(e,t){let n=er(e,t),r=await tr(e,t);(n||r)&&(await ir(t),sr(t))}function er(e,t){let n=!1;for(let r of S.readdirSync(e,{withFileTypes:!0}))!r.isFile()||!or(r.name)||ar(x.join(e,r.name),x.join(t,r.name))&&(n=!0);return n}async function tr(e,t){let n=x.join(e,`Info.plist`),r=x.join(t,`Info.plist`),i=await b(n),a=await b(r);if(!i||!a)return!1;let o=nr(i,a);if(o.length===0)return!1;for(let e of o)await rr(r,e.key,e.value,e.shouldInsert);return!0}function nr(e,t){return Zn.flatMap(n=>{let r=e[n];return r===void 0||JSON.stringify(t[n])===JSON.stringify(r)?[]:[{key:n,value:r,shouldInsert:t[n]===void 0}]})}async function rr(e,t,n,r){c(await y(`plutil`,[r?`-insert`:`-replace`,t,`-json`,JSON.stringify(n),e],{allowFailure:!0}),`Failed to update XCTest runner icon plist`,{key:t,plistPath:e})}async function ir(e){c(await y(`codesign`,[`--force`,`--sign`,`-`,`--timestamp=none`,`--generate-entitlement-der`,e],{allowFailure:!0}),`Failed to sign XCTest runner app after icon update`,{runnerAppPath:e})}function ar(e,t){if(S.existsSync(t)){let n=S.readFileSync(e),r=S.readFileSync(t);return n.equals(r)?!1:(S.copyFileSync(e,t),!0)}return S.copyFileSync(e,t),!0}function or(e){return/^AppIcon.*\.png$/.test(e)||e===`Assets.car`}function sr(e){let t=new Date;S.utimesSync(e,t,t)}function cr(e,t){let n=x.dirname(e);return t.find(e=>x.dirname(e)===n&&x.basename(e)===`AgentDeviceRunner.app`)??t.find(t=>x.dirname(t)===n&&t!==e)??null}function lr(e){return dr(e)&&ur(e)&&(e.includes(`Debug-iphonesimulator`)||e.includes(`Release-iphonesimulator`)||e.includes(`Debug-appletvsimulator`)||e.includes(`Release-appletvsimulator`))}function ur(e){return x.basename(e).endsWith(`-Runner.app`)}function dr(e){return x.basename(e).endsWith(`.app`)}const fr={PreferredScreenCaptureFormat:`screenshots`,SystemAttachmentLifetime:`keepNever`,UserAttachmentLifetime:`keepNever`};async function pr(e,t,n,r={}){let i=r.iosXctestEnvDir?.trim(),a=i?x.resolve(i):x.dirname(e);S.mkdirSync(a,{recursive:!0});let o=n.replace(/[^a-zA-Z0-9._-]/g,`_`),s=x.join(a,`AgentDeviceRunner.env.${o}.json`),c=x.join(a,`AgentDeviceRunner.env.${o}.xctestrun`),l=await mr(e);return vr(l,e=>gr(e,t)),_r(l),await hr(l,s,c),{xctestrunPath:c,jsonPath:s}}async function mr(e){let n=await y(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(n.exitCode!==0||!n.stdout.trim())throw new t(`COMMAND_FAILED`,`Failed to read xctestrun plist`,{xctestrunPath:e,stderr:n.stderr});try{let e=JSON.parse(n.stdout);if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`Root must be an object`);return e}catch(n){throw new t(`COMMAND_FAILED`,`Failed to parse xctestrun JSON`,{xctestrunPath:e,error:String(n)})}}async function hr(e,t,n){S.writeFileSync(t,JSON.stringify(e,null,2)),c(await y(`plutil`,[`-convert`,`xml1`,`-o`,n,t],{allowFailure:!0}),`Failed to write xctestrun plist`,{tmpXctestrunPath:n})}function gr(e,t){e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}}function _r(e){vr(e,e=>Object.assign(e,fr),{requireTestBundlePath:!0})}function vr(e,t,n={}){let r=e.TestConfigurations;if(Array.isArray(r))for(let e of r)!e||typeof e!=`object`||yr(e.TestTargets,t,n);for(let n of Object.values(e)){let e=br(n,{requireTestBundlePath:!0});e&&t(e)}}function yr(e,t,n){if(Array.isArray(e))for(let r of e){let e=br(r,n);e&&t(e)}}function br(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;return t.requireTestBundlePath&&!n.TestBundlePath?null:n}const xr=new Map,K=new Set;async function Sr(e,t){let n=Cr(t);if(n)return n;let i=r(),a=ie(e,i),o=oe(e,a);return await Ge(xr,o,async()=>{let n=await gn(o);try{return await Tr({device:e,options:t,projectRoot:i,expectedCacheMetadata:a,derived:o,forceRebuild:t.forceRunnerXctestrunRebuild===!0})}finally{await n()}})}function Cr(e){let n=e.iosXctestrunFile?.trim();if(!n)return null;let r=x.resolve(n);if(!S.existsSync(r))throw new t(`COMMAND_FAILED`,`Configured iOS XCTest runner .xctestrun file not found`,{configKey:`iosXctestrunFile`,xctestrunPath:r});let i=e.iosXctestDerivedDataPath?.trim(),a=i?x.resolve(i):wr(r);return G(`reuse`,`external_xctestrun`,{derived:a,xctestrunPath:r}),{xctestrunPath:r,derived:a,cache:`external`,artifact:`valid`,buildMs:0,xctestrunPathSource:`external`}}function wr(e){let t=we.createHash(`sha1`);t.update(e);let n=t.digest(`hex`).slice(0,12);return x.join(C.tmpdir(),`agent-device-ios-xctest-derived`,n)}async function Tr(e){let{device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a}=e;yn(a,e.forceRebuild);let o=await Ar({device:t,derived:a,projectRoot:r,expectedCacheMetadata:i}),s=o.reason===`reuse_ready`?`exact`:o.xctestrunPath?`restore-key`:`miss`;return o.reason!==`reuse_ready`&&G(`rebuild`,o.reason,{derived:a,xctestrunPath:o.xctestrunPath}),await Er({device:t,derived:a,expectedCacheMetadata:i,existing:o,cache:s})||(o.xctestrunPath&&(W(a),H(a)),await Dr({device:t,options:n,projectRoot:r,expectedCacheMetadata:i,derived:a,cache:s,reason:o.reason}))}async function Er(e){let{device:t,derived:n,expectedCacheMetadata:r,existing:i,cache:a}=e;if(i.reason!==`reuse_ready`)return null;let o=await Or(t,n,r,i);return o?{xctestrunPath:o,derived:n,cache:a,artifact:`valid`,buildMs:0,xctestrunPathSource:i.source}:null}async function Dr(e){let{device:n,options:r,projectRoot:i,expectedCacheMetadata:a,derived:o,cache:s,reason:c}=e,l=ce(i);if(!S.existsSync(l))throw new t(`COMMAND_FAILED`,`iOS runner project not found`,{projectPath:l});let u=Date.now();Ue({type:`command`,status:`progress`,message:`Building Apple runner...`}),await Ir(n,l,o,r);let d=Math.max(0,Date.now()-u),f=jr(o,n);if(!f)throw new t(`COMMAND_FAILED`,`Failed to locate .xctestrun after build`);let p=await Bn(f);if(!p)throw new t(`COMMAND_FAILED`,`Runner build is missing expected products`,{xctestrunPath:f});return await In(n,p,f),await Qn(p),bn(o,a,f,p),G(`build`,`built_new`,{derived:o,xctestrunPath:f}),{xctestrunPath:f,derived:o,cache:s,artifact:`rebuilt`,buildMs:d,xctestrunPathSource:`build`,reason:c}}async function Or(e,t,n,r){try{return await In(e,r.productPaths,r.xctestrunPath),G(`reuse`,`reuse_ready`,{derived:t,xctestrunPath:r.xctestrunPath}),bn(t,n,r.xctestrunPath,r.productPaths),r.xctestrunPath}catch(e){if(!Ln(e))throw e;return G(`rebuild`,`repair_failed`,{derived:t,xctestrunPath:r.xctestrunPath}),null}}async function kr(e){try{let t=r(),n=ie(e,t);return(await Ar({device:e,derived:oe(e,n),projectRoot:t,expectedCacheMetadata:n})).reason===`reuse_ready`}catch{return!1}}function Ar(e){let{device:t,derived:n,projectRoot:r,expectedCacheMetadata:i}=e;return Pn({derived:n,projectRoot:r,expectedCacheMetadata:i,findXctestrun:e=>jr(e,t),xctestrunReferencesProjectRoot:Fr,resolveExistingXctestrunProductPaths:Bn})}function jr(e,t){let n=Mr(e);return n.length===0?null:(n.sort((e,n)=>Nr(e,n,t)),n[0]?.path??null)}function Mr(e){if(!S.existsSync(e))return[];let t=[],n=[e];for(;n.length>0;){let e=n.pop(),r=S.readdirSync(e,{withFileTypes:!0});for(let i of r){let r=x.join(e,i.name);if(i.isDirectory()){n.push(r);continue}if(i.isFile()&&i.name.endsWith(`.xctestrun`))try{let e=S.statSync(r);t.push({path:r,mtimeMs:e.mtimeMs})}catch{}}}return t}function Nr(e,t,n){if(n){let r=Pr(t.path,n)-Pr(e.path,n);if(r!==0)return r}return t.mtimeMs-e.mtimeMs||e.path.localeCompare(t.path)}function Pr(e,t){let n=0,r=e.toLowerCase();x.basename(r).startsWith(`agentdevicerunner.env.`)&&(n-=1e3),r.includes(`${x.sep}macos${x.sep}`)&&(n-=5e3);let i=se(t);return i.preferred.length>0&&(i.preferred.some(e=>r.includes(e))?n+=2e3:n-=500),i.disallowed.some(e=>r.includes(e))&&(n-=2500),n}function Fr(e,t){try{let n=S.readFileSync(e,`utf8`),r=new Set([t]);try{r.add(S.realpathSync(t))}catch{}for(let e of r)if(n.includes(e))return!0;return!1}catch{return!1}}async function Ir(e,n,r,i){let a=pe(process.env),o=re(process.env,e.kind===`device`,e),c=e.kind===`device`?[`-allowProvisioningUpdates`]:[],l=le(),u=_e(),d=await sn(e);try{await s(`xcodebuild`,[`build-for-testing`,`-project`,n,`-scheme`,`AgentDeviceRunner`,`-parallel-testing-enabled`,`NO`,ae(e),`1`,`-destination`,ue(e),`-derivedDataPath`,r,...l,...u,...a,...c,...o],{detached:!0,timeoutMs:i.buildTimeoutMs,signal:i.signal,onSpawn:e=>{K.add(e),e.on(`close`,()=>{K.delete(e)})},onStdoutChunk:e=>{I(e,i.logPath,i.traceLogPath,i.verbose)},onStderrChunk:e=>{I(e,i.logPath,i.traceLogPath,i.verbose)}})}catch(e){if(O(e))throw e;let n=e instanceof t?e:new t(`COMMAND_FAILED`,String(e)),r=ut(n);throw new t(`COMMAND_FAILED`,`xcodebuild build-for-testing failed`,{error:n.message,details:n.details,logPath:i.logPath,hint:r})}finally{await d?.release()}}var Lr=e({RUNNER_INVALIDATE_WAIT_TIMEOUT_MS:()=>Rr,abortRunnerSessionsAndPrepProcesses:()=>Hr,cleanupOwnedIosRunnerLease:()=>Vr,disposeRunnerSession:()=>Br,isRunnerProcessAlive:()=>X,runnerLeaseCleanupAdapter:()=>q,stopRunnerPrepProcesses:()=>Ur});const Rr=1e3,zr=2e3,q={cleanupRunnerProcessTree:$,cleanupRunnerXcodebuildProcesses:Yr,cleanupTempFile:R};async function Br(e,t={}){let n=!1;if(t.graceful!==!1)n=await Wr(e);else if(o(e.device)){await J([e]),await Y(e);return}else await $(e.child.pid,`SIGTERM`);n||(await Gr(e,t.waitTimeoutMs??1e4),Jr(e.child.pid)&&await $(e.child.pid,`SIGKILL`)),await Y(e)}async function Vr(e){await Se(e,q)}async function Hr(e){let t=Array.from(K),n=e.filter(e=>o(e.device)),r=e.filter(e=>!o(e.device));await Z(r,`SIGINT`),await Q(t,`SIGINT`),await Z(r,`SIGTERM`),await Q(t,`SIGTERM`),await Z(r,`SIGKILL`),await Q(t,`SIGKILL`),await J(n),await Promise.allSettled(e.map(async e=>{await Y(e)}))}async function Ur(){let e=Array.from(K);await Promise.allSettled(e.map(async e=>{try{await $(e.pid,`SIGTERM`),await $(e.pid,`SIGKILL`)}finally{K.delete(e)}}))}async function Wr(e){try{return await zt(e.device,e.port,dt({command:`shutdown`}),void 0,15e3),!1}catch{return o(e.device)?(await J([e]),!0):(await $(e.child.pid,`SIGTERM`),!1)}}async function Gr(e,t){let n;try{return await Promise.race([e.testPromise.then(()=>!0,()=>!0),new Promise(e=>{n=setTimeout(()=>e(!1),t)})])||!Jr(e.child.pid)}finally{n&&clearTimeout(n)}}async function J(e){if(e.length===0)return;await Z(e,`SIGINT`);let t=await Kr(e,5e3);await Z(t,`SIGTERM`),await Z(await Kr(t,2e3),`SIGKILL`)}async function Kr(e,t){let n=await Promise.all(e.map(async e=>await Gr(e,t)));return e.filter((e,t)=>!n[t])}async function Y(e){await qr(e.device),R(e.xctestrunPath),R(e.jsonPath);try{await e.simulatorSetRedirect?.release()}finally{Ce(e.lease)}}async function qr(e){e.kind===`simulator`&&await Promise.allSettled(he.map(async t=>{try{await be(de(e,[`terminate`,e.id,t]),{allowFailure:!0,timeoutMs:zr})}catch(n){l({level:`warn`,phase:`ios_runner_simulator_app_terminate_failed`,data:{deviceId:e.id,bundleId:t,timeoutMs:zr,error:n instanceof Error?n.message:String(n)}})}}))}function Jr(e){return e?X(e)||p(e):!1}function X(e){return e?f(e):!1}async function Z(e,t){await Promise.allSettled(e.map(async e=>{await $(e.child.pid,t)}))}async function Q(e,t){await Promise.allSettled(e.map(async e=>{await $(e.pid,t),t===`SIGKILL`&&K.delete(e)}))}async function $(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}d([e],t);let n=t===`SIGINT`?`INT`:t===`SIGTERM`?`TERM`:`KILL`;try{await y(`pkill`,[`-${n}`,`-P`,String(e)],{allowFailure:!0})}catch{}}async function Yr(e,t){let n=t?`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${Xr(e)}-${Xr(t)}-`:`xcodebuild.*test-without-building.*AgentDeviceRunner\\.env\\.session-${Xr(e)}-[0-9]`;for(let t of[`TERM`,`KILL`])try{await y(`pkill`,[`-${t}`,`-f`,n],{allowFailure:!0,timeoutMs:2e3})}catch(n){l({level:`warn`,phase:`ios_runner_stale_xcodebuild_kill_failed`,data:{deviceId:e,signal:t,error:n instanceof Error?n.message:String(n)}})}}function Xr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}export{Re as A,Qe as C,Ge as D,dt as E,O as F,Ie as I,Fe as L,D as M,ze as N,Ue as O,E as P,Ae as R,it as S,N as T,zt as _,X as a,pt as b,Ur as c,pr as d,hn as f,Kt as g,It as h,Br as i,Le as j,He as k,Sr as l,Lt as m,Hr as n,q as o,sn as p,Vr as r,Lr as s,Rr as t,kr as u,Pt as v,at as w,rt as x,I as y,Be as z};
|
package/dist/src/runner-lease.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{
|
|
1
|
+
import{o as e}from"./png-worker-contract.js";import{_ as t}from"./sdk-contracts.js";import{j as n}from"./sdk-android-adb.js";import{c as r,n as i,s as a}from"./host-process.js";import{t as o}from"./owner-identity.js";import{t as s}from"./process-lock.js";import c from"node:path";import l from"node:crypto";import u from"node:fs";import d from"node:os";var f=e({RUNNER_OWNER_START_TIME:()=>m,RUNNER_OWNER_TOKEN:()=>h,buildDetachedRunnerLease:()=>N,buildRunnerLease:()=>_,cleanupOwnedRunnerLease:()=>P,cleanupRunnerLeasesForOwner:()=>F,prepareRunnerLeaseForStartup:()=>S,readStaleRunnerLease:()=>M,releaseRunnerLease:()=>I,setRunnerLeaseOwnerStateDir:()=>v,verifyLeaseRunnerPidIdentity:()=>$,withRunnerLeaseLock:()=>y,writeRunnerLease:()=>L});const p=process.pid,m=r(process.pid),h=te(p,m);let g;function _(e){return{schemaVersion:1,deviceId:e.deviceId,ownerToken:h,ownerPid:p,ownerStartTime:m,ownerStateDir:E(),sessionId:e.sessionId,runnerPid:e.runnerPid??null,runnerStartTime:e.runnerPid?r(e.runnerPid):null,port:e.port,xctestrunPath:e.xctestrunPath,jsonPath:e.jsonPath,createdAtMs:Date.now()}}function v(e){g=e?.trim()||void 0}async function y(e,t){let n=await s({lockDirPath:`${z(e)}.lock`,owner:{pid:p,startTime:m,acquiredAtMs:Date.now()},timeoutMs:3e4,pollMs:100,ownerGraceMs:5e3,description:`iOS runner lease for ${e}`});try{return await t()}finally{await n()}}function b(e){try{return U(JSON.parse(u.readFileSync(z(e),`utf8`)),e)}catch{return null}}function x(e){return e?e.ownerToken===h?{type:`owned`,lease:e}:Y(e)?X(e)?{type:`stale`,lease:e,staleReason:`owner-state-dir-gone`}:{type:`busy`,lease:e}:{type:`stale`,lease:e,staleReason:`owner-process-dead`}:{type:`empty`}}async function S(e,n,r){let i=x(b(e));if(i.type===`empty`){await n.cleanupRunnerXcodebuildProcesses(e,void 0);return}if(i.type===`busy`){if(C(i.lease)){await Z(i.lease,`same-state-dir`,n);return}if(w(i.lease,r)){await Z(i.lease,`logical-lease-takeover`,n);return}throw new t(`COMMAND_FAILED`,r?`iOS runner for ${e} is busy after device lease admission`:`iOS runner for ${e} is already owned by another agent-device daemon`,{deviceId:e,logicalLeaseContext:r,ownerPid:i.lease.ownerPid,ownerStartTime:i.lease.ownerStartTime,ownerStateDir:i.lease.ownerStateDir,ownerToken:i.lease.ownerToken,sessionId:i.lease.sessionId,hint:D(i.lease,r)})}await Z(i.lease,i.type,n)}function C(e){let t=E();return!t||!e.ownerStateDir?!1:c.resolve(t)===c.resolve(e.ownerStateDir)}function w(e,t){return!t||t.leaseProvider!==`proxy`||!t.leaseId||!t.clientId?!1:T(t.deviceKey,e.deviceId)}function T(e,t){if(!e)return!1;if(e===t)return!0;let[,,n]=e.split(`:`,3);return n===t}function E(){return g||process.env.AGENT_DEVICE_STATE_DIR?.trim()||void 0}function D(e,t){let n=O(e),r=k(e);return t?[r,n,`The device is busy because another active device lease owns it, or the runner is owned by another daemon/process after lease admission.`,`Retry after the owning session closes or after the five-minute inactivity lease expires.`].join(` `):[r,n,`If the runner is still active, wait for it to finish. Do not run prepare ios-runner from another daemon/client to recover this.`].join(` `)}function O(e){let t=`Runner owner: PID ${e.ownerPid}`;return e.ownerStateDir?`${t} with AGENT_DEVICE_STATE_DIR=${e.ownerStateDir}`:`${t}.`}function k(e){return e.ownerStateDir?`If it is stuck, stop the owning agent-device daemon for ${A(`AGENT_DEVICE_STATE_DIR`,e.ownerStateDir)} and retry.`:`If it is stuck, stop the owning agent-device daemon and retry.`}function A(e,t){return`${e}=${j(t)}`}function j(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function M(e){let t=x(b(e));return t.type===`stale`&&t.staleReason===`owner-process-dead`?t.lease:null}function N(e){return{...e,ownerToken:`detached-${e.ownerToken}`}}async function P(e,t){let n=x(b(e));n.type===`owned`&&await Z(n.lease,`owned`,t)}async function F(e,t){if(!Number.isInteger(e.pid)||e.pid<=0)return;let n=V(e);await Promise.all(n.map(async e=>{await Z(e,`owned`,t)}))}function I(e){e&&R({deviceId:e.deviceId,ownerToken:e.ownerToken,sessionId:e.sessionId})}function L(e){let t=z(e.deviceId);u.mkdirSync(c.dirname(t),{recursive:!0});let n=`${t}.${process.pid}.${Date.now()}.tmp`;u.writeFileSync(n,JSON.stringify(e,null,2),`utf8`),u.renameSync(n,t)}function R(e){let t=b(e.deviceId);if(t&&!(e.ownerToken&&t.ownerToken!==e.ownerToken)&&!(e.sessionId&&t.sessionId!==e.sessionId))try{u.unlinkSync(z(e.deviceId))}catch{}}function z(e){return c.join(B(),`${ne(e)}.json`)}function B(){let e=process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR?.trim();return e?c.resolve(e):c.join(d.homedir(),`.agent-device`,`apple-runner`,`leases`)}function V(e){let t,n=B();try{t=u.readdirSync(n,{withFileTypes:!0})}catch{return[]}let r=[];for(let i of t){if(!i.isFile()||!i.name.endsWith(`.json`))continue;let t=H(c.join(n,i.name));t&&t.ownerPid===e.pid&&(e.startTime!==void 0&&t.ownerStartTime!==e.startTime||r.push(t))}return r}function H(e){try{let t=JSON.parse(u.readFileSync(e,`utf8`)),n=G(t.deviceId);return n?U(t,n):null}catch{return null}}function U(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(n.schemaVersion!==1||n.deviceId!==t)return null;let r=W(n);return r?{schemaVersion:1,deviceId:t,...r,ownerStartTime:K(n.ownerStartTime),ownerStateDir:K(n.ownerStateDir)??void 0,runnerPid:q(n.runnerPid),runnerStartTime:K(n.runnerStartTime)}:null}function W(e){let t={ownerToken:G(e.ownerToken),ownerPid:q(e.ownerPid),sessionId:G(e.sessionId),port:q(e.port),xctestrunPath:G(e.xctestrunPath),jsonPath:G(e.jsonPath),createdAtMs:J(e.createdAtMs)};return Object.values(t).some(e=>e===null)?null:t}function G(e){return typeof e==`string`&&e.length>0?e:null}function K(e){return typeof e==`string`?e:null}function q(e){return typeof e==`number`&&Number.isInteger(e)&&e>0?e:null}function J(e){return typeof e==`number`&&Number.isFinite(e)?e:null}function Y(e){return o({owner:{pid:e.ownerPid,startTime:e.ownerStartTime}})===`live`}function X(e){return e.ownerStateDir?o({owner:{pid:e.ownerPid,startTime:e.ownerStartTime},stateDir:e.ownerStateDir})===`owner-state-dir-gone`:!1}async function Z(e,t,r){n({level:t===`stale`||t===`same-state-dir`||t===`logical-lease-takeover`?`warn`:`debug`,phase:`ios_runner_lease_cleanup`,data:{deviceId:e.deviceId,ownerPid:e.ownerPid,ownerStateDir:e.ownerStateDir,ownerToken:e.ownerToken,runnerPid:e.runnerPid,sessionId:e.sessionId,reason:t}}),await r.cleanupRunnerProcessTree(Q(e),`SIGTERM`),await r.cleanupRunnerXcodebuildProcesses(e.deviceId,e.ownerToken),await r.cleanupRunnerProcessTree(Q(e),`SIGKILL`),r.cleanupTempFile(e.xctestrunPath),r.cleanupTempFile(e.jsonPath),I(e)}function Q(e){let t=e.runnerPid??void 0;if(!(!t||!i(t))){if($(e,t))return t;n({level:`warn`,phase:`ios_runner_lease_recycled_pid_skipped`,data:{deviceId:e.deviceId,runnerPid:t,runnerStartTime:e.runnerStartTime??null,sessionId:e.sessionId}})}}function $(e,t){return e.runnerStartTime?r(t)===e.runnerStartTime:ee(a(t))}function ee(e){return!!e&&e.includes(`xcodebuild`)&&e.includes(`AgentDeviceRunner`)}function te(e,t){let n=l.createHash(`sha256`);return n.update(String(e)),n.update(`\0`),n.update(t??`unknown-start`),`owner-${e}-${n.digest(`hex`).slice(0,8)}`}function ne(e){return e.replaceAll(/[^A-Za-z0-9._-]/g,`-`)||`unknown-device`}export{S as a,f as c,y as d,L as f,P as i,v as l,N as n,M as o,_ as r,I as s,h as t,$ as u};
|
package/dist/src/runtime.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as e,i as t,n,o as r,r as i,t as a}from"./png-worker-contract.js";import{T as o,_ as s,d as c,g as l,l as u,p as d,u as f,v as p}from"./sdk-contracts.js";import{L as m,Lt as h,Ot as ee,St as te,a as ne,i as re,r as ie,w as ae,wt as oe,x as g}from"./version.js";import{
|
|
2
|
-
`)}function
|
|
3
|
-
`).toLowerCase(),n=E(e,Nt),r=E(e,Lt),i=E(e,jt,zt),a=E(e,Mt),o=Dt(t),s=Ot(t);return{dismissNodes:n,minimizeNodes:r,collapsedNodes:i,detected:At({text:t,hasReactNativeStackFrame:o,hasOverlayControl:kt(t,n,r),hasControllessRedBoxText:s,collapsedNodes:i,openDebuggerWarningNodes:a})}}function wt(e){let t=Ut(e.dismissNodes);if(t)return Kt(t,qt(t));let n=Jt(e.collapsedNodes.filter(Bt));return n?.rect?{action:`close-collapsed-banner`,point:$t(n),rect:n.rect,ref:n.ref,label:D(n)}:null}function Tt(e){return[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(` `)}function Et(e){return mt.test(e)}function Dt(e){return ht.some(t=>t.test(e))}function Ot(e){return/\buncaught\b/.test(e)&&/unable to download asset/.test(e)}function kt(e,t,n){return t.length>0||n.length>0||/\b(reload js|copy stack)\b/.test(e)}function At(e){return e.collapsedNodes.length>0||e.openDebuggerWarningNodes.length>0||e.hasControllessRedBoxText||e.hasOverlayControl&&(Et(e.text)||e.hasReactNativeStackFrame)}function jt(e){let t=e?.trim().toLowerCase();return t?_t.some(e=>t.includes(e))||gt.some(e=>e.test(t)):!1}function Mt(e){return e.includes(`open debugger to view warnings`)||/^!,\s+open debugger\b/.test(e)}function Nt(e){return Pt(e)||Ft(e)||It(e)}function Pt(e){return/^dismiss(?:\s*\([^)]*\))?$/i.test(e)}function Ft(e){return/^close(?:\s*\([^)]*\))?$/i.test(e)}function It(e){return vt.has(e)}function Lt(e){return/^minimi[sz]e(?:\b|\s|\()/i.test(e)}function Rt(e){return/^!,\s+/.test(e)}function zt(e){return!e.rect||e.rect.height<=180}function Bt(e){let t=D(e)?.trim().toLowerCase()??``;return(Mt(t)||Rt(t))&&Ht(e)}function Vt(e){return e?e.x<=1&&e.y<=1&&e.width>=300&&e.height>=600:!1}function Ht(e){return e.rect?e.rect.width>=120&&e.rect.height>=36&&e.rect.height<=180:!1}function E(e,t,n=()=>!0){let r=[];for(let i of e)i.ref&&n(i)&&[i.label,i.value,i.identifier].map(e=>e?.trim().toLowerCase()).filter(e=>!!e).some(e=>t(e))&&r.push(i);return r}function Ut(e){return Yt(e,Gt)}function Wt(e){let t=[e.type,e.role,e.subrole].join(` `).toLowerCase();return/\b(button|menuitem|link)\b/.test(t)}function Gt(e){return[Zt(Wt(e)),Zt(e.hittable),-(e.rect?ce(e.rect):1/0)]}function Kt(e,t){if(!e.rect)throw Error(`React Native overlay target node must have rect`);return{action:t,point:f(e.rect),rect:e.rect,ref:e.ref,label:D(e)}}function qt(e){let t=D(e)?.trim().toLowerCase();return t&&Pt(t)?`dismiss`:`close`}function Jt(e){return Yt(e,Xt)}function Yt(e,t){let n=e.filter(e=>e.rect);return n.length===0?null:n.sort((e,n)=>Qt(t(n),t(e)))[0]??null}function Xt(e){return[Zt(e.hittable),e.rect?.width??0,e.rect?.y??0]}function Zt(e){return+(e===!0)}function Qt(e,t){for(let n=0;n<e.length;n+=1){let r=e[n]-t[n];if(r!==0)return r}return 0}function $t(e){if(!e.rect)throw Error(`Collapsed React Native warning node must have rect`);let t=Math.min(e.rect.height,52),n=Math.min(36,Math.max(18,t*.45));return{x:Math.round(en(e.rect.x+e.rect.width-n,e.rect.x+1,e.rect.x+e.rect.width-1)),y:Math.round(e.rect.y+t/2)}}function en(e,t,n){return Math.min(n,Math.max(t,e))}function D(e){return e.label??e.value??e.identifier}function tn(e){let t=e?.trim().split(/\s+/,1)[0];if(!t||!t.startsWith(`@`)||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}function nn(e,t){try{let n=ft(e),r=w.extname(n)||`.js`;return[w.join(w.dirname(n),`${t}${r}`),w.join(w.dirname(n),`internal`,`${t}${r}`)].find(e=>dt.existsSync(e))??null}catch{return null}}var O=class extends Error{};let k=null,rn=!1,an=!1,on=0;const A=new Map;function sn(e){rn=!0,!an&&(an=!0,ut({level:`warn`,phase:`png_worker_unavailable`,data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function cn(e){let t=A.get(e.id);t&&(A.delete(e.id),dn(),e.ok?t.resolve(e.result):t.reject(new s(o(e.error.code),e.error.message,e.error.details)))}function ln(e,t){k===e&&(sn(t.message),k=null,e.terminate().catch(()=>{}),un(new O(`PNG worker failed: ${t.message}`)))}function un(e){let t=[...A.values()];A.clear();for(let n of t)n.reject(e)}function dn(){k&&(A.size>0?k.ref():k.unref())}function fn(){if(rn)return null;if(k)return k;let e=nn(import.meta.url,`png-worker`);if(!e)return sn(`worker entry module not found next to the current module`),null;try{let t=new pt(e,{execArgv:e.endsWith(`.ts`)?[`--experimental-strip-types`]:[]});return t.on(`message`,cn),t.on(`error`,e=>{ln(t,e)}),t.on(`exit`,e=>{ln(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),k=t,t}catch(e){return sn(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}function pn(e){let t=fn();if(!t)return Promise.reject(new O(`PNG worker is unavailable`));on+=1;let n=on;return new Promise((r,i)=>{A.set(n,{resolve:r,reject:i}),dn();try{t.postMessage({...e,id:n})}catch(e){A.delete(n),dn(),i(new O(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}async function j(e,t){try{return await pn(e)}catch(e){if(e instanceof O)return t();throw e}}function mn(){fn()}async function hn(){let e=k;k=null,un(new O(`PNG worker terminated`)),e&&await e.terminate()}async function M(n,r){let i=await j({kind:`decode`,png:n,label:r},()=>{let e=t(n,r);return{kind:`decode`,width:e.width,height:e.height,data:e.data}}),o=new e.PNG({width:i.width,height:i.height});return o.data=a(i.data),o}async function N(t){return a((await j({kind:`encode`,width:t.width,height:t.height,data:t.data},()=>({kind:`encode`,png:e.PNG.sync.write(t)}))).png)}async function gn(e,r,i){let{kind:a,...o}=await j({kind:`rgb-difference`,firstPng:e,secondPng:r,label:i},()=>({kind:`rgb-difference`,...n(t(e,i),t(r,i))}));return o}async function _n(e){let{kind:t,...n}=await j({kind:`diff-pixels`,...e},()=>({kind:`diff-pixels`,...i(e)}));return{...n,diffData:a(n.diffData)}}const P=[0,187,255,255];function vn(e,t){for(let n of t)n.rect.width<4||n.rect.height<4||yn(e,n.rect)}function yn(e,t){let n=bn(t);if(n==null)return;let r=I(n.x,0,e.width-1),i=I(n.y,0,e.height-1),a=I(n.right,0,e.width-1),o=I(n.bottom,0,e.height-1);for(let t=0;t<2;t+=1){for(let n=r;n<=a;n+=1)F(e,n,i+t,P),F(e,n,o-t,P);for(let n=i;n<=o;n+=1)F(e,r+t,n,P),F(e,a-t,n,P)}}function bn(e){let t=e.x+e.width-1,n=e.y+e.height-1;return[e.x,e.y,e.width,e.height,t,n].every(Number.isFinite)?{x:e.x,y:e.y,right:t,bottom:n}:null}function F(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let i=(n*e.width+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function I(e,t,n){return Number.isFinite(e)?Math.min(Math.max(e,t),n):t}const xn=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function Sn(e){let{mask:t,width:n,height:r,hooks:i}=e,a=new Uint8Array(t.length),o=new Int32Array(t.length),s=[];for(let e=0;e<t.length;e+=1){if(!Tn(t,a,e))continue;let c=0,l=wn(o,a,0,e),u=i.create(e);for(;c<l;){let e=o[c];c+=1,i.visit(u,e),l=Cn({mask:t,visited:a,queue:o,queueEnd:l,width:n,height:r,pixelIndex:e})}s.push(u)}return s}function Cn(e){let{mask:t,visited:n,queue:r,width:i,height:a,pixelIndex:o}=e,s=o%i,c=Math.floor(o/i),l=e.queueEnd;for(let e of xn){let o=s+e.x,u=c+e.y;if(!En(o,u,i,a))continue;let d=u*i+o;Tn(t,n,d)&&(l=wn(r,n,l,d))}return l}function wn(e,t,n,r){return t[r]=1,e[n]=r,n+1}function Tn(e,t,n){return e[n]===1&&t[n]!==1}function En(e,t,n,r){return e>=0&&e<n&&t>=0&&t<r}function Dn(e,t){return e.flatMap(e=>On(e,t.baseline.width,t.baseline.height)?kn(e,t,Fn(t.baseline.height)):[e])}function On(e,t,n){let r=e.maxX-e.minX+1;return e.maxY-e.minY+1>=Pn(n)&&r>=t*.35}function kn(e,t,n){let r=Nn(e,Mn(jn(An(e,t.diffMask,t.baseline.width)),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),n);if(r.length<=1)return[e];let i=r.map(([n,r])=>In(e,n,r,t)).filter(e=>e!==null);return i.length>1?i:[e]}function An(e,t,n){let r=[];for(let i=e.minY;i<=e.maxY;i+=1){let a=0;for(let r=e.minX;r<=e.maxX;r+=1)t[i*n+r]===1&&(a+=1);r.push(a)}return r}function jn(e){return e.map((t,n)=>{let r=0,i=0,a=Math.max(0,n-3),o=Math.min(e.length-1,n+3);for(let t=a;t<=o;t+=1)r+=e[t],i+=1;return Math.round(r/i)})}function Mn(e,t){let n=[],r=null;for(let i=0;i<e.length;i+=1){if(e[i]<=t){r??=i;continue}r!==null&&(i-r>=6&&n.push([r,i-1]),r=null)}return r!==null&&e.length-r>=6&&n.push([r,e.length-1]),n}function Nn(e,t,n){let r=[],i=e.minY;for(let[a,o]of t){let t=e.minY+Math.round((a+o)/2);t-i+1<n||e.maxY-t<n||(r.push([i,t]),i=t+1)}return r.push([i,e.maxY]),r}function Pn(e){return Math.max(48,Math.round(e*.07))}function Fn(e){return Math.max(24,Math.round(e*.03))}function In(e,t,n,r){let i=null;for(let a=t;a<=n;a+=1)for(let t=e.minX;t<=e.maxX;t+=1){let e=a*r.baseline.width+t;r.diffMask[e]===1&&(i??=Ln(t,a),Rn(i,e,t,a,r.baseline,r.current))}return i}function Ln(e,t){return{minX:e,minY:t,maxX:e,maxY:t,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function Rn(e,t,n,r,i,a){let o=t*4;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=i.data[o],e.baselineGreen+=i.data[o+1],e.baselineBlue+=i.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}const zn=2.5;function Bn(e){let t=Vn(e);return Dn(t.length<=2e3?Wn(t,12):t,e).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(n!==0)return n;let r=e.minY-t.minY;return r===0?e.minX-t.minX:r}).slice(0,8).map((t,n)=>qn(t,n+1,{width:e.baseline.width,height:e.baseline.height,totalPixels:e.totalPixels,differentPixels:e.differentPixels}))}function Vn(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return Sn({mask:t,width:i,height:a,hooks:{create:e=>Hn(e,i),visit:(e,t)=>Un(e,t,i,n,r)}})}function Hn(e,t){let n=e%t,r=Math.floor(e/t);return{minX:n,minY:r,maxX:n,maxY:r,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function Un(e,t,n,r,i){let a=t%n,o=Math.floor(t/n),s=t*4;e.minX=Math.min(e.minX,a),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,a),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}function Wn(e,t){let n=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return n===0?e.minX-t.minX:n})){let e=n.find(e=>Gn(e,r,t));if(!e){n.push({...r});continue}Kn(e,r)}return n}function Gn(e,t,n){return e.minX-n<=t.maxX&&t.minX-n<=e.maxX&&e.minY-n<=t.maxY&&t.minY-n<=e.maxY}function Kn(e,t){e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY),e.differentPixels+=t.differentPixels,e.baselineRed+=t.baselineRed,e.baselineGreen+=t.baselineGreen,e.baselineBlue+=t.baselineBlue,e.currentRed+=t.currentRed,e.currentGreen+=t.currentGreen,e.currentBlue+=t.currentBlue}function qn(e,t,n){let r={x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1},i={x:Math.round(e.minX+r.width/2),y:Math.round(e.minY+r.height/2)},a=Jn(e.baselineRed,e.baselineGreen,e.baselineBlue,e.differentPixels),o=Jn(e.currentRed,e.currentGreen,e.currentBlue,e.differentPixels),s=r.width*r.height;return{index:t,rect:r,normalizedRect:re({x:R(r.x/n.width),y:R(r.y/n.height),width:R(r.width/n.width),height:R(r.height/n.height)}),differentPixels:e.differentPixels,shareOfDiffPercentage:R(e.differentPixels/n.differentPixels),densityPercentage:R(e.differentPixels/s),shape:Zn(r,n.width,n.height),size:Qn(s,n.totalPixels),location:Yn(i,n.width,n.height),averageBaselineColorHex:$n(a),averageCurrentColorHex:$n(o),baselineLuminance:Math.round(L(a)),currentLuminance:Math.round(L(o)),dominantChange:Xn(a,o)}}function Jn(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function Yn(e,t,n){let r=e.x<t/3?`left`:e.x>t*2/3?`right`:`center`,i=e.y<n/3?`top`:e.y>n*2/3?`bottom`:`middle`;return r===`center`&&i===`middle`?`center`:`${i}-${r}`}function Xn(e,t){let n=L(t)-L(e);return Math.abs(n)>=12?n>0?`brighter`:`darker`:Math.max(Math.abs(t.r-e.r),Math.abs(t.g-e.g),Math.abs(t.b-e.b))>=12?`color-shift`:`mixed`}function Zn(e,t,n){return e.width>=t*.55&&e.height>=n*.12?`large-area`:e.width>=e.height*zn?`horizontal-band`:e.height>=e.width*zn?`vertical-band`:`compact`}function Qn(e,t){let n=e/t;return n>=.04?`large`:n>=.01?`medium`:`small`}function L(e){return e.r*.2126+e.g*.7152+e.b*.0722}function $n(e){return`#${er(e.r)}${er(e.g)}${er(e.b)}`}function er(e){return e.toString(16).padStart(2,`0`)}function R(e){return Math.round(e*100*100)/100}const tr=255*Math.sqrt(3);async function nr(t,n,r={}){await rr(t,`Baseline image not found`),await rr(n,`Current screenshot not found`);let i=r.outputPath,[a,o]=await Promise.all([T.readFile(t),T.readFile(n)]),[s,c]=await Promise.all([M(a,`baseline screenshot`),M(o,`current screenshot`)]);ir(s.width,s.height,`baseline screenshot`,r.maxPixels),ir(c.width,c.height,`current screenshot`,r.maxPixels);let l=r.threshold??.1;if(s.width!==c.width||s.height!==c.height){let e=s.width*s.height;return await ar(r.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:s.width,height:s.height},actual:{width:c.width,height:c.height}}}}let u=s.width*s.height,d=l*tr,{diffData:f,diffMask:p,differentPixels:m}=await _n({baselineData:s.data,currentData:c.data,width:s.width,height:s.height,maxColorDistance:d}),h=m>0?Bn({diffMask:p,baseline:s,current:c,totalPixels:u,differentPixels:m}):[];if(m>0&&i){let t=new e.PNG({width:s.width,height:s.height});t.data=f,vn(t,h),await T.mkdir(w.dirname(i),{recursive:!0}),await T.writeFile(i,await N(t))}else await ar(r.outputPath);let ee=u>0?Math.round(m/u*100*100)/100:0;return{...m>0&&i?{diffPath:i}:{},...h.length>0?{regions:h}:{},totalPixels:u,differentPixels:m,mismatchPercentage:ee,match:m===0}}async function rr(e,t){try{await T.access(e)}catch{throw new s(`INVALID_ARGS`,`${t}: ${e}`)}}function ir(e,t,n,r){if(r==null||r<=0)return;let i=e*t;if(!(i<=r))throw new s(`INVALID_ARGS`,`${n} is ${i} pixels, which exceeds the configured maxImagePixels limit of ${r}`)}async function ar(e){if(e)try{await T.unlink(e)}catch(e){if(!or(e,`ENOENT`))throw e}}function or(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}function sr(e,t){return e.map(e=>{let n=cr(e,t);return n.length>0?{...e,currentOverlayMatches:n}:e})}function cr(e,t){let n=lr(e.rect);return t.map(t=>{let r=t.overlayRect,i=ie(e.rect,r);return i<=0?null:{ref:t.ref,...t.label?{label:t.label}:{},rect:r,overlayCoveragePercentage:ur(i/lr(r)),regionCoveragePercentage:ur(i/n)}}).filter(e=>e!==null).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return n===0?t.overlayCoveragePercentage-e.overlayCoveragePercentage:n}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage}))}function lr(e){return e.width*e.height}function ur(e){return Math.round(e*100*100)/100}async function z(e,t,n){if(t.kind===`path`&&!e.policy.allowLocalInputPaths)throw new s(`INVALID_ARGS`,`Local ${n.field??`input`} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw p(e)}}async function B(e,t,n){if(t?.kind===`path`&&!e.policy.allowLocalOutputPaths)throw new s(`INVALID_ARGS`,`Local output paths are not allowed by command policy`);try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??`client-visible`,requestedClientPath:t?.kind===`downloadableArtifact`?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw p(e)}}async function dr(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw p(e)}}const fr=async(e,t)=>{if(!t.baseline)throw new s(`INVALID_ARGS`,`diff screenshot requires a baseline image`);let n=pr(t.threshold),r=t.current??{kind:`live`};if(t.overlayRefs&&!br(r))throw new s(`INVALID_ARGS`,`diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs`);let i=await z(e,t.baseline,{usage:`diff screenshot baseline`,field:`baseline`}),a,o,c,l=[];try{let s;br(r)?(o=await mr(e,t),s=o.path):(a=await z(e,r,{usage:`diff screenshot current`,field:`current`}),s=a.path),c=t.out?await B(e,t.out,{field:`diffPath`,ext:`.png`,artifactType:`screenshot-diff`}):void 0;let u=await nr(i.path,s,{threshold:n,outputPath:c?.path,maxPixels:e.policy.maxImagePixels});br(r)&&(u=await hr(e,t,c?.path,u,l));let d=u.diffPath?await c?.publish():void 0;return d&&l.push(d),u.diffPath||await c?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await c?.cleanup?.(),e}finally{await i.cleanup?.(),await a?.cleanup?.(),await o?.cleanup?.()}};function pr(e){if(e==null||e===``)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new s(`INVALID_ARGS`,`--threshold must be a number between 0 and 1`);return t}async function mr(e,t){let n=await dr(e,{prefix:`agent-device-diff-current`,ext:`.png`});try{await gr(e,t,n.path,_r(t))}catch(e){throw await n.cleanup(),e}return n}async function hr(e,t,n,r,i){if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await yr(n),r;let a=await B(e,vr(t,n),{field:`currentOverlayPath`,ext:`.png`,artifactType:`screenshot`});try{let n=await gr(e,t,a.path,{overlayRefs:!0,..._r(t)}),o=await a.publish();return o&&i.push(o),{...r,currentOverlayPath:n.path??a.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:sr(r.regions,n.overlayRefs)}:{}}}catch(e){throw await a.cleanup?.(),e}}async function gr(e,t,n,r={}){if(!e.backend.captureScreenshot)throw new s(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,r)??{}}function _r(e){return{normalizeStatusBar:e.normalizeStatusBar??!0,...e.surface?{surface:e.surface}:{}}}function vr(e,t){if(e.currentOverlayOut)return e.currentOverlayOut;if(e.out?.kind===`path`)return{kind:`path`,path:V(t??e.out.path)};if(e.out?.kind===`downloadableArtifact`)return{kind:`downloadableArtifact`,...e.out.clientPath?{clientPath:V(e.out.clientPath)}:{},...e.out.fileName?{fileName:V(e.out.fileName)}:{}}}function V(e){let t=w.extname(e);return`${t?e.slice(0,-t.length):e}.current-overlay${t||`.png`}`}async function yr(e){try{await T.unlink(V(e))}catch(e){if(!xr(e,`ENOENT`))throw e}}function br(e){return e.kind===`live`}function xr(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}async function Sr(e,t){let{min:n,max:r}=ee;if(!Number.isFinite(t)||t<n||t>r)throw new s(`INVALID_ARGS`,`Screenshot scale must be between ${n} and ${r}`);if(t===1)return;let i=await M(await T.readFile(e),`screenshot`),a=Math.max(1,Math.round(i.width*t)),o=Math.max(1,Math.round(i.height*t));await T.writeFile(e,await N(wr(i,a,o)))}async function Cr(e,t,n){if(!Number.isInteger(t)||t<1||!Number.isInteger(n)||n<1)throw new s(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let r=await M(await T.readFile(e),`screenshot`);r.width===t&&r.height===n||await T.writeFile(e,await N(wr(r,t,n)))}function wr(t,n,r){let i=new e.PNG({width:n,height:r});for(let e=0;e<r;e+=1){let a=e*t.height/r,o=(e+1)*t.height/r;for(let r=0;r<n;r+=1){let s=r*t.width/n,c=(r+1)*t.width/n,l=0,u=0,d=0,f=0,p=0;for(let e=Math.floor(a);e<Math.ceil(o);e+=1){let n=Math.min(e+1,o)-Math.max(e,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(e*t.width+r)*4;l+=(t.data[a]??0)*i,u+=(t.data[a+1]??0)*i,d+=(t.data[a+2]??0)*i,f+=(t.data[a+3]??0)*i,p+=i}}let m=(e*i.width+r)*4;i.data[m]=Math.round(l/p),i.data[m+1]=Math.round(u/p),i.data[m+2]=Math.round(d/p),i.data[m+3]=Math.round(f/p)}}return i}const Tr=async(e,t)=>{if(!e.backend.captureScreenshot)throw new s(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);h(t);let n=await B(e,t.out,{field:`path`,ext:`.png`,artifactType:`screenshot`}),r;try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},n.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,pixelDensity:t.pixelDensity,stabilize:t.stabilize,normalizeStatusBar:t.normalizeStatusBar,surface:t.surface}),t.scale!==void 0&&await Sr(n.path,t.scale),r=await n.publish()}catch(e){throw await n.cleanup?.(),e}return{path:n.path,...r?{artifacts:[r]}:{},...y(`Saved screenshot: ${n.path}`)}};function Er(e){let{nodes:t,backend:n,snapshotRaw:r}=e;if(r||!l(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let i=ne(t),a=new Set;return i.hiddenCount>0&&a.add(`offscreen-nodes`),i.nodes.some(e=>e.hiddenContentAbove)&&a.add(`scroll-hidden-above`),i.nodes.some(e=>e.hiddenContentBelow)&&a.add(`scroll-hidden-below`),{partial:a.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:t.length,reasons:[...a]}}const Dr=`A system surface (notification shade, quick settings, or another system overlay) covers the app, so this snapshot shows that surface. Interact with it or dismiss it (press back or swipe up) to reach app content.`;function Or(e){return e?.systemSurfaceOnly===!0?Dr:void 0}function kr(e,t){return e.presentationKey?e:{...e,presentationKey:u(t)}}function Ar(e){let{previous:t,current:n,options:r,identity:i}=e;if(r.forceFull===!0||r.raw===!0||!t||t.comparisonSafe===!1||n.comparisonSafe===!1||!jr(t,n,i)||!t.presentationKey||t.presentationKey!==n.presentationKey||!Mr(t,n))return;let a=r.scope?.trim();return{ageMs:Math.max(0,n.createdAt-t.createdAt),nodeCount:n.nodes.length,...r.interactiveOnly===!0?{interactiveOnly:!0}:{},...a?{scope:a}:{}}}function jr(e,t,n){return!(e.backend&&t.backend&&e.backend!==t.backend||n?.previousAppBundleId&&n.currentAppBundleId&&n.previousAppBundleId!==n.currentAppBundleId)}function Mr(e,t){return e.truncated===t.truncated?JSON.stringify(Nr(e.nodes))===JSON.stringify(Nr(t.nodes)):!1}function Nr(e){return e.map(e=>({index:e.index,depth:e.depth,parentIndex:e.parentIndex,type:e.type,role:e.role,subrole:e.subrole,label:e.label,value:e.value,identifier:e.identifier,enabled:e.enabled,selected:e.selected,focused:e.focused,hittable:e.hittable,rect:e.rect,bundleId:e.bundleId,appName:e.appName,windowTitle:e.windowTitle,surface:e.surface,hiddenContentAbove:e.hiddenContentAbove,hiddenContentBelow:e.hiddenContentBelow,interactionBlocked:e.interactionBlocked,presentationHints:e.presentationHints,actions:e.actions}))}const Pr=async(e,t)=>{let n=await Ir(e,t),r=Ar({previous:n.session?.snapshot,current:n.snapshot,options:t,identity:{previousAppBundleId:n.session?.appBundleId,currentAppBundleId:n.result.appBundleId??n.session?.appBundleId}});return await e.sessions.set(Rr(t.session,n)),{nodes:n.snapshot.nodes,truncated:n.snapshot.truncated??!1,visibility:Er({nodes:n.snapshot.nodes,backend:n.snapshot.backend,snapshotRaw:t.raw}),...te({...n.annotations,warnings:n.warnings}),...r?{unchanged:r}:{},...n.result.snapshotDiagnostics?{snapshotDiagnostics:n.result.snapshotDiagnostics}:{},...zr(n)}},Fr=async(e,t)=>{let n=await Ir(e,t),r=t.interactiveOnly===!0,i=n.session?.snapshot,a=Rr(t.session,n);if(!i){let t=Be(n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=it(i.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function Ir(e,t){if(!e.backend.captureSnapshot)throw new s(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let n=t.session??`default`,r=await e.sessions.get(n),i=await e.backend.captureSnapshot({session:n,requestId:t.requestId,appId:r?.appId,appBundleId:r?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,depth:t.depth,scope:t.scope,raw:t.raw,customActions:t.customActions}),a=kr(Lr(i,e),t),o=oe(i),c=Ge(e);return{snapshot:a,result:i,session:r,annotations:o,warnings:Br({result:i,annotations:o,snapshot:a,options:t,session:r,capturedAt:a.createdAt??c,runtimeNow:c})}}function Lr(e,t){return e.snapshot?e.snapshot:{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,createdAt:Ge(t)}}function Rr(e,t){let n=t.session?.name??e??`default`;return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}function zr(e){let t=e.result.appName??e.session?.appName,n=e.result.appBundleId??e.session?.appBundleId;return{...t||n?{appName:t??n}:{},...n?{appBundleId:n}:{}}}function Br(e){let t=[...e.annotations.warnings??[]];e.annotations.quality&&t.push(...Ve(e.annotations.quality,e.snapshot.nodes)),t.push(...Wr(e)),e.annotations.quality||(t.push(...Hr(e)),t.push(...Ur(e.snapshot.nodes)));let n=yt(e.snapshot.nodes);n&&t.push(n);let r=Vr(e.annotations);r&&t.push(r);let i=Gr(e);return i&&t.push(i),t.push(...Yr(e.annotations.freshness,e.snapshot.backend)),Array.from(new Set(t))}function Vr(e){if(e.androidSnapshot?.systemSurfaceOnly===!0)return Dr}function Hr(e){return e.snapshot.backend!==`xctest`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length!==1||e.snapshot.nodes[0]?.type!==`Application`?[]:[`iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known.`]}function Ur(e){let t=new Set(e.map(e=>e.parentIndex).filter(e=>e!==void 0));return e.filter(e=>t.has(e.index)||(e.type?.toLowerCase()??``).includes(`text`)?!1:(e.label??``).split(`, `).length>10).map(e=>{let t=(e.label??``).split(`, `).length,n=e.identifier?` (${e.identifier})`:``;return`@${e.ref} [${e.type??`element`}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})}function Wr(e){let t=e.annotations.analysis;if(e.snapshot.backend!==`android`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return typeof e.options.depth==`number`&&typeof t.maxDepth==`number`&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}function Gr(e){let t=e.session?.snapshot;if(!e.annotations.freshness&&t&&Kr(t,e.snapshot)&&qr(t,e.capturedAt,e.runtimeNow)&&Xr(t.nodes.length,e.snapshot.nodes.length))return Jr}function Kr(e,t){return e.presentationKey===void 0||t.presentationKey===void 0?!0:e.presentationKey===t.presentationKey}function qr(e,t,n){return[t,n].some(t=>{let n=t-e.createdAt;return n>=0&&n<=2e3})}const Jr=`Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.`;function Yr(e,t){return!e?.staleAfterRetries||t!==`android`?[]:e.reason===`stuck-route`?[`Recent ${e.action} was followed by a nearly identical snapshot after ${e.retryCount} automatic retr${e.retryCount===1?`y`:`ies`}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`]:e.reason===`sharp-drop`?[Jr]:[]}function Xr(e,t){return e<12?!1:t<=Math.floor(e*.2)}const Zr={screenshot:Tr,diffScreenshot:fr,snapshot:Pr,diffSnapshot:Fr},Qr=new WeakMap;function $r(e,t){ti(e)&&Qr.set(e,t)}function ei(e){return ti(e)?Qr.get(e):void 0}function ti(e){return typeof e==`object`&&!!e||typeof e==`function`}const ni=async(e,t)=>await oi(e,t,`press`),ri=async(e,t)=>await oi(e,t,`click`),ii=async(e,t)=>{if(!t.text)throw new s(`INVALID_ARGS`,`fill requires text`);let n=Ye(t),r=n.needsPreActionBaseline?null:await li(e,t);if(r)return r;let i=await Oe(e,t,{action:`fill`,requireInteractive:!0,promoteToHittableAncestor:!1,captureEvidenceBaseline:n.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.fill)throw new s(`UNSUPPORTED_OPERATION`,`fill is not supported by this backend`);let a=si(i),o=`node`in i?i.node?.type??``:``,c=o!==``&&se(o,e.backend.platform),l=t.allowNonHittableCoordinateFallback===!0&&`node`in i&&i.node?.hittable===!1,u=S(await e.backend.fill(b(e,t),a,t.text,{delayMs:t.delayMs,allowNonHittableCoordinateFallback:l})),d=o&&!c?`fill target ${di(i)} resolved to "${o}", attempting fill anyway.`:void 0;return await Xe(e,t,i,{...i,text:t.text,...d?{warning:d}:{},...u?{backendResult:u}:{}},n)},ai=async(e,t)=>{let n=t.text;if(!n)throw new s(`INVALID_ARGS`,`type requires text`);let r=fi(n);if(r)throw new s(`INVALID_ARGS`,`type does not accept a target ref like "${r}"`,{hint:`Use fill ${r} "text" to target that field, or press ${r} then type "text" to append.`});if(!e.backend.typeText)throw new s(`UNSUPPORTED_OPERATION`,`type is not supported by this backend`);let i=C(t.delayMs??0,`delay-ms`,0,1e4),a=S(await e.backend.typeText(b(e,t),n,{delayMs:i}));return{kind:`text`,text:n,delayMs:i,...a?{backendResult:a}:{},...y(`Typed ${Array.from(n).length} chars`)}};async function oi(e,t,n){let r=Ye(t),i=r.needsPreActionBaseline?null:await ci(e,t,n);if(i)return i;let a=await Oe(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0,captureEvidenceBaseline:r.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.tap)throw new s(`UNSUPPORTED_OPERATION`,`tap is not supported by this backend`);let o=si(a),c;try{c=await e.backend.tap(b(e,t),o,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap})}catch(e){throw $r(e,a),e}let l=S(c);return await Xe(e,t,a,{...a,...l?{backendResult:l}:{}},r)}function si(e){if(!e.point)throw new s(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function ci(e,t,n){if(n!==`click`||t.target.kind!==`ref`||!e.backend.tapTarget||ui(t)||t.expectedResolvedTarget)return null;let r=await Ze(e,t,t.target,n),i=S(await e.backend.tapTarget(b(e,t),{kind:`ref`,ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}}));return{kind:`ref`,target:{kind:`ref`,ref:t.target.ref},resolution:je,...r,...i?{backendResult:i}:{}}}async function li(e,t){if(t.target.kind!==`ref`||!e.backend.fillTarget||t.expectedResolvedTarget)return null;let n=await Ze(e,t,t.target,`fill`),r=S(await e.backend.fillTarget(b(e,t),{kind:`ref`,ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}},t.text,{delayMs:t.delayMs}));return{kind:`ref`,target:{kind:`ref`,ref:t.target.ref},text:t.text,resolution:je,...n,...r?{backendResult:r}:{}}}function ui(e){return e.count!==void 0||e.intervalMs!==void 0||e.holdMs!==void 0||e.jitterPx!==void 0||e.doubleTap!==void 0||e.button!==void 0&&e.button!==`primary`}function di(e){return e.target?.kind===`ref`?e.target.ref:e.target?.kind===`selector`?e.target.selector:`point`}function fi(e){return tn(e)}function H(e){return{includeRects:e===`visible`||e===`hidden`,interactiveOnly:!1}}function pi(e,t,n){let r=n??1e4,i=U(e),a=vi(),o=()=>Math.max(0,r-(U(e)-i));return{capture:async n=>{let r=!1,i=await We(e,t,o(),async e=>await a.attempt(async()=>{let t=await n(e);return r=!0,t}));return i.timedOut?{timedOut:!0,deadline:a.readableCaptures()===0?`capture-stalled`:`capture-truncated`}:(r&&a.recordReadableCapture(),i)},hasTimeRemaining:()=>o()>0,failureEvidence:()=>({timeoutMs:r,readableCaptures:a.readableCaptures(),waitedMs:U(e)-i}),rethrowIfNeverReadable:a.rethrowIfNeverReadable,sleepUntilNextPoll:async()=>await yi(e,t,Math.min(300,o())),timeoutMs:r,waitedMs:()=>U(e)-i}}function mi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.captureStalled,captureStalled:!0,...t,retriable:!0,hint:`No readable snapshot capture completed before the wait timeout. Retry, or use screenshot to inspect the current surface.`})}function hi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.deadlineExceeded,captureTruncated:!0,...t})}function gi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.targetAbsent,...t})}function _i(e,t,n){let r=t.failureEvidence();return n===`capture-stalled`?mi(e,r):n===`capture-truncated`?hi(e,r):(t.rethrowIfNeverReadable(),r.readableCaptures===0?mi(e,r):gi(e,r))}function vi(){let e=0,t;return{attempt:async e=>{try{return await e()}catch(e){if(!ke(e))throw e;t=e;return}},recordReadableCapture:()=>{e+=1},readableCaptures:()=>e,rethrowIfNeverReadable:()=>{if(e===0&&t!==void 0)throw t}}}function U(e){return e.clock?.now()??Date.now()}async function yi(e,t,n){let r=[t.signal,e.signal].filter(e=>e!==void 0);for(let e of r)e.throwIfAborted();if(n<=0)return!1;if(e.clock){await e.clock.sleep(n);for(let e of r)e.throwIfAborted();return!0}return await new Promise((e,t)=>{let i=r.length>0?AbortSignal.any(r):void 0,a=()=>i?.removeEventListener(`abort`,s),o=setTimeout(()=>{a(),e()},n),s=()=>{clearTimeout(o),a(),t(i?.reason)};i?.addEventListener(`abort`,s,{once:!0}),o.unref()}),!0}function bi(e){if(e.kind===`ambiguous`)return{selector:e.selector,selectorIndex:e.selectorIndex,matchedNodes:e.matchedNodes};if(e.kind===`resolved`)return{selector:e.resolution.selector,selectorIndex:e.resolution.selectorIndex,matchedNodes:e.matchedNodes}}function xi(e){let t=async(t,n)=>{if(n.target.kind===`sleep`)return await Oi(t,n.target.durationMs),{kind:`sleep`,waitedMs:n.target.durationMs};if(n.target.kind===`ref`){let r=await e.requireSnapshot(t,n.session),i=d(n.target.ref);if(!i)throw new s(`INVALID_ARGS`,`Invalid ref: ${n.target.ref}`);let a=c(r.snapshot.nodes,i),o=a?Re(a,r.snapshot.nodes):void 0;if(!o)throw new s(`COMMAND_FAILED`,`Ref ${n.target.ref} not found or has no label`);return await wi(e,t,n,o,n.target.timeoutMs)}if(n.target.kind===`selector`)return await Si(e,t,n,n.target.selector,n.target.timeoutMs,n.target.recordedLandmark);if(n.target.kind===`stable`)return await Ei(e,t,n,n.target.quietMs,n.target.timeoutMs);let r=fe(n.target.text);if(!r.ok)throw new s(r.code,r.message);return await wi(e,t,n,n.target.text,n.target.timeoutMs)};return{waitCommand:t,waitForTextCommand:async(e,n)=>{let r=await t(e,{...n,target:{kind:`text`,text:n.text,timeoutMs:n.timeoutMs}});if(r.kind!==`text`)throw new s(`COMMAND_FAILED`,`waitForText returned non-text result`);return r}}}async function Si(e,t,n,r,i,a){let o=pi(t,n,i),c=H(),l,u;for(;o.hasTimeRemaining();){let i=await o.capture(async r=>await e.captureSnapshot(t,{...n,signal:r},{updateSession:!0,includeHiddenContentHints:!1,...c}));if(i.timedOut){u=i.deadline;break}let s=i.value;if(s){let e=s.snapshot.nodes,n=bi(Se(e,r,_.wait,{platform:t.backend.platform}));if(n){let t=Ci(e,n,a);if(t.kind===`satisfied`)return{kind:`selector`,selector:n.selector,waitedMs:o.waitedMs(),node:t.node,preActionNodes:e};l=t.evidence}}await o.sleepUntilNextPoll()}throw u!==`capture-stalled`&&l?new s(`COMMAND_FAILED`,`wait matched selector ${r} but no candidate carried the recorded landmark identity`,{reason:Fe,...l}):_i(`wait timed out for selector: ${r}`,o,u)}function Ci(e,t,n){let r=t.matchedNodes[0];if(!n)return{kind:`satisfied`,node:r};let i=qe(e),a=tt(t.matchedNodes,i,Ee(n),n.ancestry)[0];return a?{kind:`satisfied`,node:a}:{kind:`identity-mismatch`,evidence:{matchCount:t.matchedNodes.length,observed:be(r),observedAncestry:De(r,i,Math.max(n.ancestry.length,1)).chain}}}async function wi(e,t,n,r,i){let a=pi(t,n,i),o;for(;a.hasTimeRemaining();){let i=await a.capture(async i=>t.backend.findText?(await t.backend.findText(Di(t,{...n,signal:i}),r)).found:await Ti(e,t,{...n,signal:i},r));if(i.timedOut){o=i.deadline;break}if(i.value)return{kind:`text`,text:r,waitedMs:a.waitedMs()};await a.sleepUntilNextPoll()}throw _i(`wait timed out for text: ${r}`,a,o)}async function Ti(e,t,n,r){return!!He((await e.captureSnapshot(t,n,{updateSession:!0,includeHiddenContentHints:!1})).snapshot.nodes,r)}async function Ei(e,t,n,r,i){let a=i??1e4,o=r??e.stable.defaultQuietMs,c=await e.stable.capture(t,n,{quietMs:o,timeoutMs:a});if(!c.settled)throw new s(`COMMAND_FAILED`,`wait timed out waiting for a stable UI`,{reason:g.stableTimeout,...c.stalled?{captureStalled:!0}:{},quietMs:o,timeoutMs:a,captures:c.captures,nodeCount:c.nodeCount,...c.stalled?{hint:`A snapshot capture stalled past the wait timeout, so no settle verdict is available. The UI may still be readable: retry, or use screenshot to inspect the surface.`}:{}});return{kind:`stable`,waitedMs:c.waitedMs,captures:c.captures,nodeCount:c.nodeCount,...c.nodeCount<e.stable.tinyTreeNodeCount?{hint:e.stable.tinyTreeHint}:{}}}function Di(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}async function Oi(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}const ki=xi({captureSnapshot:v,requireSnapshot:Me,stable:{defaultQuietMs:500,tinyTreeHint:rt,tinyTreeNodeCount:5,capture:at}}),Ai=ki.waitCommand,ji=ki.waitForTextCommand,Mi=async(e,t)=>{let n=t.locator??`any`;if(!t.query)throw new s(`INVALID_ARGS`,me);if(t.action===`wait`)return await zi(e,t,n);if(t.action===`list`)return await Bi(e,t,n);let{capture:r,match:i}=await Vi(e,t,n);if(!i)throw new s(`COMMAND_FAILED`,`find did not match any element`);if(t.action===`exists`)return{kind:`found`,found:!0};let a=`@${i.ref}`;return t.action===`get_attrs`?{kind:`attrs`,ref:a,node:i}:{kind:`text`,ref:a,text:await Le(e,r,i),node:i}},Ni=async(e,t)=>{if(t.target.kind===`ref`){let n=await Me(e,t.session),r=Ne(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??``,invalidRefMessage:`get text requires a ref like @e2`,notFoundMessage:`Ref ${t.target.ref} not found`});Ae(r.node,n.snapshot.nodes,t.expectedResolvedTarget,`get`);let i=le(r.node,e.backend.platform,{action:`get`,nodes:n.snapshot.nodes}),a={kind:`ref`,ref:`@${r.ref}`},o=n.snapshot.nodes;return t.property===`attrs`?{kind:`attrs`,target:a,node:r.node,selectorChain:i,preActionNodes:o}:{kind:`text`,target:a,text:await Le(e,n,r.node),node:r.node,selectorChain:i,preActionNodes:o}}let n=await Hi(e,t,t.session??`default`,{selector:t.target.selector,policy:t.property===`text`?_.readText:_.readUnique});Ae(n.node,n.capture.snapshot.nodes,t.expectedResolvedTarget,`get`);let r=le(n.node,e.backend.platform,{action:`get`,nodes:n.capture.snapshot.nodes});if(t.property===`attrs`)return{kind:`attrs`,target:{kind:`selector`,selector:n.selector},node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes};let i=await Le(e,n.capture,n.node);return{kind:`text`,target:{kind:`selector`,selector:n.selector},text:i,node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes}},Pi=async(e,t)=>{let n=await Ni(e,{...t,property:`text`,target:t.target});if(n.kind!==`text`)throw new s(`COMMAND_FAILED`,`getText returned non-text result`);return n},Fi=async(e,t)=>{let n=await Ni(e,{...t,property:`attrs`,target:t.target});if(n.kind!==`attrs`)throw new s(`COMMAND_FAILED`,`getAttrs returned non-attrs result`);return n},Ii=async(e,t)=>{let n=de(t.predicate);if(!n.ok)throw new s(n.code,n.message,{hint:n.hint});let r=n.predicate;if(r===`text`&&!t.expectedText)throw new s(`INVALID_ARGS`,ue);let i=t.selector,a=await v(e,t,{updateSession:!0,...H(r)});if(r===`exists`){let t=xe(a.snapshot.nodes,i,{platform:e.backend.platform});if(!t)throw new s(`COMMAND_FAILED`,we(i,[],{unique:!1}),{hint:Ce([])});return{predicate:r,pass:!0,selector:t.selector,matches:t.matches,selectorChain:Te(i)}}let o=ve(a.snapshot.nodes,i,{platform:e.backend.platform,...ye(_.readUnique)});if(!o)throw new s(`COMMAND_FAILED`,we(i,[],{unique:!0}),{command:`is`,reason:`selector_not_found`,predicate:r,selector:i,hint:Ce([])});Ae(o.node,a.snapshot.nodes,t.expectedResolvedTarget,`is`);let c=pe({predicate:r,node:o.node,nodes:a.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!c.pass)throw new s(`COMMAND_FAILED`,`is ${r} failed for selector ${o.selector}: ${c.details}`,{command:`is`,reason:`predicate_failed`,predicate:r,selector:o.selector,predicateDetails:c.details});return{predicate:r,pass:!0,selector:o.selector,...r===`text`?{text:c.actualText}:{},selectorChain:Te(i),node:o.node,preActionNodes:a.snapshot.nodes}},Li=async(e,t)=>await Ii(e,{...t,predicate:`visible`,selector:t.target.selector}),Ri=async(e,t)=>await Ii(e,{...t,predicate:`hidden`,selector:t.target.selector});async function zi(e,t,n){let r=pi(e,t,t.timeoutMs),i;for(;r.hasTimeRemaining();){let a=await r.capture(async r=>await Vi(e,{...t,signal:r},n,{includeHiddenContentHints:!1}));if(a.timedOut){i=a.deadline;break}if(a.value?.match)return{kind:`found`,found:!0,waitedMs:r.waitedMs()};await r.sleepUntilNextPoll()}throw _i(`find wait timed out`,r,i)}async function Bi(e,t,n){let r=_e(n,t.query),i=await v(e,t,{updateSession:!0,...H()});if(ot(i.snapshot.snapshotQuality))throw ze(i.snapshot.snapshotQuality);return{kind:`list`,matches:(r?ge(i.snapshot.nodes,r,{platform:e.backend.platform})?.matchedNodes??[]:he(i.snapshot.nodes,n,t.query,{}).matches).map(e=>({ref:`@${e.ref}`,node:e}))}}async function Vi(e,t,n,r){let i=_e(n,t.query),a=await v(e,t,{updateSession:!0,scope:Pe(e.backend.platform,n,t.query,i),includeHiddenContentHints:r?.includeHiddenContentHints,...H()});if(ot(a.snapshot.snapshotQuality))throw ze(a.snapshot.snapshotQuality);return i?{capture:a,match:ve(a.snapshot.nodes,i,{platform:e.backend.platform,...ye(_.readAny)})?.node}:{capture:a,match:he(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0]}}async function Hi(e,t,n,r){let i=await v(e,{...t,session:n},{updateSession:!0,...H()}),a=ve(i.snapshot.nodes,r.selector,{platform:e.backend.platform,...ye(r.policy)});if(!a)throw new s(`COMMAND_FAILED`,we(r.selector,[],{unique:!0}),{hint:Ce([])});return{capture:i,node:a.node,selector:a.selector,ref:`@${a.node.ref}`}}const Ui=async(e,t)=>{if(!e.backend.performGesture)throw new s(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await Ie(e,t,t.gesture.intent);let n=await $e(e,t),r=m(t.gesture,n,e.backend.platform),i=S(await e.backend.performGesture(b(e,t),r)),a=Gi(r.pointers,0),o=Gi(r.pointers,-1);return{kind:t.gesture.intent,durationMs:r.durationMs,pointerCount:r.topology===`single`?1:2,from:a,to:o,...i?{backendResult:i}:{},...y(Ki(t.gesture,a,o))}},Wi=async(e,t)=>{let n=t.gesture;return n.intent===`drag`?await nt(e,{...t,gesture:n}):await Ui(e,{...t,gesture:n})};function Gi(e,t){let n=e.map(e=>t===0?e.samples[0]?.point:e.samples.at(-1)?.point);if(n.some(e=>e===void 0))throw new s(`COMMAND_FAILED`,`Gesture plan did not contain endpoint samples.`);let r=n;return{x:r.reduce((e,t)=>e+t.x,0)/r.length,y:r.reduce((e,t)=>e+t.y,0)/r.length}}function Ki(e,t,n){switch(e.intent){case`pan`:{let r=`preset`in e?t:e.origin,i=`preset`in e?{x:n.x-t.x,y:n.y-t.y}:e.delta;return`Panned (${r.x}, ${r.y}) by (${i.x}, ${i.y})`}case`fling`:return`direction`in e?`Flung ${e.direction}`:`Flung`;case`pinch`:return`Pinched to scale ${e.scale}`;case`rotate`:return`Rotated gesture ${e.degrees} degrees`;case`transform`:return`Requested transform gesture by (${e.delta.x}, ${e.delta.y}), scale ${e.scale}, rotate ${e.degrees} degrees`}}const W={find:Mi,get:Ni,getText:Pi,getAttrs:Fi,is:Ii,isVisible:Li,isHidden:Ri,wait:Ai,waitForText:ji},G={click:ri,press:ni,fill:ii,typeText:ai,focus:Ke,longPress:Je,scroll:Qe,gesture:Wi,settleObservation:Ue};function qi(e){return{find:t=>W.find(e,t),get:t=>W.get(e,t),getText:(t,n={})=>W.getText(e,{...n,target:t}),getAttrs:(t,n={})=>W.getAttrs(e,{...n,target:t}),is:t=>W.is(e,t),isVisible:(t,n={})=>W.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>W.isHidden(e,{...n,target:t}),wait:t=>W.wait(e,t),waitForText:(t,n={})=>W.waitForText(e,{...n,text:t})}}function Ji(e){return{click:(t,n={})=>G.click(e,{...n,target:t}),press:(t,n={})=>G.press(e,{...n,target:t}),fill:(t,n,r={})=>G.fill(e,{...r,target:t,text:n}),typeText:(t,n={})=>G.typeText(e,{...n,text:t}),focus:(t,n={})=>G.focus(e,{...n,target:t}),longPress:(t,n={})=>G.longPress(e,{...n,target:t}),scroll:t=>G.scroll(e,t),gesture:t=>G.gesture(e,t),settleObservation:t=>G.settleObservation(e,t)}}function K(e,t){if(e!==void 0)return q(e,t)}function q(e,t){let n=e?.trim();if(!n)throw new s(`INVALID_ARGS`,`${t} must be a non-empty string`);return n}const Yi=async(e,t={})=>{if(!e.backend.listDevices)throw new s(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(b(e,t),t.filter)}},Xi=async(e,t={})=>{if(!e.backend.bootDevice)throw new s(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let n=oa(t.target),r=S(await e.backend.bootDevice(b(e,t),n));return{kind:`deviceBooted`,...n?{target:n}:{},...r?{backendResult:r}:{},...y(`Booted device`)}},Zi=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new s(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let n=oa(t.target),r=S(await e.backend.shutdownDevice(b(e,t),n));return{kind:`deviceShutdown`,...n?{target:n}:{},...r?{backendResult:r}:{},...y(`Shutdown device`)}},Qi=async(e,t)=>await ta(e,t,`install`),$i=async(e,t)=>await ta(e,t,`reinstall`),ea=async(e,t)=>await ta(e,t,`installFromSource`);async function ta(e,t,n){let r=n===`reinstall`?`reinstallApp`:`installApp`,i=e.backend[r];if(!i)throw new s(`UNSUPPORTED_OPERATION`,`admin.${n} is not supported by this backend`);let a=`app`in t&&t.app!==void 0?q(t.app,`app`):void 0;if(n!==`installFromSource`&&!a)throw new s(`INVALID_ARGS`,`admin.${n} requires app`);let o=b(e,t),c=await na(e,o,t.source);try{let t=await i.call(e.backend,o,{...a?{app:a}:{},source:c.source});return sa(n,a,c.source,t)}finally{await c.cleanup?.()}}async function na(e,t,n){let r=await ra(e,ia(n));try{return{source:ia(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function ra(e,t){if(t.kind===`url`)return{source:t};let n=await z(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function ia(e){if(!e||typeof e!=`object`)throw new s(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:q(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:q(e.id,`source.id`)};if(e.kind===`url`){let t=q(e.url,`source.url`);return aa(t),{kind:`url`,url:t}}throw new s(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function aa(e){let t;try{t=new URL(e)}catch{throw new s(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new s(`INVALID_ARGS`,`Install source URL must use http or https`)}function oa(e){if(!e)return;let t=K(e.id,`target.id`),n=K(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function sa(e,t,n,r){let i=S(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=J(r,`appName`),s=J(r,`appId`),c=J(r,`bundleId`),l=J(r,`packageName`),u=J(r,`launchTarget`),d=J(r,`installablePath`),f=J(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...c?{bundleId:c}:{},...l?{packageName:l}:{},...u?{launchTarget:u}:{},...d?{installablePath:d}:{},...f?{archivePath:f}:{},...i?{backendResult:i}:{},...y(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??u??t??ca(n)}`)}}function J(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function ca(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const la=/^[A-Za-z0-9_.:-]{1,64}$/,ua=async(e,t)=>{if(!e.backend.openApp)throw new s(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let n=ga(t),r=S(await e.backend.openApp(Y(e,t),n,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:`appOpened`,target:n,relaunch:t.relaunch===!0,...r?{backendResult:r}:{},...y(`Opened: ${va(n)}`)}},da=async(e,t={})=>{if(!e.backend.closeApp)throw new s(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let n=K(t.app,`app`),r=S(await e.backend.closeApp(Y(e,t),n));return{kind:`appClosed`,...n?{app:n}:{},...r?{backendResult:r}:{},...y(n?`Closed: ${n}`:`Closed app`)}},fa=async(e,t={})=>{if(!e.backend.listApps)throw new s(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(Y(e,t),ct(t.filter))}},pa=async(e,t)=>{if(!e.backend.getAppState)throw new s(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let n=q(t.app,`app`);return{kind:`appState`,app:n,state:await e.backend.getAppState(Y(e,t),n)}},ma=async(e,t)=>{if(!e.backend.pushFile)throw new s(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let n=q(t.app,`app`),r=await ya(e,t.input);try{let i=S(await e.backend.pushFile(Y(e,t),r.backendInput,n));return{kind:`appPushed`,app:n,inputKind:r.inputKind,...i?{backendResult:i}:{},...y(`Pushed to ${n}`)}}finally{await r.cleanup?.()}},ha=async(e,t)=>{if(!e.backend.triggerAppEvent)throw new s(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let n=ba(t.name);xa(t.payload,`apps.triggerEvent payload for "${n}"`);let r=S(await e.backend.triggerAppEvent(Y(e,t),{name:n,...t.payload?{payload:t.payload}:{}}));return{kind:`appEventTriggered`,name:n,...t.payload?{payload:t.payload}:{},...r?{backendResult:r}:{},...y(`Triggered app event: ${n}`)}};function ga(e){let t=K(e.app,`app`),n=K(e.appId,`appId`),r=K(e.bundleId,`bundleId`),i=K(e.packageName,`packageName`),a=K(e.url,`url`),o=K(e.activity,`activity`),c={...t?{app:t}:{},...n?{appId:n}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...a?{url:a}:{},...o?{activity:o}:{}};if(!_a(c))throw new s(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function _a(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function va(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function ya(e,t){if(!t||typeof t!=`object`)throw new s(`INVALID_ARGS`,`apps.push requires an input`);if(t.kind===`json`)return Sa(t.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:t.payload},inputKind:`json`};let n=await z(e,t,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:n.path},inputKind:`file`,...n.cleanup?{cleanup:n.cleanup}:{}}}function ba(e){let t=q(e,`name`);if(!la.test(t))throw new s(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${t}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return t}function xa(e,t){e!==void 0&&Sa(e,t,8192)}function Sa(e,t,n){if(Ca(e,t),Buffer.byteLength(wa(e,t),`utf8`)>n)throw new s(`INVALID_ARGS`,`${t} exceeds ${n} bytes`)}function Ca(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new s(`INVALID_ARGS`,`${t} must be a JSON object`)}function wa(e,t){try{let n=JSON.stringify(e);if(typeof n!=`string`)throw new s(`INVALID_ARGS`,`${t} must be JSON-serializable`);return n}catch{throw new s(`INVALID_ARGS`,`${t} must be JSON-serializable`)}}function Y(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const Ta={open:ua,close:da,list:fa,state:pa,push:ma,triggerEvent:ha},Ea={devices:Yi,boot:Xi,shutdown:Zi,install:Qi,reinstall:$i,installFromSource:ea};function Da(e){return{...x(Ta,e),list:(t={})=>Ta.list(e,{...t,filter:lt(t.filter)})}}const Oa=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,ka=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function Aa(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(ka,()=>(t=!0,`[REDACTED]`)),n=Ma(n,()=>{t=!0}),{value:n,redacted:t}}function ja(e){try{let t=new URL(e),n=Na(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Ma(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=ja(e);return n?(n.redacted&&t(),n.value):e}):e}function Na(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Oa.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const X=2048,Pa=4096,Fa=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function Ia(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=Q(e.message,Pa),r=Ua(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function La(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?Ba(e.url):void 0,i=t===`headers`||t===`all`?za(e.requestHeaders):void 0,a=t===`headers`||t===`all`?za(e.responseHeaders):void 0,o=t===`body`||t===`all`?Va(e.requestBody):void 0,s=t===`body`||t===`all`?Va(e.responseBody):void 0,c=Ua(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function Ra(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=Q(e.message,Pa),r=Ua(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function za(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(Fa.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=Q(i,X);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function Ba(e){return ja(e)??Q(e,X)}function Va(e){return e===void 0?{redacted:!1}:Ha(e)??Q(e,X)}function Ha(e){try{let t=Z(JSON.parse(e),Aa);return Wa(JSON.stringify(t.value),X,t.redacted)}catch{return}}function Ua(e){return Z(e,e=>Q(e,X))}function Z(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=Z(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(Fa.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=Z(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function Q(e,t){if(e===void 0)return{redacted:!1};let n=Aa(e);return Wa(n.value,t,n.redacted)}function Wa(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const Ga=async(e,t={})=>{if(!e.backend.readLogs)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return Ia(await e.backend.readLogs(await Ja(e,t),Ya(t)))},Ka=async(e,t={})=>{if(!e.backend.dumpNetwork)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let n=Xa(t);return La(await e.backend.dumpNetwork(await Ja(e,t),n),n.include??`summary`)},qa=async(e,t={})=>{if(!e.backend.measurePerf)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return Ra(await e.backend.measurePerf(await Ja(e,t),Za(t)))};async function Ja(e,t){let n=b(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function Ya(e){return{...Qa(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:to(e.levels,`levels`)},...e.search===void 0?{}:{search:q(e.search,`search`)},...e.source===void 0?{}:{source:q(e.source,`source`)}}}function Xa(e){return{...Qa(e,25,200,`network limit`),include:eo(e.include)}}function Za(e){return{...$a(e),...e.sampleMs===void 0?{}:{sampleMs:C(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:to(e.metrics,`metrics`,20)}}}function Qa(e,t,n,r){return{...$a(e),...e.cursor===void 0?{}:{cursor:q(e.cursor,`cursor`)},limit:e.limit===void 0?t:C(e.limit,r,1,n)}}function $a(e){return{...e.since===void 0?{}:{since:q(e.since,`since`)},...e.until===void 0?{}:{until:q(e.until,`until`)}}}function eo(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new s(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function to(e,t,n=50){if(!Array.isArray(e))throw new s(`INVALID_ARGS`,`${t} must be an array of strings`);if(e.length>n)throw new s(`INVALID_ARGS`,`${t} must contain at most ${n} entries`);return e.map((e,n)=>q(e,`${t}[${n}]`))}const no={logs:Ga,network:Ka,perf:qa},ro=async(e,t)=>{let n=co(t.action,`record`),r=n===`start`?e.backend.startRecording:e.backend.stopRecording;if(!r)throw new s(`UNSUPPORTED_OPERATION`,`record ${n} is not supported by this backend`);let i=t.out?await B(e,t.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let a=ao(t,i?.path);return lo(n,await r.call(e.backend,b(e,t),a),await i?.publish())}catch(e){throw await i?.cleanup?.(),e}},io=async(e,t)=>{let n=co(t.action,`trace`),r=n===`start`?e.backend.startTrace:e.backend.stopTrace;if(!r)throw new s(`UNSUPPORTED_OPERATION`,`trace ${n} is not supported by this backend`);let i=t.out?await B(e,t.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let a={...i?.path?{outPath:i.path}:{}};return uo(n,await r.call(e.backend,b(e,t),a),await i?.publish())}catch(e){throw await i?.cleanup?.(),e}};function ao(e,t){let n={};t&&(n.outPath=t);let r=oo(e.fps);r!==void 0&&(n.fps=r);let i=so(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function oo(e){return e===void 0?void 0:C(e,`fps`,1,60)}function so(e){if(e===void 0)return;let t=et(e);if(t===void 0)throw new s(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return t}function co(e,t){if(e===`start`||e===`stop`)return e;throw new s(`INVALID_ARGS`,`${t} action must be start or stop`)}function lo(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...fo(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function uo(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...fo(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function fo(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...y(e===`start`?r.startMessage:r.stopMessage)}}const po={record:ro,trace:io},mo=async(e,t={})=>{if(!e.backend.pressBack)throw new s(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let n=t.mode??`in-app`;if(n!==`in-app`&&n!==`system`)throw new s(`INVALID_ARGS`,`system.back mode must be in-app or system`);let r=S(await e.backend.pressBack(b(e,t),{mode:n}));return{kind:`systemBack`,mode:n,...r?{backendResult:r}:{},...y(`Back`)}},ho=async(e,t={})=>{if(!e.backend.pressHome)throw new s(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let n=S(await e.backend.pressHome(b(e,t)));return{kind:`systemHome`,...n?{backendResult:n}:{},...y(`Home`)}},go=async(e,t)=>{if(!e.backend.pressTvRemote)throw new s(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let n=ae(t.button),r=t.durationMs===void 0?void 0:C(t.durationMs,`durationMs`,0,1e4),i=S(await e.backend.pressTvRemote(b(e,t),{button:n,...r===void 0?{}:{durationMs:r}}));return{kind:`tvRemotePressed`,button:n,...r===void 0?{}:{durationMs:r},...i?{backendResult:i}:{},...y(`Pressed TV remote ${n}`)}},_o=async(e,t)=>{if(!e.backend.setOrientation)throw new s(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let n=Co(t.orientation),r=S(await e.backend.setOrientation(b(e,t),n));return{kind:`systemOrientationSet`,orientation:n,...r?{backendResult:r}:{},...y(`Rotated to ${n}`)}},vo=async(e,t={})=>{if(!e.backend.setKeyboard)throw new s(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let n=t.action??`status`;if(!st(n))throw new s(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let r=await e.backend.setKeyboard(b(e,t),{action:n}),i=S(r),a=Mo(r)?r:{};return n===`enter`||n===`return`?To(a,i):n===`dismiss`?Eo(n,a,i):Oo(n,a,i)},yo=async(e,t)=>{if(t.action===`read`){if(!e.backend.getClipboard)throw new s(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let n=await e.backend.getClipboard(b(e,t));return{kind:`clipboardText`,action:`read`,text:typeof n==`string`?n:n.text}}if(t.action!==`write`)throw new s(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new s(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof t.text!=`string`)throw new s(`INVALID_ARGS`,`system.clipboard write requires text`);let n=S(await e.backend.setClipboard(b(e,t),t.text));return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...y(`Clipboard updated`)}},bo=async(e,t={})=>{if(!e.backend.openSettings)throw new s(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let n=K(t.target,`target`),r=S(await e.backend.openSettings(b(e,t),n));return{kind:`settingsOpened`,...n?{target:n}:{},...r?{backendResult:r}:{},...y(n?`Opened settings: ${n}`:`Opened settings`)}},xo=async(e,t={})=>{if(!e.backend.handleAlert)throw new s(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let n=t.action??`get`;if(n!==`get`&&n!==`accept`&&n!==`dismiss`&&n!==`wait`)throw new s(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let r=t.timeoutMs===void 0?void 0:C(t.timeoutMs,`timeoutMs`,0,12e4);return wo(n,await e.backend.handleAlert(b(e,t),n,{timeoutMs:r}))},So=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new s(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let n=S(await e.backend.openAppSwitcher(b(e,t)));return{kind:`appSwitcherOpened`,...n?{backendResult:n}:{},...y(`Opened app switcher`)}};function Co(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new s(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function wo(e,t){return e===`get`?ko(t):e===`wait`?Ao(t):jo(e,t)}function To(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...y(`Keyboard enter pressed`)}}function Eo(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...y(Do(t))}}function Do(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function Oo(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function ko(e){if(e.kind!==`alertStatus`)throw new s(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function Ao(e){if(e.kind!==`alertWait`)throw new s(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:e.alert,...e.waitedMs===void 0?{}:{waitedMs:e.waitedMs},...e.timedOut===void 0?{}:{timedOut:e.timedOut},...y(e.alert?`Alert visible`:`Alert wait timed out`)}}function jo(e,t){if(t.kind!==`alertHandled`)throw new s(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...y(t.handled?`Alert ${e}ed`:`No alert handled`)}}function Mo(e){return!!(e&&typeof e==`object`)}const No={back:mo,home:ho,orientation:_o,keyboard:vo,clipboard:yo,settings:bo,alert:xo,appSwitcher:So,tvRemote:go};function Po(e){return{capture:x(Zr,e),selectors:qi(e),interactions:Ji(e),system:x(No,e),apps:Da(e),admin:x(Ea,e),recording:x(po,e),observability:x(no,e)}}var Fo=r({createAgentDevice:()=>Io,createMemorySessionStore:()=>Lo,localCommandPolicy:()=>zo,restrictedCommandPolicy:()=>Bo});function Io(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??Lo(),policy:e.policy??Bo(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,...Po(t)}}function Lo(e=[]){let t=new Map(e.map(e=>[e.name,$(e)]));return{get:e=>$(t.get(e)),set:e=>{t.set(e.name,$(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>$(e))}}function $(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:Ro(e.metadata)}:{}}}function Ro(e){try{return structuredClone(e)}catch{return{...e}}}function zo(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,...e}}function Bo(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,...e}}export{Lt as _,Or as a,M as c,hn as d,tn as f,Pt as g,St as h,ei as i,N as l,xt as m,zo as n,Cr as o,bt as p,Fo as r,gn as s,Io as t,mn as u};
|
|
1
|
+
import{a as e,i as t,n,o as r,r as i,t as a}from"./png-worker-contract.js";import{T as o,_ as s,d as c,g as l,l as u,p as d,u as f,v as p}from"./sdk-contracts.js";import{L as m,Lt as h,Ot as ee,St as te,a as ne,i as re,r as ie,w as ae,wt as oe,x as g}from"./version.js";import{$t as _,Ln as se,St as ce,Wt as le,Xt as ue,Yt as de,Zt as fe,dt as pe,ht as v,in as me,jn as he,jt as ge,ln as _e,nn as ve,on as ye,pn as be,pt as xe,wt as Se}from"./sdk-batch-runner.js";import{$ as Ce,A as we,B as Te,D as Ee,E as De,F as Oe,I as ke,L as Ae,M as je,N as y,O as Me,P as Ne,Q as Pe,R as Fe,T as Ie,U as Le,X as Re,_ as ze,b as Be,ct as Ve,d as He,et as Ue,f as We,g as Ge,gn as b,h as Ke,k as qe,lt as x,m as Je,ot as S,p as Ye,rn as Xe,st as C,tt as Ze,u as Qe,ut as w,v as $e,w as et,y as tt,z as nt}from"./prepare-kind.js";import{A as rt}from"./screenshot-result.js";import{f as it,p as at}from"./device.js";import{j as ot}from"./sdk-android-adb.js";import T from"node:path";import st,{promises as E}from"node:fs";import{fileURLToPath as ct}from"node:url";import{Worker as lt}from"node:worker_threads";const ut=/\b(logbox|redbox|reload js|copy stack|component stack|call stack|runtime error|open debugger to view warnings)\b/,dt=[/\b[\w.$<>/-]+\.(?:tsx?|jsx?):\d+(?::\d+)?\b/,/\b[\w.$<>/-]+\.(?:tsx?|jsx?)\s+\(\d+:\d+\)/],ft=[/^!,\s+/,/^(warn|warning|error):\s+/,/\b(?:possible\s+)?unhandled (?:promise )?rejection\b/],pt=[`open debugger to view warnings`,`getsnapshot should be cached to avoid an infinite loop`,`unique "key" prop`,`unique 'key' prop`,`virtualizedlists should never be nested`,`failed prop type`],mt=new Set([`x`,`×`,`✕`,`✖`,`⨯`]);function ht(e){if(gt(e).detected)return[`Hint: React Native warning/error overlay detected. It overlays part of the app and should be handled before interacting.`,`Run: agent-device react-native dismiss-overlay`,`The command verifies the overlay is gone. Run agent-device snapshot -i afterward only when you need fresh refs for the next action.`].join(`
|
|
2
|
+
`)}function gt(e){let t=yt(e),n=t.detected?bt(t):null;return{detected:t.detected,dismissNodes:t.dismissNodes,minimizeNodes:t.minimizeNodes,collapsedNodes:t.collapsedNodes,primaryAction:n}}function _t(e){return Dt(e.label?.trim())&&Lt(e.rect)}function vt(e,t){let n=e.label?.trim();return!n||!_t(e)?!1:t.some(e=>e.label?.trim()===n&&Rt(e))}function yt(e){let t=e.map(xt).join(`
|
|
3
|
+
`).toLowerCase(),n=D(e,kt),r=D(e,Nt),i=D(e,Dt,Ft),a=D(e,Ot),o=Ct(t),s=wt(t);return{dismissNodes:n,minimizeNodes:r,collapsedNodes:i,detected:Et({text:t,hasReactNativeStackFrame:o,hasOverlayControl:Tt(t,n,r),hasControllessRedBoxText:s,collapsedNodes:i,openDebuggerWarningNodes:a})}}function bt(e){let t=zt(e.dismissNodes);if(t)return Ht(t,Ut(t));let n=Wt(e.collapsedNodes.filter(It));return n?.rect?{action:`close-collapsed-banner`,point:Yt(n),rect:n.rect,ref:n.ref,label:O(n)}:null}function xt(e){return[e.label,e.value,e.identifier,e.type,e.role].filter(Boolean).join(` `)}function St(e){return ut.test(e)}function Ct(e){return dt.some(t=>t.test(e))}function wt(e){return/\buncaught\b/.test(e)&&/unable to download asset/.test(e)}function Tt(e,t,n){return t.length>0||n.length>0||/\b(reload js|copy stack)\b/.test(e)}function Et(e){return e.collapsedNodes.length>0||e.openDebuggerWarningNodes.length>0||e.hasControllessRedBoxText||e.hasOverlayControl&&(St(e.text)||e.hasReactNativeStackFrame)}function Dt(e){let t=e?.trim().toLowerCase();return t?pt.some(e=>t.includes(e))||ft.some(e=>e.test(t)):!1}function Ot(e){return e.includes(`open debugger to view warnings`)||/^!,\s+open debugger\b/.test(e)}function kt(e){return At(e)||jt(e)||Mt(e)}function At(e){return/^dismiss(?:\s*\([^)]*\))?$/i.test(e)}function jt(e){return/^close(?:\s*\([^)]*\))?$/i.test(e)}function Mt(e){return mt.has(e)}function Nt(e){return/^minimi[sz]e(?:\b|\s|\()/i.test(e)}function Pt(e){return/^!,\s+/.test(e)}function Ft(e){return!e.rect||e.rect.height<=180}function It(e){let t=O(e)?.trim().toLowerCase()??``;return(Ot(t)||Pt(t))&&Rt(e)}function Lt(e){return e?e.x<=1&&e.y<=1&&e.width>=300&&e.height>=600:!1}function Rt(e){return e.rect?e.rect.width>=120&&e.rect.height>=36&&e.rect.height<=180:!1}function D(e,t,n=()=>!0){let r=[];for(let i of e)i.ref&&n(i)&&[i.label,i.value,i.identifier].map(e=>e?.trim().toLowerCase()).filter(e=>!!e).some(e=>t(e))&&r.push(i);return r}function zt(e){return Gt(e,Vt)}function Bt(e){let t=[e.type,e.role,e.subrole].join(` `).toLowerCase();return/\b(button|menuitem|link)\b/.test(t)}function Vt(e){return[qt(Bt(e)),qt(e.hittable),-(e.rect?se(e.rect):1/0)]}function Ht(e,t){if(!e.rect)throw Error(`React Native overlay target node must have rect`);return{action:t,point:f(e.rect),rect:e.rect,ref:e.ref,label:O(e)}}function Ut(e){let t=O(e)?.trim().toLowerCase();return t&&At(t)?`dismiss`:`close`}function Wt(e){return Gt(e,Kt)}function Gt(e,t){let n=e.filter(e=>e.rect);return n.length===0?null:n.sort((e,n)=>Jt(t(n),t(e)))[0]??null}function Kt(e){return[qt(e.hittable),e.rect?.width??0,e.rect?.y??0]}function qt(e){return+(e===!0)}function Jt(e,t){for(let n=0;n<e.length;n+=1){let r=e[n]-t[n];if(r!==0)return r}return 0}function Yt(e){if(!e.rect)throw Error(`Collapsed React Native warning node must have rect`);let t=Math.min(e.rect.height,52),n=Math.min(36,Math.max(18,t*.45));return{x:Math.round(Xt(e.rect.x+e.rect.width-n,e.rect.x+1,e.rect.x+e.rect.width-1)),y:Math.round(e.rect.y+t/2)}}function Xt(e,t,n){return Math.min(n,Math.max(t,e))}function O(e){return e.label??e.value??e.identifier}function Zt(e){let t=e?.trim().split(/\s+/,1)[0];if(!t||!t.startsWith(`@`)||t.length<3)return null;let n=t.slice(1);return/^[A-Za-z_-]*\d[\w-]*$/i.test(n)||/^(?:ref|node|element|el)[\w-]*$/i.test(n)?t:null}function Qt(e,t){try{let n=ct(e),r=T.extname(n)||`.js`;return[T.join(T.dirname(n),`${t}${r}`),T.join(T.dirname(n),`internal`,`${t}${r}`)].find(e=>st.existsSync(e))??null}catch{return null}}var k=class extends Error{};let A=null,$t=!1,en=!1,tn=0;const j=new Map;function nn(e){$t=!0,!en&&(en=!0,ot({level:`warn`,phase:`png_worker_unavailable`,data:{reason:e}}),process.emitWarning(`PNG worker unavailable, falling back to in-process PNG processing: ${e}`))}function rn(e){let t=j.get(e.id);t&&(j.delete(e.id),sn(),e.ok?t.resolve(e.result):t.reject(new s(o(e.error.code),e.error.message,e.error.details)))}function an(e,t){A===e&&(nn(t.message),A=null,e.terminate().catch(()=>{}),on(new k(`PNG worker failed: ${t.message}`)))}function on(e){let t=[...j.values()];j.clear();for(let n of t)n.reject(e)}function sn(){A&&(j.size>0?A.ref():A.unref())}function cn(){if($t)return null;if(A)return A;let e=Qt(import.meta.url,`png-worker`);if(!e)return nn(`worker entry module not found next to the current module`),null;try{let t=new lt(e,{execArgv:e.endsWith(`.ts`)?[`--experimental-strip-types`]:[]});return t.on(`message`,rn),t.on(`error`,e=>{an(t,e)}),t.on(`exit`,e=>{an(t,Error(`PNG worker exited with code ${e}`))}),t.unref(),A=t,t}catch(e){return nn(`failed to spawn worker: ${e instanceof Error?e.message:String(e)}`),null}}function ln(e){let t=cn();if(!t)return Promise.reject(new k(`PNG worker is unavailable`));tn+=1;let n=tn;return new Promise((r,i)=>{j.set(n,{resolve:r,reject:i}),sn();try{t.postMessage({...e,id:n})}catch(e){j.delete(n),sn(),i(new k(`failed to post job to PNG worker: ${e instanceof Error?e.message:String(e)}`))}})}async function M(e,t){try{return await ln(e)}catch(e){if(e instanceof k)return t();throw e}}function un(){cn()}async function dn(){let e=A;A=null,on(new k(`PNG worker terminated`)),e&&await e.terminate()}async function N(n,r){let i=await M({kind:`decode`,png:n,label:r},()=>{let e=t(n,r);return{kind:`decode`,width:e.width,height:e.height,data:e.data}}),o=new e.PNG({width:i.width,height:i.height});return o.data=a(i.data),o}async function P(t){return a((await M({kind:`encode`,width:t.width,height:t.height,data:t.data},()=>({kind:`encode`,png:e.PNG.sync.write(t)}))).png)}async function fn(e,r,i){let{kind:a,...o}=await M({kind:`rgb-difference`,firstPng:e,secondPng:r,label:i},()=>({kind:`rgb-difference`,...n(t(e,i),t(r,i))}));return o}async function pn(e){let{kind:t,...n}=await M({kind:`diff-pixels`,...e},()=>({kind:`diff-pixels`,...i(e)}));return{...n,diffData:a(n.diffData)}}const F=[0,187,255,255];function mn(e,t){for(let n of t)n.rect.width<4||n.rect.height<4||hn(e,n.rect)}function hn(e,t){let n=gn(t);if(n==null)return;let r=L(n.x,0,e.width-1),i=L(n.y,0,e.height-1),a=L(n.right,0,e.width-1),o=L(n.bottom,0,e.height-1);for(let t=0;t<2;t+=1){for(let n=r;n<=a;n+=1)I(e,n,i+t,F),I(e,n,o-t,F);for(let n=i;n<=o;n+=1)I(e,r+t,n,F),I(e,a-t,n,F)}}function gn(e){let t=e.x+e.width-1,n=e.y+e.height-1;return[e.x,e.y,e.width,e.height,t,n].every(Number.isFinite)?{x:e.x,y:e.y,right:t,bottom:n}:null}function I(e,t,n,r){if(t<0||t>=e.width||n<0||n>=e.height)return;let i=(n*e.width+t)*4;e.data[i]=r[0],e.data[i+1]=r[1],e.data[i+2]=r[2],e.data[i+3]=r[3]}function L(e,t,n){return Number.isFinite(e)?Math.min(Math.max(e,t),n):t}const _n=[{x:-1,y:-1},{x:0,y:-1},{x:1,y:-1},{x:-1,y:0},{x:1,y:0},{x:-1,y:1},{x:0,y:1},{x:1,y:1}];function vn(e){let{mask:t,width:n,height:r,hooks:i}=e,a=new Uint8Array(t.length),o=new Int32Array(t.length),s=[];for(let e=0;e<t.length;e+=1){if(!xn(t,a,e))continue;let c=0,l=bn(o,a,0,e),u=i.create(e);for(;c<l;){let e=o[c];c+=1,i.visit(u,e),l=yn({mask:t,visited:a,queue:o,queueEnd:l,width:n,height:r,pixelIndex:e})}s.push(u)}return s}function yn(e){let{mask:t,visited:n,queue:r,width:i,height:a,pixelIndex:o}=e,s=o%i,c=Math.floor(o/i),l=e.queueEnd;for(let e of _n){let o=s+e.x,u=c+e.y;if(!Sn(o,u,i,a))continue;let d=u*i+o;xn(t,n,d)&&(l=bn(r,n,l,d))}return l}function bn(e,t,n,r){return t[r]=1,e[n]=r,n+1}function xn(e,t,n){return e[n]===1&&t[n]!==1}function Sn(e,t,n,r){return e>=0&&e<n&&t>=0&&t<r}function Cn(e,t){return e.flatMap(e=>wn(e,t.baseline.width,t.baseline.height)?Tn(e,t,jn(t.baseline.height)):[e])}function wn(e,t,n){let r=e.maxX-e.minX+1;return e.maxY-e.minY+1>=An(n)&&r>=t*.35}function Tn(e,t,n){let r=kn(e,On(Dn(En(e,t.diffMask,t.baseline.width)),Math.max(1,Math.round((e.maxX-e.minX+1)*.08))),n);if(r.length<=1)return[e];let i=r.map(([n,r])=>Mn(e,n,r,t)).filter(e=>e!==null);return i.length>1?i:[e]}function En(e,t,n){let r=[];for(let i=e.minY;i<=e.maxY;i+=1){let a=0;for(let r=e.minX;r<=e.maxX;r+=1)t[i*n+r]===1&&(a+=1);r.push(a)}return r}function Dn(e){return e.map((t,n)=>{let r=0,i=0,a=Math.max(0,n-3),o=Math.min(e.length-1,n+3);for(let t=a;t<=o;t+=1)r+=e[t],i+=1;return Math.round(r/i)})}function On(e,t){let n=[],r=null;for(let i=0;i<e.length;i+=1){if(e[i]<=t){r??=i;continue}r!==null&&(i-r>=6&&n.push([r,i-1]),r=null)}return r!==null&&e.length-r>=6&&n.push([r,e.length-1]),n}function kn(e,t,n){let r=[],i=e.minY;for(let[a,o]of t){let t=e.minY+Math.round((a+o)/2);t-i+1<n||e.maxY-t<n||(r.push([i,t]),i=t+1)}return r.push([i,e.maxY]),r}function An(e){return Math.max(48,Math.round(e*.07))}function jn(e){return Math.max(24,Math.round(e*.03))}function Mn(e,t,n,r){let i=null;for(let a=t;a<=n;a+=1)for(let t=e.minX;t<=e.maxX;t+=1){let e=a*r.baseline.width+t;r.diffMask[e]===1&&(i??=Nn(t,a),Pn(i,e,t,a,r.baseline,r.current))}return i}function Nn(e,t){return{minX:e,minY:t,maxX:e,maxY:t,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function Pn(e,t,n,r,i,a){let o=t*4;e.minX=Math.min(e.minX,n),e.minY=Math.min(e.minY,r),e.maxX=Math.max(e.maxX,n),e.maxY=Math.max(e.maxY,r),e.differentPixels+=1,e.baselineRed+=i.data[o],e.baselineGreen+=i.data[o+1],e.baselineBlue+=i.data[o+2],e.currentRed+=a.data[o],e.currentGreen+=a.data[o+1],e.currentBlue+=a.data[o+2]}const Fn=2.5;function In(e){let t=Ln(e);return Cn(t.length<=2e3?Bn(t,12):t,e).sort((e,t)=>{let n=t.differentPixels-e.differentPixels;if(n!==0)return n;let r=e.minY-t.minY;return r===0?e.minX-t.minX:r}).slice(0,8).map((t,n)=>Un(t,n+1,{width:e.baseline.width,height:e.baseline.height,totalPixels:e.totalPixels,differentPixels:e.differentPixels}))}function Ln(e){let{diffMask:t,baseline:n,current:r}=e,{width:i,height:a}=n;return vn({mask:t,width:i,height:a,hooks:{create:e=>Rn(e,i),visit:(e,t)=>zn(e,t,i,n,r)}})}function Rn(e,t){let n=e%t,r=Math.floor(e/t);return{minX:n,minY:r,maxX:n,maxY:r,differentPixels:0,baselineRed:0,baselineGreen:0,baselineBlue:0,currentRed:0,currentGreen:0,currentBlue:0}}function zn(e,t,n,r,i){let a=t%n,o=Math.floor(t/n),s=t*4;e.minX=Math.min(e.minX,a),e.minY=Math.min(e.minY,o),e.maxX=Math.max(e.maxX,a),e.maxY=Math.max(e.maxY,o),e.differentPixels+=1,e.baselineRed+=r.data[s],e.baselineGreen+=r.data[s+1],e.baselineBlue+=r.data[s+2],e.currentRed+=i.data[s],e.currentGreen+=i.data[s+1],e.currentBlue+=i.data[s+2]}function Bn(e,t){let n=[];for(let r of e.sort((e,t)=>{let n=e.minY-t.minY;return n===0?e.minX-t.minX:n})){let e=n.find(e=>Vn(e,r,t));if(!e){n.push({...r});continue}Hn(e,r)}return n}function Vn(e,t,n){return e.minX-n<=t.maxX&&t.minX-n<=e.maxX&&e.minY-n<=t.maxY&&t.minY-n<=e.maxY}function Hn(e,t){e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY),e.differentPixels+=t.differentPixels,e.baselineRed+=t.baselineRed,e.baselineGreen+=t.baselineGreen,e.baselineBlue+=t.baselineBlue,e.currentRed+=t.currentRed,e.currentGreen+=t.currentGreen,e.currentBlue+=t.currentBlue}function Un(e,t,n){let r={x:e.minX,y:e.minY,width:e.maxX-e.minX+1,height:e.maxY-e.minY+1},i={x:Math.round(e.minX+r.width/2),y:Math.round(e.minY+r.height/2)},a=Wn(e.baselineRed,e.baselineGreen,e.baselineBlue,e.differentPixels),o=Wn(e.currentRed,e.currentGreen,e.currentBlue,e.differentPixels),s=r.width*r.height;return{index:t,rect:r,normalizedRect:re({x:z(r.x/n.width),y:z(r.y/n.height),width:z(r.width/n.width),height:z(r.height/n.height)}),differentPixels:e.differentPixels,shareOfDiffPercentage:z(e.differentPixels/n.differentPixels),densityPercentage:z(e.differentPixels/s),shape:qn(r,n.width,n.height),size:Jn(s,n.totalPixels),location:Gn(i,n.width,n.height),averageBaselineColorHex:Yn(a),averageCurrentColorHex:Yn(o),baselineLuminance:Math.round(R(a)),currentLuminance:Math.round(R(o)),dominantChange:Kn(a,o)}}function Wn(e,t,n,r){return{r:Math.round(e/r),g:Math.round(t/r),b:Math.round(n/r)}}function Gn(e,t,n){let r=e.x<t/3?`left`:e.x>t*2/3?`right`:`center`,i=e.y<n/3?`top`:e.y>n*2/3?`bottom`:`middle`;return r===`center`&&i===`middle`?`center`:`${i}-${r}`}function Kn(e,t){let n=R(t)-R(e);return Math.abs(n)>=12?n>0?`brighter`:`darker`:Math.max(Math.abs(t.r-e.r),Math.abs(t.g-e.g),Math.abs(t.b-e.b))>=12?`color-shift`:`mixed`}function qn(e,t,n){return e.width>=t*.55&&e.height>=n*.12?`large-area`:e.width>=e.height*Fn?`horizontal-band`:e.height>=e.width*Fn?`vertical-band`:`compact`}function Jn(e,t){let n=e/t;return n>=.04?`large`:n>=.01?`medium`:`small`}function R(e){return e.r*.2126+e.g*.7152+e.b*.0722}function Yn(e){return`#${Xn(e.r)}${Xn(e.g)}${Xn(e.b)}`}function Xn(e){return e.toString(16).padStart(2,`0`)}function z(e){return Math.round(e*100*100)/100}const Zn=255*Math.sqrt(3);async function Qn(t,n,r={}){await $n(t,`Baseline image not found`),await $n(n,`Current screenshot not found`);let i=r.outputPath,[a,o]=await Promise.all([E.readFile(t),E.readFile(n)]),[s,c]=await Promise.all([N(a,`baseline screenshot`),N(o,`current screenshot`)]);er(s.width,s.height,`baseline screenshot`,r.maxPixels),er(c.width,c.height,`current screenshot`,r.maxPixels);let l=r.threshold??.1;if(s.width!==c.width||s.height!==c.height){let e=s.width*s.height;return await tr(r.outputPath),{match:!1,mismatchPercentage:100,totalPixels:e,differentPixels:e,dimensionMismatch:{expected:{width:s.width,height:s.height},actual:{width:c.width,height:c.height}}}}let u=s.width*s.height,d=l*Zn,{diffData:f,diffMask:p,differentPixels:m}=await pn({baselineData:s.data,currentData:c.data,width:s.width,height:s.height,maxColorDistance:d}),h=m>0?In({diffMask:p,baseline:s,current:c,totalPixels:u,differentPixels:m}):[];if(m>0&&i){let t=new e.PNG({width:s.width,height:s.height});t.data=f,mn(t,h),await E.mkdir(T.dirname(i),{recursive:!0}),await E.writeFile(i,await P(t))}else await tr(r.outputPath);let ee=u>0?Math.round(m/u*100*100)/100:0;return{...m>0&&i?{diffPath:i}:{},...h.length>0?{regions:h}:{},totalPixels:u,differentPixels:m,mismatchPercentage:ee,match:m===0}}async function $n(e,t){try{await E.access(e)}catch{throw new s(`INVALID_ARGS`,`${t}: ${e}`)}}function er(e,t,n,r){if(r==null||r<=0)return;let i=e*t;if(!(i<=r))throw new s(`INVALID_ARGS`,`${n} is ${i} pixels, which exceeds the configured maxImagePixels limit of ${r}`)}async function tr(e){if(e)try{await E.unlink(e)}catch(e){if(!nr(e,`ENOENT`))throw e}}function nr(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}function rr(e,t){return e.map(e=>{let n=ir(e,t);return n.length>0?{...e,currentOverlayMatches:n}:e})}function ir(e,t){let n=ar(e.rect);return t.map(t=>{let r=t.overlayRect,i=ie(e.rect,r);return i<=0?null:{ref:t.ref,...t.label?{label:t.label}:{},rect:r,overlayCoveragePercentage:or(i/ar(r)),regionCoveragePercentage:or(i/n)}}).filter(e=>e!==null).sort((e,t)=>{let n=t.regionCoveragePercentage-e.regionCoveragePercentage;return n===0?t.overlayCoveragePercentage-e.overlayCoveragePercentage:n}).slice(0,3).map(e=>({ref:e.ref,...e.label?{label:e.label}:{},rect:e.rect,regionCoveragePercentage:e.regionCoveragePercentage}))}function ar(e){return e.width*e.height}function or(e){return Math.round(e*100*100)/100}async function B(e,t,n){if(t.kind===`path`&&!e.policy.allowLocalInputPaths)throw new s(`INVALID_ARGS`,`Local ${n.field??`input`} paths are not allowed by command policy`);try{return await e.artifacts.resolveInput(t,n)}catch(e){throw p(e)}}async function V(e,t,n){if(t?.kind===`path`&&!e.policy.allowLocalOutputPaths)throw new s(`INVALID_ARGS`,`Local output paths are not allowed by command policy`);try{return await e.artifacts.reserveOutput(t,{...n,visibility:n.visibility??`client-visible`,requestedClientPath:t?.kind===`downloadableArtifact`?t.clientPath??n.requestedClientPath:n.requestedClientPath})}catch(e){throw p(e)}}async function sr(e,t){try{return await e.artifacts.createTempFile(t)}catch(e){throw p(e)}}const cr=async(e,t)=>{if(!t.baseline)throw new s(`INVALID_ARGS`,`diff screenshot requires a baseline image`);let n=lr(t.threshold),r=t.current??{kind:`live`};if(t.overlayRefs&&!gr(r))throw new s(`INVALID_ARGS`,`diff screenshot <current.png> cannot use --overlay-refs because saved-image comparisons have no live accessibility refs`);let i=await B(e,t.baseline,{usage:`diff screenshot baseline`,field:`baseline`}),a,o,c,l=[];try{let s;gr(r)?(o=await ur(e,t),s=o.path):(a=await B(e,r,{usage:`diff screenshot current`,field:`current`}),s=a.path),c=t.out?await V(e,t.out,{field:`diffPath`,ext:`.png`,artifactType:`screenshot-diff`}):void 0;let u=await Qn(i.path,s,{threshold:n,outputPath:c?.path,maxPixels:e.policy.maxImagePixels});gr(r)&&(u=await dr(e,t,c?.path,u,l));let d=u.diffPath?await c?.publish():void 0;return d&&l.push(d),u.diffPath||await c?.cleanup?.(),{...u,...l.length>0?{artifacts:l}:{}}}catch(e){throw await c?.cleanup?.(),e}finally{await i.cleanup?.(),await a?.cleanup?.(),await o?.cleanup?.()}};function lr(e){if(e==null||e===``)return .1;let t=Number(e);if(Number.isNaN(t)||t<0||t>1)throw new s(`INVALID_ARGS`,`--threshold must be a number between 0 and 1`);return t}async function ur(e,t){let n=await sr(e,{prefix:`agent-device-diff-current`,ext:`.png`});try{await fr(e,t,n.path,pr(t))}catch(e){throw await n.cleanup(),e}return n}async function dr(e,t,n,r,i){if(!t.overlayRefs)return r;if(r.match||r.dimensionMismatch)return n&&await hr(n),r;let a=await V(e,mr(t,n),{field:`currentOverlayPath`,ext:`.png`,artifactType:`screenshot`});try{let n=await fr(e,t,a.path,{overlayRefs:!0,...pr(t)}),o=await a.publish();return o&&i.push(o),{...r,currentOverlayPath:n.path??a.path,...n.overlayRefs?{currentOverlayRefCount:n.overlayRefs.length}:{},...r.regions&&n.overlayRefs?{regions:rr(r.regions,n.overlayRefs)}:{}}}catch(e){throw await a.cleanup?.(),e}}async function fr(e,t,n,r={}){if(!e.backend.captureScreenshot)throw new s(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);return await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata},n,r)??{}}function pr(e){return{normalizeStatusBar:e.normalizeStatusBar??!0,...e.surface?{surface:e.surface}:{}}}function mr(e,t){if(e.currentOverlayOut)return e.currentOverlayOut;if(e.out?.kind===`path`)return{kind:`path`,path:H(t??e.out.path)};if(e.out?.kind===`downloadableArtifact`)return{kind:`downloadableArtifact`,...e.out.clientPath?{clientPath:H(e.out.clientPath)}:{},...e.out.fileName?{fileName:H(e.out.fileName)}:{}}}function H(e){let t=T.extname(e);return`${t?e.slice(0,-t.length):e}.current-overlay${t||`.png`}`}async function hr(e){try{await E.unlink(H(e))}catch(e){if(!_r(e,`ENOENT`))throw e}}function gr(e){return e.kind===`live`}function _r(e,t){return typeof e==`object`&&!!e&&`code`in e&&e.code===t}async function vr(e,t){let{min:n,max:r}=ee;if(!Number.isFinite(t)||t<n||t>r)throw new s(`INVALID_ARGS`,`Screenshot scale must be between ${n} and ${r}`);if(t===1)return;let i=await N(await E.readFile(e),`screenshot`),a=Math.max(1,Math.round(i.width*t)),o=Math.max(1,Math.round(i.height*t));await E.writeFile(e,await P(br(i,a,o)))}async function yr(e,t,n){if(!Number.isInteger(t)||t<1||!Number.isInteger(n)||n<1)throw new s(`INVALID_ARGS`,`Screenshot resize dimensions must be positive integers`);let r=await N(await E.readFile(e),`screenshot`);r.width===t&&r.height===n||await E.writeFile(e,await P(br(r,t,n)))}function br(t,n,r){let i=new e.PNG({width:n,height:r});for(let e=0;e<r;e+=1){let a=e*t.height/r,o=(e+1)*t.height/r;for(let r=0;r<n;r+=1){let s=r*t.width/n,c=(r+1)*t.width/n,l=0,u=0,d=0,f=0,p=0;for(let e=Math.floor(a);e<Math.ceil(o);e+=1){let n=Math.min(e+1,o)-Math.max(e,a);for(let r=Math.floor(s);r<Math.ceil(c);r+=1){let i=n*(Math.min(r+1,c)-Math.max(r,s)),a=(e*t.width+r)*4;l+=(t.data[a]??0)*i,u+=(t.data[a+1]??0)*i,d+=(t.data[a+2]??0)*i,f+=(t.data[a+3]??0)*i,p+=i}}let m=(e*i.width+r)*4;i.data[m]=Math.round(l/p),i.data[m+1]=Math.round(u/p),i.data[m+2]=Math.round(d/p),i.data[m+3]=Math.round(f/p)}}return i}const xr=async(e,t)=>{if(!e.backend.captureScreenshot)throw new s(`UNSUPPORTED_OPERATION`,`screenshot is not supported by this backend`);h(t);let n=await V(e,t.out,{field:`path`,ext:`.png`,artifactType:`screenshot`}),r;try{await e.backend.captureScreenshot({session:t.session,requestId:t.requestId,appId:t.appId,appBundleId:t.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},n.path,{fullscreen:t.fullscreen,overlayRefs:t.overlayRefs,pixelDensity:t.pixelDensity,stabilize:t.stabilize,normalizeStatusBar:t.normalizeStatusBar,surface:t.surface}),t.scale!==void 0&&await vr(n.path,t.scale),r=await n.publish()}catch(e){throw await n.cleanup?.(),e}return{path:n.path,...r?{artifacts:[r]}:{},...b(`Saved screenshot: ${n.path}`)}};function Sr(e){let{nodes:t,backend:n,snapshotRaw:r}=e;if(r||!l(n))return{partial:!1,visibleNodeCount:t.length,totalNodeCount:t.length,reasons:[]};let i=ne(t),a=new Set;return i.hiddenCount>0&&a.add(`offscreen-nodes`),i.nodes.some(e=>e.hiddenContentAbove)&&a.add(`scroll-hidden-above`),i.nodes.some(e=>e.hiddenContentBelow)&&a.add(`scroll-hidden-below`),{partial:a.size>0,visibleNodeCount:i.nodes.length,totalNodeCount:t.length,reasons:[...a]}}const Cr=`A system surface (notification shade, quick settings, or another system overlay) covers the app, so this snapshot shows that surface. Interact with it or dismiss it (press back or swipe up) to reach app content.`;function wr(e){return e?.systemSurfaceOnly===!0?Cr:void 0}function Tr(e,t){return e.presentationKey?e:{...e,presentationKey:u(t)}}function Er(e){let{previous:t,current:n,options:r,identity:i}=e;if(r.forceFull===!0||r.raw===!0||!t||t.comparisonSafe===!1||n.comparisonSafe===!1||!Dr(t,n,i)||!t.presentationKey||t.presentationKey!==n.presentationKey||!Or(t,n))return;let a=r.scope?.trim();return{ageMs:Math.max(0,n.createdAt-t.createdAt),nodeCount:n.nodes.length,...r.interactiveOnly===!0?{interactiveOnly:!0}:{},...a?{scope:a}:{}}}function Dr(e,t,n){return!(e.backend&&t.backend&&e.backend!==t.backend||n?.previousAppBundleId&&n.currentAppBundleId&&n.previousAppBundleId!==n.currentAppBundleId)}function Or(e,t){return e.truncated===t.truncated?JSON.stringify(kr(e.nodes))===JSON.stringify(kr(t.nodes)):!1}function kr(e){return e.map(e=>({index:e.index,depth:e.depth,parentIndex:e.parentIndex,type:e.type,role:e.role,subrole:e.subrole,label:e.label,value:e.value,identifier:e.identifier,enabled:e.enabled,selected:e.selected,focused:e.focused,hittable:e.hittable,rect:e.rect,bundleId:e.bundleId,appName:e.appName,windowTitle:e.windowTitle,surface:e.surface,hiddenContentAbove:e.hiddenContentAbove,hiddenContentBelow:e.hiddenContentBelow,interactionBlocked:e.interactionBlocked,presentationHints:e.presentationHints,actions:e.actions}))}const Ar=async(e,t)=>{let n=await Mr(e,t),r=Er({previous:n.session?.snapshot,current:n.snapshot,options:t,identity:{previousAppBundleId:n.session?.appBundleId,currentAppBundleId:n.result.appBundleId??n.session?.appBundleId}});return await e.sessions.set(Pr(t.session,n)),{nodes:n.snapshot.nodes,truncated:n.snapshot.truncated??!1,visibility:Sr({nodes:n.snapshot.nodes,backend:n.snapshot.backend,snapshotRaw:t.raw}),...te({...n.annotations,warnings:n.warnings}),...r?{unchanged:r}:{},...n.result.snapshotDiagnostics?{snapshotDiagnostics:n.result.snapshotDiagnostics}:{},...Fr(n)}},jr=async(e,t)=>{let n=await Mr(e,t),r=t.interactiveOnly===!0,i=n.session?.snapshot,a=Pr(t.session,n);if(!i){let t=Ie(n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:t},lines:[],...n.warnings.length>0?{warnings:n.warnings}:{}}}let o=et(i.nodes,n.snapshot.nodes,{flatten:r});return await e.sessions.set(a),{mode:`snapshot`,baselineInitialized:!1,summary:o.summary,lines:o.lines,...n.warnings.length>0?{warnings:n.warnings}:{}}};async function Mr(e,t){if(!e.backend.captureSnapshot)throw new s(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let n=t.session??`default`,r=await e.sessions.get(n),i=await e.backend.captureSnapshot({session:n,requestId:t.requestId,appId:r?.appId,appBundleId:r?.appBundleId,signal:t.signal??e.signal,metadata:t.metadata},{interactiveOnly:t.interactiveOnly,depth:t.depth,scope:t.scope,raw:t.raw,customActions:t.customActions}),a=Tr(Nr(i,e),t),o=oe(i),c=Ve(e);return{snapshot:a,result:i,session:r,annotations:o,warnings:Ir({result:i,annotations:o,snapshot:a,options:t,session:r,capturedAt:a.createdAt??c,runtimeNow:c})}}function Nr(e,t){return e.snapshot?e.snapshot:{nodes:e.nodes??[],truncated:e.truncated,backend:e.backend,createdAt:Ve(t)}}function Pr(e,t){let n=t.session?.name??e??`default`;return{...t.session??{name:n},name:n,snapshot:t.snapshot,appName:t.result.appName??t.session?.appName,appBundleId:t.result.appBundleId??t.session?.appBundleId}}function Fr(e){let t=e.result.appName??e.session?.appName,n=e.result.appBundleId??e.session?.appBundleId;return{...t||n?{appName:t??n}:{},...n?{appBundleId:n}:{}}}function Ir(e){let t=[...e.annotations.warnings??[]];e.annotations.quality&&t.push(...Le(e.annotations.quality,e.snapshot.nodes)),t.push(...Br(e)),e.annotations.quality||(t.push(...Rr(e)),t.push(...zr(e.snapshot.nodes)));let n=ht(e.snapshot.nodes);n&&t.push(n);let r=Lr(e.annotations);r&&t.push(r);let i=Vr(e);return i&&t.push(i),t.push(...Gr(e.annotations.freshness,e.snapshot.backend)),Array.from(new Set(t))}function Lr(e){if(e.androidSnapshot?.systemSurfaceOnly===!0)return Cr}function Rr(e){return e.snapshot.backend!==`xctest`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length!==1||e.snapshot.nodes[0]?.type!==`Application`?[]:[`iOS interactive snapshot exposed only the application root. XCTest accessibility queries can fail to enumerate some simulator UI trees even when screenshots and direct gestures still work. Use screenshot as visual truth, try a scoped/full snapshot for diagnostics, and prefer direct selectors when known.`]}function zr(e){let t=new Set(e.map(e=>e.parentIndex).filter(e=>e!==void 0));return e.filter(e=>t.has(e.index)||(e.type?.toLowerCase()??``).includes(`text`)?!1:(e.label??``).split(`, `).length>10).map(e=>{let t=(e.label??``).split(`, `).length,n=e.identifier?` (${e.identifier})`:``;return`@${e.ref} [${e.type??`element`}]${n} merges ~${t} labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`})}function Br(e){let t=e.annotations.analysis;if(e.snapshot.backend!==`android`||e.options.interactiveOnly!==!0||e.snapshot.nodes.length>0||!t||(t.rawNodeCount??0)<12)return[];let n=[`Interactive snapshot is empty after filtering ${t.rawNodeCount} raw Android nodes. Likely causes: the app content is not accessibility-visible yet, a transient route change, or depth/filter options hid the target.`];return typeof e.options.depth==`number`&&typeof t.maxDepth==`number`&&t.maxDepth>=e.options.depth+2&&n.push(`Interactive output is empty at depth ${e.options.depth}; retry without -d.`),n}function Vr(e){let t=e.session?.snapshot;if(!e.annotations.freshness&&t&&Hr(t,e.snapshot)&&Ur(t,e.capturedAt,e.runtimeNow)&&Kr(t.nodes.length,e.snapshot.nodes.length))return Wr}function Hr(e,t){return e.presentationKey===void 0||t.presentationKey===void 0?!0:e.presentationKey===t.presentationKey}function Ur(e,t,n){return[t,n].some(t=>{let n=t-e.createdAt;return n>=0&&n<=2e3})}const Wr=`Recent snapshots dropped sharply in node count, which suggests stale or mid-transition UI. Use screenshot as visual truth, wait briefly, then re-snapshot once.`;function Gr(e,t){return!e?.staleAfterRetries||t!==`android`?[]:e.reason===`stuck-route`?[`Recent ${e.action} was followed by a nearly identical snapshot after ${e.retryCount} automatic retr${e.retryCount===1?`y`:`ies`}. If you expected navigation or submit, the tree may still be stale. Use screenshot as visual truth, wait briefly, then re-snapshot once.`]:e.reason===`sharp-drop`?[Wr]:[]}function Kr(e,t){return e<12?!1:t<=Math.floor(e*.2)}const qr={screenshot:xr,diffScreenshot:cr,snapshot:Ar,diffSnapshot:jr},Jr=new WeakMap;function Yr(e,t){Zr(e)&&Jr.set(e,t)}function Xr(e){return Zr(e)?Jr.get(e):void 0}function Zr(e){return typeof e==`object`&&!!e||typeof e==`function`}const Qr=async(e,t)=>await ni(e,t,`press`),$r=async(e,t)=>await ni(e,t,`click`),ei=async(e,t)=>{if(!t.text)throw new s(`INVALID_ARGS`,`fill requires text`);let n=Ge(t),r=n.needsPreActionBaseline?null:await ai(e,t);if(r)return r;let i=await we(e,t,{action:`fill`,requireInteractive:!0,promoteToHittableAncestor:!1,captureEvidenceBaseline:n.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.fill)throw new s(`UNSUPPORTED_OPERATION`,`fill is not supported by this backend`);let a=ri(i),o=`node`in i?i.node?.type??``:``,c=o!==``&&he(o,e.backend.platform),l=t.allowNonHittableCoordinateFallback===!0&&`node`in i&&i.node?.hittable===!1,u=C(await e.backend.fill(x(e,t),a,t.text,{delayMs:t.delayMs,allowNonHittableCoordinateFallback:l})),d=o&&!c?`fill target ${si(i)} resolved to "${o}", attempting fill anyway.`:void 0;return await Ke(e,t,i,{...i,text:t.text,...d?{warning:d}:{},...u?{backendResult:u}:{}},n)},ti=async(e,t)=>{let n=t.text;if(!n)throw new s(`INVALID_ARGS`,`type requires text`);let r=ci(n);if(r)throw new s(`INVALID_ARGS`,`type does not accept a target ref like "${r}"`,{hint:`Use fill ${r} "text" to target that field, or press ${r} then type "text" to append.`});if(!e.backend.typeText)throw new s(`UNSUPPORTED_OPERATION`,`type is not supported by this backend`);let i=w(t.delayMs??0,`delay-ms`,0,1e4),a=C(await e.backend.typeText(x(e,t),n,{delayMs:i}));return{kind:`text`,text:n,delayMs:i,...a?{backendResult:a}:{},...b(`Typed ${Array.from(n).length} chars`)}};async function ni(e,t,n){let r=Ge(t),i=r.needsPreActionBaseline?null:await ii(e,t,n);if(i)return i;let a=await we(e,t,{action:n,requireInteractive:!0,promoteToHittableAncestor:!0,captureEvidenceBaseline:r.needsPreActionBaseline,expectedResolvedTarget:t.expectedResolvedTarget,preresolvedTarget:t.preresolvedTarget});if(!e.backend.tap)throw new s(`UNSUPPORTED_OPERATION`,`tap is not supported by this backend`);let o=ri(a),c;try{c=await e.backend.tap(x(e,t),o,{button:t.button,count:t.count,intervalMs:t.intervalMs,holdMs:t.holdMs,jitterPx:t.jitterPx,doubleTap:t.doubleTap})}catch(e){throw Yr(e,a),e}let l=C(c);return await Ke(e,t,a,{...a,...l?{backendResult:l}:{}},r)}function ri(e){if(!e.point)throw new s(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function ii(e,t,n){if(n!==`click`||t.target.kind!==`ref`||!e.backend.tapTarget||oi(t)||t.expectedResolvedTarget)return null;let r=await qe(e,t,t.target,n),i=C(await e.backend.tapTarget(x(e,t),{kind:`ref`,ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}}));return{kind:`ref`,target:{kind:`ref`,ref:t.target.ref},resolution:De,...r,...i?{backendResult:i}:{}}}async function ai(e,t){if(t.target.kind!==`ref`||!e.backend.fillTarget||t.expectedResolvedTarget)return null;let n=await qe(e,t,t.target,`fill`),r=C(await e.backend.fillTarget(x(e,t),{kind:`ref`,ref:t.target.ref,...t.target.fallbackLabel?{fallbackLabel:t.target.fallbackLabel}:{}},t.text,{delayMs:t.delayMs}));return{kind:`ref`,target:{kind:`ref`,ref:t.target.ref},text:t.text,resolution:De,...n,...r?{backendResult:r}:{}}}function oi(e){return e.count!==void 0||e.intervalMs!==void 0||e.holdMs!==void 0||e.jitterPx!==void 0||e.doubleTap!==void 0||e.button!==void 0&&e.button!==`primary`}function si(e){return e.target?.kind===`ref`?e.target.ref:e.target?.kind===`selector`?e.target.selector:`point`}function ci(e){return Zt(e)}function U(e){return{includeRects:e===`visible`||e===`hidden`,interactiveOnly:!1}}function li(e,t,n){let r=n??1e4,i=W(e),a=mi(),o=()=>Math.max(0,r-(W(e)-i));return{capture:async n=>{let r=!1,i=await Be(e,t,o(),async e=>await a.attempt(async()=>{let t=await n(e);return r=!0,t}));return i.timedOut?{timedOut:!0,deadline:a.readableCaptures()===0?`capture-stalled`:`capture-truncated`}:(r&&a.recordReadableCapture(),i)},hasTimeRemaining:()=>o()>0,failureEvidence:()=>({timeoutMs:r,readableCaptures:a.readableCaptures(),waitedMs:W(e)-i}),rethrowIfNeverReadable:a.rethrowIfNeverReadable,sleepUntilNextPoll:async()=>await hi(e,t,Math.min(300,o())),timeoutMs:r,waitedMs:()=>W(e)-i}}function ui(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.captureStalled,captureStalled:!0,...t,retriable:!0,hint:`No readable snapshot capture completed before the wait timeout. Retry, or use screenshot to inspect the current surface.`})}function di(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.deadlineExceeded,captureTruncated:!0,...t})}function fi(e,t){return new s(`COMMAND_FAILED`,e,{reason:g.targetAbsent,...t})}function pi(e,t,n){let r=t.failureEvidence();return n===`capture-stalled`?ui(e,r):n===`capture-truncated`?di(e,r):(t.rethrowIfNeverReadable(),r.readableCaptures===0?ui(e,r):fi(e,r))}function mi(){let e=0,t;return{attempt:async e=>{try{return await e()}catch(e){if(!Te(e))throw e;t=e;return}},recordReadableCapture:()=>{e+=1},readableCaptures:()=>e,rethrowIfNeverReadable:()=>{if(e===0&&t!==void 0)throw t}}}function W(e){return e.clock?.now()??Date.now()}async function hi(e,t,n){let r=[t.signal,e.signal].filter(e=>e!==void 0);for(let e of r)e.throwIfAborted();if(n<=0)return!1;if(e.clock){await e.clock.sleep(n);for(let e of r)e.throwIfAborted();return!0}return await new Promise((e,t)=>{let i=r.length>0?AbortSignal.any(r):void 0,a=()=>i?.removeEventListener(`abort`,s),o=setTimeout(()=>{a(),e()},n),s=()=>{clearTimeout(o),a(),t(i?.reason)};i?.addEventListener(`abort`,s,{once:!0}),o.unref()}),!0}function gi(e){if(e.kind===`ambiguous`)return{selector:e.selector,selectorIndex:e.selectorIndex,matchedNodes:e.matchedNodes};if(e.kind===`resolved`)return{selector:e.resolution.selector,selectorIndex:e.resolution.selectorIndex,matchedNodes:e.matchedNodes}}function _i(e){let t=async(t,n)=>{if(n.target.kind===`sleep`)return await hi(t,n,n.target.durationMs),{kind:`sleep`,waitedMs:n.target.durationMs};if(n.target.kind===`ref`){let r=await e.requireSnapshot(t,n.session),i=d(n.target.ref);if(!i)throw new s(`INVALID_ARGS`,`Invalid ref: ${n.target.ref}`);let a=c(r.snapshot.nodes,i),o=a?Pe(a,r.snapshot.nodes):void 0;if(!o)throw new s(`COMMAND_FAILED`,`Ref ${n.target.ref} not found or has no label`);return await bi(e,t,n,o,n.target.timeoutMs)}if(n.target.kind===`selector`)return await vi(e,t,n,n.target.selector,n.target.timeoutMs,n.target.recordedLandmark);if(n.target.kind===`stable`)return await Si(e,t,n,n.target.quietMs,n.target.timeoutMs);let r=de(n.target.text);if(!r.ok)throw new s(r.code,r.message);return await bi(e,t,n,n.target.text,n.target.timeoutMs)};return{waitCommand:t,waitForTextCommand:async(e,n)=>{let r=await t(e,{...n,target:{kind:`text`,text:n.text,timeoutMs:n.timeoutMs}});if(r.kind!==`text`)throw new s(`COMMAND_FAILED`,`waitForText returned non-text result`);return r}}}async function vi(e,t,n,r,i,a){let o=li(t,n,i),c=U(),l,u;for(;o.hasTimeRemaining();){let i=await o.capture(async r=>await e.captureSnapshot(t,{...n,signal:r},{updateSession:!0,includeHiddenContentHints:!1,...c}));if(i.timedOut){u=i.deadline;break}let s=i.value;if(s){let e=s.snapshot.nodes,n=gi(v(e,r,_.wait,{platform:t.backend.platform}));if(n){let t=yi(e,n,a);if(t.kind===`satisfied`)return{kind:`selector`,selector:n.selector,waitedMs:o.waitedMs(),node:t.node,preActionNodes:e};l=t.evidence}}await o.sleepUntilNextPoll()}throw u!==`capture-stalled`&&l?new s(`COMMAND_FAILED`,`wait matched selector ${r} but no candidate carried the recorded landmark identity`,{reason:je,...l}):pi(`wait timed out for selector: ${r}`,o,u)}function yi(e,t,n){let r=t.matchedNodes[0];if(!n)return{kind:`satisfied`,node:r};let i=Ue(e),a=Ze(t.matchedNodes,i,Se(n),n.ancestry)[0];return a?{kind:`satisfied`,node:a}:{kind:`identity-mismatch`,evidence:{matchCount:t.matchedNodes.length,observed:ge(r),observedAncestry:Ce(r,i,Math.max(n.ancestry.length,1)).chain}}}async function bi(e,t,n,r,i){let a=li(t,n,i),o;for(;a.hasTimeRemaining();){let i=await a.capture(async i=>t.backend.findText?(await t.backend.findText(Ci(t,{...n,signal:i}),r)).found:await xi(e,t,{...n,signal:i},r));if(i.timedOut){o=i.deadline;break}if(i.value)return{kind:`text`,text:r,waitedMs:a.waitedMs()};await a.sleepUntilNextPoll()}throw pi(`wait timed out for text: ${r}`,a,o)}async function xi(e,t,n,r){return!!Re((await e.captureSnapshot(t,n,{updateSession:!0,includeHiddenContentHints:!1})).snapshot.nodes,r)}async function Si(e,t,n,r,i){let a=i??1e4,o=r??e.stable.defaultQuietMs,c=await e.stable.capture(t,n,{quietMs:o,timeoutMs:a});if(!c.settled)throw new s(`COMMAND_FAILED`,`wait timed out waiting for a stable UI`,{reason:g.stableTimeout,...c.stalled?{captureStalled:!0}:{},quietMs:o,timeoutMs:a,captures:c.captures,nodeCount:c.nodeCount,...c.stalled?{hint:`A snapshot capture stalled past the wait timeout, so no settle verdict is available. The UI may still be readable: retry, or use screenshot to inspect the surface.`}:{}});return{kind:`stable`,waitedMs:c.waitedMs,captures:c.captures,nodeCount:c.nodeCount,...c.nodeCount<e.stable.tinyTreeNodeCount?{hint:e.stable.tinyTreeHint}:{}}}function Ci(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const wi=_i({captureSnapshot:y,requireSnapshot:Oe,stable:{defaultQuietMs:500,tinyTreeHint:$e,tinyTreeNodeCount:5,capture:tt}}),Ti=wi.waitCommand,Ei=wi.waitForTextCommand,Di=async(e,t)=>{let n=t.locator??`any`;if(!t.query)throw new s(`INVALID_ARGS`,ye);if(t.action===`wait`)return await Pi(e,t,n);if(t.action===`list`)return await Fi(e,t,n);let{capture:r,match:i}=await Ii(e,t,n);if(!i)throw new s(`COMMAND_FAILED`,`find did not match any element`);if(t.action===`exists`)return{kind:`found`,found:!0};let a=`@${i.ref}`;return t.action===`get_attrs`?{kind:`attrs`,ref:a,node:i}:{kind:`text`,ref:a,text:await Ne(e,r,i),node:i}},Oi=async(e,t)=>{if(t.target.kind===`ref`){let n=await Oe(e,t.session),r=ke(n.snapshot.nodes,t.target.ref,{fallbackLabel:t.target.fallbackLabel??``,invalidRefMessage:`get text requires a ref like @e2`,notFoundMessage:`Ref ${t.target.ref} not found`});Ee(r.node,n.snapshot.nodes,t.expectedResolvedTarget,`get`);let i=ce(r.node,e.backend.platform,{action:`get`,nodes:n.snapshot.nodes}),a={kind:`ref`,ref:`@${r.ref}`},o=n.snapshot.nodes;return t.property===`attrs`?{kind:`attrs`,target:a,node:r.node,selectorChain:i,preActionNodes:o}:{kind:`text`,target:a,text:await Ne(e,n,r.node),node:r.node,selectorChain:i,preActionNodes:o}}let n=await Li(e,t,t.session??`default`,{selector:t.target.selector,policy:t.property===`text`?_.readText:_.readUnique});Ee(n.node,n.capture.snapshot.nodes,t.expectedResolvedTarget,`get`);let r=ce(n.node,e.backend.platform,{action:`get`,nodes:n.capture.snapshot.nodes});if(t.property===`attrs`)return{kind:`attrs`,target:{kind:`selector`,selector:n.selector},node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes};let i=await Ne(e,n.capture,n.node);return{kind:`text`,target:{kind:`selector`,selector:n.selector},text:i,node:n.node,selectorChain:r,preActionNodes:n.capture.snapshot.nodes}},ki=async(e,t)=>{let n=await Oi(e,{...t,property:`text`,target:t.target});if(n.kind!==`text`)throw new s(`COMMAND_FAILED`,`getText returned non-text result`);return n},Ai=async(e,t)=>{let n=await Oi(e,{...t,property:`attrs`,target:t.target});if(n.kind!==`attrs`)throw new s(`COMMAND_FAILED`,`getAttrs returned non-attrs result`);return n},ji=async(e,t)=>{let n=ue(t.predicate);if(!n.ok)throw new s(n.code,n.message,{hint:n.hint});let r=n.predicate;if(r===`text`&&!t.expectedText)throw new s(`INVALID_ARGS`,le);let i=t.selector,a=await y(e,t,{updateSession:!0,...U(r)});if(r===`exists`){let t=v(a.snapshot.nodes,i,_.readAny,{platform:e.backend.platform});if(t.kind!==`resolved`)throw new s(`COMMAND_FAILED`,ve(i,[],{unique:!1}),{hint:me([])});return{predicate:r,pass:!0,selector:t.resolution.selector,matches:t.resolution.matches,selectorChain:xe(i)}}let o=v(a.snapshot.nodes,i,_.readUnique,{platform:e.backend.platform});if(o.kind!==`resolved`)throw new s(`COMMAND_FAILED`,ve(i,[],{unique:!0}),{command:`is`,reason:`selector_not_found`,predicate:r,selector:i,hint:me([])});let c=o.resolution;Ee(c.node,a.snapshot.nodes,t.expectedResolvedTarget,`is`);let l=fe({predicate:r,node:c.node,nodes:a.snapshot.nodes,expectedText:t.expectedText,platform:e.backend.platform});if(!l.pass)throw new s(`COMMAND_FAILED`,`is ${r} failed for selector ${c.selector}: ${l.details}`,{command:`is`,reason:`predicate_failed`,predicate:r,selector:c.selector,predicateDetails:l.details});return{predicate:r,pass:!0,selector:c.selector,...r===`text`?{text:l.actualText}:{},selectorChain:xe(i),node:c.node,preActionNodes:a.snapshot.nodes}},Mi=async(e,t)=>await ji(e,{...t,predicate:`visible`,selector:t.target.selector}),Ni=async(e,t)=>await ji(e,{...t,predicate:`hidden`,selector:t.target.selector});async function Pi(e,t,n){let r=li(e,t,t.timeoutMs),i;for(;r.hasTimeRemaining();){let a=await r.capture(async r=>await Ii(e,{...t,signal:r},n,{includeHiddenContentHints:!1}));if(a.timedOut){i=a.deadline;break}if(a.value?.match)return{kind:`found`,found:!0,waitedMs:r.waitedMs()};await r.sleepUntilNextPoll()}throw pi(`find wait timed out`,r,i)}async function Fi(e,t,n){let r=be(n,t.query),i=await y(e,t,{updateSession:!0,...U()});if(nt(i.snapshot.snapshotQuality))throw Fe(i.snapshot.snapshotQuality);return{kind:`list`,matches:(r?pe(i.snapshot.nodes,r,{platform:e.backend.platform})?.matchedNodes??[]:_e(i.snapshot.nodes,n,t.query,{}).matches).map(e=>({ref:`@${e.ref}`,node:e}))}}async function Ii(e,t,n,r){let i=be(n,t.query),a=await y(e,t,{updateSession:!0,scope:Ae(e.backend.platform,n,t.query,i),includeHiddenContentHints:r?.includeHiddenContentHints,...U()});if(nt(a.snapshot.snapshotQuality))throw Fe(a.snapshot.snapshotQuality);if(i){let t=v(a.snapshot.nodes,i,_.readAny,{platform:e.backend.platform});return{capture:a,match:t.kind===`resolved`?t.resolution.node:void 0}}return{capture:a,match:_e(a.snapshot.nodes,n,t.query,{requireRect:!1}).matches[0]}}async function Li(e,t,n,r){let i=await y(e,{...t,session:n},{updateSession:!0,...U()}),a=v(i.snapshot.nodes,r.selector,r.policy,{platform:e.backend.platform});if(a.kind!==`resolved`)throw new s(`COMMAND_FAILED`,ve(r.selector,[],{unique:!0}),{hint:me([])});return{capture:i,node:a.resolution.node,selector:a.resolution.selector,ref:`@${a.resolution.node.ref}`}}const Ri=async(e,t)=>{if(!e.backend.performGesture)throw new s(`UNSUPPORTED_OPERATION`,`gesture is not supported by this backend`);await Me(e,t,t.gesture.intent);let n=await Ye(e,t),r=m(t.gesture,n,e.backend.platform),i=C(await e.backend.performGesture(x(e,t),r)),a=Bi(r.pointers,0),o=Bi(r.pointers,-1);return{kind:t.gesture.intent,durationMs:r.durationMs,pointerCount:r.topology===`single`?1:2,from:a,to:o,...i?{backendResult:i}:{},...b(Vi(t.gesture,a,o))}},zi=async(e,t)=>{let n=t.gesture;return n.intent===`drag`?await Qe(e,{...t,gesture:n}):await Ri(e,{...t,gesture:n})};function Bi(e,t){let n=e.map(e=>t===0?e.samples[0]?.point:e.samples.at(-1)?.point);if(n.some(e=>e===void 0))throw new s(`COMMAND_FAILED`,`Gesture plan did not contain endpoint samples.`);let r=n;return{x:r.reduce((e,t)=>e+t.x,0)/r.length,y:r.reduce((e,t)=>e+t.y,0)/r.length}}function Vi(e,t,n){switch(e.intent){case`pan`:{let r=`preset`in e?t:e.origin,i=`preset`in e?{x:n.x-t.x,y:n.y-t.y}:e.delta;return`Panned (${r.x}, ${r.y}) by (${i.x}, ${i.y})`}case`fling`:return`direction`in e?`Flung ${e.direction}`:`Flung`;case`pinch`:return`Pinched to scale ${e.scale}`;case`rotate`:return`Rotated gesture ${e.degrees} degrees`;case`transform`:return`Requested transform gesture by (${e.delta.x}, ${e.delta.y}), scale ${e.scale}, rotate ${e.degrees} degrees`}}const G={find:Di,get:Oi,getText:ki,getAttrs:Ai,is:ji,isVisible:Mi,isHidden:Ni,wait:Ti,waitForText:Ei},K={click:$r,press:Qr,fill:ei,typeText:ti,focus:He,longPress:We,scroll:Je,gesture:zi,settleObservation:ze};function Hi(e){return{find:t=>G.find(e,t),get:t=>G.get(e,t),getText:(t,n={})=>G.getText(e,{...n,target:t}),getAttrs:(t,n={})=>G.getAttrs(e,{...n,target:t}),is:t=>G.is(e,t),isVisible:(t,n={})=>G.isVisible(e,{...n,target:t}),isHidden:(t,n={})=>G.isHidden(e,{...n,target:t}),wait:t=>G.wait(e,t),waitForText:(t,n={})=>G.waitForText(e,{...n,text:t})}}function Ui(e){return{click:(t,n={})=>K.click(e,{...n,target:t}),press:(t,n={})=>K.press(e,{...n,target:t}),fill:(t,n,r={})=>K.fill(e,{...r,target:t,text:n}),typeText:(t,n={})=>K.typeText(e,{...n,text:t}),focus:(t,n={})=>K.focus(e,{...n,target:t}),longPress:(t,n={})=>K.longPress(e,{...n,target:t}),scroll:t=>K.scroll(e,t),gesture:t=>K.gesture(e,t),settleObservation:t=>K.settleObservation(e,t)}}function q(e,t){if(e!==void 0)return J(e,t)}function J(e,t){let n=e?.trim();if(!n)throw new s(`INVALID_ARGS`,`${t} must be a non-empty string`);return n}const Wi=async(e,t={})=>{if(!e.backend.listDevices)throw new s(`UNSUPPORTED_OPERATION`,`admin.devices is not supported by this backend`);return{kind:`adminDevices`,devices:await e.backend.listDevices(x(e,t),t.filter)}},Gi=async(e,t={})=>{if(!e.backend.bootDevice)throw new s(`UNSUPPORTED_OPERATION`,`admin.boot is not supported by this backend`);let n=ta(t.target),r=C(await e.backend.bootDevice(x(e,t),n));return{kind:`deviceBooted`,...n?{target:n}:{},...r?{backendResult:r}:{},...b(`Booted device`)}},Ki=async(e,t={})=>{if(!e.backend.shutdownDevice)throw new s(`UNSUPPORTED_OPERATION`,`admin.shutdown is not supported by this backend`);let n=ta(t.target),r=C(await e.backend.shutdownDevice(x(e,t),n));return{kind:`deviceShutdown`,...n?{target:n}:{},...r?{backendResult:r}:{},...b(`Shutdown device`)}},qi=async(e,t)=>await Xi(e,t,`install`),Ji=async(e,t)=>await Xi(e,t,`reinstall`),Yi=async(e,t)=>await Xi(e,t,`installFromSource`);async function Xi(e,t,n){let r=n===`reinstall`?`reinstallApp`:`installApp`,i=e.backend[r];if(!i)throw new s(`UNSUPPORTED_OPERATION`,`admin.${n} is not supported by this backend`);let a=`app`in t&&t.app!==void 0?J(t.app,`app`):void 0;if(n!==`installFromSource`&&!a)throw new s(`INVALID_ARGS`,`admin.${n} requires app`);let o=x(e,t),c=await Zi(e,o,t.source);try{let t=await i.call(e.backend,o,{...a?{app:a}:{},source:c.source});return na(n,a,c.source,t)}finally{await c.cleanup?.()}}async function Zi(e,t,n){let r=await Qi(e,$i(n));try{return{source:$i(e.backend.resolveInstallSource?await e.backend.resolveInstallSource(t,r.source):r.source),...r.cleanup?{cleanup:r.cleanup}:{}}}catch(e){if(r.cleanup)try{await r.cleanup()}catch{}throw e}}async function Qi(e,t){if(t.kind===`url`)return{source:t};let n=await B(e,t,{usage:`admin.install`,field:`source`});return{source:{kind:`path`,path:n.path},...n.cleanup?{cleanup:n.cleanup}:{}}}function $i(e){if(!e||typeof e!=`object`)throw new s(`INVALID_ARGS`,`install source is required`);if(e.kind===`path`)return{kind:`path`,path:J(e.path,`source.path`)};if(e.kind===`uploadedArtifact`)return{kind:`uploadedArtifact`,id:J(e.id,`source.id`)};if(e.kind===`url`){let t=J(e.url,`source.url`);return ea(t),{kind:`url`,url:t}}throw new s(`INVALID_ARGS`,`install source kind must be path, uploadedArtifact, or url`)}function ea(e){let t;try{t=new URL(e)}catch{throw new s(`INVALID_ARGS`,`Invalid install source URL: ${e}`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new s(`INVALID_ARGS`,`Install source URL must use http or https`)}function ta(e){if(!e)return;let t=q(e.id,`target.id`),n=q(e.name,`target.name`),r={...t?{id:t}:{},...n?{name:n}:{},...e.platform?{platform:e.platform}:{},...e.target?{target:e.target}:{},...e.headless===void 0?{}:{headless:e.headless}};return Object.keys(r).length>0?r:void 0}function na(e,t,n,r){let i=C(r),a=e===`reinstall`?`appReinstalled`:e===`installFromSource`?`appInstalledFromSource`:`appInstalled`,o=Y(r,`appName`),s=Y(r,`appId`),c=Y(r,`bundleId`),l=Y(r,`packageName`),u=Y(r,`launchTarget`),d=Y(r,`installablePath`),f=Y(r,`archivePath`);return{kind:a,...t?{app:t}:{},source:n,...s?{appId:s}:{},...o?{appName:o}:{},...c?{bundleId:c}:{},...l?{packageName:l}:{},...u?{launchTarget:u}:{},...d?{installablePath:d}:{},...f?{archivePath:f}:{},...i?{backendResult:i}:{},...b(`${e===`reinstall`?`Reinstalled`:`Installed`}: ${o??u??t??ra(n)}`)}}function Y(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}function ra(e){return e.kind===`path`?e.path:e.kind===`uploadedArtifact`?e.id:e.url}const ia=/^[A-Za-z0-9_.:-]{1,64}$/,aa=async(e,t)=>{if(!e.backend.openApp)throw new s(`UNSUPPORTED_OPERATION`,`apps.open is not supported by this backend`);let n=da(t),r=C(await e.backend.openApp(X(e,t),n,{launchArgs:t.launchArgs,relaunch:t.relaunch}));return{kind:`appOpened`,target:n,relaunch:t.relaunch===!0,...r?{backendResult:r}:{},...b(`Opened: ${pa(n)}`)}},oa=async(e,t={})=>{if(!e.backend.closeApp)throw new s(`UNSUPPORTED_OPERATION`,`apps.close is not supported by this backend`);let n=q(t.app,`app`),r=C(await e.backend.closeApp(X(e,t),n));return{kind:`appClosed`,...n?{app:n}:{},...r?{backendResult:r}:{},...b(n?`Closed: ${n}`:`Closed app`)}},sa=async(e,t={})=>{if(!e.backend.listApps)throw new s(`UNSUPPORTED_OPERATION`,`apps.list is not supported by this backend`);return{kind:`appsList`,apps:await e.backend.listApps(X(e,t),it(t.filter))}},ca=async(e,t)=>{if(!e.backend.getAppState)throw new s(`UNSUPPORTED_OPERATION`,`apps.state is not supported by this backend`);let n=J(t.app,`app`);return{kind:`appState`,app:n,state:await e.backend.getAppState(X(e,t),n)}},la=async(e,t)=>{if(!e.backend.pushFile)throw new s(`UNSUPPORTED_OPERATION`,`apps.push is not supported by this backend`);let n=J(t.app,`app`),r=await ma(e,t.input);try{let i=C(await e.backend.pushFile(X(e,t),r.backendInput,n));return{kind:`appPushed`,app:n,inputKind:r.inputKind,...i?{backendResult:i}:{},...b(`Pushed to ${n}`)}}finally{await r.cleanup?.()}},ua=async(e,t)=>{if(!e.backend.triggerAppEvent)throw new s(`UNSUPPORTED_OPERATION`,`apps.triggerEvent is not supported by this backend`);let n=ha(t.name);ga(t.payload,`apps.triggerEvent payload for "${n}"`);let r=C(await e.backend.triggerAppEvent(X(e,t),{name:n,...t.payload?{payload:t.payload}:{}}));return{kind:`appEventTriggered`,name:n,...t.payload?{payload:t.payload}:{},...r?{backendResult:r}:{},...b(`Triggered app event: ${n}`)}};function da(e){let t=q(e.app,`app`),n=q(e.appId,`appId`),r=q(e.bundleId,`bundleId`),i=q(e.packageName,`packageName`),a=q(e.url,`url`),o=q(e.activity,`activity`),c={...t?{app:t}:{},...n?{appId:n}:{},...r?{bundleId:r}:{},...i?{packageName:i}:{},...a?{url:a}:{},...o?{activity:o}:{}};if(!fa(c))throw new s(`INVALID_ARGS`,`apps.open requires app, appId, bundleId, packageName, url, or activity`);return c}function fa(e){return!!(e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity)}function pa(e){return e.app??e.appId??e.bundleId??e.packageName??e.url??e.activity??`app`}async function ma(e,t){if(!t||typeof t!=`object`)throw new s(`INVALID_ARGS`,`apps.push requires an input`);if(t.kind===`json`)return _a(t.payload,`apps.push JSON payload`,8192),{backendInput:{kind:`json`,payload:t.payload},inputKind:`json`};let n=await B(e,t,{usage:`apps.push`,field:`input`});return{backendInput:{kind:`file`,path:n.path},inputKind:`file`,...n.cleanup?{cleanup:n.cleanup}:{}}}function ha(e){let t=J(e,`name`);if(!ia.test(t))throw new s(`INVALID_ARGS`,`Invalid apps.triggerEvent name: ${t}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});return t}function ga(e,t){e!==void 0&&_a(e,t,8192)}function _a(e,t,n){if(va(e,t),Buffer.byteLength(ya(e,t),`utf8`)>n)throw new s(`INVALID_ARGS`,`${t} exceeds ${n} bytes`)}function va(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new s(`INVALID_ARGS`,`${t} must be a JSON object`)}function ya(e,t){try{let n=JSON.stringify(e);if(typeof n!=`string`)throw new s(`INVALID_ARGS`,`${t} must be JSON-serializable`);return n}catch{throw new s(`INVALID_ARGS`,`${t} must be JSON-serializable`)}}function X(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}const ba={open:aa,close:oa,list:sa,state:ca,push:la,triggerEvent:ua},xa={devices:Wi,boot:Gi,shutdown:Ki,install:qi,reinstall:Ji,installFromSource:Yi};function Sa(e){return{...S(ba,e),list:(t={})=>ba.list(e,{...t,filter:at(t.filter)})}}const Ca=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i,wa=/\b[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}\b/g;function Ta(e){let t=!1,n=e;return n=n.replaceAll(/(authorization|token|secret|password|passwd|api[-_]?key)=([^&\s]+)/gi,(e,n)=>(t=!0,`${String(n)}=[REDACTED]`)),n=n.replaceAll(/("(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)"\s*:\s*")([^"]*)(")/gi,(e,n,r,i)=>(t=!0,`${String(n)}[REDACTED]${String(i)}`)),n=n.replaceAll(/\b(Bearer\s+)([^\s",;]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(/((?:authorization|cookie|token|secret|password|passwd|api[-_]?key)\s*[:=]\s*)([^\s,;&]+)/gi,(e,n)=>(t=!0,`${String(n)}[REDACTED]`)),n=n.replaceAll(wa,()=>(t=!0,`[REDACTED]`)),n=Da(n,()=>{t=!0}),{value:n,redacted:t}}function Ea(e){try{let t=new URL(e),n=Oa(t);return(t.username||t.password)&&(t.username=`REDACTED`,t.password=`REDACTED`,n=!0),{value:t.toString(),redacted:n}}catch{return}}function Da(e,t){return/(https?:\/\/|token|secret|password|authorization|cookie|api[-_]?key)/i.test(e)?e.replaceAll(/https?:\/\/[^\s"'<>)]+/gi,e=>{let n=Ea(e);return n?(n.redacted&&t(),n.value):e}):e}function Oa(e){let t=!1;for(let n of Array.from(e.searchParams.keys()))Ca.test(n)&&(e.searchParams.set(n,`[REDACTED]`),t=!0);return t}const Z=2048,ka=4096,Aa=/(?:authorization|cookie|token|secret|password|passwd|api[-_]?key)/i;function ja(e){let t=e.redacted===!0;return{kind:`diagnosticsLogs`,entries:e.entries.map(e=>{let n=$(e.message,ka),r=Ra(e.metadata);return t||=n.redacted||r.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.level?{level:e.level}:{},message:n.value??``,...e.source?{source:e.source}:{},...r.value?{metadata:r.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function Ma(e,t){let n=e.redacted===!0;return{kind:`diagnosticsNetwork`,entries:e.entries.map(e=>{let r=e.url?Fa(e.url):void 0,i=t===`headers`||t===`all`?Pa(e.requestHeaders):void 0,a=t===`headers`||t===`all`?Pa(e.responseHeaders):void 0,o=t===`body`||t===`all`?Ia(e.requestBody):void 0,s=t===`body`||t===`all`?Ia(e.responseBody):void 0,c=Ra(e.metadata);return n||=(r?.redacted??!1)||(i?.redacted??!1)||(a?.redacted??!1)||(o?.redacted??!1)||(s?.redacted??!1)||c.redacted,{...e.timestamp?{timestamp:e.timestamp}:{},...e.method?{method:e.method}:{},...r?{url:r.value}:{},...e.status===void 0?{}:{status:e.status},...e.durationMs===void 0?{}:{durationMs:e.durationMs},...i?.value?{requestHeaders:i.value}:{},...a?.value?{responseHeaders:a.value}:{},...o?.value===void 0?{}:{requestBody:o.value},...s?.value===void 0?{}:{responseBody:s.value},...c.value?{metadata:c.value}:{}}}),...e.nextCursor?{nextCursor:e.nextCursor}:{},...e.timeWindow?{timeWindow:e.timeWindow}:{},...e.backend?{backend:e.backend}:{},redacted:n,...e.notes?{notes:e.notes}:{}}}function Na(e){let t=e.redacted===!0;return{kind:`diagnosticsPerf`,metrics:e.metrics.map(e=>{let n=$(e.message,ka),r=Ra(e.metadata);return t||=n.redacted||r.redacted,{name:e.name,...e.value===void 0?{}:{value:e.value},...e.unit?{unit:e.unit}:{},...e.status?{status:e.status}:{},...n.value===void 0?{}:{message:n.value},...r.value?{metadata:r.value}:{}}}),...e.startedAt?{startedAt:e.startedAt}:{},...e.endedAt?{endedAt:e.endedAt}:{},...e.backend?{backend:e.backend}:{},redacted:t,...e.notes?{notes:e.notes}:{}}}function Pa(e){if(!e)return{redacted:!1};let t=!1,n={};for(let[r,i]of Object.entries(e))if(Aa.test(r))n[r]=`[REDACTED]`,t=!0;else{let e=$(i,Z);n[r]=e.value??``,t||=e.redacted}return{value:n,redacted:t}}function Fa(e){return Ea(e)??$(e,Z)}function Ia(e){return e===void 0?{redacted:!1}:La(e)??$(e,Z)}function La(e){try{let t=Q(JSON.parse(e),Ta);return za(JSON.stringify(t.value),Z,t.redacted)}catch{return}}function Ra(e){return Q(e,e=>$(e,Z))}function Q(e,t){if(e===void 0)return{redacted:!1};if(typeof e==`string`)return t(e);if(!e||typeof e!=`object`)return{value:e,redacted:!1};if(Array.isArray(e)){let n=!1;return{value:e.map(e=>{let r=Q(e,t);return n||=r.redacted,r.value}),redacted:n}}let n=!1,r={};for(let[i,a]of Object.entries(e)){if(Aa.test(i)){r[i]=`[REDACTED]`,n=!0;continue}let e=Q(a,t);r[i]=e.value,n||=e.redacted}return{value:r,redacted:n}}function $(e,t){if(e===void 0)return{redacted:!1};let n=Ta(e);return za(n.value,t,n.redacted)}function za(e,t,n){if(e===void 0)return{redacted:n};let r=e;return r.length>t&&(r=`${r.slice(0,t)}...[truncated]`,n=!0),{value:r,redacted:n}}const Ba=async(e,t={})=>{if(!e.backend.readLogs)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.logs is not supported by this backend`);return ja(await e.backend.readLogs(await Ua(e,t),Wa(t)))},Va=async(e,t={})=>{if(!e.backend.dumpNetwork)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.network is not supported by this backend`);let n=Ga(t);return Ma(await e.backend.dumpNetwork(await Ua(e,t),n),n.include??`summary`)},Ha=async(e,t={})=>{if(!e.backend.measurePerf)throw new s(`UNSUPPORTED_OPERATION`,`diagnostics.perf is not supported by this backend`);return Na(await e.backend.measurePerf(await Ua(e,t),Ka(t)))};async function Ua(e,t){let n=x(e,t),r=t.session?await e.sessions.get(t.session):void 0;return{...n,...t.appId??r?.appId?{appId:t.appId??r?.appId}:{},...t.appBundleId??r?.appBundleId?{appBundleId:t.appBundleId??r?.appBundleId}:{}}}function Wa(e){return{...qa(e,100,500,`logs limit`),...e.levels===void 0?{}:{levels:Xa(e.levels,`levels`)},...e.search===void 0?{}:{search:J(e.search,`search`)},...e.source===void 0?{}:{source:J(e.source,`source`)}}}function Ga(e){return{...qa(e,25,200,`network limit`),include:Ya(e.include)}}function Ka(e){return{...Ja(e),...e.sampleMs===void 0?{}:{sampleMs:w(e.sampleMs,`sampleMs`,100,6e4)},...e.metrics===void 0?{}:{metrics:Xa(e.metrics,`metrics`,20)}}}function qa(e,t,n,r){return{...Ja(e),...e.cursor===void 0?{}:{cursor:J(e.cursor,`cursor`)},limit:e.limit===void 0?t:w(e.limit,r,1,n)}}function Ja(e){return{...e.since===void 0?{}:{since:J(e.since,`since`)},...e.until===void 0?{}:{until:J(e.until,`until`)}}}function Ya(e){if(e===void 0)return`summary`;if(e===`summary`||e===`headers`||e===`body`||e===`all`)return e;throw new s(`INVALID_ARGS`,`network include must be summary, headers, body, or all`)}function Xa(e,t,n=50){if(!Array.isArray(e))throw new s(`INVALID_ARGS`,`${t} must be an array of strings`);if(e.length>n)throw new s(`INVALID_ARGS`,`${t} must contain at most ${n} entries`);return e.map((e,n)=>J(e,`${t}[${n}]`))}const Za={logs:Ba,network:Va,perf:Ha},Qa=async(e,t)=>{let n=ro(t.action,`record`),r=n===`start`?e.backend.startRecording:e.backend.stopRecording;if(!r)throw new s(`UNSUPPORTED_OPERATION`,`record ${n} is not supported by this backend`);let i=t.out?await V(e,t.out,{field:`path`,ext:`.mp4`,artifactType:`screen-recording`}):void 0;try{let a=eo(t,i?.path);return io(n,await r.call(e.backend,x(e,t),a),await i?.publish())}catch(e){throw await i?.cleanup?.(),e}},$a=async(e,t)=>{let n=ro(t.action,`trace`),r=n===`start`?e.backend.startTrace:e.backend.stopTrace;if(!r)throw new s(`UNSUPPORTED_OPERATION`,`trace ${n} is not supported by this backend`);let i=t.out?await V(e,t.out,{field:`outPath`,ext:`.trace`,artifactType:`trace-log`}):void 0;try{let a={...i?.path?{outPath:i.path}:{}};return ao(n,await r.call(e.backend,x(e,t),a),await i?.publish())}catch(e){throw await i?.cleanup?.(),e}};function eo(e,t){let n={};t&&(n.outPath=t);let r=to(e.fps);r!==void 0&&(n.fps=r);let i=no(e.quality);return i!==void 0&&(n.quality=i),e.hideTouches!==void 0&&(n.showTouches=e.hideTouches!==!0),n}function to(e){return e===void 0?void 0:w(e,`fps`,1,60)}function no(e){if(e===void 0)return;let t=Xe(e);if(t===void 0)throw new s(`INVALID_ARGS`,`quality must be one of: medium, high (legacy numeric values 5-10 are accepted)`);return t}function ro(e,t){if(e===`start`||e===`stop`)return e;throw new s(`INVALID_ARGS`,`${t} action must be start or stop`)}function io(e,t,n){return{...typeof t.path==`string`?{path:t.path}:{},...typeof t.telemetryPath==`string`?{telemetryPath:t.telemetryPath}:{},...typeof t.warning==`string`?{warning:t.warning}:{},...oo(e,t,n,{startKind:`recordingStarted`,stopKind:`recordingStopped`,startMessage:`Recording started`,stopMessage:`Recording stopped`})}}function ao(e,t,n){return{...typeof t.outPath==`string`?{outPath:t.outPath}:{},...oo(e,t,n,{startKind:`traceStarted`,stopKind:`traceStopped`,startMessage:`Trace started`,stopMessage:`Trace stopped`})}}function oo(e,t,n,r){return{kind:e===`start`?r.startKind:r.stopKind,action:e,...n?{artifact:n}:{},backendResult:t,...b(e===`start`?r.startMessage:r.stopMessage)}}const so={record:Qa,trace:$a},co=async(e,t={})=>{if(!e.backend.pressBack)throw new s(`UNSUPPORTED_OPERATION`,`system.back is not supported by this backend`);let n=t.mode??`in-app`;if(n!==`in-app`&&n!==`system`)throw new s(`INVALID_ARGS`,`system.back mode must be in-app or system`);let r=C(await e.backend.pressBack(x(e,t),{mode:n}));return{kind:`systemBack`,mode:n,...r?{backendResult:r}:{},...b(`Back`)}},lo=async(e,t={})=>{if(!e.backend.pressHome)throw new s(`UNSUPPORTED_OPERATION`,`system.home is not supported by this backend`);let n=C(await e.backend.pressHome(x(e,t)));return{kind:`systemHome`,...n?{backendResult:n}:{},...b(`Home`)}},uo=async(e,t)=>{if(!e.backend.pressTvRemote)throw new s(`UNSUPPORTED_OPERATION`,`system.tvRemote is not supported by this backend`);let n=ae(t.button),r=t.durationMs===void 0?void 0:w(t.durationMs,`durationMs`,0,1e4),i=C(await e.backend.pressTvRemote(x(e,t),{button:n,...r===void 0?{}:{durationMs:r}}));return{kind:`tvRemotePressed`,button:n,...r===void 0?{}:{durationMs:r},...i?{backendResult:i}:{},...b(`Pressed TV remote ${n}`)}},fo=async(e,t)=>{if(!e.backend.setOrientation)throw new s(`UNSUPPORTED_OPERATION`,`system.orientation is not supported by this backend`);let n=vo(t.orientation),r=C(await e.backend.setOrientation(x(e,t),n));return{kind:`systemOrientationSet`,orientation:n,...r?{backendResult:r}:{},...b(`Rotated to ${n}`)}},po=async(e,t={})=>{if(!e.backend.setKeyboard)throw new s(`UNSUPPORTED_OPERATION`,`system.keyboard is not supported by this backend`);let n=t.action??`status`;if(!rt(n))throw new s(`INVALID_ARGS`,`system.keyboard action must be status, get, dismiss, enter, or return`);let r=await e.backend.setKeyboard(x(e,t),{action:n}),i=C(r),a=Do(r)?r:{};return n===`enter`||n===`return`?bo(a,i):n===`dismiss`?xo(n,a,i):Co(n,a,i)},mo=async(e,t)=>{if(t.action===`read`){if(!e.backend.getClipboard)throw new s(`UNSUPPORTED_OPERATION`,`system.clipboard read is not supported by this backend`);let n=await e.backend.getClipboard(x(e,t));return{kind:`clipboardText`,action:`read`,text:typeof n==`string`?n:n.text}}if(t.action!==`write`)throw new s(`INVALID_ARGS`,`system.clipboard action must be read or write`);if(!e.backend.setClipboard)throw new s(`UNSUPPORTED_OPERATION`,`system.clipboard write is not supported by this backend`);if(typeof t.text!=`string`)throw new s(`INVALID_ARGS`,`system.clipboard write requires text`);let n=C(await e.backend.setClipboard(x(e,t),t.text));return{kind:`clipboardUpdated`,action:`write`,textLength:Array.from(t.text).length,...n?{backendResult:n}:{},...b(`Clipboard updated`)}},ho=async(e,t={})=>{if(!e.backend.openSettings)throw new s(`UNSUPPORTED_OPERATION`,`system.settings is not supported by this backend`);let n=q(t.target,`target`),r=C(await e.backend.openSettings(x(e,t),n));return{kind:`settingsOpened`,...n?{target:n}:{},...r?{backendResult:r}:{},...b(n?`Opened settings: ${n}`:`Opened settings`)}},go=async(e,t={})=>{if(!e.backend.handleAlert)throw new s(`UNSUPPORTED_OPERATION`,`system.alert is not supported by this backend`);let n=t.action??`get`;if(n!==`get`&&n!==`accept`&&n!==`dismiss`&&n!==`wait`)throw new s(`INVALID_ARGS`,`system.alert action must be get, accept, dismiss, or wait`);let r=t.timeoutMs===void 0?void 0:w(t.timeoutMs,`timeoutMs`,0,12e4);return yo(n,await e.backend.handleAlert(x(e,t),n,{timeoutMs:r}))},_o=async(e,t={})=>{if(!e.backend.openAppSwitcher)throw new s(`UNSUPPORTED_OPERATION`,`system.appSwitcher is not supported by this backend`);let n=C(await e.backend.openAppSwitcher(x(e,t)));return{kind:`appSwitcherOpened`,...n?{backendResult:n}:{},...b(`Opened app switcher`)}};function vo(e){switch(e){case`portrait`:case`portrait-upside-down`:case`landscape-left`:case`landscape-right`:return e;default:throw new s(`INVALID_ARGS`,`system.orientation must be portrait, portrait-upside-down, landscape-left, or landscape-right`)}}function yo(e,t){return e===`get`?wo(t):e===`wait`?To(t):Eo(e,t)}function bo(e,t){return{kind:`keyboardEnterPressed`,action:`enter`,state:e,...t?{backendResult:t}:{},...b(`Keyboard enter pressed`)}}function xo(e,t,n){return{kind:`keyboardDismissed`,action:e,state:t,...n?{backendResult:n}:{},...b(So(t))}}function So(e){return e.dismissed===!1?`Keyboard already hidden`:e.mechanism===`dismissKey`?`Keyboard dismissed via its dismiss key`:`Keyboard dismissed`}function Co(e,t,n){return{kind:`keyboardState`,action:e,state:t,...n?{backendResult:n}:{}}}function wo(e){if(e.kind!==`alertStatus`)throw new s(`COMMAND_FAILED`,`system.alert get returned an invalid backend result`);return{kind:`alertStatus`,action:`get`,alert:e.alert}}function To(e){if(e.kind!==`alertWait`)throw new s(`COMMAND_FAILED`,`system.alert wait returned an invalid backend result`);return{kind:`alertWait`,action:`wait`,alert:e.alert,...e.waitedMs===void 0?{}:{waitedMs:e.waitedMs},...e.timedOut===void 0?{}:{timedOut:e.timedOut},...b(e.alert?`Alert visible`:`Alert wait timed out`)}}function Eo(e,t){if(t.kind!==`alertHandled`)throw new s(`COMMAND_FAILED`,`system.alert ${e} returned an invalid backend result`);return{kind:`alertHandled`,action:e,handled:t.handled,...t.alert?{alert:t.alert}:{},...t.button?{button:t.button}:{},...b(t.handled?`Alert ${e}ed`:`No alert handled`)}}function Do(e){return!!(e&&typeof e==`object`)}const Oo={back:co,home:lo,orientation:fo,keyboard:po,clipboard:mo,settings:ho,alert:go,appSwitcher:_o,tvRemote:uo};function ko(e){return{capture:S(qr,e),selectors:Hi(e),interactions:Ui(e),system:S(Oo,e),apps:Sa(e),admin:S(xa,e),recording:S(so,e),observability:S(Za,e)}}var Ao=r({createAgentDevice:()=>jo,createMemorySessionStore:()=>Mo,localCommandPolicy:()=>Fo,restrictedCommandPolicy:()=>Io});function jo(e){let t={backend:e.backend,artifacts:e.artifacts,sessions:e.sessions??Mo(),policy:e.policy??Io(),diagnostics:e.diagnostics,clock:e.clock,signal:e.signal};return{...t,...ko(t)}}function Mo(e=[]){let t=new Map(e.map(e=>[e.name,No(e)]));return{get:e=>No(t.get(e)),set:e=>{t.set(e.name,No(e))},delete:e=>{t.delete(e)},list:()=>Array.from(t.values(),e=>No(e))}}function No(e){if(e)return{...e,...e.snapshot?{snapshot:structuredClone(e.snapshot)}:{},...e.metadata?{metadata:Po(e.metadata)}:{}}}function Po(e){try{return structuredClone(e)}catch{return{...e}}}function Fo(e={}){return{allowLocalInputPaths:!0,allowLocalOutputPaths:!0,maxImagePixels:2e7,...e}}function Io(e={}){return{allowLocalInputPaths:!1,allowLocalOutputPaths:!1,maxImagePixels:2e7,...e}}export{Nt as _,wr as a,N as c,dn as d,Zt as f,At as g,vt as h,Xr as i,P as l,_t as m,Fo as n,yr as o,gt as p,Ao as r,fn as s,jo as t,un as u};
|