agent-device 0.20.5 → 0.20.7
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/README.md +5 -3
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.5.apk → agent-device-android-ime-helper-0.20.7.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.5.manifest.json → agent-device-android-ime-helper-0.20.7.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.5.apk → agent-device-android-snapshot-helper-0.20.7.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.5.manifest.json → agent-device-android-snapshot-helper-0.20.7.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +48 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +108 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +630 -89
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSelectorMatchPolicy.swift +78 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +126 -187
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +32 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +212 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +149 -10
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +161 -32
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CoordinateTextEntryTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -28
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +23 -5
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +10 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -67
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +18 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +2 -22
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SelectorMatchPolicyTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +2 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +145 -20
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -20
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +234 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +106 -448
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +4 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +602 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +18 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.h +72 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.m +89 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -1
- package/dist/src/app-lifecycle.js +7 -7
- package/dist/src/app-lifecycle2.js +2 -0
- package/dist/src/app-log-files.js +1 -0
- package/dist/src/app-log-reconnect.js +1 -0
- package/dist/src/app-log-runtime.js +4 -0
- package/dist/src/app-resolution.js +2 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/audio-probe.js +1 -1
- package/dist/src/auth-session.js +1 -0
- package/dist/src/auth.js +2 -0
- package/dist/src/boot-diagnostics.js +2 -2
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-grammar.js +1 -0
- package/dist/src/cli-help.js +204 -254
- package/dist/src/cli-output.js +1 -0
- package/dist/src/cli-runner.js +1 -2
- package/dist/src/cli.js +6 -16
- package/dist/src/client-metro.js +1 -1
- package/dist/src/cloud-artifacts.d.ts +2 -137
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/connection-runtime.js +1 -0
- package/dist/src/connection.js +5 -0
- package/dist/src/context.js +1 -1
- package/dist/src/daemon-shutdown-report.js +1 -0
- package/dist/src/daemon.js +2 -0
- package/dist/src/debug-symbols.js +3 -3
- package/dist/src/device-claim-inspection.js +1 -0
- package/dist/src/device-input-state.js +2 -2
- package/dist/src/device.js +1 -1
- package/dist/src/device2.js +2 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -0
- package/dist/src/generic.js +1 -1
- package/dist/src/harmonyos.js +1 -0
- package/dist/src/helper.js +1 -1
- package/dist/src/host-process.js +2 -2
- package/dist/src/ime-lifecycle.js +7 -7
- package/dist/src/index.d.ts +69 -18
- package/dist/src/input-actions.js +4 -4
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/input-actions3.js +1 -0
- package/dist/src/install-artifact.js +1 -5
- package/dist/src/install-artifact2.js +1 -1
- package/dist/src/install-source2.js +1 -1
- package/dist/src/interaction-runtime.js +1 -0
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction-touch-reference-frame.js +1 -0
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +2 -2
- package/dist/src/internal/daemon.js +9 -16
- package/dist/src/inventory.js +5 -0
- package/dist/src/inventory2.js +1 -0
- package/dist/src/inventory3.js +2 -0
- package/dist/src/inventory4.js +1 -0
- package/dist/src/inventory5.js +1 -0
- package/dist/src/inventory6.js +1 -0
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -0
- package/dist/src/limrun.d.ts +10 -104
- package/dist/src/limrun.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/owner-identity.js +1 -0
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-app-log-android-transport.js +1 -0
- package/dist/src/platform-runtime-app-log-process.js +1 -0
- package/dist/src/platform-runtime-host.js +1 -0
- package/dist/src/platform-runtime-network-web-transport.js +1 -0
- package/dist/src/platform-runtime-operation-host.js +5 -0
- package/dist/src/platform-runtime-toolchain-host.js +1 -0
- package/dist/src/platform-runtime.js +1 -0
- package/dist/src/prepare-kind.js +15 -0
- package/dist/src/process-entry.js +1 -0
- package/dist/src/process-exit.js +1 -0
- package/dist/src/process-lock.js +1 -1
- package/dist/src/provider-webdriver.js +1 -0
- package/dist/src/provider.js +1 -0
- package/dist/src/proxy.js +2 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-trace.js +1 -1
- package/dist/src/registry.js +25 -24
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay.js +3 -0
- package/dist/src/reporting.js +4 -4
- package/dist/src/runner-client.js +1 -1
- 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 +4 -0
- package/dist/src/runtime3.js +3 -0
- package/dist/src/runtime4.js +1 -0
- package/dist/src/runtime5.js +1 -0
- package/dist/src/runtime6.js +1 -0
- package/dist/src/runtime7.js +1 -0
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/screenshot.js +1 -0
- package/dist/src/sdk-android-adb.d.ts +20 -2
- package/dist/src/sdk-android-adb.js +2 -2
- package/dist/src/sdk-batch-runner.js +3 -3
- package/dist/src/sdk-contracts.d.ts +47 -6
- package/dist/src/sdk-contracts.js +1 -1
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +4 -20
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +601 -0
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -1
- package/dist/src/selectors.d.ts +1 -46
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +3 -3
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +10 -9
- package/dist/src/shared.js +2 -0
- package/dist/src/shell-quote.js +1 -0
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -0
- package/dist/src/snapshot-session.js +1 -0
- 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 -0
- package/dist/src/src3.js +1 -0
- package/dist/src/text-surface.js +1 -0
- package/dist/src/timing-safe-equal.js +1 -0
- 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/web.js +1 -1
- package/package.json +72 -50
- package/server.json +3 -3
- package/skills/agent-device/SKILL.md +6 -31
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.5.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.5.apk.sha256 +0 -1
- package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -225
- package/dist/src/app-log-request-scope.js +0 -1
- package/dist/src/devices.js +0 -1
- package/dist/src/devices2.js +0 -1
- package/dist/src/devices3.js +0 -1
- package/dist/src/devices4.js +0 -1
- package/dist/src/interaction.d.ts +0 -230
- package/dist/src/provider-limrun-runtime.js +0 -1
- package/dist/src/register-builtins.js +0 -1
- package/dist/src/screenshot-geometry.js +0 -1
- package/dist/src/viewport-dimension.js +0 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
import{S as e,_ as t,h as n,l as r,m as i,s as a,v as o}from"./sdk-contracts.js";import{M as s,X as c,a as l}from"./viewport-dimension.js";import{M as u,O as d,P as f,W as p}from"./sdk-batch-runner.js";import{N as m}from"./screenshot-result.js";import{c as ee,h as te,o as ne,s as h}from"./sdk-device.js";import{D as re,E as ie,F as ae,K as oe,O as se,T as ce,j as le,q as ue,z as de}from"./sdk-selectors.js";import{i as fe}from"./session-target-evidence.js";import{S as g}from"./device.js";import{i as pe,n as me,t as he}from"./runtime.js";import{j as _}from"./sdk-android-adb.js";import{r as ge}from"./app-lifecycle.js";import{h as v}from"./ime-lifecycle.js";import{j as _e}from"./runner-disposal.js";import{S as y,c as ve,g as ye,l as b,n as be,s as x,t as xe}from"./context.js";import{C as Se}from"./physical-device-control.js";import{a as S,l as Ce}from"./runner-client.js";import{Bt as we,Ht as C,Ut as w,Vt as Te,Zt as T,g as Ee,in as De,u as Oe}from"./internal/daemon.js";import{a as ke}from"./apps.js";function E(e,t){let n=pe(t);if(!n)return e;if(e.ok){let t=Ae(e.data?.warning,n);return{...e,data:{...e.data,warning:t}}}let r=e.error.details??{};return{...e,error:{...e.error,details:{...r,hint:Ae(r.hint,n)}}}}function Ae(e,t){return typeof e==`string`&&e.trim()!==``?`${e}\n${t}`:t}async function je(e,t,n){let r=e.get(t),i=r?.device??await ye(n??{});return r||await Ee(i),{session:r,device:i}}async function Me(e,t,n){let r=!e&&h(t);try{return await n()}finally{r&&(await Ce(t.id),await Ne(t))}}async function Ne(e){let t=Se();await ke(e,t).catch(n=>{_({level:`debug`,phase:`ios_sessionless_runner_host_close_failed`,data:{deviceId:e.id,bundleId:t,error:n instanceof Error?n.message:String(n)}})})}function Pe(e,t,n,r){t&&e.recordAction(t,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r})}function Fe(e){let{session:t,sessionName:n,device:r,snapshot:i,appBundleId:a}=e;return t?{...t,snapshot:i,lastComparisonSafeSnapshot:i?.comparisonSafe===!0?i:t.lastComparisonSafeSnapshot}:{name:n,device:r,createdAt:Date.now(),appBundleId:a,snapshot:i,...i?.comparisonSafe===!0?{lastComparisonSafeSnapshot:i}:{},actions:[]}}const Ie=[[`snapshotDepth`,`--depth`],[`snapshotScope`,`--scope`],[`snapshotRaw`,`--raw`]];function D(e,t){let n=Le(t);return n.length===0?null:x(`INVALID_ARGS`,`${e} @ref does not support ${n.join(`, `)}.`)}function Le(e){if(!e)return[];let t=[];for(let[n,r]of Ie)e[n]!==void 0&&t.push(r);return t}function Re(e,t){if(!t||t.settle===!0)return null;let n=[];return t.settleQuietMs!==void 0&&n.push(`--settle-quiet`),n.length===0?null:x(`INVALID_ARGS`,`${e}: ${n.join(`, `)} require${n.length===1?`s`:``} --settle.`)}function ze(e){if(e?.settle===!0)return{...e.settleQuietMs===void 0?{}:{quietMs:e.settleQuietMs},...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}}}function O(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}function k(e){let t=n(e);return t?{ok:!0,ref:t.base,generation:t.generation}:{ok:!1,response:x(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:a})}}function A(e,t){let n=O(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=k(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:x(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Be(e){let t=O(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...qe(e[2])};let n=Ke(e),r=A(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function Ve(e){let t=e[0]??``;if(t.startsWith(`@`)){let n=k(t);if(!n.ok)return{ok:!1,response:n.response};let r=l(e).text;return r?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:Ge(e)},refGeneration:n.generation,text:r}:{ok:!1,response:x(`INVALID_ARGS`,`fill requires text after ref`)}}let n=O(e);if(n){let t=e.slice(2).join(` `);return t?{ok:!0,target:{kind:`point`,x:n.x,y:n.y},text:t}:{ok:!1,response:x(`INVALID_ARGS`,`fill requires text after coordinates`)}}let r=He(e);return!r||r.kind!==`selector`?{ok:!1,response:x(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)}:r.text.trim()?{ok:!0,target:{kind:`selector`,selector:r.target.selector},text:r.text}:{ok:!1,response:x(`INVALID_ARGS`,`fill requires text after selector`)}}function He(e){try{return l(e)}catch{return null}}function Ue(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:j(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:{evidence:t,settle:n}}function We(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function j(e){return e?.startsWith(`@`)?e.slice(1):e}function Ge(e){return e.length>=3&&e[1]?.trim()||``}function Ke(e){let t=e.at(-1);return e.length>1&&Je(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function qe(e){return e===void 0?{}:{durationMs:Number(e)}}function Je(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}async function Ye(e,n){let r=await M(e);if(r){if(v(r.foregroundPackage))return`press ${n} opened an Android permission dialog (${r.foregroundPackage}) over ${r.expectedPackage}. ${r.hint}`;throw new t(`COMMAND_FAILED`,`press ${n} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}}async function M(e){if(e.device.platform!==`android`||!e.appBundleId)return null;let t=await ge(e.device),n=t.package?.trim();return!n||n===e.appBundleId||!$e(n)?null:{expectedPackage:e.appBundleId,foregroundPackage:n,activity:t.activity,hint:Qe(n)}}function Xe(e){return v(e.foregroundPackage)?`Android permission dialog is blocking ${e.expectedPackage}`:`${e.foregroundPackage} is foreground instead of ${e.expectedPackage}`}function Ze(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}function Qe(e){return v(e)?`Use "alert get" to inspect it, then "alert accept" or "alert dismiss" to respond.`:`Use screenshot as visual truth, then take a fresh snapshot -i before retrying.`}function $e(e){return e===`com.android.settings`||e===`com.android.systemui`||v(e)||e.includes(`launcher`)}function et(e,t){if(t===`exists`)return{found:!0};if(t===`wait`)return{found:!0,waitedMs:e.waitedMs};let n=typeof e.ref==`string`?e.ref:void 0;return t===`get_attrs`?{ref:n,action:`get attrs`}:{ref:n,action:`get text`,text:typeof e.text==`string`?e.text:``}}function tt(e){return e.kind===`found`?{found:!0,...typeof e.waitedMs==`number`?{waitedMs:e.waitedMs}:{}}:{ref:e.ref,...e.kind===`text`?{text:e.text}:{},node:g(e.node)}}function N(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,r=it(e),i=r?.kind===`ref`?R(r.ref):void 0,a=r?.kind===`selector`?r.selector:void 0,o={...i?{ref:i}:{},...a?{selector:a}:{},...n?{selectorChain:n}:{}};if(t===`attrs`)return o;let s=typeof e.text==`string`?e.text:``;return{...o,text:s,refLabel:rt(s)}}function P(e){let{target:t}=e;return{...t.kind===`ref`?{ref:R(t.ref)}:{},...t.kind===`selector`?{selector:t.selector}:{},...typeof e.text==`string`?{text:e.text}:{},node:g(e.node)}}function F(e){let{node:t,preActionNodes:n,...r}=e;return r}function nt(e){return{waitedMs:e.waitedMs,...typeof e.text==`string`?{text:e.text}:{},...typeof e.selector==`string`?{selector:e.selector}:{},...typeof e.captures==`number`?{captures:e.captures}:{},...typeof e.nodeCount==`number`?{nodeCount:e.nodeCount}:{},...typeof e.hint==`string`?{hint:e.hint}:{}}}function I(e){let{selectorChain:t,...n}=e;return n}function L(e,t,n,r,i,a){let o=e.get(t);if(!o)return;let s=o.recordSession&&i?fe(i,{mode:a}):void 0;e.recordAction(o,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r,interactiveObservation:m(n),...s?{targetEvidence:s}:{}})}function rt(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function it(e){let t=e.target;if(!t||typeof t!=`object`)return;let n=t;if(n.kind===`ref`&&typeof n.ref==`string`)return{kind:`ref`,ref:n.ref};if(n.kind===`selector`&&typeof n.selector==`string`)return{kind:`selector`,selector:n.selector}}function R(e){return e.startsWith(`@`)?e.slice(1):e}const at=[`application`,`window`,`tabbar`,`scrollbar`,`image`],ot=new Set([`tab bar`]);async function z(e,t){if(t.ok||!st(t.error.message)||t.error.details?.captureStalled===!0||t.error.details?.captureTruncated===!0)return t;let n=await ct(e).catch(()=>null);return n?x(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}function st(e){return/^wait timed out (?:for (?:selector|text): |waiting for a stable UI)/i.test(e)}async function ct(e){let t=[...(await T({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??``})).snapshot.nodes].sort(lt),n=B(t,6,{includeIdentifiers:!0});if(n.length===0)return null;let r=B(t.filter(e=>!dt(e)),4,{includeIdentifiers:!1}),i=B(t.filter(ft),4,{includeIdentifiers:!0});return{summary:(r.length>0?r:n.slice(0,4)).join(`, `),details:{labels:n,...i.length>0?{buttons:i}:{}}}}function B(e,t,n){let r=new Set,i=[];for(let a of e){let e=H(a,n);if(!(!e||r.has(e))&&(r.add(e),i.push(e),i.length>=t))break}return i}function lt(e,t){return V(e)-V(t)||ut(e,t)}function V(e){let t=!!H(e,{includeIdentifiers:!1});return(dt(e)?2:0)+ +!t}function ut(e,t){return e.rect&&t.rect?e.rect.y-t.rect.y||e.rect.x-t.rect.x:e.rect?-1:t.rect?1:(e.depth??0)-(t.depth??0)||e.index-t.index}function H(e,t){let n=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>typeof e==`string`?e.trim():``).find(e=>e.length>0);return n?n.replace(/\s+/g,` `).slice(0,80):``}function dt(e){let t=oe(`${e.type??``} ${e.role??``} ${e.subrole??``}`),n=`${e.label??``} ${e.value??``}`.trim().toLowerCase();return at.some(e=>t.includes(e))||ot.has(n)||n.endsWith(`.fill`)}function ft(e){return oe(`${e.type??``} ${e.role??``} ${e.subrole??``}`).includes(`button`)}function U(e,t){return!(!e||!h(e.device)||y(e.device)||t.skipPendingPostGestureStabilization&&e.postGestureStabilization)}function W(e){let{session:t,selectorExpression:n}=e;if(!U(t,{skipPendingPostGestureStabilization:!0}))return null;let r=p(n);if(!r||r.selectors.length!==1)return null;let i=r.selectors[0];if(!i||i.terms.length!==1)return null;let a=i.terms[0];return!a||typeof a.value!=`string`||!pt(a.key)?null:{key:a.key,value:a.value,raw:i.raw}}function pt(e){return e===`id`||e===`label`||e===`text`||e===`value`}function mt(e){let t=e.identifier?.trim();if(t)return{key:`id`,value:t};let n=e.label?.trim();return n?{key:`label`,value:n}:null}function G(e,t={}){let n=o(e);if(n.code===`ELEMENT_NOT_FOUND`)return t.delegateSemanticFailures===!0||t.allowElementNotFound===!0;if(n.code===`AMBIGUOUS_MATCH`)return t.delegateSemanticFailures===!0;if(n.code===`ELEMENT_OFFSCREEN`)return t.delegateSemanticFailures!==!1;if(n.code!==`COMMAND_FAILED`)return!1;let r=n.message.toLowerCase();return r.includes(`fetch failed`)||r.includes(`timed out`)||r.includes(`timeout`)||r.includes(`runner did not accept connection`)||r.includes(`invalid runner response`)}function ht(e,n={}){let r=n.plural===!0?`do`:`does`;return{resolveInput:async()=>{throw new t(`UNSUPPORTED_OPERATION`,`${e} ${r} not resolve input artifacts`)},reserveOutput:async()=>{throw new t(`UNSUPPORTED_OPERATION`,`${e} ${r} not reserve output artifacts`)},createTempFile:async()=>{throw new t(`UNSUPPORTED_OPERATION`,`${e} ${r} not create temporary files`)}}}function K(e,t={}){return{artifacts:ht(e,t),policy:me()}}async function gt(e){let{device:t,node:n,flags:r,appBundleId:i,traceOutPath:a,surface:o,contextFromFlags:s}=e,l=ae(n),u=c(n.rect);if(!u||h(t)&&l&&!ue(n.type??``))return l;try{let e=await be(t,`read`,[String(u.x),String(u.y)],void 0,{...s(r,i,a),surface:o}),c=e&&typeof e==`object`?e:void 0,d=typeof c?.text==`string`?c.text:``;return d.trim()?d:(_({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`empty_backend_text`,nodeRef:n.ref,surface:o,platform:t.platform}}),l)}catch(e){return _({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`backend_read_failed`,nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),l}}function q(e){let{session:t,sessionStore:n,sessionName:r}=e,i=0,a,o,s=t=>(e.consumedSnapshot&&(e.consumedSnapshot.state=t.snapshot),t);return{capture:async c=>{let l=Date.now(),u=Et(c,e.req.flags?.out),d=bt({timestamp:l,lastSnapshotAt:i,lastSnapshotResult:a,lastSnapshotCacheKey:o,session:t,request:c,cacheKey:u});if(d)return s(d);let f=xt({session:t,timestamp:l,request:c});if(f)return i=f.createdAt,a={snapshot:f},o=u,s(a);let p=await _t({params:e,request:c});c.signal?.throwIfAborted();let m={snapshot:p};return Ot({session:t,sessionStore:n,sessionName:r,snapshot:p}),i=l,a=m,o=u,s(m)}}}async function _t(e){let{params:t,request:n}=e,r=await J(t,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&kt(r)?await vt({runtimeParams:t,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&s(r.snapshotQuality)?await yt({runtimeParams:t,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:r}):r}async function vt(e){let{runtimeParams:t,request:n,policy:r}=e;try{return await J(t,n,void 0,!1)}catch(e){if(!r.shouldScope)throw e;return await J(t,n,r.query,!1)}}async function yt(e){let{runtimeParams:t,request:n,policy:r,snapshot:i}=e;try{return await J(t,n,r.query,!1)}catch{return i}}async function J(e,t,n,r=t.flags?.snapshotInteractiveOnly){return(await T({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:r},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??``,snapshotScope:n,includeRects:t.includeRects,signal:t.signal})).snapshot}function bt(e){let{timestamp:t,lastSnapshotAt:n,lastSnapshotResult:r,lastSnapshotCacheKey:i,session:a,request:o,cacheKey:s}=e;if(o.cache?.forceFresh!==!0&&r&&i===s&&!(t-n>=750)&&!De(a)&&!wt(a,o))return r}function xt(e){let{session:t,timestamp:n,request:r}=e,i=t?.snapshot;if(i&&St(t,r)&&Ct(i,n)&&i.presentationKey===Tt(r))return i}function St(e,t){return!(t.cache?.forceFresh===!0||t.cache?.useSessionSnapshot!==!0||De(e)||wt(e,t))}function Ct(e,t){return t-e.createdAt<750}function wt(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&!!e?.postGestureStabilization}function Tt(e){return r(i(Dt(e)))}function Et(e,t){return JSON.stringify({presentationKey:Tt(e),includeRects:e.includeRects===!0,outPath:e.outPath??t??null})}function Dt(e){return e.snapshotScope===void 0?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function Ot(e){let{session:t,sessionStore:n,sessionName:r,snapshot:i}=e;!t||s(i.snapshotQuality)||(w(t,i),n.set(r,t))}function kt(e){return e.snapshotQuality||e.backend!==`xctest`||e.nodes.length!==1?!1:e.nodes[0]?.type===`Application`}function At(e){return he({backend:jt(e),...K(`selector commands`,{plural:!0}),sessions:we({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{!e.session||!t.snapshot||(w(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}}),signal:e.signal??_e(e.req.meta?.requestId)})}async function Y(e,t){e.consumedSnapshot??={};let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:ve()};let r=n?.device??await ye(e.req.flags??{});n||await Ee(r);let i=b(t.capability,r);return i?{ok:!1,response:i}:{ok:!0,runtime:At({...e,session:n,device:r})}}function jt(e){let{req:t,session:n,device:r,logPath:i,sessionName:a,sessionStore:o}=e,s=q({device:r,session:n,sessionStore:o,sessionName:a,req:t,consumedSnapshot:e.consumedSnapshot,logPath:i});return{platform:te(r),captureSnapshot:async(e,n)=>{let i={...t.flags,...Mt(n)},a=n?.includeRects===!0,o=n?.scope??t.flags?.snapshotScope,c=t.command===`wait`||t.command===`find`||a&&r.platform===`web`;return await s.capture({flags:i,signal:e.signal,snapshotScope:o,includeRects:a,cache:{forceFresh:c,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(a,o)=>({text:await gt({device:r,node:o,flags:t.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>xe(i??``,e,t,n))})}),findText:async(t,n)=>({found:await Nt(e,n,t.signal)})}}function Mt(e){let{interactiveOnly:t,scope:n,depth:r,raw:i,includeHiddenContentHints:a}=e??{},o={};return t!==void 0&&(o.snapshotInteractiveOnly=t),n!==void 0&&(o.snapshotScope=n),r!==void 0&&(o.snapshotDepth=r),i!==void 0&&(o.snapshotRaw=i),a!==void 0&&(o.snapshotIncludeHiddenContentHints=a),o}async function Nt(e,t,n){let r=await Pt(e,t,n);return r===null?await Ft(e,t,n)===!0?!0:await Rt(e,t,n):r}async function Pt(e,t,n){return!ee(e.device)||!e.session?.surface||e.session.surface===`app`?null:await Rt(e,t,n)}async function Ft(e,t,n){let r=It(e);return r?(await S(r.device,{command:`findText`,text:t,appBundleId:r.appBundleId},{...Lt(e,r),signal:n}))?.found===!0:null}function It(e){return!ne(e.device.platform)||y(e.device)||!e.session?.appBundleId?null:{device:e.device,appBundleId:e.session.appBundleId,traceLogPath:e.session.trace?.outPath}}function Lt(e,t){return Oe({req:e.req,logPath:e.logPath,traceLogPath:t.traceLogPath})}async function Rt(e,t,n){return!!de((await zt(e,n)).nodes,t)}async function zt(e,t){let{snapshot:n}=await q({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath,consumedSnapshot:e.consumedSnapshot}).capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotIncludeHiddenContentHints:!1},signal:t,cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return n}async function Bt(e){let{req:t}=e;if(t.command!==`find`)return null;let n=u(t.positionals??[],t.flags);if(!n.ok)return x(n.code,n.message);let r=n.parsed,i=r.action;if(!f(i))return null;let a=await Y(e,{requireSession:!1,capability:`find`});return a.ok?E(await $(async()=>{let n=await a.runtime.selectors.find({session:e.sessionName,requestId:t.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});L(e.sessionStore,e.sessionName,t,et(n,i));let o=tt(n);if(typeof o.ref==`string`){let t=e.sessionStore.get(e.sessionName);if(t&&(Te(t,[o.ref]),e.sessionStore.set(e.sessionName,t),t.snapshotGeneration!==void 0))return{...o,refsGeneration:t.snapshotGeneration}}return o}),X(e)):a.response}function X(e){return e.consumedSnapshot?.state??e.sessionStore.get(e.sessionName)?.snapshot}async function Vt(e){let{req:t}=e;if(t.command!==`get`)return null;let n=ie(t.positionals?.[0]);if(!n.ok)return x(n.code,n.message);let r=n.format,i=en(t);if(!i.ok)return i.response;if(i.target.kind===`ref`){let e=D(`get`,t.flags);if(e)return e}let a=t.internal?.replayTargetGuard;if(i.target.kind===`selector`&&!a){let t=await Kt(e,r,i.target.selector);if(t)return t}let o=await Y(e,{requireSession:!0,capability:`get`});if(!o.ok)return o.response;let s=i.target.kind===`ref`?C({session:e.sessionStore.get(e.sessionName),ref:i.target.ref,mintedGeneration:i.refGeneration}):void 0;return E(await $(async()=>{let n=await o.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:i.target,expectedResolvedTarget:a});L(e.sessionStore,e.sessionName,t,N(n,r),{node:n.node,preActionNodes:n.preActionNodes});let c=P(n);return s?{...c,warning:s}:c}),X(e))}async function Ht(e){let{req:t}=e;if(t.command!==`is`)return null;let n=re(t.positionals??[]);if(!n.ok)return x(n.code,n.message,n.hint?{hint:n.hint}:void 0);let{predicate:r,expectedText:i}=n,a={selectorExpression:n.selectorExpression},o=t.internal?.replayTargetGuard,s=e.sessionStore.get(e.sessionName)?.recordSession===!0;if(!o&&!s){let t=await qt(e,r,a.selectorExpression,i);if(t)return t}let c=await Y(e,{requireSession:!0,capability:`is`});return c.ok?E(await nn(e,await $(async()=>{let n=await c.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:a.selectorExpression,expectedText:i,expectedResolvedTarget:o}),s=Wt(n),l=F(n);return L(e.sessionStore,e.sessionName,t,l,s),I(l)}),`is ${r}`),X(e)):c.response}async function Ut(e){let{req:t,sessionName:n,sessionStore:r}=e,i=d(t.positionals??[]);if(!i)return x(`INVALID_ARGS`,`wait requires a duration or text`);let{session:a,device:o}=await je(r,n,t.flags);if(i.kind!==`sleep`){let e=b(`wait`,o);if(e)return e}let s=t.internal?.replayLandmarkGuard;if(i.kind===`selector`&&!s&&!a?.recordSession){let t=await Jt({...e,session:a,device:o,selectorExpression:i.selectorExpression,timeoutMs:i.timeoutMs});if(t)return t}let c=i,l;if(i.kind===`ref`){let e=k(i.rawRef);if(!e.ok)return e.response;c={...i,rawRef:e.ref},l=C({session:a,ref:e.ref,mintedGeneration:e.generation})}e.consumedSnapshot??={};let u=async()=>{let i=At({...e,session:a,device:o}),u=await $(async()=>{let e=await i.selectors.wait({session:n,requestId:t.meta?.requestId,target:tn(c,a,s)}),o=Wt(e);L(r,n,t,F(e),o,`landmark`);let u=nt(e);return l?{...u,warning:l}:u});return await nn(e,await z({req:t,logPath:e.logPath,session:a,device:o},u),`wait`)};return i.kind===`sleep`?await u():E(await Me(a,o,u),X(e))}function Wt(e){let t=e.node,n=e.preActionNodes;if(!(!t||typeof t!=`object`||!Array.isArray(n)))return{node:t,preActionNodes:n}}function Gt(e,t,n){if(!e||e.recordSession)return null;let r=W({session:e,selectorExpression:n});return t===`text`&&r?.key!==`id`?null:r}async function Kt(e,t,n){let r=e.sessionStore.get(e.sessionName),i=Gt(r,t,n);if(!r||!i)return null;let a=await Z(e,r,i);if(Q(a))return a.response;if(!a)return null;let o=Zt(t,i.raw,a);return o?(L(e.sessionStore,e.sessionName,e.req,N(o,t)),{ok:!0,data:P(o)}):null}async function qt(e,t,n,r){if(t===`hidden`)return null;let i=await Yt(e,n);if(Q(i))return i.response;if(!i?.result.found||!i.result.node)return null;let a=t===`exists`?{predicate:t,pass:!0,selector:i.selector.raw,matches:1,selectorChain:[i.selector.raw]}:Qt(t,r,i.selector.raw,i.session,i.result.node);return a?(L(e.sessionStore,e.sessionName,e.req,a),{ok:!0,data:I(a)}):null}async function Jt(e){let t=W({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let n=Date.now(),r=await Z(e,e.session,t);if(Q(r))return r.response;if(!r?.found)return null;let i={kind:`selector`,selector:t.raw,waitedMs:Date.now()-n,selectorChain:[t.raw]};L(e.sessionStore,e.sessionName,e.req,i);let a={ok:!0,data:I(i)};return await z({req:e.req,logPath:e.logPath,session:e.session,device:e.device},a)}async function Yt(e,t){let n=e.sessionStore.get(e.sessionName),r=W({session:n,selectorExpression:t});if(!n||!r)return null;let i=await Z(e,n,r);return Q(i)?i:i?{session:n,selector:r,result:i}:null}async function Xt(e,t,n){let r=await S(e.device,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:e.appBundleId},n),i=r.found===!0,a=$t(r);return{found:i,...typeof r.text==`string`?{text:r.text}:{},...a?{node:a}:{}}}async function Z(t,n,r){try{return await Xt(n,r,Oe({req:t.req,logPath:t.logPath,traceLogPath:n.trace?.outPath}))}catch(t){return G(t,{allowElementNotFound:!0})?null:{kind:`error`,response:{ok:!1,error:e(t)}}}}function Q(e){return e!==null&&`kind`in e&&e.kind===`error`}function Zt(e,t,n){if(!n.found||!n.node)return null;let r={target:{kind:`selector`,selector:t},node:n.node,selectorChain:[t]};return e===`attrs`?{kind:`attrs`,...r}:typeof n.text==`string`?{kind:`text`,...r,text:n.text}:null}function Qt(e,t,n,r,i){let a=le({predicate:e,node:i,nodes:[i],expectedText:t,platform:r.device.platform});return{predicate:e,pass:a.pass,selector:n,...e===`text`?{text:a.actualText}:{},selectorChain:[n]}}function $t(e){let t=e.nodes;if(!Array.isArray(t))return;let n=t[0];if(!(!n||typeof n!=`object`))return n}function en(e){let t=e.positionals?.[1]??``;if(t.startsWith(`@`)){let n=k(t);return n.ok?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(` `).trim():``},refGeneration:n.generation}:{ok:!1,response:n.response}}let n=ce(e.positionals?.slice(1)??[]);return n.ok?{ok:!0,target:{kind:`selector`,selector:`selector`in n?n.selector:``}}:{ok:!1,response:x(n.code,n.message)}}function tn(e,n,r){if(e.kind===`sleep`)return{kind:`sleep`,durationMs:e.durationMs};if(e.kind===`selector`)return{kind:`selector`,selector:e.selectorExpression,timeoutMs:e.timeoutMs,...r?{recordedLandmark:r}:{}};if(e.kind===`ref`){if(!n?.snapshot)throw new t(`INVALID_ARGS`,`Ref wait requires an existing snapshot in session.`);return{kind:`ref`,ref:e.rawRef,timeoutMs:e.timeoutMs}}if(e.kind===`stable`)return{kind:`stable`,quietMs:e.quietMs,timeoutMs:e.timeoutMs};let i=se(e.text);if(!i.ok)throw new t(i.code,i.message);return{kind:`text`,text:i.text,timeoutMs:e.timeoutMs}}async function $(e){try{return{ok:!0,data:await e()}}catch(e){let t=o(e);return x(t.code,t.message,t.details)}}async function nn(e,t,n){if(t.ok)return t;let r=e.sessionStore.get(e.sessionName);if(!r)return t;let i;try{i=await M(r)}catch{return t}return i?x(t.error.code,`${n} failed because ${Xe(i)}.`,{...t.error.details??{},...i,blockedBy:`android_foreground_surface`,originalMessage:t.error.message}):t}export{Fe as C,E as D,Me as E,Re as S,je as T,Be as _,Xt as a,ze as b,mt as c,W as d,Ye as f,Ve as g,Ue as h,Ut as i,G as l,We as m,Vt as n,q as o,Ze as p,Ht as r,K as s,Bt as t,U as u,A as v,Pe as w,D as x,j as y};
|
|
1
|
+
import{S as e,_ as t,h as n,l as r,m as i,s as a,v as o}from"./sdk-contracts.js";import{x as s}from"./version.js";import{Jt as c,Kt as l,X as u,Yt as d,Zt as f,dt as p,it as m,jn as h,ln as ee,qt as te,sn as ne}from"./sdk-batch-runner.js";import{_ as re,c as ie,l as ae,s as oe}from"./sdk-device.js";import{J as se,X as ce,c as g,it as le,z as _}from"./prepare-kind.js";import{j as ue}from"./screenshot-result.js";import{i as de}from"./session-target-evidence.js";import{i as fe}from"./text-surface.js";import{a as pe,t as me}from"./runtime.js";import{A as v}from"./sdk-android-adb.js";import{r as he}from"./app-lifecycle.js";import{h as y}from"./ime-lifecycle.js";import{N as ge}from"./runner-disposal.js";import{D as _e,_ as ve,c as ye,l as be,n as xe,s as b,t as Se}from"./context.js";import{a as x}from"./runner-client.js";import{Gt as S,Ht as Ce,Kt as C,O as we,Wt as Te,en as w,in as T,sn as Ee,x as De}from"./internal/daemon.js";import{a as Oe,i as ke,r as Ae}from"./snapshot-session.js";const je=[[`snapshotDepth`,`--depth`],[`snapshotScope`,`--scope`],[`snapshotRaw`,`--raw`]];function Me(e,t){let n=Ne(t);return n.length===0?null:b(`INVALID_ARGS`,`${e} @ref does not support ${n.join(`, `)}.`)}function Ne(e){if(!e)return[];let t=[];for(let[n,r]of je)e[n]!==void 0&&t.push(r);return t}function Pe(e,t){if(!t||t.settle===!0)return null;let n=[];return t.settleQuietMs!==void 0&&n.push(`--settle-quiet`),n.length===0?null:b(`INVALID_ARGS`,`${e}: ${n.join(`, `)} require${n.length===1?`s`:``} --settle.`)}function Fe(e){if(e?.settle===!0)return{...e.settleQuietMs===void 0?{}:{quietMs:e.settleQuietMs},...e.timeoutMs===void 0?{}:{timeoutMs:e.timeoutMs}}}function E(e){if(e.length<2)return null;let t=Number(e[0]),n=Number(e[1]);return!Number.isFinite(t)||!Number.isFinite(n)?null:{x:t,y:n}}function D(e){let t=n(e);return t?{ok:!0,ref:t.base,generation:t.generation}:{ok:!1,response:b(`INVALID_ARGS`,`Invalid ref "${e}" — malformed generation suffix.`,{hint:a})}}function O(e,t){let n=E(e);if(n)return{ok:!0,target:{kind:`point`,x:n.x,y:n.y}};let r=e[0]??``;if(r.startsWith(`@`)){let t=D(r);return t.ok?{ok:!0,target:{kind:`ref`,ref:t.ref,fallbackLabel:e.slice(1).join(` `).trim()},refGeneration:t.generation}:{ok:!1,response:t.response}}let i=e.join(` `).trim();return i?{ok:!0,target:{kind:`selector`,selector:i}}:{ok:!1,response:b(`INVALID_ARGS`,`${t} requires @ref, selector expression, or x y coordinates`)}}function Ie(e){let t=E(e);if(t)return{ok:!0,target:{kind:`point`,x:t.x,y:t.y},...Ue(e[2])};let n=He(e),r=O(n.targetPositionals,`longpress`);return r.ok?{ok:!0,target:r.target,refGeneration:r.refGeneration,...n.duration}:r}function Le(e){let t=e[0]??``;if(t.startsWith(`@`)){let n=D(t);if(!n.ok)return{ok:!1,response:n.response};let r=g(e).text;return r?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:Ve(e)},refGeneration:n.generation,text:r}:{ok:!1,response:b(`INVALID_ARGS`,`fill requires text after ref`)}}let n=E(e);if(n){let t=e.slice(2).join(` `);return t?{ok:!0,target:{kind:`point`,x:n.x,y:n.y},text:t}:{ok:!1,response:b(`INVALID_ARGS`,`fill requires text after coordinates`)}}let r=Re(e);return!r||r.kind!==`selector`?{ok:!1,response:b(`INVALID_ARGS`,`fill requires x y text, @ref text, or selector text`)}:r.text.trim()?{ok:!0,target:{kind:`selector`,selector:r.target.selector},text:r.text}:{ok:!1,response:b(`INVALID_ARGS`,`fill requires text after selector`)}}function Re(e){try{return g(e)}catch{return null}}function ze(e){let t=`evidence`in e?e.evidence:void 0,n=e.settle;return e.kind===`ref`?{ref:k(e.target?.kind===`ref`?e.target.ref:void 0),refLabel:e.refLabel,selectorChain:e.selectorChain,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:e.kind===`selector`?{selector:e.target?.kind===`selector`?e.target.selector:void 0,selectorChain:e.selectorChain,refLabel:e.refLabel,targetHittable:e.targetHittable,hint:e.hint,evidence:t,settle:n,resolution:e.resolution}:{evidence:t,settle:n}}function Be(e,t){return e.kind===`point`?`coordinate tap`:t.kind===`ref`&&t.target?.kind===`ref`?t.target.ref:t.kind===`selector`&&t.target?.kind===`selector`?t.target.selector:`target`}function k(e){return e?.startsWith(`@`)?e.slice(1):e}function Ve(e){return e.length>=3&&e[1]?.trim()||``}function He(e){let t=e.at(-1);return e.length>1&&We(t)?{targetPositionals:e.slice(0,-1),duration:{durationMs:Number(t)}}:{targetPositionals:e,duration:{}}}function Ue(e){return e===void 0?{}:{durationMs:Number(e)}}function We(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function A(e,t){return!(!e||!ie(e.device)||_e(e.device)||t.skipPendingPostGestureStabilization&&T(e))}function j(e){let{session:t,selectorExpression:n}=e;return A(t,{skipPendingPostGestureStabilization:!0})?p(n):null}function Ge(e){let t=e.identifier?.trim();if(t)return{key:`id`,value:t};let n=e.label?.trim();return n?{key:`label`,value:n}:null}function M(e,t={}){let n=o(e);if(n.code===`ELEMENT_NOT_FOUND`)return t.delegateSemanticFailures===!0||t.allowElementNotFound===!0;if(n.code===`AMBIGUOUS_MATCH`)return t.delegateSemanticFailures===!0;if(n.code===`ELEMENT_OFFSCREEN`)return t.delegateSemanticFailures!==!1;if(n.code!==`COMMAND_FAILED`)return!1;let r=n.message.toLowerCase();return r.includes(`fetch failed`)||r.includes(`timed out`)||r.includes(`timeout`)||r.includes(`runner did not accept connection`)||r.includes(`invalid runner response`)}async function Ke(e,n){let r=await N(e);if(r){if(y(r.foregroundPackage))return`press ${n} opened an Android permission dialog (${r.foregroundPackage}) over ${r.expectedPackage}. ${r.hint}`;throw new t(`COMMAND_FAILED`,`press ${n} left ${e.appBundleId} and foregrounded ${r.foregroundPackage}. The tap likely escaped the app.`,r)}}async function N(e){if(e.device.platform!==`android`||!e.appBundleId)return null;let t=await he(e.device),n=t.package?.trim();return!n||n===e.appBundleId||!Xe(n)?null:{expectedPackage:e.appBundleId,foregroundPackage:n,activity:t.activity,hint:Ye(n)}}function qe(e){return y(e.foregroundPackage)?`Android permission dialog is blocking ${e.expectedPackage}`:`${e.foregroundPackage} is foreground instead of ${e.expectedPackage}`}function Je(e){return e.code===`COMMAND_FAILED`&&typeof e.details?.expectedPackage==`string`&&typeof e.details?.foregroundPackage==`string`}function Ye(e){return y(e)?`Use "alert get" to inspect it, then "alert accept" or "alert dismiss" to respond.`:`Use screenshot as visual truth, then take a fresh snapshot -i before retrying.`}function Xe(e){return e===`com.android.settings`||e===`com.android.systemui`||y(e)||e.includes(`launcher`)}function Ze(e,t){if(t===`exists`)return{found:!0};if(t===`wait`)return{found:!0,waitedMs:e.waitedMs};if(t===`list`)return{action:`list`,matches:Array.isArray(e.matches)?e.matches.length:0};let n=typeof e.ref==`string`?e.ref:void 0;return t===`get_attrs`?{ref:n,action:`get attrs`}:{ref:n,action:`get text`,text:typeof e.text==`string`?e.text:``}}function Qe(e){return e.kind===`found`?{found:!0,...typeof e.waitedMs==`number`?{waitedMs:e.waitedMs}:{}}:e.kind===`list`?{matches:e.matches.map(e=>({ref:e.ref,node:u(e.node)}))}:{ref:e.ref,...e.kind===`text`?{text:e.text}:{},node:u(e.node)}}function P(e,t){let n=Array.isArray(e.selectorChain)?e.selectorChain:void 0,r=tt(e),i=r?.kind===`ref`?z(r.ref):void 0,a=r?.kind===`selector`?r.selector:void 0,o={...i?{ref:i}:{},...a?{selector:a}:{},...n?{selectorChain:n}:{}};if(t===`attrs`)return o;let s=typeof e.text==`string`?e.text:``;return{...o,text:s,refLabel:et(s)}}function F(e){let{target:t}=e;return{...t.kind===`ref`?{ref:z(t.ref)}:{},...t.kind===`selector`?{selector:t.selector}:{},...typeof e.text==`string`?{text:e.text}:{},node:u(e.node)}}function I(e){let{node:t,preActionNodes:n,...r}=e;return r}function $e(e){return{waitedMs:e.waitedMs,...typeof e.text==`string`?{text:e.text}:{},...typeof e.selector==`string`?{selector:e.selector}:{},...typeof e.captures==`number`?{captures:e.captures}:{},...typeof e.nodeCount==`number`?{nodeCount:e.nodeCount}:{},...typeof e.hint==`string`?{hint:e.hint}:{}}}function L(e){let{selectorChain:t,...n}=e;return n}function R(e,t,n,r,i,a){let o=e.get(t);if(!o)return;let s=o.recordSession&&i?de(i,{mode:a}):void 0;e.recordAction(o,{command:n.command,positionals:n.positionals??[],flags:n.flags??{},result:r,interactiveObservation:ue(n),...s?{targetEvidence:s}:{}})}function et(e){let t=e.trim();if(!(!t||t.length>80||/[\r\n]/.test(t)))return t}function tt(e){let t=e.target;if(!t||typeof t!=`object`)return;let n=t;if(n.kind===`ref`&&typeof n.ref==`string`)return{kind:`ref`,ref:n.ref};if(n.kind===`selector`&&typeof n.selector==`string`)return{kind:`selector`,selector:n.selector}}function z(e){return e.startsWith(`@`)?e.slice(1):e}const nt=[`application`,`window`,`tabbar`,`scrollbar`,`image`],rt=new Set([`tab bar`]);async function B(e,t){if(t.ok||!it(t.error.details?.reason)||t.error.details?.captureStalled===!0||t.error.details?.captureTruncated===!0)return t;let n=await at(e).catch(()=>null);return n?b(t.error.code,`${t.error.message}. Current surface: ${n.summary}.`,{...t.error.details??{},currentSurface:n.details}):t}function it(e){return e===s.targetAbsent||e===s.stableTimeout}async function at(e){let t=[...(await w({device:e.device,session:e.session,flags:{...e.req.flags,snapshotInteractiveOnly:!0},logPath:e.logPath??``})).snapshot.nodes].sort(ot),n=V(t,6,{includeIdentifiers:!0});if(n.length===0)return null;let r=V(t.filter(e=>!U(e)),4,{includeIdentifiers:!1}),i=V(t.filter(lt),4,{includeIdentifiers:!0});return{summary:(r.length>0?r:n.slice(0,4)).join(`, `),details:{labels:n,...i.length>0?{buttons:i}:{}}}}function V(e,t,n){let r=new Set,i=[];for(let a of e){let e=ct(a,n);if(!(!e||r.has(e))&&(r.add(e),i.push(e),i.length>=t))break}return i}function ot(e,t){return H(e)-H(t)||st(e,t)}function H(e){let t=!!ct(e,{includeIdentifiers:!1});return(U(e)?2:0)+ +!t}function st(e,t){return e.rect&&t.rect?e.rect.y-t.rect.y||e.rect.x-t.rect.x:e.rect?-1:t.rect?1:(e.depth??0)-(t.depth??0)||e.index-t.index}function ct(e,t){let n=(t.includeIdentifiers?[e.label,e.value,e.identifier]:[e.label,e.value]).map(e=>typeof e==`string`?e.trim():``).find(e=>e.length>0);return n?n.replace(/\s+/g,` `).slice(0,80):``}function U(e){let t=h(`${e.type??``} ${e.role??``} ${e.subrole??``}`),n=`${e.label??``} ${e.value??``}`.trim().toLowerCase();return nt.some(e=>t.includes(e))||rt.has(n)||n.endsWith(`.fill`)}function lt(e){return h(`${e.type??``} ${e.role??``} ${e.subrole??``}`).includes(`button`)}function W(e,t){let n=pe(t);if(!n)return e;if(e.ok){let t=G(e.data?.warning,n);return{...e,data:{...e.data,warning:t}}}let r=e.error.details??{};return{...e,error:{...e.error,details:{...r,hint:G(r.hint,n)}}}}function G(e,t){return typeof e==`string`&&e.trim()!==``?`${e}\n${t}`:t}async function ut(e){let{device:t,node:n,flags:r,appBundleId:i,traceOutPath:a,surface:o,contextFromFlags:s}=e,c=se(n),l=le(n.rect);if(!l||ie(t)&&c&&!fe(n.type??``))return c;try{let e=await xe(t,`read`,[String(l.x),String(l.y)],void 0,{...s(r,i,a),surface:o}),u=e&&typeof e==`object`?e:void 0,d=typeof u?.text==`string`?u.text:``;return d.trim()?d:(v({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`empty_backend_text`,nodeRef:n.ref,surface:o,platform:t.platform}}),c)}catch(e){return v({level:`warn`,phase:`interaction_read_fallback`,data:{reason:`backend_read_failed`,nodeRef:n.ref,surface:o,platform:t.platform,error:e instanceof Error?e.message:String(e)}}),c}}function K(e){let{session:t,sessionStore:n,sessionName:r}=e,i=0,a,o,s=t=>(e.consumedSnapshot&&(e.consumedSnapshot.state=t.snapshot),t);return{capture:async c=>{let l=Date.now(),u=yt(c,e.req.flags?.out),d=mt({timestamp:l,lastSnapshotAt:i,lastSnapshotResult:a,lastSnapshotCacheKey:o,session:t,request:c,cacheKey:u});if(d)return s(d);let f=ht({session:t,timestamp:l,request:c});if(f)return i=f.createdAt,a={snapshot:f},o=u,s(a);let p=await dt({params:e,request:c});c.signal?.throwIfAborted();let m={snapshot:p};return xt({session:t,sessionStore:n,sessionName:r,snapshot:p}),i=l,a=m,o=u,s(m)}}}async function dt(e){let{params:t,request:n}=e,r=await q(t,n,n.snapshotScope);return n.recovery?.legacyIosSparse&&St(r)?await ft({runtimeParams:t,request:n,policy:n.recovery.legacyIosSparse}):n.recovery?.sparseVerdictQueryScope?.shouldScope&&_(r.snapshotQuality)?await pt({runtimeParams:t,request:n,policy:n.recovery.sparseVerdictQueryScope,snapshot:r}):r}async function ft(e){let{runtimeParams:t,request:n,policy:r}=e;try{return await q(t,n,void 0,!1)}catch(e){if(!r.shouldScope)throw e;return await q(t,n,r.query,!1)}}async function pt(e){let{runtimeParams:t,request:n,policy:r,snapshot:i}=e;try{return await q(t,n,r.query,!1)}catch{return i}}async function q(e,t,n,r=t.flags?.snapshotInteractiveOnly){return(await w({device:e.device,session:e.session,flags:{...t.flags,snapshotInteractiveOnly:r},outPath:t.outPath??e.req.flags?.out,logPath:e.logPath??``,snapshotScope:n,includeRects:t.includeRects,signal:t.signal})).snapshot}function mt(e){let{timestamp:t,lastSnapshotAt:n,lastSnapshotResult:r,lastSnapshotCacheKey:i,session:a,request:o,cacheKey:s}=e;if(o.cache?.forceFresh!==!0&&r&&i===s&&!(t-n>=750)&&!Ee(a)&&!J(a,o))return r}function ht(e){let{session:t,timestamp:n,request:r}=e,i=t?.snapshot;if(i&>(t,r)&&_t(i,n)&&i.presentationKey===vt(r))return i}function gt(e,t){return!(t.cache?.forceFresh===!0||t.cache?.useSessionSnapshot!==!0||Ee(e)||J(e,t))}function _t(e,t){return t-e.createdAt<750}function J(e,t){return t.cache?.bypassForPostGestureStabilization===!0&&T(e)}function vt(e){return r(i(bt(e)))}function yt(e,t){return JSON.stringify({presentationKey:vt(e),includeRects:e.includeRects===!0,outPath:e.outPath??t??null})}function bt(e){return e.snapshotScope===void 0?e.flags:{...e.flags,snapshotScope:e.snapshotScope}}function xt(e){let{session:t,sessionStore:n,sessionName:r,snapshot:i}=e;!t||_(i.snapshotQuality)||(C(t,i),n.set(r,t))}function St(e){return e.snapshotQuality||e.backend!==`xctest`||e.nodes.length!==1?!1:e.nodes[0]?.type===`Application`}function Ct(e){return me({backend:wt(e),...Oe(`selector commands`,{plural:!0}),sessions:Ce({sessionName:e.sessionName,getSession:()=>e.session,recordOptions:{includeSnapshot:!0},setRecord:t=>{!e.session||!t.snapshot||(C(e.session,t.snapshot),e.sessionStore.set(e.sessionName,e.session))}}),signal:e.signal??ge(e.req.meta?.requestId)})}async function Y(e,t){e.consumedSnapshot??={};let n=e.sessionStore.get(e.sessionName);if(!n&&t.requireSession)return{ok:!1,response:ye()};let r=n?.device??await ve(e.req.flags??{});n||await we(r);let i=be(t.capability,r);return i?{ok:!1,response:i}:{ok:!0,runtime:Ct({...e,session:n,device:r})}}function wt(e){let{req:t,session:n,device:r,logPath:i,sessionName:a,sessionStore:o}=e,s=K({device:r,session:n,sessionStore:o,sessionName:a,req:t,consumedSnapshot:e.consumedSnapshot,logPath:i});return{platform:re(r),captureSnapshot:async(e,n)=>{let i={...t.flags,...Tt(n)},a=n?.includeRects===!0,o=n?.scope??t.flags?.snapshotScope,c=t.command===`wait`||t.command===`find`||a&&r.platform===`web`;return await s.capture({flags:i,signal:e.signal,snapshotScope:o,includeRects:a,cache:{forceFresh:c,useSessionSnapshot:!0,bypassForPostGestureStabilization:!0}})},readText:async(a,o)=>({text:await ut({device:r,node:o,flags:t.flags,appBundleId:n?.appBundleId,traceOutPath:n?.trace?.outPath,surface:n?.surface,contextFromFlags:e.contextFromFlags??((e,t,n)=>Se(i??``,e,t,n))})}),findText:async(t,n)=>({found:await Et(e,n,t.signal)})}}function Tt(e){let{interactiveOnly:t,scope:n,depth:r,raw:i,includeHiddenContentHints:a}=e??{},o={};return t!==void 0&&(o.snapshotInteractiveOnly=t),n!==void 0&&(o.snapshotScope=n),r!==void 0&&(o.snapshotDepth=r),i!==void 0&&(o.snapshotRaw=i),a!==void 0&&(o.snapshotIncludeHiddenContentHints=a),o}async function Et(e,t,n){let r=await Dt(e,t,n);return r===null?await Ot(e,t,n)===!0?!0:await jt(e,t,n):r}async function Dt(e,t,n){return!ae(e.device)||!e.session?.surface||e.session.surface===`app`?null:await jt(e,t,n)}async function Ot(e,t,n){let r=kt(e);return r?(await x(r.device,{command:`findText`,text:t,appBundleId:r.appBundleId},{...At(e,r),signal:n}))?.found===!0:null}function kt(e){return!oe(e.device.platform)||_e(e.device)||!e.session?.appBundleId?null:{device:e.device,appBundleId:e.session.appBundleId,traceLogPath:e.session.trace?.outPath}}function At(e,t){return De({req:e.req,logPath:e.logPath,traceLogPath:t.traceLogPath})}async function jt(e,t,n){return!!ce((await Mt(e,n)).nodes,t)}async function Mt(e,t){let{snapshot:n}=await K({device:e.device,session:e.session,sessionStore:e.sessionStore,sessionName:e.sessionName,req:e.req,logPath:e.logPath,consumedSnapshot:e.consumedSnapshot}).capture({flags:{...e.req.flags,snapshotInteractiveOnly:!1,snapshotIncludeHiddenContentHints:!1},signal:t,cache:{forceFresh:!0,bypassForPostGestureStabilization:!0}});return n}async function Nt(e){let{req:t}=e;if(t.command!==`find`)return null;let n=ne(t.positionals??[],t.flags);if(!n.ok)return b(n.code,n.message);let r=n.parsed,i=r.action;if(!ee(i))return null;let a=await Y(e,{requireSession:!1,capability:`find`});return a.ok?W(await $(async()=>{let n=await a.runtime.selectors.find({session:e.sessionName,requestId:t.meta?.requestId,locator:r.locator,query:r.query,action:i,timeoutMs:r.timeoutMs});R(e.sessionStore,e.sessionName,t,Ze(n,i));let o=Qe(n),s=typeof o.ref==`string`?[o.ref]:Array.isArray(o.matches)?o.matches.map(e=>e.ref).filter(e=>typeof e==`string`):[];if(s.length>0){let t=e.sessionStore.get(e.sessionName);if(t&&(Te(t,s),e.sessionStore.set(e.sessionName,t),t.snapshotGeneration!==void 0))return{...o,refsGeneration:t.snapshotGeneration}}return o}),X(e)):a.response}function X(e){return e.consumedSnapshot?.state??e.sessionStore.get(e.sessionName)?.snapshot}async function Pt(e){let{req:t}=e;if(t.command!==`get`)return null;let n=te(t.positionals?.[0]);if(!n.ok)return b(n.code,n.message);let r=n.format,i=qt(t);if(!i.ok)return i.response;if(i.target.kind===`ref`){let e=Me(`get`,t.flags);if(e)return e}let a=t.internal?.replayTargetGuard;if(i.target.kind===`selector`&&!a){let t=await zt(e,r,i.target.selector);if(t)return t}let o=await Y(e,{requireSession:!0,capability:`get`});if(!o.ok)return o.response;let s=i.target.kind===`ref`?S({session:e.sessionStore.get(e.sessionName),ref:i.target.ref,mintedGeneration:i.refGeneration}):void 0;return W(await $(async()=>{let n=await o.runtime.selectors.get({session:e.sessionName,requestId:t.meta?.requestId,property:r,target:i.target,expectedResolvedTarget:a});R(e.sessionStore,e.sessionName,t,P(n,r),{node:n.node,preActionNodes:n.preActionNodes});let c=F(n);return s?{...c,warning:s}:c}),X(e))}async function Ft(e){let{req:t}=e;if(t.command!==`is`)return null;let n=c(t.positionals??[]);if(!n.ok)return b(n.code,n.message,n.hint?{hint:n.hint}:void 0);let{predicate:r,expectedText:i}=n,a={selectorExpression:n.selectorExpression},o=t.internal?.replayTargetGuard,s=e.sessionStore.get(e.sessionName)?.recordSession===!0;if(!o&&!s){let t=await Bt(e,r,a.selectorExpression,i);if(t)return t}let l=await Y(e,{requireSession:!0,capability:`is`});return l.ok?W(await Yt(e,await $(async()=>{let n=await l.runtime.selectors.is({session:e.sessionName,requestId:t.meta?.requestId,predicate:r,selector:a.selectorExpression,expectedText:i,expectedResolvedTarget:o}),s=Lt(n),c=I(n);return R(e.sessionStore,e.sessionName,t,c,s),L(c)}),`is ${r}`),X(e)):l.response}async function It(e){let{req:t,sessionName:n,sessionStore:r}=e,i=m(t.positionals??[]);if(!i)return b(`INVALID_ARGS`,`wait requires a duration or text`);let{session:a,device:o}=await Ae(r,n,t.flags);if(i.kind!==`sleep`){let e=be(`wait`,o);if(e)return e}let s=t.internal?.replayLandmarkGuard;if(i.kind===`selector`&&!s&&!a?.recordSession){let t=await Vt({...e,session:a,device:o,selectorExpression:i.selectorExpression,timeoutMs:i.timeoutMs});if(t)return t}let c=i,l;if(i.kind===`ref`){let e=D(i.rawRef);if(!e.ok)return e.response;c={...i,rawRef:e.ref},l=S({session:a,ref:e.ref,mintedGeneration:e.generation})}e.consumedSnapshot??={};let u=async()=>{let i=Ct({...e,session:a,device:o}),u=await $(async()=>{let e=await i.selectors.wait({session:n,requestId:t.meta?.requestId,target:Jt(c,a,s)}),o=Lt(e);R(r,n,t,I(e),o,`landmark`);let u=$e(e);return l?{...u,warning:l}:u});return await Yt(e,await B({req:t,logPath:e.logPath,session:a,device:o},u),`wait`)};return i.kind===`sleep`?await u():W(await ke(a,o,u),X(e))}function Lt(e){let t=e.node,n=e.preActionNodes;if(!(!t||typeof t!=`object`||!Array.isArray(n)))return{node:t,preActionNodes:n}}function Rt(e,t,n){if(!e||e.recordSession)return null;let r=j({session:e,selectorExpression:n});return t===`text`&&r?.key!==`id`?null:r}async function zt(e,t,n){let r=e.sessionStore.get(e.sessionName),i=Rt(r,t,n);if(!r||!i)return null;let a=await Z(e,r,i);if(Q(a))return a.response;if(!a)return null;let o=Wt(t,i.raw,a);return o?(R(e.sessionStore,e.sessionName,e.req,P(o,t)),{ok:!0,data:F(o)}):null}async function Bt(e,t,n,r){if(t===`hidden`)return null;let i=await Ht(e,n);if(Q(i))return i.response;if(!i?.result.found||!i.result.node)return null;let a=t===`exists`?{predicate:t,pass:!0,selector:i.selector.raw,matches:1,selectorChain:[i.selector.raw]}:Gt(t,r,i.selector.raw,i.session,i.result.node);return a?(R(e.sessionStore,e.sessionName,e.req,a),{ok:!0,data:L(a)}):null}async function Vt(e){let t=j({session:e.session,selectorExpression:e.selectorExpression});if(!e.session||!t)return null;let n=Date.now(),r=await Z(e,e.session,t);if(Q(r))return r.response;if(!r?.found)return null;let i={kind:`selector`,selector:t.raw,waitedMs:Date.now()-n,selectorChain:[t.raw]};R(e.sessionStore,e.sessionName,e.req,i);let a={ok:!0,data:L(i)};return await B({req:e.req,logPath:e.logPath,session:e.session,device:e.device},a)}async function Ht(e,t){let n=e.sessionStore.get(e.sessionName),r=j({session:n,selectorExpression:t});if(!n||!r)return null;let i=await Z(e,n,r);return Q(i)?i:i?{session:n,selector:r,result:i}:null}async function Ut(e,t,n){let r=await x(e.device,{command:`querySelector`,selectorKey:t.key,selectorValue:t.value,appBundleId:e.appBundleId},n),i=r.found===!0,a=Kt(r);return{found:i,...typeof r.text==`string`?{text:r.text}:{},...a?{node:a}:{}}}async function Z(t,n,r){try{return await Ut(n,r,De({req:t.req,logPath:t.logPath,traceLogPath:n.trace?.outPath}))}catch(t){return M(t,{allowElementNotFound:!0})?null:{kind:`error`,response:{ok:!1,error:e(t)}}}}function Q(e){return e!==null&&`kind`in e&&e.kind===`error`}function Wt(e,t,n){if(!n.found||!n.node)return null;let r={target:{kind:`selector`,selector:t},node:n.node,selectorChain:[t]};return e===`attrs`?{kind:`attrs`,...r}:typeof n.text==`string`?{kind:`text`,...r,text:n.text}:null}function Gt(e,t,n,r,i){let a=f({predicate:e,node:i,nodes:[i],expectedText:t,platform:r.device.platform});return{predicate:e,pass:a.pass,selector:n,...e===`text`?{text:a.actualText}:{},selectorChain:[n]}}function Kt(e){let t=e.nodes;if(!Array.isArray(t))return;let n=t[0];if(!(!n||typeof n!=`object`))return n}function qt(e){let t=e.positionals?.[1]??``;if(t.startsWith(`@`)){let n=D(t);return n.ok?{ok:!0,target:{kind:`ref`,ref:n.ref,fallbackLabel:e.positionals.length>2?e.positionals.slice(2).join(` `).trim():``},refGeneration:n.generation}:{ok:!1,response:n.response}}let n=l(e.positionals?.slice(1)??[]);return n.ok?{ok:!0,target:{kind:`selector`,selector:`selector`in n?n.selector:``}}:{ok:!1,response:b(n.code,n.message)}}function Jt(e,n,r){if(e.kind===`sleep`)return{kind:`sleep`,durationMs:e.durationMs};if(e.kind===`selector`)return{kind:`selector`,selector:e.selectorExpression,timeoutMs:e.timeoutMs,...r?{recordedLandmark:r}:{}};if(e.kind===`ref`){if(!n?.snapshot)throw new t(`INVALID_ARGS`,`Ref wait requires an existing snapshot in session.`);return{kind:`ref`,ref:e.rawRef,timeoutMs:e.timeoutMs}}if(e.kind===`stable`)return{kind:`stable`,quietMs:e.quietMs,timeoutMs:e.timeoutMs};let i=d(e.text);if(!i.ok)throw new t(i.code,i.message);return{kind:`text`,text:i.text,timeoutMs:e.timeoutMs}}async function $(e){try{return{ok:!0,data:await e()}}catch(e){let t=o(e);return b(t.code,t.message,t.details)}}async function Yt(e,t,n){if(t.ok)return t;let r=e.sessionStore.get(e.sessionName);if(!r)return t;let i;try{i=await N(r)}catch{return t}return i?b(t.error.code,`${n} failed because ${qe(i)}.`,{...t.error.details??{},...i,blockedBy:`android_foreground_surface`,originalMessage:t.error.message}):t}export{Pe as S,Ie as _,Ut as a,Fe as b,Ke as c,M as d,A as f,Le as g,ze as h,It as i,Je as l,Be as m,Pt as n,K as o,j as p,Ft as r,W as s,Nt as t,Ge as u,O as v,Me as x,k as y};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{H as t}from"./screenshot-geometry.js";import{h as n,i as r,m as i}from"./sdk-device.js";import{a}from"./sdk-remote-config.js";import{i as o,r as s}from"./device.js";import{v as c}from"./sdk-android-adb.js";import{n as l}from"./version.js";import{n as u,o as d}from"./host-process.js";import{r as ee}from"./entities.js";import{t as te}from"./parser.js";import f from"node:path";import p from"node:crypto";import m from"node:fs";import ne from"node:os";import h from"node:fs/promises";import{setTimeout as g}from"node:timers/promises";function re(e,t){let n=p.createHash(`sha256`).update(e).digest(),r=p.createHash(`sha256`).update(t).digest();return p.timingSafeEqual(n,r)}const _={support:`supported`},v={support:`unsupported`},ie={lease:_,inventory:{support:`partial`,note:`Inventory exposes only the leased cloud device, not the provider catalog.`},install:{support:`partial`,note:`Requires provider-specific upload or a path visible to the remote Appium server.`},open:_,close:_,snapshot:{support:`partial`,note:`Uses Appium page source XML, not agent-device native snapshot backends.`},screenshot:_,tap:_,doubleTap:_,longPress:_,swipe:_,scroll:{support:`partial`,note:`Implemented as viewport-relative W3C pointer gestures.`},fill:_,type:_,back:_,home:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},orientation:{support:`partial`,note:`Uses the WebDriver rotation/orientation endpoints; four-way rotation collapses to portrait/landscape on drivers that only accept the two-way endpoint. Rotates the current display, so an activity that does not pin its orientation may need rotating again once it is foreground.`},appSwitcher:{support:`partial`,note:`Uses provider/Appium mobile pressButton support where available.`},tvRemote:v,"clipboard.read":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},"clipboard.write":{support:`partial`,note:`Uses provider/Appium clipboard extension support where available.`},settings:v,pinch:v,rotateGesture:v,transformGesture:v,logs:v,record:v,artifacts:v,portReverse:v,nativeSnapshotBackend:{support:`unsupported`,note:`Cloud WebDriver cannot upload or run agent-device native runner/helper backends.`}};function ae(e){return{provider:e.provider,platform:e.platform,snapshotBackend:e.platform===`ios`?`xctest`:`android`,snapshotSource:`appium-page-source`,operations:se(ie,e.overrides)}}function oe(e,t){return e.operations[t].support!==`unsupported`}function y(e,t){let n=e.operations[t],r=n.note?` ${n.note}`:``;return`${e.provider} WebDriver runtime does not support ${t}.${r}`}function se(e,t){let n={...e};for(let[r,i]of Object.entries(t??{}))n[r]=typeof i==`string`?{...e[r],support:i}:{...e[r],...i};return n}function b(e){return{provider:e.provider,providerSessionId:e.providerSessionId,status:e.artifacts.length>0?`ready`:`pending`,cloudArtifacts:e.artifacts,...e.artifacts.length>0?{}:{message:e.pendingMessage}}}function ce(e){return{provider:e.provider,providerSessionId:e.providerSessionId,status:`unavailable`,cloudArtifacts:[],message:e.error instanceof Error?e.error.message:String(e.error)}}function le(e,t){let n=e?.bundleId??t?.appIdentifierHint,r=e?.packageName??t?.packageNameHint;return{bundleId:n,packageName:r,appName:e?.appName,launchTarget:de(e?.launchTarget,n,r)}}function ue(e){return e===`ios`?`xctest`:`android`}function de(...e){return e.find(e=>e!==void 0)}function x(e){return{"x-agent-device-client":`agent-device-cli`,"x-agent-device-version":e}}function fe(e,t){return typeof e==`function`?e(t):e}function S(e){return`Basic ${Buffer.from(`${e.username}:${e.accessKey}`).toString(`base64`)}`}function pe(e){let t=0;for(;t<e.length&&e.charCodeAt(t)===47;)t+=1;return t===0?e:e.slice(t)}function me(e){let t=e.length-1;for(;t>=0&&e.charCodeAt(t)===47;)--t;return t===e.length-1?e:e.slice(0,t+1)}function he(e){if(e.pathname.endsWith(`/`))return e;let t=new URL(e);return t.pathname=`${t.pathname}/`,t}var ge=class{endpoint;headers;requestPolicy;sessionId;constructor(e){this.endpoint=he(new URL(e.endpoint)),this.headers={...x(e.clientVersion),...e.auth?{Authorization:S(e.auth)}:{},...e.headers},this.requestPolicy={timeoutMs:e.requestPolicy?.timeoutMs??3e4,retryAttempts:e.requestPolicy?.retryAttempts??1,retryDelayMs:e.requestPolicy?.retryDelayMs??250}}async createSession(e){let t=ye(await this.requestValue(`POST`,`/session`,{capabilities:ve(e)}));return this.sessionId=t.sessionId,t}async deleteSession(){let e=this.requireSessionId();await this.requestValue(`DELETE`,`/session/${e}`),this.sessionId=void 0}async installApp(e){await this.sessionRequest(`POST`,`/appium/device/install_app`,{appPath:e})}async activateApp(e){try{await this.sessionRequest(`POST`,`/appium/device/activate_app`,{appId:e})}catch{await this.executeScript(`mobile: activateApp`,[{appId:e,bundleId:e}])}}async terminateApp(e){try{await this.sessionRequest(`POST`,`/appium/device/terminate_app`,{appId:e})}catch{await this.executeScript(`mobile: terminateApp`,[{appId:e,bundleId:e}])}}async performActions(e){await this.sessionRequest(`POST`,`/actions`,{actions:e})}async releaseActions(){await this.sessionRequest(`DELETE`,`/actions`,void 0,{retryAttempts:0})}async sendKeys(e){await this.sessionRequest(`POST`,`/keys`,{value:Array.from(e)})}async hideKeyboard(){await this.sessionRequest(`POST`,`/appium/device/hide_keyboard`,void 0,{retryAttempts:0})}async back(){await this.sessionRequest(`POST`,`/back`)}async setRotation(e){await this.sessionRequest(`POST`,`/rotation`,{x:0,y:0,z:e})}async setOrientation(e){await this.sessionRequest(`POST`,`/orientation`,{orientation:e})}async source(){let t=await this.sessionRequest(`GET`,`/source`);if(typeof t!=`string`)throw new e(`COMMAND_FAILED`,`WebDriver source response was not a string`,{valueType:typeof t});return t}async screenshot(t){let n=await this.sessionRequest(`GET`,`/screenshot`);if(typeof n!=`string`)throw new e(`COMMAND_FAILED`,`WebDriver screenshot response was not base64 text`,{valueType:typeof n});await h.writeFile(t,Buffer.from(n,`base64`))}async windowRect(){return _e(await this.sessionRequest(`GET`,`/window/rect`))}async executeScript(e,t=[]){return await this.sessionRequest(`POST`,`/execute/sync`,{script:e,args:t})}async sessionRequest(e,t,n,r){let i=this.requireSessionId();return await this.requestValue(e,`/session/${i}${t}`,n,r)}requireSessionId(){if(!this.sessionId)throw new e(`SESSION_NOT_FOUND`,`WebDriver session has not been created yet.`);return this.sessionId}async requestValue(e,t,n,r){let i,a=r?.retryAttempts??this.requestPolicy.retryAttempts;for(let r=0;r<=a;r+=1)try{return await this.requestValueOnce(e,t,n)}catch(e){if(i=e,!Ce(e)||r>=a)throw e;await g(this.requestPolicy.retryDelayMs)}throw i}async requestValueOnce(e,t,n){let r=await fetch(new URL(pe(t),this.endpoint),{method:e,headers:{Accept:`application/json`,...n===void 0?{}:{"Content-Type":`application/json`},...this.headers},body:n===void 0?void 0:JSON.stringify(n),signal:AbortSignal.timeout(this.requestPolicy.timeoutMs)}),i=await r.text(),a=i?xe(i):{};if(!r.ok)throw Se(r.status,a);return be(a)}};function _e(t){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`WebDriver window rect response was empty.`);let n=t,r={x:C(n,`x`),y:C(n,`y`),width:C(n,`width`),height:C(n,`height`)};if(r.x===void 0||r.y===void 0||r.width===void 0||r.height===void 0)throw new e(`COMMAND_FAILED`,`WebDriver window rect response was invalid.`,{response:n});return r}function C(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}function ve(e){return`alwaysMatch`in e||`firstMatch`in e?e:{alwaysMatch:e}}function ye(t){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`WebDriver create-session response was empty.`);let n=t,r=typeof n.sessionId==`string`?n.sessionId:typeof n.session_id==`string`?n.session_id:void 0;if(!r)throw new e(`COMMAND_FAILED`,`WebDriver create-session response missed sessionId.`,{response:n});return{sessionId:r,capabilities:n.capabilities&&typeof n.capabilities==`object`?n.capabilities:{}}}function be(e){if(!e||typeof e!=`object`)return e;let t=e;return`value`in t?t.value:e}function xe(t){try{return JSON.parse(t)}catch(n){throw new e(`COMMAND_FAILED`,`WebDriver response was not valid JSON.`,{text:t},n)}}function Se(t,n){let r=n&&typeof n==`object`&&`value`in n?n.value:n;return new e(`COMMAND_FAILED`,r&&typeof r==`object`&&typeof r.message==`string`?r.message:`WebDriver request failed with HTTP ${t}.`,{status:t,response:n})}function Ce(t){if(t instanceof e){let e=t.details?.status;return typeof e==`number`&&e>=500}return t instanceof TypeError||t instanceof Error&&t.name===`TimeoutError`}function we(e,t){return{type:`pointer`,id:e,parameters:{pointerType:`touch`},actions:t}}function Te(t){let n;try{n=te(t)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse WebDriver page source XML: ${t instanceof Error?t.message:String(t)}`,void 0,t)}let r=[];for(let e of n)Ee(r,e);return r}function Ee(e,t,n,r=0){let i=Object.keys(t.attributes).length===0?n:De(e,t,n,r),a=i===n?r:r+1;for(let n of t.children)Ee(e,n,i,a)}function De(e,t,n,r){let i=e.length;return e.push(Oe(i,t.name,t.attributes,n,r)),i}function Oe(e,t,n,r,i){let a=ke(n),o=E(n.enabled,!0),s=E(n.displayed??n.visible,!0);return{index:e,type:t,role:Ae(t,n),label:w(n,[`content-desc`,`label`,`text`,`name`]),value:T(n.value),identifier:w(n,[`resource-id`,`id`,`accessibility-id`,`name`]),rect:a,enabled:o,selected:E(n.selected),focused:E(n.focused),visibleToUser:s,hittable:s&&o&&a!==void 0&&a.width>0&&a.height>0,depth:i,parentIndex:r}}function ke(e){let t=ee(e.bounds??null);if(t)return t;let n=D(e.x),r=D(e.y),i=D(e.width),a=D(e.height);if(!(n===void 0||r===void 0||i===void 0||a===void 0))return{x:n,y:r,width:i,height:a}}function w(e,t){for(let n of t){let t=T(e[n]);if(t!==void 0)return t}}function T(e){return e||void 0}function E(e,t=!1){return e===void 0?t:e===`true`||e===`1`}function D(e){if(e===void 0||e===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function Ae(e,t){return T(t.class)??T(e.replace(/^XCUIElementType/,``).toLowerCase())}function je(e){let t=Te(e).flatMap(e=>Me(e)&&Ne(e.rect)?[e.rect]:[]).sort((e,t)=>t.width*t.height-e.width*e.height)[0];return t?{x:t.x,y:t.y,width:t.width,height:t.height}:void 0}function Me(e){let t=e.type?.toLowerCase()??``;return e.visibleToUser!==!1&&(t.includes(`scrollview`)||t.includes(`listview`)||t.includes(`recyclerview`))}function Ne(e){return!!e&&e.width>=50&&e.height>=50}async function Pe(t,n,r){let i=[];for(let e of n===`android`?[`rotation`,`orientation`]:[`orientation`,`rotation`])try{await ze(t,e,r);return}catch(t){if(!Le(t))throw t;i.push({transport:e,error:t instanceof Error?t.message:String(t)})}throw new e(`COMMAND_FAILED`,`Could not set device orientation to ${r} on the hosted WebDriver session.`,{hint:`The provider driver rejected both orientation endpoints. Set the orientation as a session capability instead, for example connect --provider-device-orientation portrait.`,rotation:r,attempts:i})}const Fe=new Set([`unknown command`,`unknown method`]),Ie=new Set([404,405]);function Le(t){if(!(t instanceof e)||t.code===`SESSION_NOT_FOUND`)return!1;let n=Re(t.details?.response);if(n)return Fe.has(n);let r=t.details?.status;return typeof r==`number`&&Ie.has(r)}function Re(e){if(!e||typeof e!=`object`)return``;let t=e.value;if(!t||typeof t!=`object`)return``;let n=t.error;return typeof n==`string`?n:``}async function ze(e,t,n){if(t===`rotation`){await e.setRotation(o(n));return}await e.setOrientation(s(n))}function Be(e){return new Ve(e.client,e.backend,e.capabilities)}var Ve=class{client;backend;capabilities;constructor(e,t,n){this.client=e,this.backend=t,this.capabilities=n}async open(e,t){if(this.requireSupport(`open`),t?.url){await this.client.executeScript(`mobile: deepLink`,[{url:t.url,package:e}]);return}let n=t?.appBundleId??e;n&&await this.client.activateApp(n)}async openDevice(){this.requireSupport(`open`),await this.client.executeScript(`mobile: activateApp`,[{}])}async close(e){this.requireSupport(`close`),e&&await this.client.terminateApp(e)}async tap(e,t){return this.requireSupport(`tap`),await this.pointerGesture(`tap`,[{type:`pointerMove`,duration:0,x:e,y:t},{type:`pointerDown`,button:0},{type:`pointerUp`,button:0}]),{backend:`webdriver`,x:e,y:t}}async doubleTap(e,t){return this.requireSupport(`doubleTap`),await this.pointerGesture(`doubleTap`,[{type:`pointerMove`,duration:0,x:e,y:t},{type:`pointerDown`,button:0},{type:`pointerUp`,button:0},{type:`pause`,duration:80},{type:`pointerDown`,button:0},{type:`pointerUp`,button:0}]),{backend:`webdriver`,x:e,y:t}}async swipe(e,t,n,r,i=400){return this.requireSupport(`swipe`),await this.pointerGesture(`swipe`,[{type:`pointerMove`,duration:0,x:e,y:t},{type:`pointerDown`,button:0},{type:`pointerMove`,duration:i,x:n,y:r},{type:`pointerUp`,button:0}]),{backend:`webdriver`,x1:e,y1:t,x2:n,y2:r,durationMs:i}}async longPress(e,t,n=600){return this.requireSupport(`longPress`),await this.pointerGesture(`longPress`,[{type:`pointerMove`,duration:0,x:e,y:t},{type:`pointerDown`,button:0},{type:`pause`,duration:n},{type:`pointerUp`,button:0}]),{backend:`webdriver`,x:e,y:t,durationMs:n}}async focus(e,t){return await this.tap(e,t)}async type(e){this.requireSupport(`type`),await this.client.sendKeys(e)}async fill(e,t,n,r){return this.requireSupport(`fill`),await this.tap(e,t),await this.type(n),{backend:`webdriver`,x:e,y:t,text:n}}async scroll(e,n){this.requireSupport(`scroll`);let r=n?.durationMs??350;await this.client.hideKeyboard().catch(()=>void 0);let i=await this.scrollGestureFrame(),a=t({direction:e,amount:n?.amount,pixels:n?.pixels,referenceWidth:i.width,referenceHeight:i.height}),o={...a,x1:a.x1+i.x,y1:a.y1+i.y,x2:a.x2+i.x,y2:a.y2+i.y};return await this.swipe(o.x1,o.y1,o.x2,o.y2,r),{backend:`webdriver`,...o,distance:a.pixels,durationMs:r}}async gestureViewport(){return await this.scrollGestureFrame()}async performGesture(e){return this.requireSupport(Ue(e)),await this.client.performActions(e.pointers.map(e=>we(`gesture-pointer-${e.pointerId}`,He(e.samples)))),await this.client.releaseActions().catch(()=>void 0),{backend:`webdriver-w3c-actions`}}async screenshot(e,t){this.requireSupport(`screenshot`),await this.client.screenshot(e)}async snapshot(e){return this.requireSupport(`snapshot`),{backend:this.backend,nodes:Te(await this.client.source())}}async back(e){this.requireSupport(`back`),await this.client.back()}async home(){this.requireSupport(`home`),await this.client.executeScript(`mobile: pressButton`,[{name:`home`}])}async setOrientation(e){this.requireSupport(`orientation`),await Pe(this.client,this.backend,e)}async appSwitcher(){this.requireSupport(`appSwitcher`),await this.client.executeScript(`mobile: pressButton`,[{name:`appSwitch`}])}async tvRemote(e,t){this.unsupported(`tvRemote`)}async readClipboard(){this.requireSupport(`clipboard.read`);let e=await this.client.executeScript(`mobile: getClipboard`,[{}]);return typeof e==`string`?e:``}async writeClipboard(e){this.requireSupport(`clipboard.write`),await this.client.executeScript(`mobile: setClipboard`,[{content:e}])}async setSetting(e,t,n,r){this.unsupported(`settings`)}async pointerGesture(e,t){await this.client.performActions([we(e,t)]),await this.client.releaseActions().catch(()=>void 0)}async scrollGestureFrame(){return await this.client.source().then(e=>je(e)).catch(()=>void 0)||await this.client.windowRect()}requireSupport(e){oe(this.capabilities,e)||this.unsupported(e)}unsupported(t){throw new e(`UNSUPPORTED_OPERATION`,y(this.capabilities,t),{provider:this.capabilities.provider,platform:this.capabilities.platform,operation:t})}};function He(t){let n=t[0];if(!n)throw new e(`INVALID_ARGS`,`WebDriver gesture pointer requires samples`);let r=[{type:`pointerMove`,duration:0,x:n.point.x,y:n.point.y},{type:`pointerDown`,button:0}];for(let e=1;e<t.length;e+=1){let n=t[e-1],i=t[e];r.push({type:`pointerMove`,duration:i.offsetMs-n.offsetMs,x:i.point.x,y:i.point.y})}return r.push({type:`pointerUp`,button:0}),r}function Ue(e){if(e.topology===`single`)return`swipe`;switch(e.intent){case`pan`:case`transform`:return`transformGesture`;case`pinch`:return`pinch`;case`rotate`:return`rotateGesture`}}function O(e){return new We(e)}function k(e,t,n={}){return{platformName:e===`ios`?`iOS`:`Android`,"appium:deviceName":t,...n}}var We=class{provider;leaseLifecycle;cloudArtifacts;deviceInventoryProvider;capabilities;sessionsByLeaseId=new Map;releasedProviderSessionIdsByLeaseId=new Map;options;constructor(e){this.options=e,this.provider=e.provider,this.capabilities=ae({provider:e.provider,platform:e.platform,overrides:e.capabilityOverrides}),this.leaseLifecycle={allocate:async(e,t)=>await this.allocate(e,t),heartbeat:async e=>this.heartbeat(e),release:async e=>await this.release(e)},this.cloudArtifacts={listCloudArtifacts:async e=>await this.listCloudArtifacts(e)},this.deviceInventoryProvider=async e=>{if(e.leaseProvider!==this.provider)return null;if(!e.leaseId)return[];let t=this.sessionsByLeaseId.get(e.leaseId);return t?[t.device]:[]}}ownsDevice(e){return[...this.sessionsByLeaseId.values()].some(t=>t.device.id===e.id)}getInteractor(e){return[...this.sessionsByLeaseId.values()].find(t=>t.device.id===e.id)?.interactor}async installApp(e,t,n,r){let i=this.findSessionForDevice(e);if(!i)return;let a=await this.uploadAppIfNeeded(i,e,t,n,r);return await i.client.installApp(a?.appReference??n),le(a,r)}async installInstallablePath(e,t,n){return await this.installApp(e,``,t,n)}async shutdown(){await Promise.allSettled([...this.sessionsByLeaseId.values()].map(async e=>await this.closeSession(e))),this.sessionsByLeaseId.clear()}async allocate(e,t){if(e.leaseProvider!==this.provider)return;if(this.sessionsByLeaseId.has(e.leaseId))return this.heartbeat(e);let n=await this.prepareSession(e,t),r=new ge({clientVersion:this.options.clientVersion,endpoint:n.endpoint,auth:n.auth,headers:n.headers,requestPolicy:this.options.requestPolicy}),i=await this.createSessionWithPreparedCleanup(r,n),a=this.deviceForLease(e,n),o=n.providerSessionId??i.sessionId,s=this.capabilitiesForPlatform(n.platform);return this.sessionsByLeaseId.set(e.leaseId,{lease:e,device:a,client:r,prepared:n,capabilities:s,webDriverSessionId:i.sessionId,providerSessionId:o,interactor:Be({client:r,backend:ue(n.platform),capabilities:s})}),{provider:this.provider,deviceId:a.id,sessionId:i.sessionId,providerSessionId:o,capabilities:s,...n.providerData}}async createSessionWithPreparedCleanup(e,t){try{return await e.createSession(t.webdriverCapabilities)}catch(e){throw await Ge(t,e),e}}heartbeat(e){if(e.leaseProvider===this.provider&&this.sessionsByLeaseId.has(e.leaseId))return{provider:this.provider}}async release(e){if(e.leaseProvider!==this.provider)return;let t=this.sessionsByLeaseId.get(e.leaseId);if(!t)return;this.sessionsByLeaseId.delete(e.leaseId),this.releasedProviderSessionIdsByLeaseId.set(e.leaseId,t.providerSessionId);let n=await this.closeSession(t),r=await this.safeListArtifacts(t);return{provider:this.provider,providerSessionId:t.providerSessionId,...n.cleanup,...n.warnings.length>0?{warnings:n.warnings}:{},...r?{cloudArtifacts:r}:{}}}async listCloudArtifacts(e){if(e.provider!==this.provider)return;let t=e.leaseId?this.sessionsByLeaseId.get(e.leaseId):void 0;if(t)return await this.safeListArtifacts(t);let n=e.providerSessionId??(e.leaseId?this.releasedProviderSessionIdsByLeaseId.get(e.leaseId):void 0);if(!(!n||!this.options.listArtifacts))return await this.options.listArtifacts({provider:this.provider,providerSessionId:n})}async prepareSession(e,t){let n=this.baseSessionForLease(e);return this.options.prepareSession?await this.options.prepareSession({lease:e,req:t,base:n}):n}capabilitiesForPlatform(e){return ae({provider:this.provider,platform:e,overrides:this.options.capabilityOverrides})}baseSessionForLease(e){let t=typeof this.options.webdriverCapabilities==`function`?this.options.webdriverCapabilities(e):this.options.webdriverCapabilities??{};return{provider:this.provider,endpoint:this.options.endpoint,platform:this.options.platform,deviceName:this.options.deviceName,auth:this.options.auth,headers:this.options.headers,webdriverCapabilities:k(this.options.platform,this.options.deviceName,t)}}deviceForLease(e,t){return{...r(t.platform),id:t.deviceId??this.options.deviceId?.(e)??`${this.provider}:${t.platform}:${e.leaseId}`,name:t.deviceName,kind:`device`,target:`mobile`,booted:!0}}findSessionForDevice(e){return[...this.sessionsByLeaseId.values()].find(t=>t.device.id===e.id)}async uploadAppIfNeeded(t,r,i,a,o){if(!oe(t.capabilities,`install`))throw new e(`UNSUPPORTED_OPERATION`,y(t.capabilities,`install`),{provider:this.provider,deviceId:r.id,platform:n(r)});let s=t.prepared.uploadApp??this.options.uploadApp;if(s)return await s({provider:this.provider,lease:t.lease,device:r,app:i,appPath:a,options:o})}async closeSession(e){let t=[],n;try{await e.client.deleteSession()}catch(e){t.push({code:`WEBDRIVER_SESSION_DELETE_FAILED`,message:A(e)})}try{n=await e.prepared.cleanup?.()}catch(e){t.push({code:`PROVIDER_CLEANUP_FAILED`,message:A(e)})}return{cleanup:n,warnings:t}}async safeListArtifacts(e){let t=e.prepared.listArtifacts??this.options.listArtifacts;if(t)try{return await t({provider:this.provider,lease:e.lease,device:e.device,webDriverSessionId:e.webDriverSessionId,providerSessionId:e.providerSessionId})}catch(t){return ce({provider:this.provider,providerSessionId:e.providerSessionId,error:t})}}};function A(e){return e instanceof Error?e.message:String(e)}async function Ge(t,n){try{await t.cleanup?.()}catch(t){n instanceof e&&(n.details={...n.details,cleanupError:A(t)})}}async function j(e,t,n){if(t)return b({provider:e,providerSessionId:t,artifacts:(await Promise.all([n.listArtifacts(t,`FILE`),n.listArtifacts(t,`LOG`)])).flat().flatMap(n=>qe(e,t,n)),pendingMessage:`AWS Device Farm artifacts are not ready yet.`})}function Ke(e){if(!e||typeof e!=`object`)return[];let t=e.artifacts;return Array.isArray(t)?t:[]}function qe(e,t,n){let r=n.url;return typeof r!=`string`||r.length===0?[]:[{provider:e,providerSessionId:t,kind:Je(n.type),name:n.name??n.type??`AWS Device Farm artifact`,url:r,providerArtifactId:n.arn,extension:n.extension,availability:`ready`,metadata:{awsType:n.type,...n.metadata?{awsMetadata:n.metadata}:{}}}]}function Je(e){switch(e){case`VIDEO`:return`video`;case`APPIUM_SERVER_OUTPUT`:return`appium-log`;case`DEVICE_LOG`:return`device-log`;case`MESSAGE_LOG`:case`UNKNOWN`:return`automation-log`;default:return`raw`}}const M={browserStack:`browserstack`,awsDeviceFarm:`aws-device-farm`},Ye=new Set(Object.values(M));function Xe(e){return e!==void 0&&Ye.has(e)}M.awsDeviceFarm;const Ze={install:{support:`unsupported`,note:`Pass appArn when creating the remote access session; local artifact upload/install is not implemented.`},portReverse:{support:`unsupported`,note:`AWS Device Farm remote access does not expose agent-device port reverse.`},artifacts:{support:`supported`,note:`AWS Device Farm remote access exposes provider-hosted video, Appium logs, and device logs after session completion.`}};function N(e){let t=P(e);return{createRemoteAccessSession:async e=>F(await t(`create-remote-access-session`,[`--project-arn`,e.projectArn,`--device-arn`,e.deviceArn,`--name`,e.name,...e.appArn?[`--app-arn`,e.appArn]:[],...e.interactionMode?[`--interaction-mode`,e.interactionMode]:[],...e.configuration?[`--configuration`,JSON.stringify(e.configuration)]:[]])),getRemoteAccessSession:async e=>F(await t(`get-remote-access-session`,[`--arn`,e])),stopRemoteAccessSession:async e=>F(await t(`stop-remote-access-session`,[`--arn`,e])),listArtifacts:async(e,n)=>Ke(await t(`list-artifacts`,[`--arn`,e,`--type`,n]))}}function Qe(t){return async({lease:n,base:r})=>{let i=await tt((await t.client.createRemoteAccessSession({projectArn:t.projectArn,deviceArn:t.deviceArn,appArn:t.appArn,name:fe(t.sessionName,n)??`agent-device-${n.leaseId}`,interactionMode:t.interactionMode,configuration:t.configuration})).arn,t),a=$e(i);if(!a)throw new e(`COMMAND_FAILED`,`AWS Device Farm did not expose a WebDriver endpoint.`,{sessionArn:i.arn,status:i.status});let o=i.device?.name??t.deviceName,s=typeof t.webdriverCapabilities==`function`?t.webdriverCapabilities(n):t.webdriverCapabilities??{};return{...r,endpoint:a,platform:t.platform,deviceName:o,webdriverCapabilities:k(t.platform,o,s),cleanup:async()=>(await t.client.stopRemoteAccessSession(i.arn),{awsDeviceFarmSessionArn:i.arn}),providerSessionId:i.arn,providerData:{awsDeviceFarmSessionArn:i.arn}}}}function $e(e){let t=e.endpoints&&typeof e.endpoints==`object`?Object.values(e.endpoints):[],n=[e.remoteDriverEndpoint,e.endpoint,...t,e.remoteDebugUrl,e.remoteRecordAppUrl].filter(e=>typeof e==`string`&&e.length>0).find(e=>!/^wss?:\/\//i.test(e));return n?et(n):void 0}function et(e){return/^https?:\/\//i.test(e)?e:`http://${e}`}async function tt(t,n){let r=n.startupTimeoutMs??12e4,i=n.pollIntervalMs??5e3,a=Date.now(),o=await n.client.getRemoteAccessSession(t);for(;Date.now()-a<r;){if(o.status===`RUNNING`)return o;if(o.status===`ERRORED`||o.status===`STOPPED`||o.status===`COMPLETED`)throw new e(`COMMAND_FAILED`,`AWS Device Farm remote access session did not start.`,{sessionArn:t,status:o.status,result:o.result});await g(i),o=await n.client.getRemoteAccessSession(t)}throw new e(`COMMAND_FAILED`,`Timed out waiting for AWS Device Farm remote access.`,{sessionArn:t,status:o.status,result:o.result,timeoutMs:r})}async function nt(t,n,r){let i=await t(n,r);try{return JSON.parse(i.stdout)}catch(t){throw new e(`COMMAND_FAILED`,`AWS Device Farm returned invalid JSON.`,void 0,t)}}function P(e){let t=e.region?[`--region`,e.region]:[],n=e.awsCommand??`aws`;return async(r,i)=>await nt(e.runHostCommand,n,[`devicefarm`,r,...t,...i,`--output`,`json`])}function F(t){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`AWS Device Farm response was not an object.`,{response:t});let n=t.remoteAccessSession;if(!n||typeof n!=`object`)throw new e(`COMMAND_FAILED`,`AWS Device Farm response missed remoteAccessSession.`,{response:t});return n}const I=[{field:`providerDeviceOrientation`,capability:`deviceOrientation`,flag:`--provider-device-orientation`,type:`enum`,enumValues:a},{field:`providerGeoLocation`,capability:`geoLocation`,flag:`--provider-geo-location`,type:`string`},{field:`providerTimezone`,capability:`timezone`,flag:`--provider-timezone`,type:`string`},{field:`providerLanguage`,capability:`language`,flag:`--provider-language`,type:`string`},{field:`providerLocale`,capability:`locale`,flag:`--provider-locale`,type:`string`},{field:`providerNetworkProfile`,capability:`networkProfile`,flag:`--provider-network-profile`,type:`string`},{field:`providerCustomNetwork`,capability:`customNetwork`,flag:`--provider-custom-network`,type:`string`},{field:`providerNoResignApp`,capability:`resignApp`,flag:`--provider-no-resign-app`,type:`negated-boolean`,platform:`ios`}];function rt(e,t){lt(e);let n={};for(let r of I){let i=e[r.field];i===void 0||i===!1||i===``||(ct(r,t),n[r.capability]=r.type===`negated-boolean`?!1:i)}return n}function it(e){return I.filter(t=>{let n=e?.[t.field];return n!==void 0&&n!==!1&&n!==``}).map(e=>e.flag)}function L(t,n){let r=it(t);if(r.length===0)return;let i=r.length!==1;throw new e(`INVALID_ARGS`,`${r.join(`, `)} ${i?`are`:`is`} only supported by BrowserStack, not ${n}.`,{hint:`Drop ${i?`those flags`:`the flag`} or use the browserstack provider.`,provider:n,flags:r})}function at(e){let t={};for(let n of I){let r=e?.[n.field];if(n.type===`negated-boolean`){r===!0&&(t.providerNoResignApp=!0);continue}typeof r!=`string`||r.length===0||ot(t,n,r)}return t}function ot(e,t,n){if(t.field===`providerDeviceOrientation`){e.providerDeviceOrientation=st(t,n);return}t.field!==`providerNoResignApp`&&(e[t.field]=n)}function st(t,n){let r=a.find(e=>e===n);if(r)return r;throw new e(`INVALID_ARGS`,`Invalid ${t.flag} value: ${n}.`,{hint:`Use ${a.join(`|`)}.`,flag:t.flag,capability:t.capability})}function ct(t,n){if(!(!t.platform||t.platform===n))throw new e(`INVALID_ARGS`,`${t.flag} applies to ${t.platform} sessions only, but the session platform is ${n}.`,{hint:`Drop ${t.flag} or connect with --platform ${t.platform}.`,flag:t.flag,capability:t.capability,platform:n})}function lt(t){if(!(!t.providerNetworkProfile||!t.providerCustomNetwork))throw new e(`INVALID_ARGS`,`BrowserStack accepts either a named network profile or a custom network shape, not both.`,{hint:`Pass only one of --provider-network-profile or --provider-custom-network.`,networkProfile:t.providerNetworkProfile,customNetwork:t.providerCustomNetwork})}M.browserStack;const ut={install:{support:`partial`,note:`Local app artifacts are uploaded to BrowserStack App Automate, then installed with Appium.`},portReverse:{support:`unsupported`,note:`Use BrowserStack Local for network tunneling; agent-device port reverse is not available.`},artifacts:{support:`supported`,note:`BrowserStack session details expose provider-hosted video, Appium logs, device logs, and dashboard links.`}};async function R(e,t,n){if(t)return b({provider:e,providerSessionId:t,artifacts:ht(e,t,await mt(t,n)),pendingMessage:`BrowserStack artifacts are not ready yet.`})}async function z(t,n){let r=await h.readFile(t),i=new FormData;i.set(`file`,new Blob([r]),f.basename(t));let a=await fetch(n.endpoint??`https://api-cloud.browserstack.com/app-automate/upload`,{method:`POST`,headers:{...x(n.clientVersion),Authorization:S(n)},body:i}),o=await a.json(),s=gt(o);if(!a.ok||!s)throw new e(`COMMAND_FAILED`,`BrowserStack app upload failed.`,{status:a.status,response:o});return s}function dt(e){return async({appPath:t,options:n})=>({appReference:await z(t,e),bundleId:n?.appIdentifierHint,packageName:n?.packageNameHint,launchTarget:n?.appIdentifierHint??n?.packageNameHint})}function ft(e){let{"bstack:options":t,...n}=e.configured??{};return{device:e.deviceName,os_version:e.osVersion,...e.app?{app:e.app}:{},...n,"bstack:options":{...e.projectName?{projectName:e.projectName}:{},buildName:e.buildName,sessionName:e.sessionName,...e.deviceFeatures??{},...pt(t)}}}function pt(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}async function mt(t,n){let r=new URL(`${me(String(n.endpoint??`https://api-cloud.browserstack.com/app-automate/sessions`))}/${t}.json`),i=await fetch(r,{headers:{...x(n.clientVersion),Authorization:S(n)}}),a=await i.json();if(!i.ok||!a||typeof a!=`object`)throw new e(`COMMAND_FAILED`,`BrowserStack session details lookup failed.`,{status:i.status,response:a});let o=a.automation_session??a;return o&&typeof o==`object`?o:{}}function ht(e,t,n){return[B(e,t,n,`video_url`,`video`,`Session video`),B(e,t,n,`appium_logs_url`,`appium-log`,`Appium logs`),B(e,t,n,`device_logs_url`,`device-log`,`Device logs`),B(e,t,n,`browser_url`,`provider-session`,`BrowserStack dashboard`),B(e,t,n,`public_url`,`provider-session`,`Public session link`)].filter(e=>e!==void 0)}function B(e,t,n,r,i,a){let o=n[r];if(!(typeof o!=`string`||o.length===0))return{provider:e,providerSessionId:t,kind:i,name:a,url:o,availability:`ready`}}function gt(e){if(!e||typeof e!=`object`)return;let t=e.app_url;return typeof t==`string`?t:void 0}function V(e){return/^arn:[^:]+:devicefarm:([^:]+):/.exec(e)?.[1]}async function _t(t,n){let r=P({runHostCommand:n,region:t.region}),[i,a,o]=await Promise.all([r(`get-project`,[`--arn`,t.projectArn]),r(`get-device`,[`--arn`,t.deviceArn]),t.appArn?r(`get-upload`,[`--arn`,t.appArn]):void 0]),s=H(i,`project`),c=H(a,`device`),l=yt(c.platform);if(l!==t.platform)throw new e(`INVALID_ARGS`,`AWS Device Farm device "${U(c.name)??t.deviceArn}" is ${l}, not ${t.platform}.`);let u=t.appArn?vt(H(o,`upload`),t):{status:`missing`,message:`No app upload is attached; AWS Device Farm does not support install after allocation. Reconnect with --aws-app-arn <arn>.`};return{provider:`aws-device-farm`,service:`AWS Device Farm`,verificationMessage:t.appArn?`Credentials, project, device, and app upload verified.`:`Credentials, project, and device verified.`,project:{name:U(s.name),reference:t.projectArn},device:{status:`verified`,name:U(c.name)??t.deviceArn,reference:t.deviceArn,platform:l,osVersion:U(c.os),availability:U(c.availability)},app:u}}function vt(t,n){let r=U(t.status);if(r!==`SUCCEEDED`)throw new e(`COMMAND_FAILED`,`AWS Device Farm app upload is not ready (${r??`unknown status`}).`,{status:r,hint:`Wait for the upload to succeed or reconnect with a different --aws-app-arn.`});let i=n.platform===`android`?`ANDROID_APP`:`IOS_APP`,a=U(t.type);if(a!==i)throw new e(`INVALID_ARGS`,`AWS Device Farm app upload type is ${a??`unknown`}, expected ${i}.`);return{status:`verified`,name:U(t.name),reference:n.appArn}}function H(t,n){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`AWS Device Farm ${n} response was not an object.`);let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`COMMAND_FAILED`,`AWS Device Farm response missed ${n}.`);return r}function yt(t){if(t===`ANDROID`)return`android`;if(t===`IOS`)return`ios`;throw new e(`UNSUPPORTED_PLATFORM`,`AWS Device Farm device platform is ${String(t)}.`)}function U(e){return typeof e==`string`&&e.length>0?e:void 0}async function bt(t,n){let r={username:t.username,accessKey:t.accessKey},i=Ct(await W(t.devicesEndpoint??`https://api-cloud.browserstack.com/app-automate/devices.json`,r,n)).find(e=>e.device===t.deviceName&&e.os.toLowerCase()===t.platform&&St(e.osVersion,t.osVersion));if(!i)throw new e(`INVALID_ARGS`,`BrowserStack device "${t.deviceName}" with ${t.platform} ${t.osVersion} is not available.`,{hint:`Choose an exact device and OS version from the BrowserStack App Automate device list.`});let a=await xt(t,r,n);return{provider:`browserstack`,service:`BrowserStack`,verificationMessage:a.status===`verified`?`Credentials, device, and uploaded app verified.`:`Credentials and device access verified; app availability is checked when the session is created.`,device:{status:`verified`,name:i.device,platform:t.platform,osVersion:i.osVersion},app:a}}async function xt(e,t,n){let{app:r}=e;if(r.startsWith(`bs://`)){let i=wt(await W(e.appsEndpoint??`https://api-cloud.browserstack.com/app-automate/recent_apps?limit=100`,t,n)).find(e=>e.reference===r);return i?{status:`verified`,...i}:{status:`configured`,reference:r,message:`App reference was not found in the 100 most recent uploads; BrowserStack validates it when creating the session.`}}return/^https?:\/\//i.test(r)?{status:`configured`,reference:r,message:`Public app URL configured; BrowserStack validates it when creating the session.`}:{status:`configured`,name:f.basename(r),reference:r,message:`Local app artifact is ready and will be uploaded when creating the session.`}}async function W(t,n,r){try{let i=await fetch(t,{headers:{...x(r),Authorization:S(n)},signal:AbortSignal.timeout(15e3)});if(!i.ok){let t=i.status===401||i.status===403;throw new e(t?`UNAUTHORIZED`:`COMMAND_FAILED`,`BrowserStack rejected connection verification.`,{status:i.status,hint:t?`Check BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY.`:`Retry connect or check the BrowserStack service status.`})}return await i.json()}catch(t){throw t instanceof e?t:new e(`COMMAND_FAILED`,`BrowserStack connection verification failed.`,{hint:`Check network access to api-cloud.browserstack.com and retry connect.`},t)}}function St(e,t){let n=e=>e.replace(/(?:\.0)+$/,``);return n(e)===n(t)}function Ct(t){if(!Array.isArray(t))throw new e(`COMMAND_FAILED`,`BrowserStack device verification response was not a list.`);return t.flatMap(e=>{let t=G(e),n=t?.os_version;return t&&typeof t.device==`string`&&typeof t.os==`string`&&(typeof n==`string`||typeof n==`number`)?[{device:t.device,os:t.os,osVersion:String(n)}]:[]})}function wt(t){let n=G(t);if(n&&Object.keys(n).length===0)return[];if(!Array.isArray(t))throw new e(`COMMAND_FAILED`,`BrowserStack app verification response was not a list.`);return t.flatMap(e=>{let t=G(e);return!t||typeof t.app_url!=`string`?[]:[{reference:t.app_url,...typeof t.app_name==`string`?{name:t.app_name}:{},...typeof t.app_version==`string`?{version:t.app_version}:{}}]})}function G(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}async function Tt(e,t){return e.provider===`browserstack`?await bt(e,t.clientVersion):await _t(e,t.runHostCommand)}function Et(e){return[{provider:M.browserStack,createRuntime:t=>O({clientVersion:e.clientVersion,provider:M.browserStack,platform:`android`,deviceName:`BrowserStack device`,endpoint:t.BROWSERSTACK_WEBDRIVER_ENDPOINT??`https://hub-cloud.browserstack.com/wd/hub/`,capabilityOverrides:ut,listArtifacts:async({provider:n,providerSessionId:r})=>{let i=X(t,`BROWSERSTACK_USERNAME`,`BrowserStack artifact lookup`),a=X(t,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack artifact lookup`);return await R(n,r,{clientVersion:e.clientVersion,username:i,accessKey:a,endpoint:t.BROWSERSTACK_SESSION_DETAILS_ENDPOINT})},prepareSession:async({req:n,lease:r,base:i})=>{let a=K(n,`BrowserStack`),o=X(t,`BROWSERSTACK_USERNAME`,`BrowserStack`),s=X(t,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack`),c=q(a,`BrowserStack`),l=J(a,`device`,`BrowserStack requires --device <name>.`),u=J(a,`providerOsVersion`,`BrowserStack requires --provider-os-version <version>.`),d=await Dt({clientVersion:e.clientVersion,app:J(a,`providerApp`,`BrowserStack requires --provider-app <bs://app-id-or-local-path>.`),cwd:a.cwd,username:o,accessKey:s,uploadEndpoint:t.BROWSERSTACK_APP_UPLOAD_ENDPOINT});return{...i,platform:c,deviceName:l,auth:{username:o,accessKey:s},uploadApp:dt({clientVersion:e.clientVersion,username:o,accessKey:s,endpoint:t.BROWSERSTACK_APP_UPLOAD_ENDPOINT??`https://api-cloud.browserstack.com/app-automate/upload`}),webdriverCapabilities:ft({deviceName:l,osVersion:u,app:d,projectName:Y(a,`providerProject`),buildName:Y(a,`providerBuild`)??r.runId,sessionName:Y(a,`providerSessionName`)??r.leaseId,deviceFeatures:rt(at(a.flags),c),configured:k(c,l)})}}}),listArtifactsFromEnv:async(t,n)=>{let r=X(n,`BROWSERSTACK_USERNAME`,`BrowserStack artifact lookup`),i=X(n,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack artifact lookup`);return await R(M.browserStack,t,{clientVersion:e.clientVersion,username:r,accessKey:i,endpoint:n.BROWSERSTACK_SESSION_DETAILS_ENDPOINT})}},{provider:M.awsDeviceFarm,createRuntime:t=>O({clientVersion:e.clientVersion,provider:M.awsDeviceFarm,endpoint:`http://127.0.0.1/`,platform:`android`,deviceName:`AWS Device Farm device`,capabilityOverrides:Ze,listArtifacts:async({provider:n,providerSessionId:r})=>await j(n,r,N({runHostCommand:e.runHostCommand,region:t.AWS_REGION??t.AWS_DEFAULT_REGION??V(r??``)})),prepareSession:async({req:n,lease:r,base:i})=>{let a=K(n,`AWS Device Farm`);L(a.flags,M.awsDeviceFarm);let o=q(a,`AWS Device Farm`);return await Qe({client:N({runHostCommand:e.runHostCommand,region:Y(a,`awsRegion`)??t.AWS_REGION??t.AWS_DEFAULT_REGION}),projectArn:kt(a,t,`awsProjectArn`,`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`),deviceArn:kt(a,t,`awsDeviceArn`,`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`),appArn:Y(a,`awsAppArn`)??t.AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN??t.AWS_DEVICE_FARM_APP_ARN,platform:o,deviceName:Y(a,`device`)??`AWS Device Farm device`,sessionName:Y(a,`providerSessionName`)??r.leaseId,interactionMode:At(a)})({lease:r,req:n,base:i})}}),listArtifactsFromEnv:async(t,n)=>{let r=N({runHostCommand:e.runHostCommand,region:n.AWS_REGION??n.AWS_DEFAULT_REGION??V(t)});return await j(M.awsDeviceFarm,t,r)}}]}async function Dt(t){if(Ot(t.app))return t.app;let n=f.resolve(t.cwd??process.cwd(),t.app);if(!m.existsSync(n))throw new e(`INVALID_ARGS`,`BrowserStack --provider-app must be a bs:// app id, URL, or existing local app path.`,{providerApp:t.app});return await z(n,{clientVersion:t.clientVersion,username:t.username,accessKey:t.accessKey,endpoint:t.uploadEndpoint})}function Ot(e){return e.startsWith(`bs://`)||/^https?:\/\//.test(e)}function K(t,n){if(t)return t;throw new e(`INVALID_ARGS`,`${n} lease allocation requires provider profile flags on the request.`)}function q(t,n){let r=t.flags?.platform;if(r===`android`||r===`ios`)return r;throw new e(`INVALID_ARGS`,`${n} requires --platform ios|android.`)}function J(t,n,r){let i=Y(t,n);if(i)return i;throw new e(`INVALID_ARGS`,r)}function Y(e,t){let n=e.flags?.[t];return typeof n==`string`&&n.length>0?n:void 0}function X(t,n,r){let i=t[n];if(i)return i;throw new e(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function kt(t,n,r,i,a){let o=Y(t,r)??n[i]??n[a];if(o)return o;throw new e(`INVALID_ARGS`,`AWS Device Farm requires --${jt(String(r))} or ${a}.`)}function At(e){let t=Y(e,`awsInteractionMode`);if(t===`INTERACTIVE`||t===`NO_VIDEO`||t===`VIDEO_ONLY`)return t}function jt(e){return e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function Mt(e){let t=Et(e);return{providerIds:t.map(e=>e.provider),createDefaultRuntimes:(e=process.env)=>t.map(t=>t.createRuntime(e)),listArtifactsFromEnv:async(e,n)=>{if(e.providerSessionId)return await t.find(t=>t.provider===e.provider)?.listArtifactsFromEnv(e.providerSessionId,n)},verifyConnection:async t=>await Tt(t,e)}}const Nt=Mt({clientVersion:l(),runHostCommand:async(e,t)=>({stdout:(await c(e,[...t],{maxBuffer:10*1024*1024,timeoutMs:3e4})).stdout})});function Pt(){return{pid:process.pid,startTime:d(process.pid)}}function Ft(e,t){return e.pid===t.pid&&e.startTime===t.startTime}function It(e){let{owner:t,stateDir:n}=e;if(!u(t.pid)||t.startTime&&d(t.pid)!==t.startTime)return`owner-process-dead`;if(!n)return`live`;try{return m.statSync(n),`live`}catch(e){let t=e?.code;return t===`ENOENT`||t===`ENOTDIR`?`owner-state-dir-gone`:`unknown`}}function Z(){let e=process.env.AGENT_DEVICE_CLAIMS_DIR?.trim();return e?f.resolve(e):f.join(ne.homedir(),`.agent-device`,`device-claims`)}function Lt(e){let t=p.createHash(`sha256`).update(e).digest(`hex`);return f.join(Z(),`${t}.json`)}function Rt(e){let t=Z(),n=zt(t);return`claims`in n?n.claims:n.entries.filter(e=>e.isFile()&&e.name.endsWith(`.json`)).map(e=>Wt(f.join(t,e.name))).filter(e=>e!==null).filter(t=>Bt(t.claim,e))}function zt(e){try{return{entries:m.readdirSync(e,{withFileTypes:!0})}}catch(t){let n=t.code;return n===`ENOENT`||n===`ENOTDIR`?{claims:[]}:{claims:[{fileName:f.basename(e),classification:`unknown`,error:String(t)}]}}}function Bt(e,t){return e?[Vt(e,t.udid??t.serial),Ht(e,t.device),Ut(e,t.platform)].every(Boolean):!0}function Vt(e,t){return!t||e.device.id===t}function Ht(e,t){return!t||e.device.name===t||e.device.id===t}function Ut(e,t){return i({...r(e.device.platform),appleOs:e.device.appleOs},t)}function Wt(e){let t=f.basename(e);try{return Gt(t,m.readFileSync(e,`utf8`))}catch(e){let n=e.code;return n===`ENOENT`||n===`ENOTDIR`?null:{fileName:t,classification:`unknown`,error:String(e)}}}function Gt(e,t){try{let n=Kt(JSON.parse(t));return n?{fileName:e,deviceKey:n.deviceKey,claim:n,classification:It({owner:{pid:n.ownerPid,startTime:n.ownerStartTime},stateDir:n.stateDir})}:{fileName:e,classification:`inconsistent`}}catch(t){return{fileName:e,classification:`inconsistent`,error:String(t)}}}function Kt(e){if(!qt(e))return null;let t=e;return Jt(t)?t:null}function qt(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function Jt(e){return e.schemaVersion===1&&Yt(e.device)&&[e.deviceKey,e.session,e.workspace,e.stateDir,e.ownerToken].every(Xt)&&Zt(e.ownerPid)&&Qt(e.createdAtMs)&&Qt(e.updatedAtMs)}function Yt(e){if(!qt(e))return!1;let t=e;return[t.id,t.name,t.platform,t.kind].every(Xt)}function Xt(e){return typeof e==`string`&&e.length>0}function Zt(e){return typeof e==`number`&&Number.isInteger(e)&&e>0}function Qt(e){return typeof e==`number`&&Number.isFinite(e)}function $t(e,t){let n={providerReleases:{released:t.released.map(nn),pending:t.pending.map(nn)}},r=Q(e),i=`${r}.${process.pid}.${Date.now()}.tmp`;try{m.writeFileSync(i,`${JSON.stringify(n)}\n`,{mode:384}),m.renameSync(i,r),m.chmodSync(r,384)}catch{try{m.rmSync(i,{force:!0})}catch{}}}function en(e){try{let t=JSON.parse(m.readFileSync(Q(e),`utf8`));return rn(t)?t:null}catch{return null}}function tn(e){try{m.rmSync(Q(e),{force:!0})}catch{}}function Q(e){return f.join(e,`daemon-shutdown.json`)}function nn(e){return{leaseId:e.leaseId,...e.leaseProvider?{provider:e.leaseProvider}:{}}}function rn(e){if(!e||typeof e!=`object`)return!1;let t=e.providerReleases;if(!t||typeof t!=`object`)return!1;let n=t;return Array.isArray(n.released)&&Array.isArray(n.pending)&&n.released.every(an)&&n.pending.every(an)}function an(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.leaseId==`string`&&t.leaseId.trim().length>0&&(t.provider===void 0||typeof t.provider==`string`)}const $={control:{retryMaxRetries:3},command:{retryTapMaxAttempts:2,targetLookupTimeoutMs:17e3,optionalTargetLookupTimeoutMs:7e3,scrollUntilVisibleTimeoutMs:2e4,waitForAnimationToEndTimeoutMs:15e3,waitForAnimationToEndDifferencePercent:.005,longPressDurationMs:3e3,swipeDurationMs:400,repeatDelayMs:100,scrollUntilVisibleSpeed:40,scrollUntilVisiblePercentage:100,eraseTextMaxCharacters:50},observation:{pollIntervalMs:200,defaultSettleAttempts:10},targetSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9},screenSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9,centerFraction:.5,downStartFraction:.2,upStartFraction:{android:.5,ios:.9}},scrollUntilVisibleSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9}};function on(e){return Math.trunc(1e3*(100-e)/100)+1}const sn={assertVisibleTimeoutMs:$.command.targetLookupTimeoutMs,assertNotVisibleTimeoutMs:$.command.targetLookupTimeoutMs,extendedWaitUntilTimeoutMs:$.command.targetLookupTimeoutMs,runFlowConditionTimeoutMs:$.command.optionalTargetLookupTimeoutMs},cn=$.observation.pollIntervalMs*$.observation.defaultSettleAttempts,ln=[`id`,`text`,`enabled`,`selected`],un=[...ln,`label`],dn=[`id`,`text`,`label`],fn=[`enabled`,`selected`];export{Xe as C,M as S,Ft as _,sn as a,V as b,on as c,$t as d,Wt as f,It as g,Z as h,dn as i,tn as l,Lt as m,fn as n,$ as o,Rt as p,un as r,cn as s,ln as t,en as u,Pt as v,re as w,L as x,Nt as y};
|
|
1
|
+
const e={control:{retryMaxRetries:3},command:{retryTapMaxAttempts:2,targetLookupTimeoutMs:17e3,optionalTargetLookupTimeoutMs:7e3,scrollUntilVisibleTimeoutMs:2e4,waitForAnimationToEndTimeoutMs:15e3,waitForAnimationToEndDifferencePercent:.005,longPressDurationMs:3e3,swipeDurationMs:400,repeatDelayMs:100,scrollUntilVisibleSpeed:40,scrollUntilVisiblePercentage:100,eraseTextMaxCharacters:50},observation:{pollIntervalMs:200,defaultSettleAttempts:10},targetSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9},screenSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9,centerFraction:.5,downStartFraction:.2,upStartFraction:{android:.5,ios:.9}},scrollUntilVisibleSwipe:{nearEdgeFraction:.1,farEdgeFraction:.9}};function t(e){return Math.trunc(1e3*(100-e)/100)+1}const n={assertVisibleTimeoutMs:e.command.targetLookupTimeoutMs,assertNotVisibleTimeoutMs:e.command.targetLookupTimeoutMs,extendedWaitUntilTimeoutMs:e.command.targetLookupTimeoutMs,runFlowConditionTimeoutMs:e.command.optionalTargetLookupTimeoutMs},r=e.observation.pollIntervalMs*e.observation.defaultSettleAttempts,i=[`id`,`text`,`enabled`,`selected`],a=[...i,`label`],o={textKeys:[`id`,`text`,`label`],booleanKeys:[`enabled`,`selected`]};export{e as a,n as i,o as n,r as o,a as r,t as s,i as t};
|
package/dist/src/selectors.d.ts
CHANGED
|
@@ -1,47 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as DisambiguationTiebreak } from "./interaction.js";
|
|
3
|
-
import { a as SelectorChain, c as tryParseSelectorChain, i as Selector, o as isSelectorToken, s as parseSelectorChain } from "./sdk-finders.js";
|
|
4
|
-
//#region src/selectors/resolve.d.ts
|
|
5
|
-
type SelectorDiagnostics = {
|
|
6
|
-
selector: string;
|
|
7
|
-
matches: number;
|
|
8
|
-
};
|
|
9
|
-
/** Present only when the heuristic picked among N>1 matches (ADR 0012). */
|
|
10
|
-
type SelectorDisambiguationDisclosure = {
|
|
11
|
-
matchCount: number;
|
|
12
|
-
tiebreak: DisambiguationTiebreak;
|
|
13
|
-
/** Every losing matched node, document order, uncapped (response layer caps). */
|
|
14
|
-
alternatives: SnapshotNode[];
|
|
15
|
-
};
|
|
16
|
-
type SelectorResolution = {
|
|
17
|
-
node: SnapshotNode;
|
|
18
|
-
selector: Selector;
|
|
19
|
-
selectorIndex: number;
|
|
20
|
-
matches: number;
|
|
21
|
-
diagnostics: SelectorDiagnostics[];
|
|
22
|
-
disambiguation?: SelectorDisambiguationDisclosure;
|
|
23
|
-
};
|
|
24
|
-
declare function resolveSelectorChain(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
25
|
-
platform: Platform | PublicPlatform;
|
|
26
|
-
requireRect?: boolean;
|
|
27
|
-
requireUnique?: boolean;
|
|
28
|
-
disambiguateAmbiguous?: boolean;
|
|
29
|
-
}): SelectorResolution | null;
|
|
30
|
-
declare function findSelectorChainMatch(nodes: SnapshotState['nodes'], chain: SelectorChain, options: {
|
|
31
|
-
platform: Platform | PublicPlatform;
|
|
32
|
-
requireRect?: boolean;
|
|
33
|
-
}): {
|
|
34
|
-
selectorIndex: number;
|
|
35
|
-
selector: Selector;
|
|
36
|
-
matches: number;
|
|
37
|
-
diagnostics: SelectorDiagnostics[];
|
|
38
|
-
} | null;
|
|
39
|
-
declare function formatSelectorFailure(chain: SelectorChain, diagnostics: SelectorDiagnostics[], options: {
|
|
40
|
-
unique?: boolean;
|
|
41
|
-
}): string;
|
|
42
|
-
//#endregion
|
|
43
|
-
//#region src/selectors/node.d.ts
|
|
44
|
-
declare function isNodeVisible(node: SnapshotNode): boolean;
|
|
45
|
-
declare function isNodeEditable(node: SnapshotNode, platform: Platform | PublicPlatform): boolean;
|
|
46
|
-
//#endregion
|
|
1
|
+
import { a as resolveSelectorChain, c as parseSelectorChain, i as findSelectorChainMatch, l as tryParseSelectorChain, n as isNodeEditable, o as SelectorChain, r as isNodeVisible, s as isSelectorToken, t as formatSelectorFailure, u as SelectorDiagnostics } from "./sdk-selectors.js";
|
|
47
2
|
export { type SelectorChain, type SelectorDiagnostics, findSelectorChainMatch, formatSelectorFailure, isNodeEditable, isNodeVisible, isSelectorToken, parseSelectorChain, resolveSelectorChain, tryParseSelectorChain };
|
package/dist/src/selectors.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{_n as e,bn as t,en as n,gn as r,nn as i,xn as a,yn as o}from"./sdk-batch-runner.js";import{t as s}from"./sdk-selectors.js";export{n as findSelectorChainMatch,s as formatSelectorFailure,t as isNodeEditable,a as isNodeVisible,r as isSelectorToken,e as parseSelectorChain,i as resolveSelectorChain,o as tryParseSelectorChain};
|
package/dist/src/server.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{S as e,_ as t,n,o as r}from"./sdk-contracts.js";import{Ft as i,Qt as a,gt as o}from"./viewport-dimension.js";import{C as s,G as c}from"./sdk-batch-runner.js";import{r as l,t as u}from"./sdk-device.js";import{_ as d,g as f,s as p,v as m}from"./registry.js";import{i as ee,n as te,t as ne}from"./command-metadata.js";import{n as re}from"./version.js";import{i as ie,n as ae,r as oe,t as se}from"./cli-config.js";const h=[`simulator`,`emulator`,`device`];function g(e){return{type:`number`,...e?{description:e}:{}}}function _(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function v(e){return{type:`string`,const:e}}function y(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const b={type:`array`,items:{type:`string`}},x=y({wallClockMs:g(`Total wall-clock time for the request in milliseconds.`),runnerRoundTrips:g(`Number of real runner round-trips made while serving the request.`),nodeCount:g(`Number of nodes in the original node tree when the response carries one.`)},[`wallClockMs`,`runnerRoundTrips`]),S=y({field:m(),artifactType:m(),path:m(),localPath:m(),fileName:m()},[`field`]);function C(e={}){let t=e.properties??{},n=e.required??[];return y({targetKind:_([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:g(`Resolved interaction x coordinate when available.`),y:g(`Resolved interaction y coordinate when available.`),referenceWidth:g(`Reference frame width for visualizing the interaction point.`),referenceHeight:g(`Reference frame height for visualizing the interaction point.`),ref:m(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:m(`Selector expression when the target was a selector.`),selectorChain:b,refLabel:m(),targetHittable:f(),hint:m(),warning:m(),message:m(),evidence:T,resolution:ce,cost:x,maestroNonHittableCoordinateFallbackAllowed:f(`Whether the direct iOS Maestro coordinate fallback was allowed for this selector.`),maestroNonHittableCoordinateFallbackUsed:f(`Whether the direct iOS Maestro coordinate fallback was actually used.`),maestroFallbackReason:v(`non-hittable-coordinate`),...t},[`targetKind`,...n])}const w=y({diagnosticRef:m(`Opaque non-@ diagnostic token. Never a snapshot ref: not issued via refsGeneration and cannot be pinned or reused as an @ref target. UTF-8 truncated to 256 bytes.`),role:m(`UTF-8 truncated to 256 bytes.`),label:m(`UTF-8 truncated to 256 bytes.`)},[`diagnosticRef`]),ce={type:`object`,description:`Pre-action disclosure of how the acting path resolved its target. Absent when resolutionDisclosure is inapplicable for the path.`,oneOf:[y({source:v(`runtime`),phase:v(`pre-action`),kind:v(`unique`)},[`source`,`phase`,`kind`]),y({source:v(`runtime`),phase:v(`pre-action`),kind:v(`disambiguated`),matchCount:g(`Total matches resolveSelectorChain found before disambiguation.`),winnerDiagnostic:w,tiebreak:_([`visible`,`deepest`,`smallest-area`],`The comparison that decided the winner.`),alternatives:{type:`array`,description:`At most 5 losing candidates, document order. Present at default/full response levels and omitted in digest. The winner is never included.`,items:w}},[`source`,`phase`,`kind`,`matchCount`,`winnerDiagnostic`,`tiebreak`]),y({source:v(`ref`),phase:v(`pre-action`),kind:v(`exact`)},[`source`,`phase`,`kind`]),y({source:v(`ref`),phase:v(`pre-action`),kind:v(`label-fallback`)},[`source`,`phase`,`kind`]),y({source:v(`direct-ios`),kind:v(`not-observed`)},[`source`,`kind`])]},T=y({foregroundApp:m(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:g(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:g(`Subset of nodeCount the platform reports as hittable.`),digest:m(`Order-independent digest of the post-action node multiset.`),changedFromBefore:f(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure.`)},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),E=y({settled:f(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:g(),captures:g(),quietMs:g(),timeoutMs:g(),refsGeneration:g(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:y({ref:m(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},diff:y({summary:y({additions:g(),removals:g(),unchanged:g()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:y({kind:_([`added`,`removed`]),text:m(),ref:m(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:f(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),tail:{type:`array`,description:`Unchanged interactive refs tail: still-present, actionable elements from the settled tree, attached only when diff carries zero added-line refs (a modal-dismiss/toast-only diff).`,items:y({ref:m(`Plain ref body (e12) minted from the stored settled tree.`),role:m(),label:m()},[`ref`,`role`])},tailTruncated:f(`Present (true) when tail candidates exceeded the response cap.`),hint:m()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),D={platform:_(l),target:_(u),device:m(`Human-readable device name.`),id:m(`Stable device id.`),kind:_(h)},O=[`platform`,`target`,`device`,`id`,`kind`],le=y({success:f(),exitCode:g(),stdout:m(),stderr:m(),error:d(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]),k=C({properties:{evidence:T,settle:E,button:_([`secondary`,`middle`]),count:g(`Number of press/click repetitions.`),intervalMs:g(`Delay between repeated press/click actions.`),holdMs:g(`Hold duration for each action.`),jitterPx:g(`Randomization radius in pixels.`),doubleTap:f(`Whether the command requested a double-tap action.`)}}),ue={press:k,click:k,fill:C({properties:{text:m(`Text submitted to the field.`),delayMs:g(`Delay between typed characters in milliseconds.`),evidence:T,settle:E},required:[`text`]}),longpress:C({properties:{durationMs:g(),settle:E,gesture:v(`longpress`)}}),find:y({ref:m(`Snapshot ref without the @ prefix when the find action returns one.`),refsGeneration:g(`ADR 0014 ref frame epoch for read-only find actions.`),found:f(`Whether a wait/exists/read-only find satisfied its condition.`),waitedMs:g(`Milliseconds waited for a read-only find condition.`),text:m(`Text value returned by find get_text.`),node:d(`Snapshot node for find get_attrs/get_text.`),locator:m(`Locator kind used for the find action.`),query:m(`Query argument used for the find action.`),x:g(`Resolved x coordinate for mutating find actions.`),y:g(`Resolved y coordinate for mutating find actions.`),message:m(`Diagnostic message for mutating find actions.`),settle:E,cost:x},[],`Daemon response data for the find command.`),boot:y({...D,booted:{type:`boolean`,const:!0}},[...O,`booted`]),shutdown:y({...D,shutdown:le},[...O,`shutdown`]),viewport:y({width:g(),height:g(),message:m()},[`width`,`height`,`message`]),...p,wait:y({waitedMs:g(),kind:v(`selector`),text:m(),selector:m(),captures:g(),nodeCount:g(),hint:m(),warning:m()},[`waitedMs`]),prepare:y({action:v(`ios-runner`),platform:_(l),deviceId:m(),deviceName:m(),kind:_(h),durationMs:g(),runner:y({},[]),cache:_([`exact`,`restore-key`,`miss`,`external`]),artifact:_([`valid`,`rebuilt`]),buildMs:g(),connectMs:g(),healthCheckMs:g(),xctestrunPath:m(),recoveryReason:m(),failureReason:m(),timing:y({totalMs:g(),additiveParts:y({buildMs:g(),connectAfterBuildMs:g(),healthCheckMs:g()},[`connectAfterBuildMs`,`healthCheckMs`]),containment:y({connectMs:{type:`array`,items:v(`buildMs`)},healthCheckMs:{type:`array`,items:m()}},[`healthCheckMs`]),note:m()},[`totalMs`,`additiveParts`,`containment`,`note`]),message:m()},[`action`,`platform`,`deviceId`,`deviceName`,`kind`,`durationMs`,`runner`,`connectMs`,`healthCheckMs`,`timing`,`message`]),push:{type:`object`,oneOf:[y({platform:v(`ios`),bundleId:m(),message:m()},[`platform`,`bundleId`,`message`]),y({platform:v(`android`),package:m(),action:m(),extrasCount:g(),message:m()},[`platform`,`package`,`action`,`extrasCount`,`message`])]},"trigger-app-event":y({event:m(),eventUrl:m(),transport:v(`deep-link`),message:m()},[`event`,`eventUrl`,`transport`,`message`]),clipboard:{type:`object`,oneOf:[y({action:v(`read`),text:m()},[`action`,`text`]),y({action:v(`write`),textLength:g(),message:m()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[y({platform:_([`ios`,`macos`]),appName:m(),appBundleId:m(),source:v(`session`),surface:_(i),device_udid:m(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),y({platform:v(`android`),package:m(),activity:m()},[`platform`,`package`,`activity`])]},keyboard:y({platform:_([`android`,`ios`]),action:_([`status`,`dismiss`,`enter`]),visible:f(),wasVisible:f(),dismissed:f(),attempts:g(),inputType:m(),type:_([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:m(),focusedPackage:m(),focusedResourceId:m(),inputOwner:_([`app`,`ime`,`unknown`]),message:m()},[`platform`,`action`]),doctor:y({status:_([`pass`,`warn`,`fail`,`info`]),summary:m(),kind:_([`auto`,`react-native`,`expo`,`repack`]),platform:m(),target:_(u),targetApp:m(),metro:y({host:m(),port:g()},[`host`,`port`]),checks:{type:`array`,items:y({id:m(),status:_([`pass`,`warn`,`fail`,`info`]),summary:m(),hint:m(),command:m(),evidence:d()},[`id`,`status`,`summary`])}},[`status`,`summary`,`kind`,`checks`]),diff:y({mode:v(`snapshot`),baselineInitialized:f(),summary:y({additions:g(),removals:g(),unchanged:g()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:y({kind:_([`added`,`removed`]),text:m(),ref:m()},[`kind`,`text`])},warnings:b},[`mode`,`baselineInitialized`,`summary`,`lines`]),replay:y({replayed:g(),healed:g(),session:m(),sessionActive:f(`True iff the session is still active — the script had no terminal close.`),artifactPaths:b,snapshotDiagnostics:d(),message:m()},[`replayed`,`healed`,`session`,`sessionActive`,`artifactPaths`,`message`]),test:y({total:g(),executed:g(),passed:g(),failed:g(),skipped:g(),notRun:g(),durationMs:g(),failures:{type:`array`,items:d()},tests:{type:`array`,items:d()},snapshotDiagnostics:d()},[`total`,`executed`,`passed`,`failed`,`skipped`,`notRun`,`durationMs`,`failures`,`tests`]),record:{type:`object`,oneOf:[y({recording:v(`started`),outPath:m(),sessionStateDir:m(),recordingBackend:m(),recordingScope:m(),recordOnlySession:f(),activeSessionApp:d(),showTouches:f()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),y({recording:v(`stopped`),outPath:m(),telemetryPath:m(),artifacts:{type:`array`,items:S},recordingBackend:m(),recordingScope:m(),recordOnlySession:f(),activeSessionApp:d(),durationMs:g(),showTouches:f(),warning:m(),overlayWarning:m(),chunks:{type:`array`,items:d()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[y({trace:v(`started`),outPath:m()},[`trace`,`outPath`]),y({trace:v(`stopped`),outPath:m(),artifacts:{type:`array`,items:S}},[`trace`,`outPath`,`artifacts`])]}},de={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:l},target:{type:`string`,enum:u},kind:{type:`string`,enum:h},id:{type:`string`},name:{type:`string`}},required:[`platform`,`target`,`kind`,`id`,`name`]}}},required:[`devices`]},apps:{type:`object`,properties:{apps:{type:`array`,items:{type:`string`}}},required:[`apps`]}},A={...ue,...de};function j(t){return e(t)}function M(e){let t=[`Error (${e.code}): ${e.message}`];e.hint&&t.push(`Hint: ${e.hint}`),e.supportedOn&&t.push(`Supported on: ${e.supportedOn}`);let n=o(e.details);return n&&t.push(n),t.join(`
|
|
2
|
-
`)}function N(e,t,n){let r=se({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&oe(t,e)&&(i[t]=a);return ie(i,t)}const P={devices:e=>({devices:e.map(a)}),apps:e=>({apps:e})};function F(e,t){let n=P[e];return n?n(t):t}function I(){let e=new Map;return{pinInput:(t,n,r)=>ve(t,n,B(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>H(e,t,n,r,i),mergeDivergenceScreen:(t,n,r)=>ge(e,V(n,r),t)}}const L=new Set([`snapshot`,`find`]),R=new Set([`press`,`click`,`fill`,`longpress`]),z=new Set([`press`,`click`,`fill`,`longpress`,`get`]);function B(e,t,n){return e.get(V(t,n))}function V(e,t){let n=typeof t==`string`&&t.length>0?t:`default`;return`${e??``}\u0000${n}`}function H(e,t,n,r,i){let a=V(r,i);if(R.has(t)){me(e,a,n);return}L.has(t)&&(t===`find`?pe(e,a,n):fe(e,a,n))}function fe(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`){e.delete(t);return}let i=[];for(let{ref:e}of n.refs??[])i.push(e);for(let e of n.nodes??[])i.push(e.ref);U(e,t,i,r)}function pe(e,t,n){let r=n.refsGeneration,i=n.ref;typeof r!=`number`||typeof i!=`string`||!i.startsWith(`@`)||U(e,t,[i.slice(1)],r)}function me(e,t,n){let{settle:r}=n;r?.refsGeneration!==void 0&&U(e,t,[...r.diff?.lines??[],...r.refs??[],...r.tail??[]].map(e=>e.ref).filter(e=>typeof e==`string`),r.refsGeneration)}function U(e,t,n,r){if(n.length===0)return;let i=e.get(t)??new Map;e.set(t,i),he(i,n,r)}function he(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;)e.delete(e.keys().next().value)}function ge(e,t,n){let r=c(c(n?.divergence)?.screen);if(r?.state!==`available`)return;let i=r.refsGeneration;if(typeof i!=`number`)return;let a=[];_e(r.refs,a),U(e,t,a,i)}function _e(e,t){if(Array.isArray(e))for(let n of e){let e=c(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function ve(e,t,n){return n===void 0||n.size===0?t:e===`wait`?ye(t,n)??t:z.has(e)?be(t,n)??t:t}function ye(e,t){if(typeof e.ref!=`string`)return;let n=W(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function be(e,t){let n=c(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=W(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function W(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}function xe(){return ee().map(e=>{let t=e.name in A?A[e.name]:void 0;return{name:e.name,description:e.description,inputSchema:G(e.name,e.inputSchema),...t?{outputSchema:t}:{}}})}function Se(e={}){let n=I();return{execute:async(r,i)=>{if(!te(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=G(r,ne(r).inputSchema).properties,o=N(r,i,a),s=De(o),c=je(o),l=n.pinInput(r,c,s.client.stateDir),u=await Te(e,s.client);try{let t=await(e.runCommand??Ee)(u,r,l);return n.mergeCommandResult(r,t,s.client.stateDir,c.session),{isError:!1,structuredContent:F(r,t),content:[{type:`text`,text:Me({name:r,input:c,result:t,outputFormat:s.outputFormat,responseLevel:s.client.responseLevel})}]}}catch(e){return Ce(e,n,s.client.stateDir,c.session)}}}}function Ce(e,t,n,r){let i=j(e);return t.mergeDivergenceScreen(i.details,n,r),{isError:!0,structuredContent:i,content:[{type:`text`,text:M(i)}]}}const we=Se();async function Te(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./agent-device-client.js`).then(e=>e.t);return n(t)}async function Ee(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function De(e){return{client:Oe(e),outputFormat:Ae(e.mcpOutputFormat)}}function Oe(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0){if(typeof n!=`string`||n.length===0)throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);a.stateDir=n}if(r!==void 0){if(typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r&&(a.cost=!0)}let o=ke(i);return o!==void 0&&(a.responseLevel=o),a}function ke(e){if(e===void 0)return;let r=n.find(t=>t===e);if(r===void 0)throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return r}function Ae(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function je(e){let{stateDir:t,mcpOutputFormat:n,includeCost:r,responseLevel:i,...a}=e;return a}function G(e,t){let n=s(e);return{...t,properties:{...t.properties,...n&&!t.properties?.noRecord?{noRecord:{type:`boolean`,description:`Do not record this action.`}}:{},stateDir:{type:`string`,description:`Agent-device state directory.`},mcpOutputFormat:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`},includeCost:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`},responseLevel:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}}}function Me(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return K(e.result);let t=ae({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?t.text:K(t?.data??e.result)}function K(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}async function Ne(e){if(e.jsonrpc!==`2.0`||typeof e.method!=`string`)return q(e.id??null,-32600,`Invalid JSON-RPC request.`);if(e.id===void 0)return null;try{return Re(e.id,await Pe(e.method,e.params))}catch(t){return t instanceof X?q(e.id,-32601,t.message):q(e.id,-32602,t instanceof Error?t.message:String(t))}}async function Pe(e,t){switch(e){case`initialize`:return{protocolVersion:Ie(t),capabilities:{tools:{}},serverInfo:{name:`agent-device`,version:re()}};case`ping`:return{};case`tools/list`:return{tools:xe()};case`tools/call`:return await Fe(t);default:throw new X(`Unsupported MCP method: ${e}`)}}async function Fe(e){let t=J(e),n=ze(t,`name`);try{return await we.execute(n,Y(t.arguments))}catch(e){return Le(M(j(e)),!0)}}function Ie(e){return`2025-11-25`}function Le(e,t=!1){return{isError:t,content:[{type:`text`,text:e}]}}function Re(e,t){return{jsonrpc:`2.0`,id:e,result:t}}function q(e,t,n){return{jsonrpc:`2.0`,id:e,error:{code:t,message:n}}}function J(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Expected object parameters.`);return e}function Y(e){return e===void 0?{}:J(e)}function ze(e,n){let r=e[n];if(typeof r!=`string`||r.length===0)throw new t(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}var X=class extends Error{};async function Be(){let e=Ve(),t=new Ke(t=>{e.push(t)});process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{try{t.push(e)}catch(e){$({jsonrpc:`2.0`,id:null,error:{code:-32700,message:e instanceof Error?e.message:String(e)}})}}),await new Promise(e=>{process.stdin.on(`end`,e),process.stdin.on(`close`,e),process.stdin.resume()}),await e.idle()}function Ve(e={}){let t=e.handlePayload??He,n=e.write??$,r=Promise.resolve();return{push:e=>{let i=Ge(e);r=r.then(async()=>{let r=await t(e);r&&n(r)}).catch(e=>{n({jsonrpc:`2.0`,id:i,error:{code:-32603,message:e instanceof Error?e.message:String(e)}})})},idle:async()=>{await r}}}function He(e){return Array.isArray(e)?Ue(e):Z(e)}async function Ue(e){let t=[];for(let n of e)t.push(...qe(await Z(n)));return t.length>0?t:null}async function Z(e){let t;try{t=r.parse(e)}catch{return We(Q(e))}return Ne(t)}function We(e){return{jsonrpc:`2.0`,id:e,error:{code:-32600,message:`Invalid JSON-RPC request.`}}}function Ge(e){return Array.isArray(e)?e.length===1?Q(e[0]):null:Q(e)}function Q(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t=e.id;if(typeof t==`string`||typeof t==`number`||t===null)return t}return null}var Ke=class{buffer=``;sink;constructor(e){this.sink=e}push(e){for(this.buffer+=e;;){let e=this.tryReadLineMessage();if(e!==void 0){this.emit(e);continue}break}}tryReadLineMessage(){let e=this.buffer.indexOf(`
|
|
3
|
-
`);if(e===-1)return;let t=this.buffer.slice(0,e).trim();return this.buffer=this.buffer.slice(e+1),t.length>0?t:void 0}emit(e){this.sink(JSON.parse(e))}};function
|
|
1
|
+
import{S as e,_ as t,n,o as r}from"./sdk-contracts.js";import{n as i}from"./version.js";import{Hn as a,S as o,g as s,h as c}from"./sdk-batch-runner.js";import{i as l,t as u}from"./sdk-device.js";import{Et as ee,Ot as te,kt as ne,qt as re,un as ie}from"./prepare-kind.js";import{_ as d,g as f,h as ae,s as oe,v as p}from"./registry.js";import{i as se,n as ce,t as le}from"./command-metadata.js";import{n as ue,r as de,t as fe}from"./cli-config.js";import{t as pe}from"./cli-output.js";const m=[`simulator`,`emulator`,`device`];function h(e){return{type:`number`,...e?{description:e}:{}}}function g(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function _(e){return{type:`string`,const:e}}function v(e){return{type:[`string`,`null`],...e?{description:e}:{}}}function y(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const b={type:`array`,items:{type:`string`}},x=y({wallClockMs:h(`Total wall-clock time for the request in milliseconds.`),runnerRoundTrips:h(`Number of real runner round-trips made while serving the request.`),nodeCount:h(`Number of nodes in the original node tree when the response carries one.`)},[`wallClockMs`,`runnerRoundTrips`]),S=y({field:p(),artifactType:p(),path:p(),localPath:p(),fileName:p()},[`field`]);function C(e={}){let t=e.properties??{},n=e.required??[];return y({targetKind:g([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:h(`Resolved interaction x coordinate when available.`),y:h(`Resolved interaction y coordinate when available.`),referenceWidth:h(`Reference frame width for visualizing the interaction point.`),referenceHeight:h(`Reference frame height for visualizing the interaction point.`),ref:p(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:p(`Selector expression when the target was a selector.`),selectorChain:b,refLabel:p(),targetHittable:f(),hint:p(),warning:p(),message:p(),evidence:T,resolution:me,cost:x,maestroNonHittableCoordinateFallbackAllowed:f(`Whether the direct iOS Maestro coordinate fallback was allowed for this selector.`),maestroNonHittableCoordinateFallbackUsed:f(`Whether the direct iOS Maestro coordinate fallback was actually used.`),maestroFallbackReason:_(`non-hittable-coordinate`),...t},[`targetKind`,...n])}const w=y({diagnosticRef:p(`Opaque non-@ diagnostic token. Never a snapshot ref: not issued via refsGeneration and cannot be pinned or reused as an @ref target. UTF-8 truncated to 256 bytes.`),role:p(`UTF-8 truncated to 256 bytes.`),label:p(`UTF-8 truncated to 256 bytes.`)},[`diagnosticRef`]),me={type:`object`,description:`Pre-action disclosure of how the acting path resolved its target. Absent when resolutionDisclosure is inapplicable for the path.`,oneOf:[y({source:_(`runtime`),phase:_(`pre-action`),kind:_(`unique`)},[`source`,`phase`,`kind`]),y({source:_(`runtime`),phase:_(`pre-action`),kind:_(`disambiguated`),matchCount:h(`Total matches resolveSelectorChain found before disambiguation.`),winnerDiagnostic:w,tiebreak:g([`visible`,`deepest`,`smallest-area`,`structural-equivalence`],`The comparison that decided the winner.`),alternatives:{type:`array`,description:`At most 5 losing candidates, document order. Present at default/full response levels and omitted in digest. The winner is never included.`,items:w}},[`source`,`phase`,`kind`,`matchCount`,`winnerDiagnostic`,`tiebreak`]),y({source:_(`ref`),phase:_(`pre-action`),kind:_(`exact`)},[`source`,`phase`,`kind`]),y({source:_(`ref`),phase:_(`pre-action`),kind:_(`label-fallback`)},[`source`,`phase`,`kind`]),y({source:_(`direct-ios`),kind:_(`not-observed`)},[`source`,`kind`])]},T=y({foregroundApp:p(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:h(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:h(`Subset of nodeCount the platform reports as hittable.`),digest:p(`Order-independent digest of the post-action node multiset.`),changedFromBefore:f(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure.`)},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),E=y({settled:f(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:h(),captures:h(),quietMs:h(),timeoutMs:h(),refsGeneration:h(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:y({ref:p(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},diff:y({summary:y({additions:h(),removals:h(),unchanged:h()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:y({kind:g([`added`,`removed`]),text:p(),ref:p(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:f(`Lines were capped to the response bound.`)},[`summary`,`lines`],`Settled diff vs the pre-action tree (changed lines only).`),tail:{type:`array`,description:`Unchanged interactive refs tail: still-present, actionable elements from the settled tree, attached only when diff carries zero added-line refs (a modal-dismiss/toast-only diff).`,items:y({ref:p(`Plain ref body (e12) minted from the stored settled tree.`),role:p(),label:p()},[`ref`,`role`])},tailTruncated:f(`Present (true) when tail candidates exceeded the response cap.`),hint:p()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),D={platform:g(l),target:g(u),device:p(`Human-readable device name.`),id:p(`Stable device id.`),kind:g(m)},O=[`platform`,`target`,`device`,`id`,`kind`],he=y({success:f(),exitCode:h(),stdout:p(),stderr:p(),error:d(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]);function ge(e){return{...e,properties:{...e.properties??{},settle:E}}}const _e=C({properties:{evidence:T,settle:E,button:g([`secondary`,`middle`]),count:h(`Number of press/click repetitions.`),intervalMs:h(`Delay between repeated press/click actions.`),holdMs:h(`Hold duration for each action.`),jitterPx:h(`Randomization radius in pixels.`),doubleTap:f(`Whether the command requested a double-tap action.`)}}),k={text:p(`Text submitted to the field.`),delayMs:h(`Delay between typed characters in milliseconds.`),evidence:T,settle:E},ve=y({resourceId:v(`Android resource id of the exact field that changed.`),className:v(`Android class name of the exact field that changed.`),packageName:v(`Android package name that owns the exact field.`),rect:y({x:h(),y:h(),width:h(),height:h()},[`x`,`y`,`width`,`height`],`Screen-space rectangle of the exact field that changed.`)},[`resourceId`,`className`,`packageName`,`rect`],`Target identity captured before fill and matched after fill.`),ye={press:_e,click:_e,fill:{type:`object`,description:`Fill response. Android may return target-bound unconfirmed evidence when the exact app-owned field changed but formatting prevented raw equality.`,oneOf:[{...C({properties:k,required:[`text`]}),not:y({},[`verification`])},C({properties:{...k,verification:_(`unconfirmed`),requested:p(`Literal text requested by the fill command.`),before:v(`Raw target text captured before the fill.`),after:v(`Raw target text captured after the fill.`),target:ve},required:[`text`,`verification`,`requested`,`before`,`after`,`target`]})]},longpress:C({properties:{durationMs:h(),settle:E,gesture:_(`longpress`)}}),find:y({ref:p(`Snapshot ref without the @ prefix when the find action returns one.`),refsGeneration:h(`ADR 0014 ref frame epoch for read-only find actions.`),found:f(`Whether a wait/exists/read-only find satisfied its condition.`),waitedMs:h(`Milliseconds waited for a read-only find condition.`),text:p(`Text value returned by find get_text.`),node:d(`Snapshot node for find get_attrs/get_text.`),matches:{type:`array`,description:`Every match for the read-only find list action (#1625): { ref, node } each.`,items:d(`One listed match with its snapshot ref and node.`)},locator:p(`Locator kind used for the find action.`),query:p(`Query argument used for the find action.`),x:h(`Resolved x coordinate for mutating find actions.`),y:h(`Resolved y coordinate for mutating find actions.`),message:p(`Diagnostic message for mutating find actions.`),settle:E,cost:x},[],`Daemon response data for the find command.`),boot:y({...D,booted:{type:`boolean`,const:!0}},[...O,`booted`]),shutdown:y({...D,shutdown:he},[...O,`shutdown`]),viewport:y({width:h(),height:h(),message:p()},[`width`,`height`,`message`]),...oe,back:ge(oe.back),wait:y({waitedMs:h(),kind:_(`selector`),text:p(),selector:p(),captures:h(),nodeCount:h(),hint:p(),warning:p()},[`waitedMs`]),prepare:y({action:_(`ios-runner`),platform:g(l),deviceId:p(),deviceName:p(),kind:g(m),durationMs:h(),runner:y({},[]),cache:g([`exact`,`restore-key`,`miss`,`external`]),artifact:g([`valid`,`rebuilt`]),buildMs:h(),connectMs:h(),healthCheckMs:h(),xctestrunPath:p(),recoveryReason:p(),failureReason:p(),timing:y({totalMs:h(),additiveParts:y({buildMs:h(),connectAfterBuildMs:h(),healthCheckMs:h()},[`connectAfterBuildMs`,`healthCheckMs`]),containment:y({connectMs:{type:`array`,items:_(`buildMs`)},healthCheckMs:{type:`array`,items:p()}},[`healthCheckMs`]),note:p()},[`totalMs`,`additiveParts`,`containment`,`note`]),message:p()},[`action`,`platform`,`deviceId`,`deviceName`,`kind`,`durationMs`,`runner`,`connectMs`,`healthCheckMs`,`timing`,`message`]),push:{type:`object`,oneOf:[y({platform:_(`ios`),bundleId:p(),message:p()},[`platform`,`bundleId`,`message`]),y({platform:_(`android`),package:p(),action:p(),extrasCount:h(),message:p()},[`platform`,`package`,`action`,`extrasCount`,`message`])]},"trigger-app-event":y({event:p(),eventUrl:p(),transport:_(`deep-link`),message:p()},[`event`,`eventUrl`,`transport`,`message`]),clipboard:{type:`object`,oneOf:[y({action:_(`read`),text:p()},[`action`,`text`]),y({action:_(`write`),textLength:h(),message:p()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[y({platform:g([`ios`,`macos`]),appName:p(),appBundleId:p(),source:_(`session`),surface:g(re),device_udid:p(`iOS only — the session device UDID.`),ios_simulator_device_set:{type:[`string`,`null`],description:`iOS only — the simulator set path, or null when unknown.`}},[`platform`,`appName`,`source`,`surface`]),y({platform:_(`android`),package:p(),activity:p()},[`platform`,`package`,`activity`])]},keyboard:y({platform:g([`android`,`ios`]),action:g([`status`,`dismiss`,`enter`]),visible:f(),wasVisible:f(),dismissed:f(),attempts:h(),inputType:p(),type:g([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:p(),focusedPackage:p(),focusedResourceId:p(),inputOwner:g([`app`,`ime`,`unknown`]),message:p()},[`platform`,`action`]),doctor:y({status:g([`pass`,`warn`,`fail`,`info`]),summary:p(),kind:g([`auto`,`react-native`,`expo`,`repack`]),platform:p(),target:g(u),targetApp:p(),metro:y({host:p(),port:h()},[`host`,`port`]),checks:{type:`array`,items:y({id:p(),status:g([`pass`,`warn`,`fail`,`info`]),summary:p(),hint:p(),command:p(),evidence:d()},[`id`,`status`,`summary`])}},[`status`,`summary`,`kind`,`checks`]),diff:y({mode:_(`snapshot`),baselineInitialized:f(),summary:y({additions:h(),removals:h(),unchanged:h()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:y({kind:g([`added`,`removed`]),text:p(),ref:p()},[`kind`,`text`])},warnings:b},[`mode`,`baselineInitialized`,`summary`,`lines`]),replay:y({replayed:h(),healed:h(),session:p(),sessionActive:f(`True iff the session is still active — the script had no terminal close.`),artifactPaths:b,snapshotDiagnostics:d(),message:p()},[`replayed`,`healed`,`session`,`sessionActive`,`artifactPaths`,`message`]),test:y({total:h(),executed:h(),passed:h(),failed:h(),skipped:h(),notRun:h(),durationMs:h(),failures:{type:`array`,items:d()},tests:{type:`array`,items:d()},snapshotDiagnostics:d()},[`total`,`executed`,`passed`,`failed`,`skipped`,`notRun`,`durationMs`,`failures`,`tests`]),record:{type:`object`,oneOf:[y({recording:_(`started`),outPath:p(),sessionStateDir:p(),recordingBackend:p(),recordingScope:p(),recordOnlySession:f(),activeSessionApp:d(),showTouches:f()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),y({recording:_(`stopped`),outPath:p(),telemetryPath:p(),artifacts:{type:`array`,items:S},recordingBackend:p(),recordingScope:p(),recordOnlySession:f(),activeSessionApp:d(),durationMs:h(),showTouches:f(),warning:p(),overlayWarning:p(),chunks:{type:`array`,items:d()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[y({trace:_(`started`),outPath:p()},[`trace`,`outPath`]),y({trace:_(`stopped`),outPath:p(),artifacts:{type:`array`,items:S}},[`trace`,`outPath`,`artifacts`])]}},be={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:l},target:{type:`string`,enum:u},kind:{type:`string`,enum:m},id:{type:`string`},name:{type:`string`}},required:[`platform`,`target`,`kind`,`id`,`name`]}}},required:[`devices`]},apps:{type:`object`,properties:{apps:{type:`array`,items:{type:`string`}}},required:[`apps`]}},A={...ye,...be};function xe(t){return e(t)}function Se(e){let t=[`Error (${e.code}): ${e.message}`];e.hint&&t.push(`Hint: ${e.hint}`),t.push(...te(e.details)),e.supportedOn&&t.push(`Supported on: ${e.supportedOn}`);let n=ee(e.details);return n&&t.push(n),t.join(`
|
|
2
|
+
`)}function Ce(e,t,n){let r=fe({command:e,cwd:process.cwd(),cliFlags:t}),i={};for(let[t,a]of Object.entries(r))Object.hasOwn(n,t)&&ue(t,e)&&(i[t]=a);return de(i,t)}const we={devices:e=>({devices:e.map(ie)}),apps:e=>({apps:e})};function Te(e,t){let n=we[e];return n?n(t):t}function Ee(){let e=new Map;return{pinInput:(t,n,r)=>Be(t,n,je(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>Me(e,t,n,r,i),mergeErrorDetails:(t,n,r)=>{let i=j(n,r);De(e,i,t),Re(e,i,t)}}}function De(e,t,n){let r=n?.refsGeneration;typeof r==`number`&&M(e,t,ne(n),r)}const Oe=new Set([`snapshot`,`find`]),ke=new Set(c.map(e=>e.name).filter(ce).filter(e=>s(e))),Ae=new Set([`press`,`click`,`fill`,`longpress`,`get`]);function je(e,t,n){return e.get(j(t,n))}function j(e,t){let n=typeof t==`string`&&t.length>0?t:`default`;return`${e??``}\u0000${n}`}function Me(e,t,n,r,i){let a=j(r,i);if(ke.has(t)){Fe(e,a,Ie(n));return}Oe.has(t)&&(t===`find`?Pe(e,a,n):Ne(e,a,n))}function Ne(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`){e.delete(t);return}let i=[];for(let{ref:e}of n.refs??[])i.push(e);for(let e of n.nodes??[])i.push(e.ref);M(e,t,i,r)}function Pe(e,t,n){let r=n.refsGeneration;if(typeof r!=`number`)return;let i=[];typeof n.ref==`string`&&n.ref.startsWith(`@`)&&i.push(n.ref.slice(1));for(let e of n.matches??[])typeof e.ref==`string`&&e.ref.length>0&&i.push(e.ref.startsWith(`@`)?e.ref.slice(1):e.ref);M(e,t,i,r)}function Fe(e,t,n){n?.refsGeneration!==void 0&&M(e,t,[...n.diff?.lines??[],...n.refs??[],...n.tail??[]].map(e=>e.ref).filter(e=>typeof e==`string`),n.refsGeneration)}function Ie(e){let t=e.settle;return typeof t==`object`&&t?t:void 0}function M(e,t,n,r){if(n.length===0)return;let i=e.get(t)??new Map;e.set(t,i),Le(i,n,r)}function Le(e,t,n){for(let r of t)e.delete(r),e.set(r,n);for(;e.size>1e3;)e.delete(e.keys().next().value)}function Re(e,t,n){let r=a(a(n?.divergence)?.screen);if(r?.state!==`available`)return;let i=r.refsGeneration;if(typeof i!=`number`)return;let o=[];ze(r.refs,o),M(e,t,o,i)}function ze(e,t){if(Array.isArray(e))for(let n of e){let e=a(n)?.ref;typeof e==`string`&&e.length>0&&t.push(e)}}function Be(e,t,n){return n===void 0||n.size===0?t:e===`wait`?Ve(t,n)??t:Ae.has(e)?He(t,n)??t:t}function Ve(e,t){if(typeof e.ref!=`string`)return;let n=N(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function He(e,t){let n=a(e.target);if(n?.kind!==`ref`||typeof n.ref!=`string`)return;let r=N(n.ref,t);return r===n.ref?void 0:{...e,target:{...n,ref:r}}}function N(e,t){if(!e.startsWith(`@`)||e.includes(`~`))return e;let n=t.get(e.slice(1));return n===void 0?e:`${e}~s${n}`}function Ue(){return se().map(e=>{let t=e.name in A?A[e.name]:void 0;return{name:e.name,description:ae(e),inputSchema:P(e.name,e.inputSchema),...t?{outputSchema:t}:{}}})}function We(e={}){let n=Ee();return{execute:async(r,i)=>{if(!ce(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=P(r,le(r).inputSchema).properties,o=Ce(r,i,a),s=Ye(o),c=$e(o),l=n.pinInput(r,c,s.client.stateDir),u=await qe(e,s.client);try{let t=await(e.runCommand??Je)(u,r,l);return n.mergeCommandResult(r,t,s.client.stateDir,c.session),{isError:!1,structuredContent:Te(r,t),content:[{type:`text`,text:et({name:r,input:c,result:t,outputFormat:s.outputFormat,responseLevel:s.client.responseLevel})}]}}catch(e){return Ge(e,n,s.client.stateDir,c.session)}}}}function Ge(e,t,n,r){let i=xe(e);return t.mergeErrorDetails(i.details,n,r),{isError:!0,structuredContent:i,content:[{type:`text`,text:Se(i)}]}}const Ke=We();async function qe(e,t){if(e.createClient)return await e.createClient(t);let{createAgentDeviceClient:n}=await import(`./agent-device-client.js`).then(e=>e.t);return n(t)}async function Je(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function Ye(e){return{client:Xe(e),outputFormat:Qe(e.mcpOutputFormat)}}function Xe(e){let n=e.stateDir,r=e.includeCost,i=e.responseLevel,a={};if(n!==void 0){if(typeof n!=`string`||n.length===0)throw new t(`INVALID_ARGS`,`Expected stateDir to be a non-empty string.`);a.stateDir=n}if(r!==void 0){if(typeof r!=`boolean`)throw new t(`INVALID_ARGS`,`Expected includeCost to be a boolean.`);r&&(a.cost=!0)}let o=Ze(i);return o!==void 0&&(a.responseLevel=o),a}function Ze(e){if(e===void 0)return;let r=n.find(t=>t===e);if(r===void 0)throw new t(`INVALID_ARGS`,`Expected responseLevel to be one of 'digest', 'default', or 'full'.`);return r}function Qe(e){if(e===void 0)return`optimized`;if(e!==`optimized`&&e!==`json`)throw new t(`INVALID_ARGS`,`Expected mcpOutputFormat to be "optimized" or "json".`);return e}function $e(e){let{stateDir:t,mcpOutputFormat:n,includeCost:r,responseLevel:i,...a}=e;return a}function P(e,t){let n=o(e);return{...t,properties:{...t.properties,...n&&!t.properties?.noRecord?{noRecord:{type:`boolean`,description:`Do not record this action.`}}:{},stateDir:{type:`string`,description:`Agent-device state directory.`},mcpOutputFormat:{type:`string`,enum:[`optimized`,`json`],description:`MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately.`},includeCost:{type:`boolean`,description:`Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged.`},responseLevel:{type:`string`,enum:[`digest`,`default`,`full`],description:`Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged.`}}}}function et(e){if(e.outputFormat===`json`||e.responseLevel!==void 0&&e.responseLevel!=="default")return F(e.result);let t=pe({name:e.name,input:e.input,result:e.result});return typeof t?.text==`string`?t.text:F(t?.data??e.result)}function F(e){return typeof e==`string`?e:JSON.stringify(e,null,2)}const I=`2026-07-28`,L=[I],R=[`2025-11-25`,`2025-06-18`],z=[...L,...R],B=`server/discover`,tt=new Set([`initialize`,`ping`]),V=`io.modelcontextprotocol/protocolVersion`,H=`io.modelcontextprotocol/clientCapabilities`,U=`io.modelcontextprotocol/clientInfo`,W=36e5;var G=class extends Error{requested;constructor(e){super(`Unsupported MCP protocol version: ${e}. Supported: ${z.join(`, `)}.`),this.requested=e}get data(){return{supported:z,requested:this.requested}}};function nt(e,n){let r=X(X(n)._meta),i=ut(r,V);if(i===void 0){if(e===B)throw new t(`INVALID_ARGS`,`Expected _meta["${V}"] on ${B}.`);return`legacy`}if(!z.includes(i))throw new G(i);if(!q(r[H]))throw new t(`INVALID_ARGS`,`Expected _meta["${H}"] to be an object.`);let a=r[U];if(a!==void 0&&!st(a))throw new t(`INVALID_ARGS`,`Expected _meta["${U}"] to be a valid Implementation.`);if(!L.includes(i)){if(e===B)throw new G(i);return`legacy`}return`modern`}function rt(e){let t=ut(X(e),`protocolVersion`);return t!==void 0&&R.includes(t)?t:`2025-11-25`}function it(e,t){return t===`modern`&&tt.has(e)}function K(){return{name:`agent-device`,version:i()}}function at(e,t){return t===`legacy`||typeof e!=`object`||!e?e:{resultType:`complete`,...e,_meta:{...e._meta,"io.modelcontextprotocol/serverInfo":K()}}}function ot(e,t){return e===`modern`?{ttlMs:t,cacheScope:`public`}:void 0}function q(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function st(e){return!q(e)||!Y(e.name)||!Y(e.version)?!1:J(e.title,Y)&&J(e.description,Y)&&J(e.websiteUrl,Y)&&J(e.icons,e=>Array.isArray(e)&&e.every(ct))}function ct(e){return!q(e)||!Y(e.src)?!1:J(e.mimeType,Y)&&J(e.sizes,lt)&&J(e.theme,e=>e===`light`||e===`dark`)}function J(e,t){return e===void 0||t(e)}function Y(e){return typeof e==`string`}function lt(e){return Array.isArray(e)&&e.every(Y)}function X(e){return q(e)?e:{}}function ut(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:void 0}async function dt(e){if(e.jsonrpc!==`2.0`||typeof e.method!=`string`)return Z(e.id??null,-32600,`Invalid JSON-RPC request.`);if(e.id===void 0)return null;try{let t=nt(e.method,e.params),n=await ft(e.method,e.params,t);return ht(e.id,at(n,t))}catch(t){return t instanceof G?Z(e.id,-32022,t.message,t.data):t instanceof Q?Z(e.id,-32601,t.message):Z(e.id,-32602,t instanceof Error?t.message:String(t))}}async function ft(e,t,n){if(it(e,n))throw new Q(`${e} was removed in MCP ${I}.`);switch(e){case`server/discover`:return{supportedVersions:z,capabilities:{tools:{}},instructions:`agent-device drives iOS, Android, tvOS, Android TV, macOS, Linux, and web targets. Each tool mirrors the CLI command of the same name; tool descriptions carry the per-command contract.`,ttlMs:W,cacheScope:`public`};case`initialize`:return{protocolVersion:rt(t),capabilities:{tools:{}},serverInfo:K()};case`ping`:return{};case`tools/list`:return{tools:Ue(),...ot(n,W)};case`tools/call`:return await pt(t);default:throw new Q(`Unsupported MCP method: ${e}`)}}async function pt(e){let t=gt(e),n=vt(t,`name`);try{return await Ke.execute(n,_t(t.arguments))}catch(e){return mt(Se(xe(e)),!0)}}function mt(e,t=!1){return{isError:t,content:[{type:`text`,text:e}]}}function ht(e,t){return{jsonrpc:`2.0`,id:e,result:t}}function Z(e,t,n,r){return{jsonrpc:`2.0`,id:e,error:{code:t,message:n,...r?{data:r}:{}}}}function gt(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`Expected object parameters.`);return e}function _t(e){return e===void 0?{}:gt(e)}function vt(e,n){let r=e[n];if(typeof r!=`string`||r.length===0)throw new t(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}var Q=class extends Error{};async function yt(){let e=bt(),t=new Et(t=>{e.push(t)});process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{try{t.push(e)}catch(e){Ot({jsonrpc:`2.0`,id:null,error:{code:-32700,message:e instanceof Error?e.message:String(e)}})}}),await new Promise(e=>{process.stdin.on(`end`,e),process.stdin.on(`close`,e),process.stdin.resume()}),await e.idle()}function bt(e={}){let t=e.handlePayload??xt,n=e.write??Ot,r=Promise.resolve();return{push:e=>{let i=Tt(e);r=r.then(async()=>{let r=await t(e);r&&n(r)}).catch(e=>{n({jsonrpc:`2.0`,id:i,error:{code:-32603,message:e instanceof Error?e.message:String(e)}})})},idle:async()=>{await r}}}function xt(e){return Array.isArray(e)?St(e):Ct(e)}async function St(e){let t=[];for(let n of e)t.push(...Dt(await Ct(n)));return t.length>0?t:null}async function Ct(e){let t;try{t=r.parse(e)}catch{return wt($(e))}return dt(t)}function wt(e){return{jsonrpc:`2.0`,id:e,error:{code:-32600,message:`Invalid JSON-RPC request.`}}}function Tt(e){return Array.isArray(e)?e.length===1?$(e[0]):null:$(e)}function $(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t=e.id;if(typeof t==`string`||typeof t==`number`||t===null)return t}return null}var Et=class{buffer=``;sink;constructor(e){this.sink=e}push(e){for(this.buffer+=e;;){let e=this.tryReadLineMessage();if(e!==void 0){this.emit(e);continue}break}}tryReadLineMessage(){let e=this.buffer.indexOf(`
|
|
3
|
+
`);if(e===-1)return;let t=this.buffer.slice(0,e).trim();return this.buffer=this.buffer.slice(e+1),t.length>0?t:void 0}emit(e){this.sink(JSON.parse(e))}};function Dt(e){return e?[e]:[]}function Ot(e){process.stdout.write(`${JSON.stringify(e)}\n`)}export{yt as runAgentDeviceMcpServer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{At as e,Bt as t,Ft as n,Nt as r,Tt as i,Vt as a,jt as o}from"./sdk-batch-runner.js";import{$ as s,et as c,it as l,tt as u}from"./prepare-kind.js";import{rn as d}from"./internal/daemon.js";function f(e){return e.matchedRefs.length===0?{path:2,outcome:`unverifiable`,reason:`selector-miss`}:e.identitySetRefs.length===0?{path:3,outcome:`unverifiable`,reason:`identity-set-empty`}:e.identitySetRefs.length===1?e.identitySetRefs[0]===e.winnerRef?{path:4,outcome:`verified`}:{path:5,outcome:`unverifiable`,reason:`unique-but-wrong`}:e.siblingMatchRefs.length===1?e.siblingMatchRefs[0]===e.winnerRef?{path:6,outcome:`verified`}:{path:6,outcome:`unverifiable`,reason:`signal-isolated-wrong`}:e.regionMemberRefs!==void 0&&e.regionMemberRefs.length>0&&e.viewportCandidateRef!==void 0?e.viewportCandidateRef===e.winnerRef?{path:6,outcome:`verified`}:{path:6,outcome:`unverifiable`,reason:`signal-isolated-wrong`}:{path:6,outcome:`unverifiable`,reason:`no-signal-isolation`}}function p(e,t={}){let n=t.mode??`action`,{node:r,preActionNodes:a}=e;if(typeof r.index!=`number`)return;let o=c(a),l=i(_(r),a);if(n===`landmark`&&l.id===void 0&&l.label===void 0)return;let u=s(r,o,8),d=u.chain,f=v(a,r),p=y(r,o),b=x(r),C=+(d.length>0),w=e=>{let t=d.slice(0,e),n=S({nodes:a,byIndex:o,node:r,identity:l,ancestry:t,sibling:f,scrollRegion:p});return{candidate:{...l,ancestry:t,sibling:f,viewportOrder:n.viewportOrder,...p?{scrollRegion:p}:{},...b?{rect:b}:{},verification:`verified`},domain:n}};for(let e=d.length;e>=C;--e){let{candidate:t,domain:i}=w(e);if(h(t))return t.verification=m({node:r,domain:i,mode:n,brokenWalk:u.broken}),t;if(e===C)return g(t)}}function m(e){return e.brokenWalk?`unverifiable`:e.mode===`landmark`?`verified`:w({node:e.node,domain:e.domain})}function h(e){return a(t({...e,verification:`unverifiable`}))<=n}function g(e){return e.verification=`unverifiable`,a(t(e))>4096&&delete e.rect,e}const _=o;function v(e,t){return r(e,t)}function y(e,t){let n=d(e,t);if(!n)return;let r=_(n);return{role:r.role,...r.id===void 0?r.label===void 0?{}:{label:r.label}:{id:r.id}}}function b(t,n){return!t&&!n?!0:!t||!n?!1:e(t,n)}function x(e){let t=e.rect;if(t)return{x:t.x,y:t.y,width:t.width,height:t.height}}function S(e){let{nodes:t,byIndex:n,node:r,identity:i,ancestry:a,sibling:o,scrollRegion:s}=e,c=u(t,n,i,a),l=c.filter(e=>v(t,e)===o),d=c.length>0?c.filter(e=>b(y(e,n),s)):void 0,f=d?C(d):[];return{identitySet:c,siblingMatches:l,regionMembers:d,orderedRegion:f,viewportOrder:Math.max(f.findIndex(e=>e.index===r.index),0)}}function C(e){return e.map((e,t)=>({node:e,documentOrder:t,center:l(e.rect)})).sort((e,t)=>!e.center&&!t.center?e.documentOrder-t.documentOrder:e.center?t.center?e.center.y===t.center.y?e.center.x===t.center.x?e.documentOrder-t.documentOrder:e.center.x-t.center.x:e.center.y-t.center.y:-1:1).map(e=>e.node)}function w(e){let{node:t,domain:n}=e,r=t.ref,i=n.identitySet.map(e=>e.ref);return f({winnerRef:r,matchedRefs:i,identitySetRefs:i,siblingMatchRefs:n.siblingMatches.map(e=>e.ref),regionMemberRefs:n.regionMembers?.map(e=>e.ref),viewportCandidateRef:n.orderedRegion[n.viewportOrder]?.ref}).outcome}export{C as a,p as i,y as n,b as o,v as r,f as s,_ as t};
|