agent-device 0.20.4 → 0.20.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +2 -0
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.4.apk → agent-device-android-ime-helper-0.20.6.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.6.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.4.manifest.json → agent-device-android-ime-helper-0.20.6.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.4.apk → agent-device-android-snapshot-helper-0.20.6.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.6.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.4.manifest.json → agent-device-android-snapshot-helper-0.20.6.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +28 -0
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +1 -0
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +41 -1
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +298 -92
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +126 -187
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.h +32 -0
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedTextEntry.m +212 -0
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +118 -8
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +134 -27
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +23 -5
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +10 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +0 -67
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +11 -1
  21. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +2 -22
  22. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +48 -11
  23. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +0 -20
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedTextEntry.swift +177 -0
  25. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +105 -448
  26. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntryPolicyTests.swift +4 -0
  27. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextTyping.swift +587 -0
  28. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +18 -0
  29. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.h +72 -0
  30. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerXCTestEventBridge.m +89 -0
  31. package/dist/src/agent-device-client.js +2 -2
  32. package/dist/src/android.js +1 -1
  33. package/dist/src/app-log-request-scope.js +1 -1
  34. package/dist/src/app-resolution.js +1 -1
  35. package/dist/src/apps.js +5 -5
  36. package/dist/src/cli-config.js +1 -1
  37. package/dist/src/cli-help.js +34 -24
  38. package/dist/src/cli-runner.js +1 -1
  39. package/dist/src/cli.js +15 -15
  40. package/dist/src/command-metadata.js +1 -1
  41. package/dist/src/command-schema.js +3 -3
  42. package/dist/src/context.js +1 -1
  43. package/dist/src/debug-symbols.js +1 -1
  44. package/dist/src/find.js +1 -1
  45. package/dist/src/finders.js +1 -1
  46. package/dist/src/generic-settle.js +1 -0
  47. package/dist/src/generic.js +1 -1
  48. package/dist/src/ime-lifecycle.js +3 -3
  49. package/dist/src/index.d.ts +27 -7
  50. package/dist/src/input-actions.js +4 -4
  51. package/dist/src/interaction-runtime.js +1 -0
  52. package/dist/src/interaction-snapshot.js +1 -1
  53. package/dist/src/interaction-touch-reference-frame.js +1 -0
  54. package/dist/src/interaction.js +1 -1
  55. package/dist/src/interactor.js +2 -2
  56. package/dist/src/interactor2.js +1 -1
  57. package/dist/src/internal/bin.js +2 -2
  58. package/dist/src/internal/daemon.js +15 -15
  59. package/dist/src/lease-context.js +1 -1
  60. package/dist/src/lease.js +1 -1
  61. package/dist/src/limrun.d.ts +23 -2
  62. package/dist/src/linux.js +1 -1
  63. package/dist/src/process-exit.js +1 -0
  64. package/dist/src/react-native.js +1 -1
  65. package/dist/src/record-trace.js +1 -1
  66. package/dist/src/register-builtins.js +1 -1
  67. package/dist/src/registry.js +25 -24
  68. package/dist/src/remote-config.js +1 -1
  69. package/dist/src/remote-config2.js +1 -1
  70. package/dist/src/reporting.js +2 -2
  71. package/dist/src/runner-client.js +1 -1
  72. package/dist/src/runner-disposal.js +1 -1
  73. package/dist/src/runner-lease.js +1 -1
  74. package/dist/src/runtime.js +3 -3
  75. package/dist/src/screenshot-geometry.js +1 -1
  76. package/dist/src/screenshot-result.js +4 -4
  77. package/dist/src/sdk-android-adb.d.ts +20 -2
  78. package/dist/src/sdk-android-adb.js +1 -1
  79. package/dist/src/sdk-batch-runner.js +3 -3
  80. package/dist/src/sdk-contracts.d.ts +17 -2
  81. package/dist/src/sdk-finders.d.ts +4 -20
  82. package/dist/src/sdk-finders.js +1 -1
  83. package/dist/src/{interaction.d.ts → sdk-selectors.d.ts} +98 -3
  84. package/dist/src/sdk-selectors.js +1 -1
  85. package/dist/src/selector-runtime.js +1 -1
  86. package/dist/src/selector-vocabulary.js +1 -1
  87. package/dist/src/selectors.d.ts +1 -46
  88. package/dist/src/selectors.js +1 -1
  89. package/dist/src/server.js +3 -3
  90. package/dist/src/session-target-evidence.js +1 -1
  91. package/dist/src/session.js +9 -8
  92. package/dist/src/snapshot2.js +1 -1
  93. package/dist/src/text-surface.js +1 -0
  94. package/dist/src/viewport-dimension.js +13 -12
  95. package/dist/src/web.js +1 -1
  96. package/package.json +42 -34
  97. package/server.json +3 -3
  98. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.4.apk.sha256 +0 -1
  99. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.4.apk.sha256 +0 -1
  100. package/dist/apple/runner/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -225
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{V 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
+ import{_ as e}from"./sdk-contracts.js";import{nt 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={textKeys:[`id`,`text`,`label`],booleanKeys:[`enabled`,`selected`]};export{re as C,Xe as S,Pt as _,$ as a,L as b,tn as c,Wt as d,Rt as f,Ft as g,It as h,sn as i,en as l,Z as m,dn as n,cn as o,Lt as p,un as r,on as s,ln as t,$t as u,Nt as v,M as x,V as y};
@@ -1,47 +1,2 @@
1
- import { A as SnapshotNode, N as SnapshotState, U as PublicPlatform, V as Platform } from "./sdk-contracts.js";
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 };
@@ -1 +1 @@
1
- import{H as e,V as t,W as n}from"./sdk-batch-runner.js";import{O as r,f as i,h as a,k as o,p as s}from"./sdk-selectors.js";export{i as findSelectorChainMatch,s as formatSelectorFailure,r as isNodeEditable,o as isNodeVisible,t as isSelectorToken,e as parseSelectorChain,a as resolveSelectorChain,n as tryParseSelectorChain};
1
+ import{Bt as e,Ct as t,Ht as n,Tt as r,Ut as i,Wt as a,zt as o}from"./sdk-batch-runner.js";import{t as s}from"./sdk-selectors.js";export{t as findSelectorChainMatch,s as formatSelectorFailure,i as isNodeEditable,a as isNodeVisible,o as isSelectorToken,e as parseSelectorChain,r as resolveSelectorChain,n as tryParseSelectorChain};
@@ -1,3 +1,3 @@
1
- import{S as e,_ as t,n,o as r}from"./sdk-contracts.js";import{Pt as i,Zt as a,ht 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 qe(e){return e?[e]:[]}function $(e){process.stdout.write(`${JSON.stringify(e)}\n`)}export{Be as runAgentDeviceMcpServer};
1
+ import{S as e,_ as t,n,o as r}from"./sdk-contracts.js";import{S as i,dn as a,g as o,h as s}from"./sdk-batch-runner.js";import{r as c,t as l}from"./sdk-device.js";import{Ct as u,Tt as d,Ut as ee,on as te}from"./viewport-dimension.js";import{_ as ne,b as f,s as p,v as m,y as h}from"./registry.js";import{i as re,n as g,t as _}from"./command-metadata.js";import{n as v}from"./version.js";import{i as ie,n as ae,r as oe,t as se}from"./cli-config.js";const y=[`simulator`,`emulator`,`device`];function b(e){return{type:`number`,...e?{description:e}:{}}}function x(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function S(e){return{type:`string`,const:e}}function C(e,t=[],n){return{type:`object`,...n?{description:n}:{},properties:e,...t.length>0?{required:t}:{}}}const w={type:`array`,items:{type:`string`}},T=C({wallClockMs:b(`Total wall-clock time for the request in milliseconds.`),runnerRoundTrips:b(`Number of real runner round-trips made while serving the request.`),nodeCount:b(`Number of nodes in the original node tree when the response carries one.`)},[`wallClockMs`,`runnerRoundTrips`]),E=C({field:f(),artifactType:f(),path:f(),localPath:f(),fileName:f()},[`field`]);function D(e={}){let t=e.properties??{},n=e.required??[];return C({targetKind:x([`point`,`ref`,`selector`],`Resolved interaction target kind.`),x:b(`Resolved interaction x coordinate when available.`),y:b(`Resolved interaction y coordinate when available.`),referenceWidth:b(`Reference frame width for visualizing the interaction point.`),referenceHeight:b(`Reference frame height for visualizing the interaction point.`),ref:f(`Snapshot ref without the @ prefix when the target was an @ref.`),selector:f(`Selector expression when the target was a selector.`),selectorChain:w,refLabel:f(),targetHittable:m(),hint:f(),warning:f(),message:f(),evidence:k,resolution:ce,cost:T,maestroNonHittableCoordinateFallbackAllowed:m(`Whether the direct iOS Maestro coordinate fallback was allowed for this selector.`),maestroNonHittableCoordinateFallbackUsed:m(`Whether the direct iOS Maestro coordinate fallback was actually used.`),maestroFallbackReason:S(`non-hittable-coordinate`),...t},[`targetKind`,...n])}const O=C({diagnosticRef:f(`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:f(`UTF-8 truncated to 256 bytes.`),label:f(`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:[C({source:S(`runtime`),phase:S(`pre-action`),kind:S(`unique`)},[`source`,`phase`,`kind`]),C({source:S(`runtime`),phase:S(`pre-action`),kind:S(`disambiguated`),matchCount:b(`Total matches resolveSelectorChain found before disambiguation.`),winnerDiagnostic:O,tiebreak:x([`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:O}},[`source`,`phase`,`kind`,`matchCount`,`winnerDiagnostic`,`tiebreak`]),C({source:S(`ref`),phase:S(`pre-action`),kind:S(`exact`)},[`source`,`phase`,`kind`]),C({source:S(`ref`),phase:S(`pre-action`),kind:S(`label-fallback`)},[`source`,`phase`,`kind`]),C({source:S(`direct-ios`),kind:S(`not-observed`)},[`source`,`kind`])]},k=C({foregroundApp:f(`Foreground app bundle id or name, when the capture carries it.`),nodeCount:b(`Node count in the post-action interactive-only capture.`),interactiveNodeCount:b(`Subset of nodeCount the platform reports as hittable.`),digest:f(`Order-independent digest of the post-action node multiset.`),changedFromBefore:m(`Whether the post-action digest differs from the pre-action capture digest. false is evidence, not failure.`)},[`nodeCount`,`interactiveNodeCount`,`digest`,`changedFromBefore`]),A=C({settled:m(`Whether the UI held the quiet window before the deadline. false is advisory, not failure.`),waitedMs:b(),captures:b(),quietMs:b(),timeoutMs:b(),refsGeneration:b(`Snapshot generation of the stored settled tree; refs on added diff lines were minted from it.`),refs:{type:`array`,items:C({ref:f(`Plain ref body (e12) minted from the stored settled tree.`)},[`ref`])},diff:C({summary:C({additions:b(),removals:b(),unchanged:b()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:C({kind:x([`added`,`removed`]),text:f(),ref:f(`Plain ref body (e12) for added lines.`)},[`kind`,`text`])},truncated:m(`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:C({ref:f(`Plain ref body (e12) minted from the stored settled tree.`),role:f(),label:f()},[`ref`,`role`])},tailTruncated:m(`Present (true) when tail candidates exceeded the response cap.`),hint:f()},[`settled`,`waitedMs`,`captures`,`quietMs`,`timeoutMs`]),j={platform:x(c),target:x(l),device:f(`Human-readable device name.`),id:f(`Stable device id.`),kind:x(y)},M=[`platform`,`target`,`device`,`id`,`kind`],le=C({success:m(),exitCode:b(),stdout:f(),stderr:f(),error:h(`Normalized error detail when shutdown failed.`)},[`success`,`exitCode`,`stdout`,`stderr`]);function ue(e){return{...e,properties:{...e.properties??{},settle:A}}}const N=D({properties:{evidence:k,settle:A,button:x([`secondary`,`middle`]),count:b(`Number of press/click repetitions.`),intervalMs:b(`Delay between repeated press/click actions.`),holdMs:b(`Hold duration for each action.`),jitterPx:b(`Randomization radius in pixels.`),doubleTap:m(`Whether the command requested a double-tap action.`)}}),de={press:N,click:N,fill:D({properties:{text:f(`Text submitted to the field.`),delayMs:b(`Delay between typed characters in milliseconds.`),evidence:k,settle:A},required:[`text`]}),longpress:D({properties:{durationMs:b(),settle:A,gesture:S(`longpress`)}}),find:C({ref:f(`Snapshot ref without the @ prefix when the find action returns one.`),refsGeneration:b(`ADR 0014 ref frame epoch for read-only find actions.`),found:m(`Whether a wait/exists/read-only find satisfied its condition.`),waitedMs:b(`Milliseconds waited for a read-only find condition.`),text:f(`Text value returned by find get_text.`),node:h(`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:h(`One listed match with its snapshot ref and node.`)},locator:f(`Locator kind used for the find action.`),query:f(`Query argument used for the find action.`),x:b(`Resolved x coordinate for mutating find actions.`),y:b(`Resolved y coordinate for mutating find actions.`),message:f(`Diagnostic message for mutating find actions.`),settle:A,cost:T},[],`Daemon response data for the find command.`),boot:C({...j,booted:{type:`boolean`,const:!0}},[...M,`booted`]),shutdown:C({...j,shutdown:le},[...M,`shutdown`]),viewport:C({width:b(),height:b(),message:f()},[`width`,`height`,`message`]),...p,back:ue(p.back),wait:C({waitedMs:b(),kind:S(`selector`),text:f(),selector:f(),captures:b(),nodeCount:b(),hint:f(),warning:f()},[`waitedMs`]),prepare:C({action:S(`ios-runner`),platform:x(c),deviceId:f(),deviceName:f(),kind:x(y),durationMs:b(),runner:C({},[]),cache:x([`exact`,`restore-key`,`miss`,`external`]),artifact:x([`valid`,`rebuilt`]),buildMs:b(),connectMs:b(),healthCheckMs:b(),xctestrunPath:f(),recoveryReason:f(),failureReason:f(),timing:C({totalMs:b(),additiveParts:C({buildMs:b(),connectAfterBuildMs:b(),healthCheckMs:b()},[`connectAfterBuildMs`,`healthCheckMs`]),containment:C({connectMs:{type:`array`,items:S(`buildMs`)},healthCheckMs:{type:`array`,items:f()}},[`healthCheckMs`]),note:f()},[`totalMs`,`additiveParts`,`containment`,`note`]),message:f()},[`action`,`platform`,`deviceId`,`deviceName`,`kind`,`durationMs`,`runner`,`connectMs`,`healthCheckMs`,`timing`,`message`]),push:{type:`object`,oneOf:[C({platform:S(`ios`),bundleId:f(),message:f()},[`platform`,`bundleId`,`message`]),C({platform:S(`android`),package:f(),action:f(),extrasCount:b(),message:f()},[`platform`,`package`,`action`,`extrasCount`,`message`])]},"trigger-app-event":C({event:f(),eventUrl:f(),transport:S(`deep-link`),message:f()},[`event`,`eventUrl`,`transport`,`message`]),clipboard:{type:`object`,oneOf:[C({action:S(`read`),text:f()},[`action`,`text`]),C({action:S(`write`),textLength:b(),message:f()},[`action`,`textLength`,`message`])]},appstate:{type:`object`,oneOf:[C({platform:x([`ios`,`macos`]),appName:f(),appBundleId:f(),source:S(`session`),surface:x(ee),device_udid:f(`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`]),C({platform:S(`android`),package:f(),activity:f()},[`platform`,`package`,`activity`])]},keyboard:C({platform:x([`android`,`ios`]),action:x([`status`,`dismiss`,`enter`]),visible:m(),wasVisible:m(),dismissed:m(),attempts:b(),inputType:f(),type:x([`text`,`number`,`email`,`phone`,`password`,`datetime`,`unknown`]),inputMethodPackage:f(),focusedPackage:f(),focusedResourceId:f(),inputOwner:x([`app`,`ime`,`unknown`]),message:f()},[`platform`,`action`]),doctor:C({status:x([`pass`,`warn`,`fail`,`info`]),summary:f(),kind:x([`auto`,`react-native`,`expo`,`repack`]),platform:f(),target:x(l),targetApp:f(),metro:C({host:f(),port:b()},[`host`,`port`]),checks:{type:`array`,items:C({id:f(),status:x([`pass`,`warn`,`fail`,`info`]),summary:f(),hint:f(),command:f(),evidence:h()},[`id`,`status`,`summary`])}},[`status`,`summary`,`kind`,`checks`]),diff:C({mode:S(`snapshot`),baselineInitialized:m(),summary:C({additions:b(),removals:b(),unchanged:b()},[`additions`,`removals`,`unchanged`]),lines:{type:`array`,items:C({kind:x([`added`,`removed`]),text:f(),ref:f()},[`kind`,`text`])},warnings:w},[`mode`,`baselineInitialized`,`summary`,`lines`]),replay:C({replayed:b(),healed:b(),session:f(),sessionActive:m(`True iff the session is still active — the script had no terminal close.`),artifactPaths:w,snapshotDiagnostics:h(),message:f()},[`replayed`,`healed`,`session`,`sessionActive`,`artifactPaths`,`message`]),test:C({total:b(),executed:b(),passed:b(),failed:b(),skipped:b(),notRun:b(),durationMs:b(),failures:{type:`array`,items:h()},tests:{type:`array`,items:h()},snapshotDiagnostics:h()},[`total`,`executed`,`passed`,`failed`,`skipped`,`notRun`,`durationMs`,`failures`,`tests`]),record:{type:`object`,oneOf:[C({recording:S(`started`),outPath:f(),sessionStateDir:f(),recordingBackend:f(),recordingScope:f(),recordOnlySession:m(),activeSessionApp:h(),showTouches:m()},[`recording`,`outPath`,`sessionStateDir`,`showTouches`]),C({recording:S(`stopped`),outPath:f(),telemetryPath:f(),artifacts:{type:`array`,items:E},recordingBackend:f(),recordingScope:f(),recordOnlySession:m(),activeSessionApp:h(),durationMs:b(),showTouches:m(),warning:f(),overlayWarning:f(),chunks:{type:`array`,items:h()}},[`recording`,`outPath`,`artifacts`,`durationMs`,`showTouches`])]},trace:{type:`object`,oneOf:[C({trace:S(`started`),outPath:f()},[`trace`,`outPath`]),C({trace:S(`stopped`),outPath:f(),artifacts:{type:`array`,items:E}},[`trace`,`outPath`,`artifacts`])]}},fe={devices:{type:`object`,properties:{devices:{type:`array`,items:{type:`object`,properties:{platform:{type:`string`,enum:c},target:{type:`string`,enum:l},kind:{type:`string`,enum:y},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`]}},P={...de,...fe};function F(t){return e(t)}function I(e){let t=[`Error (${e.code}): ${e.message}`];e.hint&&t.push(`Hint: ${e.hint}`),t.push(...d(e.details)),e.supportedOn&&t.push(`Supported on: ${e.supportedOn}`);let n=u(e.details);return n&&t.push(n),t.join(`
2
+ `)}function L(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 R={devices:e=>({devices:e.map(te)}),apps:e=>({apps:e})};function z(e,t){let n=R[e];return n?n(t):t}function B(){let e=new Map;return{pinInput:(t,n,r)=>we(t,n,he(e,r,n.session)),mergeCommandResult:(t,n,r,i)=>ge(e,t,n,r,i),mergeDivergenceScreen:(t,n,r)=>Se(e,H(n,r),t)}}const V=new Set([`snapshot`,`find`]),pe=new Set(s.map(e=>e.name).filter(g).filter(e=>o(e))),me=new Set([`press`,`click`,`fill`,`longpress`,`get`]);function he(e,t,n){return e.get(H(t,n))}function H(e,t){let n=typeof t==`string`&&t.length>0?t:`default`;return`${e??``}\u0000${n}`}function ge(e,t,n,r,i){let a=H(r,i);if(pe.has(t)){ye(e,a,be(n));return}V.has(t)&&(t===`find`?ve(e,a,n):_e(e,a,n))}function _e(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 ve(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);U(e,t,i,r)}function ye(e,t,n){n?.refsGeneration!==void 0&&U(e,t,[...n.diff?.lines??[],...n.refs??[],...n.tail??[]].map(e=>e.ref).filter(e=>typeof e==`string`),n.refsGeneration)}function be(e){let t=e.settle;return typeof t==`object`&&t?t:void 0}function U(e,t,n,r){if(n.length===0)return;let i=e.get(t)??new Map;e.set(t,i),xe(i,n,r)}function xe(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 Se(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=[];Ce(r.refs,o),U(e,t,o,i)}function Ce(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 we(e,t,n){return n===void 0||n.size===0?t:e===`wait`?Te(t,n)??t:me.has(e)?Ee(t,n)??t:t}function Te(e,t){if(typeof e.ref!=`string`)return;let n=W(e.ref,t);return n===e.ref?void 0:{...e,ref:n}}function Ee(e,t){let n=a(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 De(){return re().map(e=>{let t=e.name in P?P[e.name]:void 0;return{name:e.name,description:ne(e),inputSchema:G(e.name,e.inputSchema),...t?{outputSchema:t}:{}}})}function Oe(e={}){let n=B();return{execute:async(r,i)=>{if(!g(r))throw new t(`INVALID_ARGS`,`Unknown command tool: ${r}`);let a=G(r,_(r).inputSchema).properties,o=L(r,i,a),s=Ne(o),c=Le(o),l=n.pinInput(r,c,s.client.stateDir),u=await je(e,s.client);try{let t=await(e.runCommand??Me)(u,r,l);return n.mergeCommandResult(r,t,s.client.stateDir,c.session),{isError:!1,structuredContent:z(r,t),content:[{type:`text`,text:Re({name:r,input:c,result:t,outputFormat:s.outputFormat,responseLevel:s.client.responseLevel})}]}}catch(e){return ke(e,n,s.client.stateDir,c.session)}}}}function ke(e,t,n,r){let i=F(e);return t.mergeDivergenceScreen(i.details,n,r),{isError:!0,structuredContent:i,content:[{type:`text`,text:I(i)}]}}const Ae=Oe();async function je(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 Me(e,t,n){return await(await import(`./command-surface.js`).then(e=>e.t)).runCommand(e,t,n)}function Ne(e){return{client:Pe(e),outputFormat:Ie(e.mcpOutputFormat)}}function Pe(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=Fe(i);return o!==void 0&&(a.responseLevel=o),a}function Fe(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 Ie(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 Le(e){let{stateDir:t,mcpOutputFormat:n,includeCost:r,responseLevel:i,...a}=e;return a}function G(e,t){let n=i(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 Re(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 ze(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 We(e.id,await Be(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 Be(e,t){switch(e){case`initialize`:return{protocolVersion:He(t),capabilities:{tools:{}},serverInfo:{name:`agent-device`,version:v()}};case`ping`:return{};case`tools/list`:return{tools:De()};case`tools/call`:return await Ve(t);default:throw new X(`Unsupported MCP method: ${e}`)}}async function Ve(e){let t=J(e),n=Y(t,`name`);try{return await Ae.execute(n,Ge(t.arguments))}catch(e){return Ue(I(F(e)),!0)}}function He(e){return`2025-11-25`}function Ue(e,t=!1){return{isError:t,content:[{type:`text`,text:e}]}}function We(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 Ge(e){return e===void 0?{}:J(e)}function Y(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 Ke(){let e=qe(),t=new Qe(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 qe(e={}){let t=e.handlePayload??Je,n=e.write??$,r=Promise.resolve();return{push:e=>{let i=Ze(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 Je(e){return Array.isArray(e)?Ye(e):Z(e)}async function Ye(e){let t=[];for(let n of e)t.push(...$e(await Z(n)));return t.length>0?t:null}async function Z(e){let t;try{t=r.parse(e)}catch{return Xe(Q(e))}return ze(t)}function Xe(e){return{jsonrpc:`2.0`,id:e,error:{code:-32600,message:`Invalid JSON-RPC request.`}}}function Ze(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 Qe=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 $e(e){return e?[e]:[]}function $(e){process.stdout.write(`${JSON.stringify(e)}\n`)}export{Ke as runAgentDeviceMcpServer};
@@ -1 +1 @@
1
- import{B as e,H as t,K as n,V as r,W as i,Y as a}from"./viewport-dimension.js";import{a as o,l as s,s as c}from"./sdk-selectors.js";import{tn as l}from"./internal/daemon.js";import{TARGET_ANNOTATION_MAX_ANCESTRY as u,TARGET_ANNOTATION_MAX_PAYLOAD_BYTES as d,serializeTargetAnnotationV1 as f,utf8ByteLength as p}from"@agent-device/ad-script";function m(t,n={}){let i=n.mode??`action`,{node:a,preActionNodes:o}=t;if(typeof a.index!=`number`)return;let s=r(o),c=C(v(a),o);if(i===`landmark`&&c.id===void 0&&c.label===void 0)return;let l=e(a,s,u),d=l.chain,f=y(o,a),p=b(a,s),m=S(a),x=+(d.length>0),T=e=>{let t=d.slice(0,e),n=w({nodes:o,byIndex:s,node:a,identity:c,ancestry:t,sibling:f,scrollRegion:p});return{candidate:{...c,ancestry:t,sibling:f,viewportOrder:n.viewportOrder,...p?{scrollRegion:p}:{},...m?{rect:m}:{},verification:`verified`},domain:n}};for(let e=d.length;e>=x;--e){let{candidate:t,domain:n}=T(e);if(g(t))return t.verification=h({node:a,domain:n,mode:i,brokenWalk:l.broken}),t;if(e===x)return _(t)}}function h(e){return e.brokenWalk?`unverifiable`:e.mode===`landmark`?`verified`:E({node:e.node,domain:e.domain})}function g(e){return p(f({...e,verification:`unverifiable`}))<=d}function _(e){return e.verification=`unverifiable`,p(f(e))>d&&delete e.rect,e}const v=c;function y(e,t){return s(e,t)}function b(e,t){let n=l(e,t);if(!n)return;let r=v(n);return{role:r.role,...r.id===void 0?r.label===void 0?{}:{label:r.label}:{id:r.id}}}function x(e,t){return!e&&!t?!0:!e||!t?!1:n(e,t)}function S(e){let t=e.rect;if(t)return{x:t.x,y:t.y,width:t.width,height:t.height}}function C(e,t){return o(e,t)}function w(e){let{nodes:n,byIndex:r,node:i,identity:a,ancestry:o,sibling:s,scrollRegion:c}=e,l=t(n,r,a,o),u=l.filter(e=>y(n,e)===s),d=l.length>0?l.filter(e=>x(b(e,r),c)):void 0,f=d?T(d):[];return{identitySet:l,siblingMatches:u,regionMembers:d,orderedRegion:f,viewportOrder:Math.max(f.findIndex(e=>e.index===i.index),0)}}function T(e){return e.map((e,t)=>({node:e,documentOrder:t,center:a(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 E(e){let{node:t,domain:n}=e,r=t.ref,a=n.identitySet.map(e=>e.ref);return i({winnerRef:r,matchedRefs:a,identitySetRefs:a,siblingMatchRefs:n.siblingMatches.map(e=>e.ref),regionMemberRefs:n.regionMembers?.map(e=>e.ref),viewportCandidateRef:n.orderedRegion[n.viewportOrder]?.ref}).outcome}export{T as a,m as i,b as n,x as o,y as r,v as t};
1
+ import{$ as e,J as t,et as n,it as r,lt as i,nt as a,ut as o}from"./sdk-batch-runner.js";import{Q as s,X as c,Z as l,tt as u}from"./viewport-dimension.js";import{$t 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,n={}){let r=n.mode??`action`,{node:i,preActionNodes:a}=e;if(typeof i.index!=`number`)return;let o=l(a),s=t(_(i),a);if(r===`landmark`&&s.id===void 0&&s.label===void 0)return;let u=c(i,o,8),d=u.chain,f=v(a,i),p=y(i,o),b=x(i),C=+(d.length>0),w=e=>{let t=d.slice(0,e),n=S({nodes:a,byIndex:o,node:i,identity:s,ancestry:t,sibling:f,scrollRegion:p});return{candidate:{...s,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:n}=w(e);if(h(t))return t.verification=m({node:i,domain:n,mode:r,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 o(i({...e,verification:`unverifiable`}))<=r}function g(e){return e.verification=`unverifiable`,o(i(e))>4096&&delete e.rect,e}const _=n;function v(e,t){return a(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:c}=e,l=s(t,n,i,a),u=l.filter(e=>v(t,e)===o),d=l.length>0?l.filter(e=>b(y(e,n),c)):void 0,f=d?C(d):[];return{identitySet:l,siblingMatches:u,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:u(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};