agent-device 0.21.2 → 0.21.3

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 (74) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.2.apk → agent-device-android-ime-helper-0.21.3.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.3.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.21.2.manifest.json → agent-device-android-ime-helper-0.21.3.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.2.apk → agent-device-android-snapshot-helper-0.21.3.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.3.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.21.2.manifest.json → agent-device-android-snapshot-helper-0.21.3.manifest.json} +7 -7
  7. package/dist/src/agent-device-client.js +1 -1
  8. package/dist/src/app-launch.js +1 -1
  9. package/dist/src/auth.js +1 -1
  10. package/dist/src/back-mode.js +1 -1
  11. package/dist/src/cli.js +2 -2
  12. package/dist/src/client-types.d.ts +1 -1
  13. package/dist/src/command-schema.js +1 -1
  14. package/dist/src/config.js +1 -1
  15. package/dist/src/connection-runtime.js +1 -1
  16. package/dist/src/connection.js +1 -1
  17. package/dist/src/daemon-client-lifecycle.js +1 -1
  18. package/dist/src/daemon-registration.js +1 -1
  19. package/dist/src/daemon-resolution.js +1 -0
  20. package/dist/src/daemon.js +1 -1
  21. package/dist/src/device-claim-rule.js +1 -1
  22. package/dist/src/harmonyos.js +1 -1
  23. package/dist/src/human-control-contract.js +1 -1
  24. package/dist/src/human-control.js +1 -1
  25. package/dist/src/interaction.js +1 -1
  26. package/dist/src/interactor.js +1 -1
  27. package/dist/src/interactors.js +1 -1
  28. package/dist/src/internal/bin.js +1 -1
  29. package/dist/src/internal/daemon.js +2 -2
  30. package/dist/src/lease-scope.js +1 -1
  31. package/dist/src/mechanics.js +16 -16
  32. package/dist/src/perf-runtime-plan.js +1 -1
  33. package/dist/src/physical-device-control.js +1 -1
  34. package/dist/src/platform-request-scope.js +1 -1
  35. package/dist/src/platform-runtime-host.js +1 -1
  36. package/dist/src/platform-runtime-operation-host.js +1 -1
  37. package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -1
  38. package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -1
  39. package/dist/src/platform-runtime.js +1 -1
  40. package/dist/src/provider-webdriver.js +1 -1
  41. package/dist/src/record-runtime.js +1 -1
  42. package/dist/src/register-builtins.js +1 -1
  43. package/dist/src/registry.js +3 -3
  44. package/dist/src/request-providers.js +1 -1
  45. package/dist/src/runner-cache-metadata.js +2 -2
  46. package/dist/src/runner-client.js +1 -1
  47. package/dist/src/runner-disposal.js +1 -1
  48. package/dist/src/runtime.js +1 -1
  49. package/dist/src/runtime2.js +1 -1
  50. package/dist/src/runtime4.js +5 -5
  51. package/dist/src/runtime6.js +1 -1
  52. package/dist/src/runtime9.js +1 -1
  53. package/dist/src/screen-recording-resource-recovery.js +1 -1
  54. package/dist/src/screen-recording-runtime.js +1 -1
  55. package/dist/src/screenshot-runtime.js +1 -1
  56. package/dist/src/sdk-batch.js +2 -2
  57. package/dist/src/sdk-remote-config.d.ts +1 -0
  58. package/dist/src/sdk-remote-config.js +1 -1
  59. package/dist/src/selector-runtime.js +1 -1
  60. package/dist/src/session-routing.js +1 -1
  61. package/dist/src/session-snapshot.js +1 -1
  62. package/dist/src/session2.js +5 -5
  63. package/dist/src/simulator.js +1 -1
  64. package/dist/src/snapshot-runtime-binding.js +1 -1
  65. package/dist/src/snapshot-runtime.js +1 -1
  66. package/dist/src/snapshot4.js +1 -1
  67. package/dist/src/src3.js +1 -1
  68. package/dist/src/src4.js +1 -1
  69. package/package.json +1 -1
  70. package/server.json +2 -2
  71. package/android/ime-helper/dist/agent-device-android-ime-helper-0.21.2.apk.sha256 +0 -1
  72. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.21.2.apk.sha256 +0 -1
  73. package/dist/src/config2.js +0 -1
  74. package/dist/src/provider-device-runtime.js +0 -1
@@ -1 +1 @@
1
- import{C as e,D as t}from"./sdk-contracts.js";import{a as n,v as r}from"./sdk-device.js";import{Jt as i}from"./sdk-batch.js";import{d as a}from"./scroll-gesture.js";import{c as o}from"./sdk-remote-config.js";import"./device.js";import{i as s,r as c}from"./device-rotation.js";import{c as l}from"./exec.js";import"./command.js";import{r as u}from"./version.js";import{n as d,r as f,t as p}from"./capabilities.js";import{t as ee}from"./webdriver-source.js";import{t as m}from"./providers.js";import h from"node:path";import te from"node:fs";import g from"node:fs/promises";import{setTimeout as ne}from"node:timers/promises";function re(e,t){let n=e?.bundleId??t?.appIdentifierHint,r=e?.packageName??t?.packageNameHint;return{bundleId:n,packageName:r,appName:e?.appName,launchTarget:ae(e?.launchTarget,n,r)}}function ie(e){return e===`ios`?`xctest`:`android`}function ae(...e){return e.find(e=>e!==void 0)}function oe(e){let t=async(t,n,r,i,a)=>{let o=e.findSessionForDevice(t);if(!o)return;let s=await ce(e,o,t,n,r,i,a);return await o.client.installApp(s?.appReference??r,a),re(s,i)};return Object.freeze({fact:t=>se(e.findSessionForDevice(t)),installApp:t,installInstallablePath:async(e,n,r,i)=>await t(e,``,n,r,i),deployApp:async(e,n,r)=>_(await t(e,n.app,n.appPath,{relaunch:n.replaceExisting,appIdentifierHint:n.app,packageNameHint:n.app},r),n.app),deployMaterializedApp:async(e,n,r)=>_(await t(e,``,n.artifact.installablePath,{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r))})}function se(e){return e?p(e.capabilities,`install`)?Object.freeze({available:!0}):Object.freeze({available:!1,reason:`owner-capability-missing`,hint:f(e.capabilities,`install`)}):Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The WebDriver provider session is no longer active for this device.`})}async function ce(t,n,i,a,o,s,c){if(!p(n.capabilities,`install`))throw new e(`UNSUPPORTED_OPERATION`,f(n.capabilities,`install`),{provider:t.provider,deviceId:i.id,platform:r(i)});let l=n.prepared.uploadApp??t.uploadApp;if(l)return await l({provider:t.provider,lease:n.lease,device:i,app:a,appPath:o,options:s,signal:c})}function _(t,n){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session no longer supports app deployment.`);return{...t.bundleId?{bundleId:t.bundleId}:{},...t.packageName?{packageName:t.packageName}:{},...t.appName?{appName:t.appName}:{},...t.launchTarget??n?{launchTarget:t.launchTarget??n}:{}}}function v(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 le(e){return{provider:e.provider,providerSessionId:e.providerSessionId,status:`unavailable`,cloudArtifacts:[],message:e.error instanceof Error?e.error.message:String(e.error)}}function y(e){return{"x-agent-device-client":`agent-device-cli`,"x-agent-device-version":e}}async function ue(n,r){try{await r()}catch(r){n instanceof e&&(n.details={...n.details,cleanupError:t(r)})}}function de(e,t){return typeof e==`function`?e(t):e}function b(e){return`Basic ${Buffer.from(`${e.username}:${e.accessKey}`).toString(`base64`)}`}function fe(e){let t=0;for(;t<e.length&&e.charCodeAt(t)===47;)t+=1;return t===0?e:e.slice(t)}function pe(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 me(e){if(e.pathname.endsWith(`/`))return e;let t=new URL(e);return t.pathname=`${t.pathname}/`,t}const x=`webdriver_request_timeout`;function S(t){return t instanceof e&&t.details?.reason===x}var he=class{endpoint;headers;requestPolicy;constructor(e){this.endpoint=me(new URL(e.endpoint)),this.headers={...y(e.clientVersion),...e.auth?{Authorization:b(e.auth)}:{},...e.headers},this.requestPolicy={timeoutMs:e.requestPolicy?.timeoutMs??3e4,retryAttempts:e.requestPolicy?.retryAttempts??1,retryDelayMs:e.requestPolicy?.retryDelayMs??250}}async requestValue(e,t,n,r){return await this.requestValueWithRetries(e,t,n,{retryAttempts:r?.retryAttempts??this.requestPolicy.retryAttempts,timeoutMs:r?.timeoutMs??this.requestPolicy.timeoutMs,signal:r?.signal})}async requestValueWithRetries(e,t,n,r){let i;for(let a=0;a<=r.retryAttempts;a+=1)try{return await this.requestValueOnce(e,t,n,r.timeoutMs,r.signal)}catch(e){if(i=e,!ge(e,a,r.retryAttempts,r.signal))throw e;await ne(this.requestPolicy.retryDelayMs,void 0,{signal:r.signal})}throw i}async requestValueOnce(e,t,n,r,i){let{ok:a,status:o,text:s}=await this.fetchWebDriver(e,t,n,r,i),c=s?ve(s):{};if(!a)throw ye(o,c);return _e(c)}async fetchWebDriver(e,t,n,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{let r=await fetch(new URL(fe(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:o});return{ok:r.ok,status:r.status,text:await r.text()}}catch(n){throw a.aborted&&!i?.aborted?be(e,t,r,n):n}}};function ge(e,t,n,r){return!r?.aborted&&xe(e)&&t<n}function _e(e){if(!e||typeof e!=`object`)return e;let t=e;return`value`in t?t.value:e}function ve(t){try{return JSON.parse(t)}catch(n){throw new e(`COMMAND_FAILED`,`WebDriver response was not valid JSON.`,{text:t},n)}}function ye(t,n){let r=n&&typeof n==`object`&&`value`in n?n.value:n,i=r&&typeof r==`object`&&typeof r.message==`string`?r.message:`WebDriver request failed with HTTP ${t}.`;return new e(`COMMAND_FAILED`,i,{status:t,response:n})}function be(t,n,r,i){return new e(`COMMAND_FAILED`,`WebDriver ${t} ${n} timed out after ${r}ms.`,{reason:x,method:t,path:n,timeoutMs:r},i instanceof Error?i:void 0)}function xe(t){if(S(t))return!0;if(t instanceof e){let e=t.details?.status;return typeof e==`number`&&e>=500}return t instanceof TypeError}var Se=class{transport;sessionCreateTimeoutMs;sessionId;constructor(e){this.transport=new he(e),this.sessionCreateTimeoutMs=e.requestPolicy?.sessionCreateTimeoutMs??18e4}async createSession(e,t){let n=we(await this.requestValue(`POST`,`/session`,{capabilities:Ce(e)},{retryAttempts:0,timeoutMs:Oe(this.sessionCreateTimeoutMs,t?.deadline)}));return this.sessionId=n.sessionId,n}async deleteSession(){let e=this.requireSessionId();await this.requestValue(`DELETE`,`/session/${e}`),this.sessionId=void 0}async installApp(e,t){await this.sessionRequest(`POST`,`/appium/device/install_app`,{appPath:e},{signal:t})}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 isKeyboardShown(e){let t;try{t=await this.sessionRequest(`GET`,`/appium/device/is_keyboard_shown`,void 0,{retryAttempts:0,...e===void 0?{}:{timeoutMs:e}})}catch(e){if(O(e))return`unsupported`;throw e}return typeof t==`boolean`?t:`unsupported`}async activeElement(e){let t=e===void 0?void 0:Date.now()+e,n;try{n=De(await this.sessionRequest(`GET`,`/element/active`,void 0,T(t)))}catch(e){if(O(e))return`unsupported`;if(D(e))return`none`;throw e}if(n===void 0)return`unsupported`;try{let e=await this.sessionRequest(`GET`,`/element/${encodeURIComponent(n)}/rect`,void 0,T(t));return{id:n,rect:C(e)}}catch(e){if(O(e))return`unsupported`;if(D(e))return`none`;throw e}}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(t){let n=await this.sessionRequest(`GET`,`/source`,void 0,t);if(typeof n!=`string`)throw new e(`COMMAND_FAILED`,`WebDriver source response was not a string`,{valueType:typeof n});return n}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 g.writeFile(t,Buffer.from(n,`base64`))}async windowRect(){return C(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){return await this.transport.requestValue(e,t,n,r)}};function C(t){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`WebDriver window rect response was empty.`);let n=t,r={x:w(n,`x`),y:w(n,`y`),width:w(n,`width`),height:w(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 w(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}function Ce(e){return`alwaysMatch`in e||`firstMatch`in e?e:{alwaysMatch:e}}function we(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:{}}}const Te=new Set([405,501]),Ee=new Set([`unknown command`,`unknown method`]);function De(e){if(!e||typeof e!=`object`)return;let t=e,n=t[`element-6066-11e4-a52e-4f735466cecf`]??t.ELEMENT;return typeof n==`string`&&n.length>0?n:void 0}function T(e){return e===void 0?{retryAttempts:0}:{retryAttempts:0,timeoutMs:E(e)}}function Oe(e,t){return t===void 0?e:Math.min(e,E(t))}function E(e){return Math.max(0,e-Date.now())}function D(t){return t instanceof e&&k(t).toLowerCase()===`no such element`}function O(t){if(!(t instanceof e))return!1;let n=t.details?.status;return typeof n==`number`&&Te.has(n)?!0:Ee.has(k(t).toLowerCase())}function k(e){let t=e.details?.response,n=t&&typeof t==`object`?t.value:void 0,r=n&&typeof n==`object`?n.error:void 0;return typeof r==`string`?r:``}function A(e,t){return{type:`pointer`,id:e,parameters:{pointerType:`touch`},actions:t}}async function ke(e){return j(ee(e,`android`).nodes)}function Ae(e){return j(ee(e).nodes)}function j(e){let t=e.flatMap(e=>je(e)&&Me(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 je(e){let t=e.type?.toLowerCase()??``;return e.visibleToUser!==!1&&(t.includes(`scrollview`)||t.includes(`listview`)||t.includes(`recyclerview`))}function Me(e){return!!e&&e.width>=50&&e.height>=50}async function Ne(t,n,r){let i=[];for(let e of n===`android`?[`rotation`,`orientation`]:[`orientation`,`rotation`])try{await Re(t,e,r);return}catch(t){if(!Ie(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 Pe=new Set([`unknown command`,`unknown method`]),Fe=new Set([404,405]);function Ie(t){if(!(t instanceof e)||t.code===`SESSION_NOT_FOUND`)return!1;let n=Le(t.details?.response);if(n)return Pe.has(n);let r=t.details?.status;return typeof r==`number`&&Fe.has(r)}function Le(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 Re(e,t,n){if(t===`rotation`){await e.setRotation(s(n));return}await e.setOrientation(c(n))}const M=1500;function ze(e){return new Promise(t=>setTimeout(t,e))}function N(t,n,r){return new e(`COMMAND_FAILED`,`fill tapped (${t}, ${n}) but ${r}`,{reason:`text_entry_focus_not_observed`,x:t,y:n,hint:`The tap most likely missed the field. Re-check the target with snapshot -i and fill the element it reports, rather than retrying the same coordinates.`})}function Be(t,n){return new e(`COMMAND_FAILED`,`fill tapped (${t}, ${n}) but this driver reports neither the focused element nor keyboard state, so the text was not sent`,{reason:`text_entry_focus_unobservable`,x:t,y:n,hint:`This provider cannot confirm a field took focus. Use press <target> followed by type <text> to enter it anyway, accepting that nothing witnesses which field receives the keys.`})}function Ve(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function He(e){return new Ue(e.client,e.backend,e.capabilities,e.targetId)}var Ue=class{client;backend;capabilities;targetId;constructor(e,t,n,r){this.client=e,this.backend=t,this.capabilities=n,this.targetId=r}async open(e,t){if(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(){await this.client.executeScript(`mobile: activateApp`,[{}])}async close(e){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(t,n,r,i){if(this.requireSupport(`fill`),r.length===0)throw new e(`UNSUPPORTED_OPERATION`,`fill with empty text (clear field) is not supported on the webdriver backend`,{hint:`Use a visible clear/reset control in the app, or fill the field with the intended replacement text directly.`});let a=await this.readTextEntryState();await this.tap(t,n);let o=await this.awaitTextEntryReadiness(a,t,n);return await this.type(r),{backend:`webdriver`,x:t,y:n,text:r,textEntryReadiness:o}}async scroll(e,t){this.requireSupport(`scroll`);let n=t?.durationMs??350;await this.client.hideKeyboard().catch(()=>void 0);let r=await this.scrollGestureFrame(),i=a({direction:e,amount:t?.amount,pixels:t?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o={...i,x1:i.x1+r.x,y1:i.y1+r.y,x2:i.x2+r.x,y2:i.y2+r.y};return await this.swipe(o.x1,o.y1,o.x2,o.y2,n),{backend:`webdriver`,...o,distance:i.pixels,durationMs:n}}async gestureViewport(){return await this.scrollGestureFrame()}async performGesture(e){return this.requireSupport(Ge(e)),await this.client.performActions(e.pointers.map(e=>A(`gesture-pointer-${e.pointerId}`,We(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`),await this.captureSource(e?.signal)}async captureSource(e){let t=await this.readSource(e);if(this.backend===`xctest`){let{acquireWebDriverIosSnapshot:e}=await import(`./webdriver-ios-snapshot.js`);return e(t,this.targetId)}let{parseWebDriverSourceFacts:n}=await import(`./webdriver-source.js`).then(e=>e.n);return{backend:`android`,producer:`appium-source`,nodes:n(t,`android`).nodes}}async readSource(e){try{return await this.client.source(e===void 0?{}:{signal:e})}catch(e){throw S(e)?Ke(e):e}}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 Ne(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 readAlert(){this.unsupported(`alert`)}async awaitAlert(){this.unsupported(`alert`)}async acceptAlert(){this.unsupported(`alert`)}async dismissAlert(){this.unsupported(`alert`)}async awaitTextEntryReadiness(e,t,n){let r=e.keyboard,i=Date.now()+2e3,a=e.focusedElementId,o=await this.pollWithinBudget(i,async e=>{let r=await this.client.activeElement(e);return r===`unsupported`?`abandon`:r===`none`?`retry`:r.id!==a||Ve(r.rect,t,n)?`satisfied`:`retry`});if(o===`satisfied`)return`focused-element`;if(o===`expired`)throw N(t,n,`nothing there took text-entry focus, so the text was not sent`);if(r===`unsupported`)throw Be(t,n);if(r)throw N(t,n,`the keyboard was already up and this driver cannot report which field holds focus, so the text was not sent`);if(await this.pollWithinBudget(i,async e=>await this.client.isKeyboardShown(e)===!0?`satisfied`:`retry`)===`satisfied`)return`keyboard-shown`;throw N(t,n,`no keyboard appeared, so the text was not sent`)}async readTextEntryState(){let[e,t]=await Promise.all([this.client.isKeyboardShown(M),this.client.activeElement(M)]);return{keyboard:e,focusedElementId:t===`none`||t===`unsupported`?void 0:t.id}}async pollWithinBudget(e,t){let n=!1,r;for(;;){let i=e-Date.now();if(i<=0)break;try{let e=await t(Math.min(M,i));if(n=!0,e!==`retry`)return e}catch(e){r=e}let a=e-Date.now();if(a<=0)break;await ze(Math.min(100,a))}if(!n&&r!==void 0)throw r;return`expired`}async pointerGesture(e,t){await this.client.performActions([A(e,t)]),await this.client.releaseActions().catch(()=>void 0)}async scrollGestureFrame(){return await this.client.source().then(e=>this.backend===`xctest`?Ae(e):ke(e)).catch(()=>void 0)||await this.client.windowRect()}requireSupport(e){p(this.capabilities,e)||this.unsupported(e)}unsupported(t){throw new e(`UNSUPPORTED_OPERATION`,f(this.capabilities,t),{provider:this.capabilities.provider,platform:this.capabilities.platform,operation:t})}};function We(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 Ge(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 Ke(t){return new e(`COMMAND_FAILED`,`The cloud driver did not finish reading the screen in its budget.`,{...t.details,hint:`A screen that never goes idle (looping video, live ticker, continuous animation) gives the driver no moment to read the UI tree. This read has the transport's own budget and does not grow with --timeout; take a screenshot, or drive the screen from refs an earlier snapshot already captured.`},t)}var qe=class{sessionsByLeaseId=new Map;ownedDeviceIds=new Set;releasedProviderSessionIdsByLeaseId=new Map;options;constructor(e){this.options=e}ownsDevice(e){return this.ownedDeviceIds.has(e.id)}findSessionForDevice(e){return[...this.sessionsByLeaseId.values()].find(t=>t.device.id===e.id)}findSessionForLease(e){return this.sessionsByLeaseId.get(e)}getInteractor(e){return this.findSessionForDevice(e)?.interactor}heartbeat(e){if(e.leaseProvider===this.options.provider&&this.sessionsByLeaseId.has(e.leaseId))return{provider:this.options.provider}}async allocate(e,t){if(e.leaseProvider!==this.options.provider)return;if(this.sessionsByLeaseId.has(e.leaseId))return this.heartbeat(e);let n=await this.prepareSession(e,t),r=new Se({clientVersion:this.options.clientVersion,endpoint:n.endpoint,auth:n.auth,headers:n.headers,requestPolicy:this.options.requestPolicy}),i=await this.createSessionWithPreparedCleanup(r,n,e,t),a=this.deviceForLease(e,n),o=n.providerSessionId??i.sessionId,s=d({provider:this.options.provider,platform:n.platform,overrides:this.options.capabilityOverrides});return this.sessionsByLeaseId.set(e.leaseId,Object.freeze({lease:e,device:a,client:r,prepared:n,capabilities:s,webDriverSessionId:i.sessionId,providerSessionId:o,interactor:He({client:r,backend:ie(n.platform),capabilities:s,targetId:a.id})})),this.ownedDeviceIds.add(a.id),{provider:this.options.provider,deviceId:a.id,sessionId:i.sessionId,providerSessionId:o,capabilities:s,...n.providerData}}async release(e){if(e.leaseProvider!==this.options.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.options.provider,providerSessionId:t.providerSessionId,...n.cleanup,...n.warnings.length>0?{warnings:n.warnings}:{},...r?{cloudArtifacts:r}:{}}}async listCloudArtifacts(e){if(e.provider!==this.options.provider)return;let t=this.sessionsByLeaseId.get(e.leaseId??``);return t?await this.listActiveCloudArtifacts(t,e.providerSessionId):await this.listReleasedCloudArtifacts(e)}async listActiveCloudArtifacts(e,t){if(!(t&&t!==e.providerSessionId))return await this.safeListArtifacts(e)}async listReleasedCloudArtifacts(e){let t=this.releasedProviderSessionIdsByLeaseId.get(e.leaseId??``);if(!(!t||!this.options.listArtifacts)&&!(e.providerSessionId&&e.providerSessionId!==t))return await this.options.listArtifacts({provider:this.options.provider,providerSessionId:t})}async shutdown(){await Promise.allSettled([...this.sessionsByLeaseId.values()].map(async e=>await this.closeSession(e))),this.sessionsByLeaseId.clear(),this.ownedDeviceIds.clear()}async createSessionWithPreparedCleanup(e,t,n,r){try{return await e.createSession(t.webdriverCapabilities,{deadline:r?.deadline})}catch(e){let r=S(e)?Je(e,this.options.provider,n,t):e;throw await ue(r,()=>t.cleanup?.()),r}}async prepareSession(e,t){let n=this.baseSessionForLease(e);return this.options.prepareSession?await this.options.prepareSession({lease:e,req:t,base:n}):n}baseSessionForLease(e){let t=typeof this.options.webdriverCapabilities==`function`?this.options.webdriverCapabilities(e):this.options.webdriverCapabilities??{};return{provider:this.options.provider,endpoint:this.options.endpoint,platform:this.options.platform,deviceName:this.options.deviceName,auth:this.options.auth,headers:this.options.headers,webdriverCapabilities:P(this.options.platform,this.options.deviceName,t)}}deviceForLease(e,t){return{...n(t.platform),...t.platform===`ios`?{appleOs:`ios`}:{},id:t.deviceId??this.options.deviceId?.(e)??`${this.options.provider}:${t.platform}:${e.leaseId}`,name:t.deviceName,kind:`device`,target:`mobile`,booted:!0}}async closeSession(e){let n=[],r;try{await e.client.deleteSession()}catch(e){n.push({code:`WEBDRIVER_SESSION_DELETE_FAILED`,message:t(e)})}try{r=await e.prepared.cleanup?.()}catch(e){n.push({code:`PROVIDER_CLEANUP_FAILED`,message:t(e)})}return{cleanup:r,warnings:n}}async safeListArtifacts(e){let t=e.prepared.listArtifacts??this.options.listArtifacts;if(t)try{return await t({provider:this.options.provider,lease:e.lease,device:e.device,webDriverSessionId:e.webDriverSessionId,providerSessionId:e.providerSessionId})}catch(t){return le({provider:this.options.provider,providerSessionId:e.providerSessionId,error:t})}}};function P(e,t,n={}){return{platformName:e===`ios`?`iOS`:`Android`,"appium:deviceName":t,...n}}function Je(t,n,r,i){let a=t.details?.timeoutMs;return new e(`COMMAND_FAILED`,`${n} did not create the WebDriver session within ${String(a)}ms.`,{reason:`provider_session_create_timeout`,provider:n,leaseId:r.leaseId,runId:r.runId,timeoutMs:a,...i.providerSessionId?{providerSessionId:i.providerSessionId}:{},hint:`${n} may still finish creating the session after agent-device stopped waiting, and that session would keep billing until the provider reaps it. Before retrying, check ${n} for a running session created for lease ${r.leaseId} (run ${r.runId}) and stop it.`},t)}function F(e){return new Ye(e)}var Ye=class{provider;owner;leaseLifecycle;cloudArtifacts;deviceInventoryProvider;capabilities;platformRuntimeModule;sessions;deployment;constructor(e){this.provider=e.provider,this.owner=i(e.provider,e.platform),this.capabilities=d({provider:e.provider,platform:e.platform,overrides:e.capabilityOverrides}),this.sessions=new qe(e),this.deployment=oe({provider:e.provider,uploadApp:e.uploadApp,findSessionForDevice:e=>this.sessions.findSessionForDevice(e)}),this.platformRuntimeModule=Object.freeze({owner:this.owner,loadRuntime:async e=>await this.loadRuntime(e)}),this.leaseLifecycle={allocate:async(e,t)=>await this.sessions.allocate(e,t),heartbeat:async e=>this.sessions.heartbeat(e),release:async e=>await this.sessions.release(e)},this.cloudArtifacts={listCloudArtifacts:async e=>await this.sessions.listCloudArtifacts(e)},this.deviceInventoryProvider=async e=>{if(e.leaseProvider!==this.provider)return null;if(!e.leaseId)return[];let t=this.sessions.findSessionForLease(e.leaseId);return t?[t.device]:[]}}async loadRuntime(e){let{createWebDriverPlatformRuntimeOwner:t}=await import(`./platform-runtime2.js`);return t({host:e,owner:this.owner,ownsDevice:e=>this.ownsDevice(e),isSessionActive:e=>this.sessions.findSessionForDevice(e)!==void 0,deployment:this.deployment,capabilities:this.capabilities,snapshotAvailable:this.capabilities.operations.snapshot.support!==`unsupported`,screenshotAvailable:this.capabilities.operations.screenshot.support!==`unsupported`,getInteractor:e=>this.getInteractor(e)})}ownsDevice(e){return this.sessions.ownsDevice(e)}getInteractor(e){return this.sessions.getInteractor(e)}async installApp(e,t,n,r){return await this.deployment.installApp(e,t,n,r)}async installInstallablePath(e,t,n){return await this.deployment.installInstallablePath(e,t,n)}async shutdown(){await this.sessions.shutdown()}};async function I(e,t,n){return t?v({provider:e,providerSessionId:t,artifacts:(await Promise.all([n.listArtifacts(t,`FILE`),n.listArtifacts(t,`LOG`)])).flat().flatMap(n=>Ze(e,t,n)),pendingMessage:`AWS Device Farm artifacts are not ready yet.`}):void 0}function Xe(e){if(!e||typeof e!=`object`)return[];let t=e.artifacts;return Array.isArray(t)?t:[]}function Ze(e,t,n){let r=n.url;return typeof r!=`string`||r.length===0?[]:[{provider:e,providerSessionId:t,kind:Qe(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 Qe(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`}}m.awsDeviceFarm;const $e={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 L(e){let t=R(e);return{createRemoteAccessSession:async e=>z(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=>z(await t(`get-remote-access-session`,[`--arn`,e])),stopRemoteAccessSession:async e=>z(await t(`stop-remote-access-session`,[`--arn`,e])),listArtifacts:async(e,n)=>Xe(await t(`list-artifacts`,[`--arn`,e,`--type`,n]))}}function et(t){return async({lease:n,req:r,base:i})=>{let a=await t.client.createRemoteAccessSession({projectArn:t.projectArn,deviceArn:t.deviceArn,appArn:t.appArn,name:de(t.sessionName,n)??`agent-device-${n.leaseId}`,interactionMode:t.interactionMode,configuration:t.configuration}),o,s;try{if(o=await rt(a.arn,t,r),s=tt(o),!s)throw new e(`COMMAND_FAILED`,`AWS Device Farm did not expose a WebDriver endpoint.`,{sessionArn:o.arn,status:o.status})}catch(e){throw await ue(e,()=>t.client.stopRemoteAccessSession(a.arn)),e}let c=o.device?.name??t.deviceName,l=typeof t.webdriverCapabilities==`function`?t.webdriverCapabilities(n):t.webdriverCapabilities??{},u=t.platform===`android`?{"appium:autoLaunch":!1}:{};return{...i,endpoint:s,platform:t.platform,deviceName:c,webdriverCapabilities:P(t.platform,c,{...u,...l}),cleanup:async()=>(await t.client.stopRemoteAccessSession(o.arn),{awsDeviceFarmSessionArn:o.arn}),providerSessionId:o.arn,providerData:{awsDeviceFarmSessionArn:o.arn}}}}function tt(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?nt(n):void 0}function nt(e){return/^https?:\/\//i.test(e)?e:`http://${e}`}async function rt(t,n,r){let i=n.pollIntervalMs??5e3,a=Date.now(),o=r?.deadline??a+(n.startupTimeoutMs??12e4),s=r?.signal,c=await n.client.getRemoteAccessSession(t);for(;Date.now()<o;){if(s?.throwIfAborted(),c.status===`RUNNING`)return c;at(c),await ne(i,void 0,{signal:s}).catch(()=>s?.throwIfAborted()),c=await n.client.getRemoteAccessSession(t)}throw new e(`COMMAND_FAILED`,`Timed out waiting for AWS Device Farm remote access.`,{sessionArn:t,status:c.status,result:c.result,timeoutMs:o-a})}const it=new Set([`ERRORED`,`STOPPED`,`COMPLETED`]);function at(t){if(!(!t.status||!it.has(t.status)))throw new e(`COMMAND_FAILED`,`AWS Device Farm remote access session did not start.`,{sessionArn:t.arn,status:t.status,result:t.result})}async function ot(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 R(e){let t=e.region?[`--region`,e.region]:[],n=e.awsCommand??`aws`;return async(r,i)=>await ot(e.runHostCommand,n,[`devicefarm`,r,...t,...i,`--output`,`json`])}function z(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 B=[{field:`providerDeviceOrientation`,capability:`deviceOrientation`,flag:`--provider-device-orientation`,type:`enum`,enumValues:o},{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 st(e,t){pt(e);let n={};for(let r of B){let i=e[r.field];i!==void 0&&i!==!1&&i!==``&&(ft(r,t),n[r.capability]=r.type!==`negated-boolean`&&i)}return n}function ct(e){return B.filter(t=>{let n=e?.[t.field];return n!==void 0&&n!==!1&&n!==``}).map(e=>e.flag)}function V(t,n){let r=ct(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 lt(e){let t={};for(let n of B){let r=e?.[n.field];if(n.type===`negated-boolean`){r===!0&&(t.providerNoResignApp=!0);continue}typeof r==`string`&&r.length!==0&&ut(t,n,r)}return t}function ut(e,t,n){if(t.field===`providerDeviceOrientation`){e.providerDeviceOrientation=dt(t,n);return}t.field!==`providerNoResignApp`&&(e[t.field]=n)}function dt(t,n){let r=o.find(e=>e===n);if(r)return r;throw new e(`INVALID_ARGS`,`Invalid ${t.flag} value: ${n}.`,{hint:`Use ${o.join(`|`)}.`,flag:t.flag,capability:t.capability})}function ft(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 pt(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 mt={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 H(e,t,n){return t?v({provider:e,providerSessionId:t,artifacts:yt(e,t,await vt(t,n)),pendingMessage:`BrowserStack artifacts are not ready yet.`}):void 0}async function U(t,n,r){r?.throwIfAborted();let i=await g.readFile(t),a=new FormData;a.set(`file`,new Blob([i]),h.basename(t));let o=await fetch(n.endpoint??`https://api-cloud.browserstack.com/app-automate/upload`,{method:`POST`,headers:{...y(n.clientVersion),Authorization:b(n)},body:a,signal:r}),s=await o.json(),c=bt(s);if(!o.ok||!c)throw new e(`COMMAND_FAILED`,`BrowserStack app upload failed.`,{status:o.status,response:s});return c}function ht(e){return async({appPath:t,options:n,signal:r})=>({appReference:await U(t,e,r),bundleId:n?.appIdentifierHint,packageName:n?.packageNameHint,launchTarget:n?.appIdentifierHint??n?.packageNameHint})}function gt(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??{},..._t(t)}}}function _t(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}async function vt(t,n){let r=new URL(`${pe(String(n.endpoint??`https://api-cloud.browserstack.com/app-automate/sessions`))}/${t}.json`),i=await fetch(r,{headers:{...y(n.clientVersion),Authorization:b(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 yt(e,t,n){return[W(e,t,n,`video_url`,`video`,`Session video`),W(e,t,n,`appium_logs_url`,`appium-log`,`Appium logs`),W(e,t,n,`device_logs_url`,`device-log`,`Device logs`),W(e,t,n,`browser_url`,`provider-session`,`BrowserStack dashboard`),W(e,t,n,`public_url`,`provider-session`,`Public session link`)].filter(e=>e!==void 0)}function W(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 bt(e){if(!e||typeof e!=`object`)return;let t=e.app_url;return typeof t==`string`?t:void 0}function G(e){return/^arn:[^:]+:devicefarm:([^:]+):/.exec(e)?.[1]}async function xt(t,n){let r=R({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=K(i,`project`),c=K(a,`device`),l=Ct(c.platform);if(l!==t.platform)throw new e(`INVALID_ARGS`,`AWS Device Farm device "${q(c.name)??t.deviceArn}" is ${l}, not ${t.platform}.`);let u=t.appArn?St(K(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:q(s.name),reference:t.projectArn},device:{status:`verified`,name:q(c.name)??t.deviceArn,reference:t.deviceArn,platform:l,osVersion:q(c.os),availability:q(c.availability)},app:u}}function St(t,n){let r=q(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=q(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:q(t.name),reference:n.appArn}}function K(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 Ct(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 q(e){return typeof e==`string`&&e.length>0?e:void 0}async function wt(t,n){let r={username:t.username,accessKey:t.accessKey},i=Dt(await J(t.devicesEndpoint??`https://api-cloud.browserstack.com/app-automate/devices.json`,r,n)).find(e=>e.device===t.deviceName&&e.os.toLowerCase()===t.platform&&Et(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 Tt(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 Tt(e,t,n){let{app:r}=e;if(r.startsWith(`bs://`)){let i=Ot(await J(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:h.basename(r),reference:r,message:`Local app artifact is ready and will be uploaded when creating the session.`}}async function J(t,n,r){try{let i=await fetch(t,{headers:{...y(r),Authorization:b(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 Et(e,t){let n=e=>e.replace(/(?:\.0)+$/,``);return n(e)===n(t)}function Dt(t){if(!Array.isArray(t))throw new e(`COMMAND_FAILED`,`BrowserStack device verification response was not a list.`);return t.flatMap(e=>{let t=Y(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 Ot(t){let n=Y(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=Y(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 Y(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}async function kt(e,t){return e.provider===`browserstack`?await wt(e,t.clientVersion):await xt(e,t.runHostCommand)}function At(e){return[{provider:m.browserStack,createRuntime:t=>F({clientVersion:e.clientVersion,provider:m.browserStack,platform:`android`,deviceName:`BrowserStack device`,endpoint:t.BROWSERSTACK_WEBDRIVER_ENDPOINT??`https://hub-cloud.browserstack.com/wd/hub/`,capabilityOverrides:mt,listArtifacts:async({provider:n,providerSessionId:r})=>{let i=$(t,`BROWSERSTACK_USERNAME`,`BrowserStack artifact lookup`),a=$(t,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack artifact lookup`);return await H(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=X(n,`BrowserStack`),o=$(t,`BROWSERSTACK_USERNAME`,`BrowserStack`),s=$(t,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack`),c=Nt(a,`BrowserStack`),l=Z(a,`device`,`BrowserStack requires --device <name>.`),u=Z(a,`providerOsVersion`,`BrowserStack requires --provider-os-version <version>.`),d=await jt({clientVersion:e.clientVersion,app:Z(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,signal:a.signal});return{...i,platform:c,deviceName:l,auth:{username:o,accessKey:s},uploadApp:ht({clientVersion:e.clientVersion,username:o,accessKey:s,endpoint:t.BROWSERSTACK_APP_UPLOAD_ENDPOINT??`https://api-cloud.browserstack.com/app-automate/upload`}),webdriverCapabilities:gt({deviceName:l,osVersion:u,app:d,projectName:Q(a,`providerProject`),buildName:Q(a,`providerBuild`)??r.runId,sessionName:Q(a,`providerSessionName`)??r.leaseId,deviceFeatures:st(lt(a.flags),c),configured:P(c,l)})}}}),listArtifactsFromEnv:async(t,n)=>{let r=$(n,`BROWSERSTACK_USERNAME`,`BrowserStack artifact lookup`),i=$(n,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack artifact lookup`);return await H(m.browserStack,t,{clientVersion:e.clientVersion,username:r,accessKey:i,endpoint:n.BROWSERSTACK_SESSION_DETAILS_ENDPOINT})}},{provider:m.awsDeviceFarm,createRuntime:t=>F({clientVersion:e.clientVersion,provider:m.awsDeviceFarm,endpoint:`http://127.0.0.1/`,platform:`android`,deviceName:`AWS Device Farm device`,capabilityOverrides:$e,listArtifacts:async({provider:n,providerSessionId:r})=>await I(n,r,L({runHostCommand:e.runHostCommand,region:t.AWS_REGION??t.AWS_DEFAULT_REGION??G(r??``)})),prepareSession:async({req:n,lease:r,base:i})=>{let a=X(n,`AWS Device Farm`);V(a.flags,m.awsDeviceFarm);let o=Nt(a,`AWS Device Farm`);return await et({client:L({runHostCommand:e.runHostCommand,region:Q(a,`awsRegion`)??t.AWS_REGION??t.AWS_DEFAULT_REGION}),projectArn:Pt(a,t,`awsProjectArn`,`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`),deviceArn:Pt(a,t,`awsDeviceArn`,`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`),appArn:Q(a,`awsAppArn`)??t.AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN??t.AWS_DEVICE_FARM_APP_ARN,platform:o,deviceName:Q(a,`device`)??`AWS Device Farm device`,sessionName:Q(a,`providerSessionName`)??r.leaseId,interactionMode:Ft(a)})({lease:r,req:n,base:i})}}),listArtifactsFromEnv:async(t,n)=>{let r=L({runHostCommand:e.runHostCommand,region:n.AWS_REGION??n.AWS_DEFAULT_REGION??G(t)});return await I(m.awsDeviceFarm,t,r)}}]}async function jt(t){if(Mt(t.app))return t.app;let n=h.resolve(t.cwd??process.cwd(),t.app);if(!te.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 U(n,{clientVersion:t.clientVersion,username:t.username,accessKey:t.accessKey,endpoint:t.uploadEndpoint},t.signal)}function Mt(e){return e.startsWith(`bs://`)||/^https?:\/\//.test(e)}function X(t,n){if(t)return t;throw new e(`INVALID_ARGS`,`${n} lease allocation requires provider profile flags on the request.`)}function Nt(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 Z(t,n,r){let i=Q(t,n);if(i)return i;throw new e(`INVALID_ARGS`,r)}function Q(e,t){let n=e.flags?.[t];return typeof n==`string`&&n.length>0?n:void 0}function $(t,n,r){let i=t[n];if(i)return i;throw new e(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function Pt(t,n,r,i,a){let o=Q(t,r)??n[i]??n[a];if(o)return o;throw new e(`INVALID_ARGS`,`AWS Device Farm requires --${It(String(r))} or ${a}.`)}function Ft(e){let t=Q(e,`awsInteractionMode`);if(t===`INTERACTIVE`||t===`NO_VIDEO`||t===`VIDEO_ONLY`)return t}function It(e){return e.replaceAll(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function Lt(e){let t=At(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 kt(t,e)}}const Rt=Lt({clientVersion:u(),runHostCommand:async(e,t)=>({stdout:(await l(e,[...t],{maxBuffer:10485760,timeoutMs:3e4})).stdout})});export{G as n,V as r,Rt as t};
1
+ import{C as e,D as t}from"./sdk-contracts.js";import{a as n,v as r}from"./sdk-device.js";import{Jt as i}from"./sdk-batch.js";import{d as a}from"./scroll-gesture.js";import{c as o}from"./sdk-remote-config.js";import"./device.js";import{i as s,r as c}from"./device-rotation.js";import{c as l}from"./exec.js";import"./command.js";import{r as u}from"./version.js";import{n as d,r as f,t as p}from"./capabilities.js";import{t as ee}from"./webdriver-source.js";import{t as m}from"./providers.js";import h from"node:path";import te from"node:fs";import g from"node:fs/promises";import{setTimeout as ne}from"node:timers/promises";function re(e,t){let n=e?.bundleId??t?.appIdentifierHint,r=e?.packageName??t?.packageNameHint;return{bundleId:n,packageName:r,appName:e?.appName,launchTarget:ae(e?.launchTarget,n,r)}}function ie(e){return e===`ios`?`xctest`:`android`}function ae(...e){return e.find(e=>e!==void 0)}function oe(e){let t=async(t,n,r,i,a)=>{let o=e.findSessionForDevice(t);if(!o)return;let s=await ce(e,o,t,n,r,i,a);return await o.client.installApp(s?.appReference??r,a),re(s,i)};return Object.freeze({fact:t=>se(e.findSessionForDevice(t)),installApp:t,installInstallablePath:async(e,n,r,i)=>await t(e,``,n,r,i),deployApp:async(e,n,r)=>_(await t(e,n.app,n.appPath,{relaunch:n.replaceExisting,appIdentifierHint:n.app,packageNameHint:n.app},r),n.app),deployMaterializedApp:async(e,n,r)=>_(await t(e,``,n.artifact.installablePath,{appIdentifierHint:n.artifact.bundleId,packageNameHint:n.artifact.packageName},r))})}function se(e){return e?p(e.capabilities,`install`)?Object.freeze({available:!0}):Object.freeze({available:!1,reason:`owner-capability-missing`,hint:f(e.capabilities,`install`)}):Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The WebDriver provider session is no longer active for this device.`})}async function ce(t,n,i,a,o,s,c){if(!p(n.capabilities,`install`))throw new e(`UNSUPPORTED_OPERATION`,f(n.capabilities,`install`),{provider:t.provider,deviceId:i.id,platform:r(i)});let l=n.prepared.uploadApp??t.uploadApp;if(l)return await l({provider:t.provider,lease:n.lease,device:i,app:a,appPath:o,options:s,signal:c})}function _(t,n){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The WebDriver provider session no longer supports app deployment.`);return{...t.bundleId?{bundleId:t.bundleId}:{},...t.packageName?{packageName:t.packageName}:{},...t.appName?{appName:t.appName}:{},...t.launchTarget??n?{launchTarget:t.launchTarget??n}:{}}}function v(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 le(e){return{provider:e.provider,providerSessionId:e.providerSessionId,status:`unavailable`,cloudArtifacts:[],message:e.error instanceof Error?e.error.message:String(e.error)}}function y(e){return{"x-agent-device-client":`agent-device-cli`,"x-agent-device-version":e}}async function ue(n,r){try{await r()}catch(r){n instanceof e&&(n.details={...n.details,cleanupError:t(r)})}}function de(e,t){return typeof e==`function`?e(t):e}function b(e){return`Basic ${Buffer.from(`${e.username}:${e.accessKey}`).toString(`base64`)}`}function fe(e){let t=0;for(;t<e.length&&e.charCodeAt(t)===47;)t+=1;return t===0?e:e.slice(t)}function pe(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 me(e){if(e.pathname.endsWith(`/`))return e;let t=new URL(e);return t.pathname=`${t.pathname}/`,t}const x=`webdriver_request_timeout`;function S(t){return t instanceof e&&t.details?.reason===x}var he=class{endpoint;headers;requestPolicy;constructor(e){this.endpoint=me(new URL(e.endpoint)),this.headers={...y(e.clientVersion),...e.auth?{Authorization:b(e.auth)}:{},...e.headers},this.requestPolicy={timeoutMs:e.requestPolicy?.timeoutMs??3e4,retryAttempts:e.requestPolicy?.retryAttempts??1,retryDelayMs:e.requestPolicy?.retryDelayMs??250}}async requestValue(e,t,n,r){return await this.requestValueWithRetries(e,t,n,{retryAttempts:r?.retryAttempts??this.requestPolicy.retryAttempts,timeoutMs:r?.timeoutMs??this.requestPolicy.timeoutMs,signal:r?.signal})}async requestValueWithRetries(e,t,n,r){let i;for(let a=0;a<=r.retryAttempts;a+=1)try{return await this.requestValueOnce(e,t,n,r.timeoutMs,r.signal)}catch(e){if(i=e,!ge(e,a,r.retryAttempts,r.signal))throw e;await ne(this.requestPolicy.retryDelayMs,void 0,{signal:r.signal})}throw i}async requestValueOnce(e,t,n,r,i){let{ok:a,status:o,text:s}=await this.fetchWebDriver(e,t,n,r,i),c=s?ve(s):{};if(!a)throw ye(o,c);return _e(c)}async fetchWebDriver(e,t,n,r,i){let a=AbortSignal.timeout(r),o=i?AbortSignal.any([i,a]):a;try{let r=await fetch(new URL(fe(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:o});return{ok:r.ok,status:r.status,text:await r.text()}}catch(n){throw a.aborted&&!i?.aborted?be(e,t,r,n):n}}};function ge(e,t,n,r){return!r?.aborted&&xe(e)&&t<n}function _e(e){if(!e||typeof e!=`object`)return e;let t=e;return`value`in t?t.value:e}function ve(t){try{return JSON.parse(t)}catch(n){throw new e(`COMMAND_FAILED`,`WebDriver response was not valid JSON.`,{text:t},n)}}function ye(t,n){let r=n&&typeof n==`object`&&`value`in n?n.value:n,i=r&&typeof r==`object`&&typeof r.message==`string`?r.message:`WebDriver request failed with HTTP ${t}.`;return new e(`COMMAND_FAILED`,i,{status:t,response:n})}function be(t,n,r,i){return new e(`COMMAND_FAILED`,`WebDriver ${t} ${n} timed out after ${r}ms.`,{reason:x,method:t,path:n,timeoutMs:r},i instanceof Error?i:void 0)}function xe(t){if(S(t))return!0;if(t instanceof e){let e=t.details?.status;return typeof e==`number`&&e>=500}return t instanceof TypeError}var Se=class{transport;sessionCreateTimeoutMs;sessionId;constructor(e){this.transport=new he(e),this.sessionCreateTimeoutMs=e.requestPolicy?.sessionCreateTimeoutMs??18e4}async createSession(e,t){let n=we(await this.requestValue(`POST`,`/session`,{capabilities:Ce(e)},{retryAttempts:0,timeoutMs:Oe(this.sessionCreateTimeoutMs,t?.deadline)}));return this.sessionId=n.sessionId,n}async deleteSession(){let e=this.requireSessionId();await this.requestValue(`DELETE`,`/session/${e}`),this.sessionId=void 0}async installApp(e,t){await this.sessionRequest(`POST`,`/appium/device/install_app`,{appPath:e},{signal:t})}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 isKeyboardShown(e){let t;try{t=await this.sessionRequest(`GET`,`/appium/device/is_keyboard_shown`,void 0,{retryAttempts:0,...e===void 0?{}:{timeoutMs:e}})}catch(e){if(O(e))return`unsupported`;throw e}return typeof t==`boolean`?t:`unsupported`}async activeElement(e){let t=e===void 0?void 0:Date.now()+e,n;try{n=De(await this.sessionRequest(`GET`,`/element/active`,void 0,T(t)))}catch(e){if(O(e))return`unsupported`;if(D(e))return`none`;throw e}if(n===void 0)return`unsupported`;try{let e=await this.sessionRequest(`GET`,`/element/${encodeURIComponent(n)}/rect`,void 0,T(t));return{id:n,rect:C(e)}}catch(e){if(O(e))return`unsupported`;if(D(e))return`none`;throw e}}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(t){let n=await this.sessionRequest(`GET`,`/source`,void 0,t);if(typeof n!=`string`)throw new e(`COMMAND_FAILED`,`WebDriver source response was not a string`,{valueType:typeof n});return n}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 g.writeFile(t,Buffer.from(n,`base64`))}async windowRect(){return C(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){return await this.transport.requestValue(e,t,n,r)}};function C(t){if(!t||typeof t!=`object`)throw new e(`COMMAND_FAILED`,`WebDriver window rect response was empty.`);let n=t,r={x:w(n,`x`),y:w(n,`y`),width:w(n,`width`),height:w(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 w(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}function Ce(e){return`alwaysMatch`in e||`firstMatch`in e?e:{alwaysMatch:e}}function we(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:{}}}const Te=new Set([405,501]),Ee=new Set([`unknown command`,`unknown method`]);function De(e){if(!e||typeof e!=`object`)return;let t=e,n=t[`element-6066-11e4-a52e-4f735466cecf`]??t.ELEMENT;return typeof n==`string`&&n.length>0?n:void 0}function T(e){return e===void 0?{retryAttempts:0}:{retryAttempts:0,timeoutMs:E(e)}}function Oe(e,t){return t===void 0?e:Math.min(e,E(t))}function E(e){return Math.max(0,e-Date.now())}function D(t){return t instanceof e&&k(t).toLowerCase()===`no such element`}function O(t){if(!(t instanceof e))return!1;let n=t.details?.status;return typeof n==`number`&&Te.has(n)?!0:Ee.has(k(t).toLowerCase())}function k(e){let t=e.details?.response,n=t&&typeof t==`object`?t.value:void 0,r=n&&typeof n==`object`?n.error:void 0;return typeof r==`string`?r:``}function A(e,t){return{type:`pointer`,id:e,parameters:{pointerType:`touch`},actions:t}}async function ke(e){return j(ee(e,`android`).nodes)}function Ae(e){return j(ee(e).nodes)}function j(e){let t=e.flatMap(e=>je(e)&&Me(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 je(e){let t=e.type?.toLowerCase()??``;return e.visibleToUser!==!1&&(t.includes(`scrollview`)||t.includes(`listview`)||t.includes(`recyclerview`))}function Me(e){return!!e&&e.width>=50&&e.height>=50}async function Ne(t,n,r){let i=[];for(let e of n===`android`?[`rotation`,`orientation`]:[`orientation`,`rotation`])try{await Re(t,e,r);return}catch(t){if(!Ie(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 Pe=new Set([`unknown command`,`unknown method`]),Fe=new Set([404,405]);function Ie(t){if(!(t instanceof e)||t.code===`SESSION_NOT_FOUND`)return!1;let n=Le(t.details?.response);if(n)return Pe.has(n);let r=t.details?.status;return typeof r==`number`&&Fe.has(r)}function Le(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 Re(e,t,n){if(t===`rotation`){await e.setRotation(s(n));return}await e.setOrientation(c(n))}const M=1500;function ze(e){return new Promise(t=>setTimeout(t,e))}function N(t,n,r){return new e(`COMMAND_FAILED`,`fill tapped (${t}, ${n}) but ${r}`,{reason:`text_entry_focus_not_observed`,x:t,y:n,hint:`The tap most likely missed the field. Re-check the target with snapshot -i and fill the element it reports, rather than retrying the same coordinates.`})}function Be(t,n){return new e(`COMMAND_FAILED`,`fill tapped (${t}, ${n}) but this driver reports neither the focused element nor keyboard state, so the text was not sent`,{reason:`text_entry_focus_unobservable`,x:t,y:n,hint:`This provider cannot confirm a field took focus. Use press <target> followed by type <text> to enter it anyway, accepting that nothing witnesses which field receives the keys.`})}function Ve(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function He(e){return new Ue(e.client,e.backend,e.capabilities,e.targetId)}var Ue=class{client;backend;capabilities;targetId;constructor(e,t,n,r){this.client=e,this.backend=t,this.capabilities=n,this.targetId=r}async open(e,t){if(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(){await this.client.executeScript(`mobile: activateApp`,[{}])}async close(e){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(t,n,r,i){if(this.requireSupport(`fill`),r.length===0)throw new e(`UNSUPPORTED_OPERATION`,`fill with empty text (clear field) is not supported on the webdriver backend`,{hint:`Use a visible clear/reset control in the app, or fill the field with the intended replacement text directly.`});let a=await this.readTextEntryState();await this.tap(t,n);let o=await this.awaitTextEntryReadiness(a,t,n);return await this.type(r),{backend:`webdriver`,x:t,y:n,text:r,textEntryReadiness:o}}async scroll(e,t){this.requireSupport(`scroll`);let n=t?.durationMs??350;await this.client.hideKeyboard().catch(()=>void 0);let r=await this.scrollGestureFrame(),i=a({direction:e,amount:t?.amount,pixels:t?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o={...i,x1:i.x1+r.x,y1:i.y1+r.y,x2:i.x2+r.x,y2:i.y2+r.y};return await this.swipe(o.x1,o.y1,o.x2,o.y2,n),{backend:`webdriver`,...o,distance:i.pixels,durationMs:n}}async gestureViewport(){return await this.scrollGestureFrame()}async performGesture(e){return this.requireSupport(Ge(e)),await this.client.performActions(e.pointers.map(e=>A(`gesture-pointer-${e.pointerId}`,We(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`),await this.captureSource(e?.signal)}async captureSource(e){let t=await this.readSource(e);if(this.backend===`xctest`){let{acquireWebDriverIosSnapshot:e}=await import(`./webdriver-ios-snapshot.js`);return e(t,this.targetId)}let{parseWebDriverSourceFacts:n}=await import(`./webdriver-source.js`).then(e=>e.n);return{backend:`android`,producer:`appium-source`,nodes:n(t,`android`).nodes}}async readSource(e){try{return await this.client.source(e===void 0?{}:{signal:e})}catch(e){throw S(e)?Ke(e):e}}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 Ne(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 readAlert(){this.unsupported(`alert`)}async awaitAlert(){this.unsupported(`alert`)}async acceptAlert(){this.unsupported(`alert`)}async dismissAlert(){this.unsupported(`alert`)}async awaitTextEntryReadiness(e,t,n){let r=e.keyboard,i=Date.now()+2e3,a=e.focusedElementId,o=await this.pollWithinBudget(i,async e=>{let r=await this.client.activeElement(e);return r===`unsupported`?`abandon`:r===`none`?`retry`:r.id!==a||Ve(r.rect,t,n)?`satisfied`:`retry`});if(o===`satisfied`)return`focused-element`;if(o===`expired`)throw N(t,n,`nothing there took text-entry focus, so the text was not sent`);if(r===`unsupported`)throw Be(t,n);if(r)throw N(t,n,`the keyboard was already up and this driver cannot report which field holds focus, so the text was not sent`);if(await this.pollWithinBudget(i,async e=>await this.client.isKeyboardShown(e)===!0?`satisfied`:`retry`)===`satisfied`)return`keyboard-shown`;throw N(t,n,`no keyboard appeared, so the text was not sent`)}async readTextEntryState(){let[e,t]=await Promise.all([this.client.isKeyboardShown(M),this.client.activeElement(M)]);return{keyboard:e,focusedElementId:t===`none`||t===`unsupported`?void 0:t.id}}async pollWithinBudget(e,t){let n=!1,r;for(;;){let i=e-Date.now();if(i<=0)break;try{let e=await t(Math.min(M,i));if(n=!0,e!==`retry`)return e}catch(e){r=e}let a=e-Date.now();if(a<=0)break;await ze(Math.min(100,a))}if(!n&&r!==void 0)throw r;return`expired`}async pointerGesture(e,t){await this.client.performActions([A(e,t)]),await this.client.releaseActions().catch(()=>void 0)}async scrollGestureFrame(){return await this.client.source().then(e=>this.backend===`xctest`?Ae(e):ke(e)).catch(()=>void 0)||await this.client.windowRect()}requireSupport(e){p(this.capabilities,e)||this.unsupported(e)}unsupported(t){throw new e(`UNSUPPORTED_OPERATION`,f(this.capabilities,t),{provider:this.capabilities.provider,platform:this.capabilities.platform,operation:t})}};function We(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 Ge(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 Ke(t){return new e(`COMMAND_FAILED`,`The cloud driver did not finish reading the screen in its budget.`,{...t.details,hint:`A screen that never goes idle (looping video, live ticker, continuous animation) gives the driver no moment to read the UI tree. This read has the transport's own budget and does not grow with --timeout; take a screenshot, or drive the screen from refs an earlier snapshot already captured.`},t)}var qe=class{sessionsByLeaseId=new Map;ownedDeviceIds=new Set;releasedProviderSessionIdsByLeaseId=new Map;options;constructor(e){this.options=e}ownsDevice(e){return this.ownedDeviceIds.has(e.id)}findSessionForDevice(e){return[...this.sessionsByLeaseId.values()].find(t=>t.device.id===e.id)}findSessionForLease(e){return this.sessionsByLeaseId.get(e)}getInteractor(e){return this.findSessionForDevice(e)?.interactor}heartbeat(e){if(e.leaseProvider===this.options.provider&&this.sessionsByLeaseId.has(e.leaseId))return{provider:this.options.provider}}async allocate(e,t){if(e.leaseProvider!==this.options.provider)return;if(this.sessionsByLeaseId.has(e.leaseId))return this.heartbeat(e);let n=await this.prepareSession(e,t),r=new Se({clientVersion:this.options.clientVersion,endpoint:n.endpoint,auth:n.auth,headers:n.headers,requestPolicy:this.options.requestPolicy}),i=await this.createSessionWithPreparedCleanup(r,n,e,t),a=this.deviceForLease(e,n),o=n.providerSessionId??i.sessionId,s=d({provider:this.options.provider,platform:n.platform,overrides:this.options.capabilityOverrides});return this.sessionsByLeaseId.set(e.leaseId,Object.freeze({lease:e,device:a,client:r,prepared:n,capabilities:s,webDriverSessionId:i.sessionId,providerSessionId:o,interactor:He({client:r,backend:ie(n.platform),capabilities:s,targetId:a.id})})),this.ownedDeviceIds.add(a.id),{provider:this.options.provider,deviceId:a.id,sessionId:i.sessionId,providerSessionId:o,capabilities:s,...n.providerData}}async release(e){if(e.leaseProvider!==this.options.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.options.provider,providerSessionId:t.providerSessionId,...n.cleanup,...n.warnings.length>0?{warnings:n.warnings}:{},...r?{cloudArtifacts:r}:{}}}async listCloudArtifacts(e){if(e.provider!==this.options.provider)return;let t=this.sessionsByLeaseId.get(e.leaseId??``);return t?await this.listActiveCloudArtifacts(t,e.providerSessionId):await this.listReleasedCloudArtifacts(e)}async listActiveCloudArtifacts(e,t){if(!(t&&t!==e.providerSessionId))return await this.safeListArtifacts(e)}async listReleasedCloudArtifacts(e){let t=this.releasedProviderSessionIdsByLeaseId.get(e.leaseId??``);if(!(!t||!this.options.listArtifacts)&&!(e.providerSessionId&&e.providerSessionId!==t))return await this.options.listArtifacts({provider:this.options.provider,providerSessionId:t})}async shutdown(){await Promise.allSettled([...this.sessionsByLeaseId.values()].map(async e=>await this.closeSession(e))),this.sessionsByLeaseId.clear(),this.ownedDeviceIds.clear()}async createSessionWithPreparedCleanup(e,t,n,r){try{return await e.createSession(t.webdriverCapabilities,{deadline:r?.deadline})}catch(e){let r=S(e)?Je(e,this.options.provider,n,t):e;throw await ue(r,()=>t.cleanup?.()),r}}async prepareSession(e,t){let n=this.baseSessionForLease(e);return this.options.prepareSession?await this.options.prepareSession({lease:e,req:t,base:n}):n}baseSessionForLease(e){let t=typeof this.options.webdriverCapabilities==`function`?this.options.webdriverCapabilities(e):this.options.webdriverCapabilities??{};return{provider:this.options.provider,endpoint:this.options.endpoint,platform:this.options.platform,deviceName:this.options.deviceName,auth:this.options.auth,headers:this.options.headers,webdriverCapabilities:P(this.options.platform,this.options.deviceName,t)}}deviceForLease(e,t){return{...n(t.platform),...t.platform===`ios`?{appleOs:`ios`}:{},id:t.deviceId??this.options.deviceId?.(e)??`${this.options.provider}:${t.platform}:${e.leaseId}`,name:t.deviceName,kind:`device`,target:`mobile`,booted:!0}}async closeSession(e){let n=[],r;try{await e.client.deleteSession()}catch(e){n.push({code:`WEBDRIVER_SESSION_DELETE_FAILED`,message:t(e)})}try{r=await e.prepared.cleanup?.()}catch(e){n.push({code:`PROVIDER_CLEANUP_FAILED`,message:t(e)})}return{cleanup:r,warnings:n}}async safeListArtifacts(e){let t=e.prepared.listArtifacts??this.options.listArtifacts;if(t)try{return await t({provider:this.options.provider,lease:e.lease,device:e.device,webDriverSessionId:e.webDriverSessionId,providerSessionId:e.providerSessionId})}catch(t){return le({provider:this.options.provider,providerSessionId:e.providerSessionId,error:t})}}};function P(e,t,n={}){return{platformName:e===`ios`?`iOS`:`Android`,"appium:deviceName":t,...n}}function Je(t,n,r,i){let a=t.details?.timeoutMs;return new e(`COMMAND_FAILED`,`${n} did not create the WebDriver session within ${String(a)}ms.`,{reason:`provider_session_create_timeout`,provider:n,leaseId:r.leaseId,runId:r.runId,timeoutMs:a,...i.providerSessionId?{providerSessionId:i.providerSessionId}:{},hint:`${n} may still finish creating the session after agent-device stopped waiting, and that session would keep billing until the provider reaps it. Before retrying, check ${n} for a running session created for lease ${r.leaseId} (run ${r.runId}) and stop it.`},t)}function F(e){return new Ye(e)}var Ye=class{provider;owner;leaseLifecycle;cloudArtifacts;deviceInventoryProvider;capabilities;platformRuntimeModule;sessions;deployment;constructor(e){this.provider=e.provider,this.owner=i(e.provider,e.platform),this.capabilities=d({provider:e.provider,platform:e.platform,overrides:e.capabilityOverrides}),this.sessions=new qe(e),this.deployment=oe({provider:e.provider,uploadApp:e.uploadApp,findSessionForDevice:e=>this.sessions.findSessionForDevice(e)}),this.platformRuntimeModule=Object.freeze({owner:this.owner,loadRuntime:async e=>await this.loadRuntime(e)}),this.leaseLifecycle={allocate:async(e,t)=>await this.sessions.allocate(e,t),heartbeat:async e=>this.sessions.heartbeat(e),release:async e=>await this.sessions.release(e)},this.cloudArtifacts={listCloudArtifacts:async e=>await this.sessions.listCloudArtifacts(e)},this.deviceInventoryProvider=async e=>{if(e.leaseProvider!==this.provider)return null;if(!e.leaseId)return[];let t=this.sessions.findSessionForLease(e.leaseId);return t?[t.device]:[]}}async loadRuntime(e){let{createWebDriverPlatformRuntimeOwner:t}=await import(`./platform-runtime2.js`);return t({host:e,owner:this.owner,ownsDevice:e=>this.ownsDevice(e),isSessionActive:e=>this.sessions.findSessionForDevice(e)!==void 0,deployment:this.deployment,capabilities:this.capabilities,snapshotAvailable:this.capabilities.operations.snapshot.support!==`unsupported`,screenshotAvailable:this.capabilities.operations.screenshot.support!==`unsupported`,getInteractor:e=>this.getInteractor(e)})}ownsDevice(e){return this.sessions.ownsDevice(e)}getInteractor(e){return this.sessions.getInteractor(e)}async installApp(e,t,n,r){return await this.deployment.installApp(e,t,n,r)}async installInstallablePath(e,t,n){return await this.deployment.installInstallablePath(e,t,n)}async shutdown(){await this.sessions.shutdown()}};async function I(e,t,n){return t?v({provider:e,providerSessionId:t,artifacts:(await Promise.all([n.listArtifacts(t,`FILE`),n.listArtifacts(t,`LOG`)])).flat().flatMap(n=>Ze(e,t,n)),pendingMessage:`AWS Device Farm artifacts are not ready yet.`}):void 0}function Xe(e){if(!e||typeof e!=`object`)return[];let t=e.artifacts;return Array.isArray(t)?t:[]}function Ze(e,t,n){let r=n.url;return typeof r!=`string`||r.length===0?[]:[{provider:e,providerSessionId:t,kind:Qe(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 Qe(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`}}m.awsDeviceFarm;const $e={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 L(e){let t=R(e);return{createRemoteAccessSession:async e=>z(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=>z(await t(`get-remote-access-session`,[`--arn`,e])),stopRemoteAccessSession:async e=>z(await t(`stop-remote-access-session`,[`--arn`,e])),listArtifacts:async(e,n)=>Xe(await t(`list-artifacts`,[`--arn`,e,`--type`,n]))}}function et(t){return async({lease:n,req:r,base:i})=>{let a=await t.client.createRemoteAccessSession({projectArn:t.projectArn,deviceArn:t.deviceArn,appArn:t.appArn,name:de(t.sessionName,n)??`agent-device-${n.leaseId}`,interactionMode:t.interactionMode,configuration:t.configuration}),o,s;try{if(o=await rt(a.arn,t,r),s=tt(o),!s)throw new e(`COMMAND_FAILED`,`AWS Device Farm did not expose a WebDriver endpoint.`,{sessionArn:o.arn,status:o.status})}catch(e){throw await ue(e,()=>t.client.stopRemoteAccessSession(a.arn)),e}let c=o.device?.name??t.deviceName,l=typeof t.webdriverCapabilities==`function`?t.webdriverCapabilities(n):t.webdriverCapabilities??{},u=t.platform===`android`?{"appium:autoLaunch":!1}:{};return{...i,endpoint:s,platform:t.platform,deviceName:c,webdriverCapabilities:P(t.platform,c,{...u,...l}),cleanup:async()=>(await t.client.stopRemoteAccessSession(o.arn),{awsDeviceFarmSessionArn:o.arn}),providerSessionId:o.arn,providerData:{awsDeviceFarmSessionArn:o.arn}}}}function tt(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?nt(n):void 0}function nt(e){return/^https?:\/\//i.test(e)?e:`http://${e}`}async function rt(t,n,r){let i=n.pollIntervalMs??5e3,a=Date.now(),o=r?.deadline??a+(n.startupTimeoutMs??12e4),s=r?.signal,c=await n.client.getRemoteAccessSession(t);for(;Date.now()<o;){if(s?.throwIfAborted(),c.status===`RUNNING`)return c;at(c),await ne(i,void 0,{signal:s}).catch(()=>s?.throwIfAborted()),c=await n.client.getRemoteAccessSession(t)}throw new e(`COMMAND_FAILED`,`Timed out waiting for AWS Device Farm remote access.`,{sessionArn:t,status:c.status,result:c.result,timeoutMs:o-a})}const it=new Set([`ERRORED`,`STOPPED`,`COMPLETED`]);function at(t){if(!(!t.status||!it.has(t.status)))throw new e(`COMMAND_FAILED`,`AWS Device Farm remote access session did not start.`,{sessionArn:t.arn,status:t.status,result:t.result})}async function ot(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 R(e){let t=e.region?[`--region`,e.region]:[],n=e.awsCommand??`aws`;return async(r,i)=>await ot(e.runHostCommand,n,[`devicefarm`,r,...t,...i,`--output`,`json`])}function z(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 B=[{field:`providerDeviceOrientation`,capability:`deviceOrientation`,flag:`--provider-device-orientation`,type:`enum`,enumValues:o},{field:`providerGeoLocation`,capability:`geoLocation`,flag:`--provider-geo-location`,type:`string`},{field:`providerTimezone`,capability:`timezone`,flag:`--provider-timezone`,type:`string`},{field:`providerAppiumVersion`,capability:`appiumVersion`,flag:`--provider-appium-version`,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 st(e,t){pt(e);let n={};for(let r of B){let i=e[r.field];i!==void 0&&i!==!1&&i!==``&&(ft(r,t),n[r.capability]=r.type!==`negated-boolean`&&i)}return n}function ct(e){return B.filter(t=>{let n=e?.[t.field];return n!==void 0&&n!==!1&&n!==``}).map(e=>e.flag)}function V(t,n){let r=ct(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 lt(e){let t={};for(let n of B){let r=e?.[n.field];if(n.type===`negated-boolean`){r===!0&&(t.providerNoResignApp=!0);continue}typeof r==`string`&&r.length!==0&&ut(t,n,r)}return t}function ut(e,t,n){if(t.field===`providerDeviceOrientation`){e.providerDeviceOrientation=dt(t,n);return}t.field!==`providerNoResignApp`&&(e[t.field]=n)}function dt(t,n){let r=o.find(e=>e===n);if(r)return r;throw new e(`INVALID_ARGS`,`Invalid ${t.flag} value: ${n}.`,{hint:`Use ${o.join(`|`)}.`,flag:t.flag,capability:t.capability})}function ft(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 pt(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 mt={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 H(e,t,n){return t?v({provider:e,providerSessionId:t,artifacts:yt(e,t,await vt(t,n)),pendingMessage:`BrowserStack artifacts are not ready yet.`}):void 0}async function U(t,n,r){r?.throwIfAborted();let i=await g.readFile(t),a=new FormData;a.set(`file`,new Blob([i]),h.basename(t));let o=await fetch(n.endpoint??`https://api-cloud.browserstack.com/app-automate/upload`,{method:`POST`,headers:{...y(n.clientVersion),Authorization:b(n)},body:a,signal:r}),s=await o.json(),c=bt(s);if(!o.ok||!c)throw new e(`COMMAND_FAILED`,`BrowserStack app upload failed.`,{status:o.status,response:s});return c}function ht(e){return async({appPath:t,options:n,signal:r})=>({appReference:await U(t,e,r),bundleId:n?.appIdentifierHint,packageName:n?.packageNameHint,launchTarget:n?.appIdentifierHint??n?.packageNameHint})}function gt(e){let{"bstack:options":t,...n}=e.configured??{};return{"appium:deviceName":e.deviceName,"appium:platformVersion":e.osVersion,...e.app?{"appium:app":e.app}:{},...n,"bstack:options":{...e.projectName?{projectName:e.projectName}:{},buildName:e.buildName,sessionName:e.sessionName,...e.deviceFeatures??{},..._t(t)}}}function _t(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:{}}async function vt(t,n){let r=new URL(`${pe(String(n.endpoint??`https://api-cloud.browserstack.com/app-automate/sessions`))}/${t}.json`),i=await fetch(r,{headers:{...y(n.clientVersion),Authorization:b(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 yt(e,t,n){return[W(e,t,n,`video_url`,`video`,`Session video`),W(e,t,n,`appium_logs_url`,`appium-log`,`Appium logs`),W(e,t,n,`device_logs_url`,`device-log`,`Device logs`),W(e,t,n,`browser_url`,`provider-session`,`BrowserStack dashboard`),W(e,t,n,`public_url`,`provider-session`,`Public session link`)].filter(e=>e!==void 0)}function W(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 bt(e){if(!e||typeof e!=`object`)return;let t=e.app_url;return typeof t==`string`?t:void 0}function G(e){return/^arn:[^:]+:devicefarm:([^:]+):/.exec(e)?.[1]}async function xt(t,n){let r=R({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=K(i,`project`),c=K(a,`device`),l=Ct(c.platform);if(l!==t.platform)throw new e(`INVALID_ARGS`,`AWS Device Farm device "${q(c.name)??t.deviceArn}" is ${l}, not ${t.platform}.`);let u=t.appArn?St(K(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:q(s.name),reference:t.projectArn},device:{status:`verified`,name:q(c.name)??t.deviceArn,reference:t.deviceArn,platform:l,osVersion:q(c.os),availability:q(c.availability)},app:u}}function St(t,n){let r=q(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=q(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:q(t.name),reference:n.appArn}}function K(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 Ct(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 q(e){return typeof e==`string`&&e.length>0?e:void 0}async function wt(t,n){let r={username:t.username,accessKey:t.accessKey},i=Dt(await J(t.devicesEndpoint??`https://api-cloud.browserstack.com/app-automate/devices.json`,r,n)).find(e=>e.device===t.deviceName&&e.os.toLowerCase()===t.platform&&Et(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 Tt(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 Tt(e,t,n){let{app:r}=e;if(r.startsWith(`bs://`)){let i=Ot(await J(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:h.basename(r),reference:r,message:`Local app artifact is ready and will be uploaded when creating the session.`}}async function J(t,n,r){try{let i=await fetch(t,{headers:{...y(r),Authorization:b(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 Et(e,t){let n=e=>e.replace(/(?:\.0)+$/,``);return n(e)===n(t)}function Dt(t){if(!Array.isArray(t))throw new e(`COMMAND_FAILED`,`BrowserStack device verification response was not a list.`);return t.flatMap(e=>{let t=Y(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 Ot(t){let n=Y(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=Y(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 Y(e){return e&&typeof e==`object`&&!Array.isArray(e)?e:void 0}async function kt(e,t){return e.provider===`browserstack`?await wt(e,t.clientVersion):await xt(e,t.runHostCommand)}function At(e){return[{provider:m.browserStack,createRuntime:t=>F({clientVersion:e.clientVersion,provider:m.browserStack,platform:`android`,deviceName:`BrowserStack device`,endpoint:t.BROWSERSTACK_WEBDRIVER_ENDPOINT??`https://hub-cloud.browserstack.com/wd/hub/`,capabilityOverrides:mt,listArtifacts:async({provider:n,providerSessionId:r})=>{let i=$(t,`BROWSERSTACK_USERNAME`,`BrowserStack artifact lookup`),a=$(t,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack artifact lookup`);return await H(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=X(n,`BrowserStack`),o=$(t,`BROWSERSTACK_USERNAME`,`BrowserStack`),s=$(t,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack`),c=Nt(a,`BrowserStack`),l=Z(a,`device`,`BrowserStack requires --device <name>.`),u=Z(a,`providerOsVersion`,`BrowserStack requires --provider-os-version <version>.`),d=await jt({clientVersion:e.clientVersion,app:Z(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,signal:a.signal});return{...i,platform:c,deviceName:l,auth:{username:o,accessKey:s},uploadApp:ht({clientVersion:e.clientVersion,username:o,accessKey:s,endpoint:t.BROWSERSTACK_APP_UPLOAD_ENDPOINT??`https://api-cloud.browserstack.com/app-automate/upload`}),webdriverCapabilities:gt({deviceName:l,osVersion:u,app:d,projectName:Q(a,`providerProject`),buildName:Q(a,`providerBuild`)??r.runId,sessionName:Q(a,`providerSessionName`)??r.leaseId,deviceFeatures:st(lt(a.flags),c),configured:P(c,l)})}}}),listArtifactsFromEnv:async(t,n)=>{let r=$(n,`BROWSERSTACK_USERNAME`,`BrowserStack artifact lookup`),i=$(n,`BROWSERSTACK_ACCESS_KEY`,`BrowserStack artifact lookup`);return await H(m.browserStack,t,{clientVersion:e.clientVersion,username:r,accessKey:i,endpoint:n.BROWSERSTACK_SESSION_DETAILS_ENDPOINT})}},{provider:m.awsDeviceFarm,createRuntime:t=>F({clientVersion:e.clientVersion,provider:m.awsDeviceFarm,endpoint:`http://127.0.0.1/`,platform:`android`,deviceName:`AWS Device Farm device`,capabilityOverrides:$e,listArtifacts:async({provider:n,providerSessionId:r})=>await I(n,r,L({runHostCommand:e.runHostCommand,region:t.AWS_REGION??t.AWS_DEFAULT_REGION??G(r??``)})),prepareSession:async({req:n,lease:r,base:i})=>{let a=X(n,`AWS Device Farm`);V(a.flags,m.awsDeviceFarm);let o=Nt(a,`AWS Device Farm`);return await et({client:L({runHostCommand:e.runHostCommand,region:Q(a,`awsRegion`)??t.AWS_REGION??t.AWS_DEFAULT_REGION}),projectArn:Pt(a,t,`awsProjectArn`,`AGENT_DEVICE_AWS_DEVICE_FARM_PROJECT_ARN`,`AWS_DEVICE_FARM_PROJECT_ARN`),deviceArn:Pt(a,t,`awsDeviceArn`,`AGENT_DEVICE_AWS_DEVICE_FARM_DEVICE_ARN`,`AWS_DEVICE_FARM_DEVICE_ARN`),appArn:Q(a,`awsAppArn`)??t.AGENT_DEVICE_AWS_DEVICE_FARM_APP_ARN??t.AWS_DEVICE_FARM_APP_ARN,platform:o,deviceName:Q(a,`device`)??`AWS Device Farm device`,sessionName:Q(a,`providerSessionName`)??r.leaseId,interactionMode:Ft(a)})({lease:r,req:n,base:i})}}),listArtifactsFromEnv:async(t,n)=>{let r=L({runHostCommand:e.runHostCommand,region:n.AWS_REGION??n.AWS_DEFAULT_REGION??G(t)});return await I(m.awsDeviceFarm,t,r)}}]}async function jt(t){if(Mt(t.app))return t.app;let n=h.resolve(t.cwd??process.cwd(),t.app);if(!te.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 U(n,{clientVersion:t.clientVersion,username:t.username,accessKey:t.accessKey,endpoint:t.uploadEndpoint},t.signal)}function Mt(e){return e.startsWith(`bs://`)||/^https?:\/\//.test(e)}function X(t,n){if(t)return t;throw new e(`INVALID_ARGS`,`${n} lease allocation requires provider profile flags on the request.`)}function Nt(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 Z(t,n,r){let i=Q(t,n);if(i)return i;throw new e(`INVALID_ARGS`,r)}function Q(e,t){let n=e.flags?.[t];return typeof n==`string`&&n.length>0?n:void 0}function $(t,n,r){let i=t[n];if(i)return i;throw new e(`INVALID_ARGS`,`${r} requires ${n} in the environment.`)}function Pt(t,n,r,i,a){let o=Q(t,r)??n[i]??n[a];if(o)return o;throw new e(`INVALID_ARGS`,`AWS Device Farm requires --${It(String(r))} or ${a}.`)}function Ft(e){let t=Q(e,`awsInteractionMode`);if(t===`INTERACTIVE`||t===`NO_VIDEO`||t===`VIDEO_ONLY`)return t}function It(e){return e.replaceAll(/[A-Z]/g,e=>`-${e.toLowerCase()}`)}function Lt(e){let t=At(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 kt(t,e)}}const Rt=Lt({clientVersion:u(),runHostCommand:async(e,t)=>({stdout:(await l(e,[...t],{maxBuffer:10485760,timeoutMs:3e4})).stdout})});export{G as n,V as r,Rt as t};
@@ -1 +1 @@
1
- import{C as e,M as t}from"./sdk-contracts.js";import{c as n}from"./capture.js";import{g as r}from"./sdk-batch-runner.js";import{D as i,w as a}from"./sdk-device.js";import{D as o,E as s,O as c}from"./sdk-batch.js";import{n as l,r as u}from"./recording-export-quality.js";import{c as d,l as f}from"./back-mode.js";import{c as p}from"./session-store.js";import{r as m}from"./diagnostics.js";import"./diagnostics2.js";import{i as h}from"./output-path.js";import{n as g}from"./request-runtime-binding.js";import{n as _}from"./dispatch-resolve.js";import{a as v,t as y}from"./session-routing.js";import{a as b,c as x,i as S,o as C,s as w,t as T}from"./screen-recording-resource-recovery.js";import{t as E}from"./telemetry.js";import D from"node:path";import O from"node:fs";const k=[`clientOutPath`,`telemetryPath`,`warning`,`overlayWarning`];function A(e){let{resourcePath:t,record:n}=M(e);if(n.status!==`decoded`)return{kind:`none`};if(N(e,n.envelope),n.envelope.lifecycle!==`completed`)return{kind:`open`,resourcePath:t};let r=P(n.envelope.metadata);return r===void 0?(m({level:`warn`,phase:`screen_recording_completed_manifest_unreplayable`,data:{resourcePath:t}}),{kind:`none`}):O.existsSync(r.outPath)?{kind:`completed`,completion:r}:{kind:`none`}}function j(e){let{record:t}=M(e);return t.status===`decoded`&&t.envelope.lifecycle===`completed`}function M(e){let t=x.resourcePath(e.sessionStore,e.sessionName);return{resourcePath:t,record:x.store.read(t)}}function N(t,n){if(n.sessionId!==t.sessionName)throw new e(`COMMAND_FAILED`,`Screen recording recovery record does not belong to the requested session`,{reason:`runtime-contract-invalid`});if(!i(n.device,a(t.device)))throw new e(`COMMAND_FAILED`,`Screen recording recovery device does not match the selected device`,{reason:`runtime-contract-invalid`})}function P(e){let t=e?.[S];if(!(!r(t)||!F(t)||!I(t)))return t}function F(e){return L(e.outPath)&&L(e.backend)&&z(e.startedAt)&&z(e.completedAt)&&(e.capturedDurationMs===void 0||z(e.capturedDurationMs))&&d(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function I(e){return k.every(t=>R(e[t]))&&V(e.activeSessionApp)&&U(e.chunks)}function L(e){return typeof e==`string`&&e.length>0}function R(e){return e===void 0||L(e)}function z(e){return typeof e==`number`&&Number.isFinite(e)}function B(e){return!r(e)||!L(e.bundleId)?!1:R(e.name)}function V(e){return e===void 0||B(e)}function H(e){return Array.isArray(e)&&e.every(e=>r(e)&&Number.isFinite(e.index)&&L(e.path)&&R(e.clientOutPath))}function U(e){return e===void 0||H(e)}function ee(t){let r=n(`record`,t.flags);if(r)throw new e(`INVALID_ARGS`,r);let i=t.flags?.fps;if(i!==void 0&&(!Number.isInteger(i)||i<1||i>120))throw new e(`INVALID_ARGS`,`fps must be an integer between 1 and 120`);let a=u(t.flags?.quality);if(t.flags?.quality!==void 0&&a===void 0)throw new e(`INVALID_ARGS`,`quality must be one of: ${l.join(`, `)} (legacy numeric values 5-10 are accepted)`);return{scope:W(t.flags?.recordingScope),...i===void 0?{}:{fps:i},...a===void 0?{}:{exportQuality:a},showTouches:t.flags?.hideTouches!==!0,hideTouchesRequested:t.flags?.hideTouches===!0}}function W(t){if(t===void 0)return`app`;if(t===`app`||t===`device`||t===`system`)return t;throw new e(`INVALID_ARGS`,`record scope must be app, device, or system`)}function G(e){return{ok:!1,error:{code:`INVALID_ARGS`,message:y(e)?`record start with app scope and an explicit session requires an active app session; run open <app> first, or use --scope device to record the full screen`:`record start defaults to app scope and requires an active app session; run open <app> first, or use --scope device to record the full screen`}}}function K(e,t,n){return{ok:!0,data:{recording:`started`,outPath:e.clientOutPath??n,sessionStateDir:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,showTouches:e.showTouches}}}function q(e){return{action:`start`,...e.clientOutPath?{requestedFileName:D.basename(e.clientOutPath)}:{},showTouches:e.showTouches}}function J(e){return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:`record is not supported on this device`,hint:e.hint??`Select an Apple, Android, physical HarmonyOS, or web target that supports screen recording.`,details:{reason:e.reason}}}}function Y(e){let t=[X(e)];if(e.chunks&&e.chunks.length>1&&t.push(...e.chunks.slice(1).map(e=>({field:`chunkPath`,artifactType:`screen-recording-chunk`,path:e.path,localPath:e.clientOutPath,fileName:D.basename(e.clientOutPath??e.path)}))),e.telemetryPath){let n=e.clientOutPath?E(e.clientOutPath):void 0;t.push({field:`telemetryPath`,artifactType:`screen-recording-telemetry`,path:e.telemetryPath,localPath:n,fileName:D.basename(e.telemetryPath)})}return{ok:!0,data:{recording:`stopped`,outPath:e.outPath,telemetryPath:e.telemetryPath,artifacts:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,durationMs:Math.max(0,e.completedAt-e.startedAt),...e.capturedDurationMs===void 0?{}:{capturedDurationMs:e.capturedDurationMs},showTouches:e.showTouches,warning:e.warning,overlayWarning:e.overlayWarning,chunks:e.chunks?.map(e=>({index:e.index,path:e.clientOutPath??e.path}))}}}function X(e){return{field:`outPath`,artifactType:`screen-recording`,path:e.outPath,localPath:e.clientOutPath,fileName:D.basename(e.clientOutPath??e.outPath)}}async function Z(e){try{return await Q(e)}catch(e){return{ok:!1,error:t(e)}}}async function Q(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n),{plan:a,scope:o}=$(t,i);if(a.kind===`start`&&!f(o)&&!i)return G(t);let s=await te(e,i),{session:c}=s;return a.kind===`start`?await ne(e,c,ee(t),a.use,s.needsReadiness):await oe(e,c,a.kind,s.needsReadiness)}function $(e,t){let n=W(e.flags?.recordingScope);return{scope:n,plan:s({action:e.positionals?.[0],scope:n,hasLiveHandle:t?.screenRecording!==void 0})}}async function te(e,t){let n=t?.device??await _(e.req.flags??{});return await e.retainDeviceExecutionLock(n.id),t?{session:t,needsReadiness:!1}:{session:le(e,n),needsReadiness:!0}}async function ne(e,t,n,r,i){if(t.screenRecording)return{ok:!1,error:{code:`INVALID_ARGS`,message:`recording already in progress`}};let a=await e.bindDevice(t.device,o);i&&await g(a);let s=a.facts.screenRecordingStart;if(!s.available)return J(s);let c=await e.bindDevice(t.device,r),{fence:l,outputPaths:u}=re(e,t),d=await c.operations.screenRecordingStart(ie(e,t,n,l,u.outputPath));await b({admissionLedger:e.admissionLedger,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore,device:t.device,owner:c.owner,fence:l,...d,throwIfCanceled:e.throwIfCanceled});let f=e.sessionStore.get(e.sessionName)?.screenRecording;if(!f)throw TypeError(`Screen recording adoption did not publish a live handle`);let m=f.handle.inspect();return p(e.sessionStore,t,e.req,e.req.command,q(m)),K(m,e.sessionStore.ensureSessionDir(e.sessionName),u.requestedPath)}function re(e,t){let n=x.resourcePath(e.sessionStore,e.sessionName);return{fence:x.createNextFence({admissionLedger:e.admissionLedger,resourcePath:n,device:t.device}),outputPaths:h({requestedPath:e.req.positionals?.[1],platform:t.device.platform,cwd:e.req.meta?.cwd})}}function ie(e,t,n,r,i){return{sessionId:e.sessionName,outputPath:i,clientOutputPath:e.req.meta?.clientArtifactPaths?.outPath,scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:n.hideTouchesRequested,recordOnlySession:t.recordOnlySession===!0,activeSessionApp:ae(t),exportQuality:n.exportQuality,fps:n.fps,fence:r}}function ae(e){if(e.appBundleId)return{bundleId:e.appBundleId,...e.appName?{name:e.appName}:{}}}async function oe(e,t,n,r){let i;try{i=n===`stop-live`?{completion:await C({session:t,sessionName:e.sessionName,sessionStore:e.sessionStore}),recordsSessionAction:!0}:await ce(e,t,r)}catch(n){throw se(e,t),n}let a=i.completion,o=Y(a);return i.recordsSessionAction&&p(e.sessionStore,t,e.req,e.req.command,{action:`stop`,outPath:a.outPath,...a.clientOutPath?{requestedFileName:D.basename(a.clientOutPath)}:{},showTouches:a.showTouches}),t.recordOnlySession&&e.sessionStore.delete(e.sessionName),o}function se(e,t){t.recordOnlySession&&j(e)&&e.sessionStore.delete(e.sessionName)}async function ce(t,n,r){let i=A({sessionName:t.sessionName,sessionStore:t.sessionStore,device:n.device});if(i.kind===`completed`)return{completion:i.completion,recordsSessionAction:!1};if(i.kind===`none`)throw new e(`INVALID_ARGS`,`no active recording`);return{completion:await w({resourcePath:i.resourcePath,scope:t.requestScope,acquireControl:async(e,i)=>{let a=await t.bindExactDevice(n.device,e.owner,e.fence,c,i);return r&&await g(a),T({runtime:a,dispose:async()=>{}})}}),recordsSessionAction:!0}}function le(e,t){return{name:e.sessionName,sessionScope:v(e.req),device:t,createdAt:Date.now(),recordOnlySession:!0,actions:[]}}export{Z as t};
1
+ import{C as e,M as t}from"./sdk-contracts.js";import{c as n}from"./capture.js";import{g as r}from"./sdk-batch-runner.js";import{D as i,w as a}from"./sdk-device.js";import{D as o,E as s,O as c}from"./sdk-batch.js";import{n as l,r as u}from"./recording-export-quality.js";import{c as d,l as f}from"./back-mode.js";import{c as p}from"./session-store.js";import{r as m}from"./diagnostics.js";import"./diagnostics2.js";import{i as h}from"./output-path.js";import{n as g}from"./request-runtime-binding.js";import{n as _}from"./dispatch-resolve.js";import{a as v,t as y}from"./session-routing.js";import{a as b,c as x,i as S,o as C,s as w,t as T}from"./screen-recording-resource-recovery.js";import{t as E}from"./telemetry.js";import D from"node:path";import O from"node:fs";const k=[`clientOutPath`,`telemetryPath`,`warning`,`overlayWarning`];function A(e){let{resourcePath:t,record:n}=M(e);if(n.status!==`decoded`)return{kind:`none`};if(N(e,n.envelope),n.envelope.lifecycle!==`completed`)return{kind:`open`,resourcePath:t};let r=P(n.envelope.metadata);return r===void 0?(m({level:`warn`,phase:`screen_recording_completed_manifest_unreplayable`,data:{resourcePath:t}}),{kind:`none`}):O.existsSync(r.outPath)?{kind:`completed`,completion:r}:{kind:`none`}}function j(e){let{record:t}=M(e);return t.status===`decoded`&&t.envelope.lifecycle===`completed`}function M(e){let t=x.resourcePath(e.sessionStore,e.sessionName);return{resourcePath:t,record:x.store.read(t)}}function N(t,n){if(n.sessionId!==t.sessionName)throw new e(`COMMAND_FAILED`,`Screen recording recovery record does not belong to the requested session`,{reason:`runtime-contract-invalid`});if(!i(n.device,a(t.device)))throw new e(`COMMAND_FAILED`,`Screen recording recovery device does not match the selected device`,{reason:`runtime-contract-invalid`})}function P(e){let t=e?.[S];if(!(!r(t)||!F(t)||!I(t)))return t}function F(e){return L(e.outPath)&&L(e.backend)&&z(e.startedAt)&&z(e.completedAt)&&(e.capturedDurationMs===void 0||z(e.capturedDurationMs))&&d(e.scope)&&typeof e.showTouches==`boolean`&&typeof e.recordOnlySession==`boolean`}function I(e){return k.every(t=>R(e[t]))&&V(e.activeSessionApp)&&U(e.chunks)}function L(e){return typeof e==`string`&&e.length>0}function R(e){return e===void 0||L(e)}function z(e){return typeof e==`number`&&Number.isFinite(e)}function B(e){return!r(e)||!L(e.bundleId)?!1:R(e.name)}function V(e){return e===void 0||B(e)}function H(e){return Array.isArray(e)&&e.every(e=>r(e)&&Number.isFinite(e.index)&&L(e.path)&&R(e.clientOutPath))}function U(e){return e===void 0||H(e)}function ee(t){let r=n(`record`,t.flags);if(r)throw new e(`INVALID_ARGS`,r);let i=t.flags?.fps;if(i!==void 0&&(!Number.isInteger(i)||i<1||i>120))throw new e(`INVALID_ARGS`,`fps must be an integer between 1 and 120`);let a=u(t.flags?.quality);if(t.flags?.quality!==void 0&&a===void 0)throw new e(`INVALID_ARGS`,`quality must be one of: ${l.join(`, `)} (legacy numeric values 5-10 are accepted)`);return{scope:W(t.flags?.recordingScope),...i===void 0?{}:{fps:i},...a===void 0?{}:{exportQuality:a},showTouches:t.flags?.hideTouches!==!0,hideTouchesRequested:t.flags?.hideTouches===!0}}function W(t){if(t===void 0)return`app`;if(t===`app`||t===`device`||t===`system`)return t;throw new e(`INVALID_ARGS`,`record scope must be app, device, or system`)}function G(e){return{ok:!1,error:{code:`INVALID_ARGS`,message:y(e)?`record start with app scope and an explicit session requires an active app session; run open <app> first, or use --scope device to record the full screen`:`record start defaults to app scope and requires an active app session; run open <app> first, or use --scope device to record the full screen`}}}function K(e,t,n){return{ok:!0,data:{recording:`started`,outPath:e.clientOutPath??n,sessionStateDir:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,showTouches:e.showTouches}}}function q(e){return{action:`start`,...e.clientOutPath?{requestedFileName:D.basename(e.clientOutPath)}:{},showTouches:e.showTouches}}function J(e){return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:`record is not supported on this device`,hint:e.hint??`Select an Apple, Android, physical HarmonyOS, or web target that supports screen recording.`,details:{reason:e.reason}}}}function Y(e){let t=[X(e)];if(e.chunks&&e.chunks.length>1&&t.push(...e.chunks.slice(1).map(e=>({field:`chunkPath`,artifactType:`screen-recording-chunk`,path:e.path,localPath:e.clientOutPath,fileName:D.basename(e.clientOutPath??e.path)}))),e.telemetryPath){let n=e.clientOutPath?E(e.clientOutPath):void 0;t.push({field:`telemetryPath`,artifactType:`screen-recording-telemetry`,path:e.telemetryPath,localPath:n,fileName:D.basename(e.telemetryPath)})}return{ok:!0,data:{recording:`stopped`,outPath:e.outPath,telemetryPath:e.telemetryPath,artifacts:t,recordingBackend:e.backend,recordingScope:e.scope,recordOnlySession:e.recordOnlySession,activeSessionApp:e.activeSessionApp,durationMs:Math.max(0,e.completedAt-e.startedAt),...e.capturedDurationMs===void 0?{}:{capturedDurationMs:e.capturedDurationMs},showTouches:e.showTouches,warning:e.warning,overlayWarning:e.overlayWarning,chunks:e.chunks?.map(e=>({index:e.index,path:e.clientOutPath??e.path}))}}}function X(e){return{field:`outPath`,artifactType:`screen-recording`,path:e.outPath,localPath:e.clientOutPath,fileName:D.basename(e.clientOutPath??e.outPath)}}async function Z(e){try{return await Q(e)}catch(e){return{ok:!1,error:t(e)}}}async function Q(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n),{plan:a,scope:o}=$(t,i);if(a.kind===`start`&&!f(o)&&!i)return G(t);let s=await te(e,i),{session:c}=s;return a.kind===`start`?await ne(e,c,ee(t),a.use,s.needsReadiness):await oe(e,c,a.kind,s.needsReadiness)}function $(e,t){let n=W(e.flags?.recordingScope);return{scope:n,plan:s({action:e.positionals?.[0],scope:n,hasLiveHandle:t?.screenRecording!==void 0})}}async function te(e,t){let n=t?.device??await _(e.req.flags??{});return await e.retainDeviceExecutionLock(n.id),t?{session:t,needsReadiness:!1}:{session:le(e,n),needsReadiness:!0}}async function ne(e,t,n,r,i){if(t.screenRecording)return{ok:!1,error:{code:`INVALID_ARGS`,message:`recording already in progress`}};let a=await e.bindDevice(t.device,o);i&&await g(a);let s=a.facts.screenRecordingStart;if(!s.available)return J(s);let c=await e.bindDevice(t.device,r),{fence:l,outputPaths:u}=re(e,t),d=await c.operations.screenRecordingStart(ie(e,t,n,l,u.outputPath));await b({admissionLedger:e.admissionLedger,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore,device:t.device,owner:c.owner,fence:l,...d,throwIfCanceled:e.throwIfCanceled});let f=e.sessionStore.get(e.sessionName)?.screenRecording;if(!f)throw TypeError(`Screen recording adoption did not publish a live handle`);let m=f.handle.inspect();return p(e.sessionStore,t,e.req,e.req.command,q(m)),K(m,e.sessionStore.ensureSessionDir(e.sessionName),u.requestedPath)}function re(e,t){let n=x.resourcePath(e.sessionStore,e.sessionName);return{fence:x.createNextFence({admissionLedger:e.admissionLedger,resourcePath:n,device:t.device}),outputPaths:h({requestedPath:e.req.positionals?.[1],platform:t.device.platform,cwd:e.req.meta?.cwd})}}function ie(e,t,n,r,i){return{sessionId:e.sessionName,outputPath:i,clientOutputPath:e.req.meta?.clientArtifactPaths?.outPath,scope:n.scope,showTouches:n.showTouches,hideTouchesRequested:n.hideTouchesRequested,recordOnlySession:t.recordOnlySession===!0,activeSessionApp:ae(t),exportQuality:n.exportQuality,fps:n.fps,fence:r}}function ae(e){if(e.appBundleId)return{bundleId:e.appBundleId,...e.appName?{name:e.appName}:{}}}async function oe(e,t,n,r){let i;try{i=n===`stop-live`?{completion:await C({intent:`capture`,session:t,sessionName:e.sessionName,sessionStore:e.sessionStore}),recordsSessionAction:!0}:await ce(e,t,r)}catch(n){throw se(e,t),n}let a=i.completion,o=Y(a);return i.recordsSessionAction&&p(e.sessionStore,t,e.req,e.req.command,{action:`stop`,outPath:a.outPath,...a.clientOutPath?{requestedFileName:D.basename(a.clientOutPath)}:{},showTouches:a.showTouches}),t.recordOnlySession&&e.sessionStore.delete(e.sessionName),o}function se(e,t){t.recordOnlySession&&j(e)&&e.sessionStore.delete(e.sessionName)}async function ce(t,n,r){let i=A({sessionName:t.sessionName,sessionStore:t.sessionStore,device:n.device});if(i.kind===`completed`)return{completion:i.completion,recordsSessionAction:!1};if(i.kind===`none`)throw new e(`INVALID_ARGS`,`no active recording`);return{completion:await w({resourcePath:i.resourcePath,scope:t.requestScope,acquireControl:async(e,i)=>{let a=await t.bindExactDevice(n.device,e.owner,e.fence,c,i);return r&&await g(a),T({runtime:a,dispose:async()=>{}})}}),recordsSessionAction:!0}}function le(e,t){return{name:e.sessionName,sessionScope:v(e.req),device:t,createdAt:Date.now(),recordOnlySession:!0,actions:[]}}export{Z as t};
@@ -1 +1 @@
1
- import{C as e}from"./sdk-contracts.js";import{t}from"./src2.js";import{i as n}from"./src4.js";const r=new Map;function i(e){for(let t of e.platforms){if(r.has(t))throw Error(`PlatformPlugin already registered for platform "${t}"`);r.set(t,e)}}function a(t){let n=r.get(t);if(!n)throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform: ${t}`);return n}function o(e){return r.get(e)}const s=[t,{id:`android`,platforms:[`android`],providers:{platformGatedResolvers:[`androidAdbProvider`]},createInteractor:async(e,t)=>{let{createAndroidInteractor:n}=await import(`./android.js`).then(e=>e.t);return n(e,void 0,t)}},{id:`harmonyos`,platforms:[`harmonyos`],createInteractor:async(e,t)=>{let{createHarmonyInteractor:n}=await import(`./harmonyos.js`);return n(e,t)}},n,{id:`linux`,platforms:[`linux`],providers:{platformGatedResolvers:[`linuxToolProvider`]},createInteractor:async()=>{let{createLinuxInteractor:e}=await import(`./linux.js`);return e()}},{id:`web`,platforms:[`web`],providers:{platformGatedResolvers:[`webProvider`]},createInteractor:async()=>{let{createWebInteractor:e}=await import(`./web2.js`);return await e()}}];let c=!1;function l(){if(!c){for(let e of s)i(e);c=!0}}export{a as n,o as r,l as t};
1
+ import{C as e}from"./sdk-contracts.js";import{t}from"./src2.js";import{i as n}from"./src3.js";const r=new Map;function i(e){for(let t of e.platforms){if(r.has(t))throw Error(`PlatformPlugin already registered for platform "${t}"`);r.set(t,e)}}function a(t){let n=r.get(t);if(!n)throw new e(`UNSUPPORTED_PLATFORM`,`Unsupported platform: ${t}`);return n}function o(e){return r.get(e)}const s=[t,{id:`android`,platforms:[`android`],providers:{platformGatedResolvers:[`androidAdbProvider`]},createInteractor:async(e,t)=>{let{createAndroidInteractor:n}=await import(`./android.js`).then(e=>e.t);return n(e,void 0,t)}},{id:`harmonyos`,platforms:[`harmonyos`],createInteractor:async(e,t)=>{let{createHarmonyInteractor:n}=await import(`./harmonyos.js`);return n(e,t)}},n,{id:`linux`,platforms:[`linux`],providers:{platformGatedResolvers:[`linuxToolProvider`]},createInteractor:async()=>{let{createLinuxInteractor:e}=await import(`./linux.js`);return e()}},{id:`web`,platforms:[`web`],providers:{platformGatedResolvers:[`webProvider`]},createInteractor:async()=>{let{createWebInteractor:e}=await import(`./web2.js`);return await e()}}];let c=!1;function l(){if(!c){for(let e of s)i(e);c=!0}}export{a as n,o as r,l as t};
@@ -1,7 +1,7 @@
1
- import{C as e,S as t,_ as n,h as r,t as i,u as a,v as o}from"./sdk-contracts.js";import{d as s,f as c,i as ee,l as te,n as ne,p as re,t as ie,u as ae}from"./capture.js";import{D as oe,c as se,d as ce,f as le,g as l,l as ue,o as de,p as fe,s as pe,u as me}from"./sdk-batch-runner.js";import{t as he}from"./viewport.js";import{r as ge,t as _e}from"./sdk-device.js";import{i as ve,s as ye}from"./lease-scope.js";import{Dn as be,Nr as xe,Or as Se,Tn as Ce,Wr as we,ar as Te,fr as Ee,i as De,in as Oe,jn as ke,m as Ae,nn as je,or as Me,p as Ne,s as Pe,sr as Fe,ur as Ie,vr as Le}from"./sdk-batch.js";import{n as Re}from"./recording-export-quality.js";import{i as ze,r as Be,s as Ve,t as He}from"./back-mode.js";import{a as Ue,n as We,o as Ge,r as Ke,s as qe}from"./scroll-gesture.js";import{E as Je,T as Ye,b as Xe,v as Ze,w as Qe}from"./script.js";import{a as $e,i as et,r as tt}from"./vars.js";import{n as nt,r as rt,t as it}from"./format.js";import{n as u,t as at}from"./catalog.js";import{a as ot}from"./sdk-remote-config.js";import{t as st}from"./session.js";import{a as ct,c as lt,d as ut,f as dt,g as ft,h as pt,i as mt,l as ht,n as gt,o as _t,p as vt,s as yt,t as bt,u as xt}from"./observability.js";import{t as St}from"./success-text.js";import{t as Ct}from"./alert-contract.js";import{i as wt,t as Tt}from"./location-coordinates.js";import{t as Et}from"./snapshot-quality-backend-capabilities.js";import{a as Dt,d as Ot,f as kt,l as At,t as jt,u as Mt}from"./absence-observation-errors.js";import{t as Nt}from"./mobile-snapshot-semantics.js";import{t as Pt}from"./click-button.js";import{n as Ft}from"./scroll-command.js";import{n as It,t as Lt}from"./interaction-positionals.js";import{t as Rt}from"./app-inventory.js";import"./device.js";import{a as zt,t as Bt}from"./device-rotation.js";import"./app-inventory-contract.js";import{t as Vt}from"./prepare-kind.js";import{n as Ht,t as Ut}from"./path-resolution.js";import"./file.js";import{n as Wt,r as Gt,s as Kt,t as qt}from"./tv-remote.js";import d from"node:path";import f from"node:fs";const Jt=[`path`,`start`,`stop`,`doctor`,`mark`,`clear`],Yt=new Set(Be().map(e=>e.key));function Xt(e){let t=ve(e);return oe({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...ye(t),provider:e.provider,providerSessionId:e.providerSessionId,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,sessionIsolation:e.sessionIsolation,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,surface:e.surface,activity:e.activity,launchConsole:e.launchConsole,launchArgs:e.launchArgs,relaunch:e.relaunch,shutdown:e.shutdown,saveScript:e.saveScript,deviceHub:e.deviceHub,testIme:e.testIme,noRecord:e.noRecord,recordAs:e.recordAs,record:e.record,backMode:e.backMode,metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,launchUrl:e.launchUrl,...n(e,a),...te(e),appsFilter:e.appsFilter,kind:e.kind,out:e.out,count:e.count,fps:e.fps,quality:e.quality,hideTouches:e.hideTouches,recordingScope:e.recordingScope,intervalMs:e.intervalMs,delayMs:e.delayMs,durationMs:e.durationMs,holdMs:e.holdMs,jitterPx:e.jitterPx,pixels:e.pixels,until:e.until,doubleTap:e.doubleTap,verify:e.verify,settle:e.settle,settleQuietMs:e.settleQuietMs,clickButton:e.clickButton,pauseMs:e.pauseMs,pattern:e.pattern,headless:e.headless,restart:e.restart,replayUpdate:e.replayUpdate,replayBackend:e.replayBackend,replayEnv:e.replayEnv,replayShellEnv:e.replayShellEnv,replayScriptSource:e.replayScriptSource,replayScriptSources:e.replayScriptSources,replayFrom:e.replayFrom,replayPlanDigest:e.replayPlanDigest,replayKeepSession:e.replayKeepSession,failFast:e.failFast,timeoutMs:e.timeoutMs,retries:e.retries,recordVideo:e.recordVideo,artifactsDir:e.artifactsDir,shardAll:e.shardAll,shardSplit:e.shardSplit,findFirst:e.findFirst,findLast:e.findLast,networkInclude:e.networkInclude,batchOnError:e.batchOnError,batchMaxSteps:e.batchMaxSteps,batchSteps:e.batchSteps,verbose:e.debug})}function Zt(e,t){return{...Xt(e),...t}}function Qt(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!Yt.has(e))continue;let t=i[e];$t(t)&&(r[e]=t)}return r}function $t(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}function en(e){return{kind:`operator`,source:e}}function tn(e,t){return`${e} is not accepted as a tool argument. ${nn(e,t)}`}function nn(e,t){if(`operatorPath`in t)return t.operatorPath;let n=`for the process serving these tools.`,r=(t.envFlagKeys??[e]).map(ot).join(` or `);return r===``?`Set ${e} in ~/.agent-device/config.json ${n}`:`Set the ${r} environment variable${t.operatorConfig?` (or ${e} in ~/.agent-device/config.json)`:``} ${n}`}function rn(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function an(t,n){let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}function on(t,n){let r=t[n];if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}function sn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a string.`);return r}}function p(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}}function cn(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function ln(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`boolean`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a boolean.`);return r}}function un(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}function dn(t,n,r){let i=t[n];if(i!==void 0){if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}}function fn(t,n){let r=t[n];if(r!==void 0){if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}}function pn(t,n){let r=t[n];if(r!==void 0){if(!Array.isArray(r)||r.some(e=>typeof e!=`string`))throw new e(`INVALID_ARGS`,`Expected ${n} to be an array of strings.`);return r}}function mn(t,n,r,i){let a=new Set(n),o=Object.keys(t).filter(e=>!a.has(e));if(o.length>0)throw new e(`INVALID_ARGS`,`${r} has unknown field(s): ${o.join(`, `)}.`,i===void 0?void 0:{hint:i})}function m(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}const hn=en({operatorConfig:!0}),gn={session:{schema:{type:`string`,description:`Agent-device session name.`},read:e=>p(e,`session`),flagKey:`session`,flagIn:[`input`]},platform:{schema:{type:`string`,enum:ge,description:`Platform selector used to resolve a device.`},read:e=>dn(e,`platform`,ge),flagKey:`platform`,flagIn:[`input`,`selection`]},deviceTarget:{schema:{type:`string`,enum:_e,description:`Device target form. Maps to the CLI --target flag.`},read:Sn,clientKey:`target`,flagKey:`target`,flagIn:[`input`,`selection`]},target:{schema:{type:`string`,enum:_e,description:`Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element.`}},device:{schema:{type:`string`,description:`Device name selector (a UDID belongs in udid, a serial in serial).`},read:e=>p(e,`device`),flagKey:`device`,flagIn:[`input`,`selection`]},udid:{schema:{type:`string`,description:`Apple device or simulator UDID; the selector that pins one device when several share a name.`},read:e=>p(e,`udid`),flagKey:`udid`,flagIn:[`input`,`selection`]},serial:{schema:{type:`string`,description:`Android, HarmonyOS, or Vega VVD serial selector.`},read:e=>p(e,`serial`),flagKey:`serial`,flagIn:[`input`,`selection`]},iosSimulatorDeviceSet:{schema:{type:`string`,description:`iOS simulator device-set path used for device resolution.`},read:e=>p(e,`iosSimulatorDeviceSet`),audience:en({envFlagKeys:[],operatorConfig:!0}),flagKey:`iosSimulatorDeviceSet`,flagIn:[`input`,`selection`]},iosXctestrunFile:{schema:{type:`string`,description:`Externally built iOS XCTest runner .xctestrun artifact path.`},read:e=>p(e,`iosXctestrunFile`),audience:hn,flagKey:`iosXctestrunFile`,flagIn:[`input`]},iosXctestDerivedDataPath:{schema:{type:`string`,description:`Derived data path for external iOS XCTest runner execution.`},read:e=>p(e,`iosXctestDerivedDataPath`),audience:hn,flagKey:`iosXctestDerivedDataPath`,flagIn:[`input`]},iosXctestEnvDir:{schema:{type:`string`,description:`Writable directory for iOS XCTest runner env overlays.`},read:e=>p(e,`iosXctestEnvDir`),audience:hn,flagKey:`iosXctestEnvDir`,flagIn:[`input`]},androidDeviceAllowlist:{schema:{type:`string`,description:`Android serial allowlist used for device resolution.`},read:e=>p(e,`androidDeviceAllowlist`),flagKey:`androidDeviceAllowlist`,flagIn:[`input`,`selection`]},noRecord:{read:e=>ln(e,`noRecord`),flagKey:`noRecord`,flagIn:[`input`,`selection`]},daemonBaseUrl:{schema:{type:`string`,description:`Remote daemon base URL.`},read:e=>p(e,`daemonBaseUrl`),audience:hn},daemonAuthToken:{schema:{type:`string`,description:`Remote daemon auth token.`},read:e=>p(e,`daemonAuthToken`),audience:hn},tenant:{schema:{type:`string`,description:`Remote tenant identifier.`},read:e=>p(e,`tenant`)},runId:{schema:{type:`string`,description:`Lease run identifier.`},read:e=>p(e,`runId`)},leaseId:{schema:{type:`string`,description:`Existing lease identifier.`},read:e=>p(e,`leaseId`)},cwd:{schema:{type:`string`,description:`Working directory for command execution.`},read:e=>p(e,`cwd`),audience:en({operatorPath:`Start the process serving these tools in the desired working directory, or pass absolute paths.`})},debug:{schema:{type:`boolean`,description:`Enable debug diagnostics.`},read:e=>ln(e,`debug`)}},_n=Object.entries(gn),vn=Object.fromEntries(_n.flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]));function yn(){return Object.fromEntries(_n.flatMap(([e,t])=>t.schema?[[e,t.schema]]:[]))}function bn(e,t={}){let n={};for(let[r,i]of _n)i.read&&(n[r]=i.read(e,t));return n}function h(e){let t={};for(let[n,r]of _n)r.read&&(t[r.clientKey??n]=e[n]);return m(t)}function xn(e,t){let n={};for(let[r,i]of _n){if(i.flagIn===void 0||!i.flagIn.includes(t))continue;let a=t===`selection`?i.clientKey??r:r;n[a]=e[i.flagKey]}return n}function Sn(t,n){let r=dn(t,`deviceTarget`,_e);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=dn(t,`target`,_e);if(r!==void 0&&i!==r)throw new e(`INVALID_ARGS`,`Expected target alias to match deviceTarget when both are set.`);return r??i}function g(e,t){return n=>_(e,t?t(n):[],n)}function _(e,t,n,r){return{command:e,positionals:t,...r?{input:r}:{},options:Cn(n)}}function Cn(e){let t=wn(e.deviceTarget??e.target);if(t===void 0&&e.target===void 0)return e;let{target:n,...r}=e;return t===void 0?r:{...r,target:t}}function wn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function v(e){return m(xn(e,`input`))}function Tn(e){return m({record:e.record})}function En(e){return xn(e,`selection`)}function Dn(e){return m({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function On(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function kn(e){return m({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function An(e){return m({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function jn(e){if(`ref`in e&&e.ref!==void 0)return m({kind:`ref`,ref:e.ref,label:e.label});if(`selector`in e&&e.selector!==void 0)return{kind:`selector`,selector:e.selector};let t=e;return{kind:`point`,x:t.x,y:t.y}}function Mn(t){let n=Pn(t);if(typeof n.ref==`string`)return[n.ref,...In(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(Fn(n.x,`x`)),String(Fn(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function Nn(t){let n=Pn(t);if(typeof n.ref==`string`)return[n.ref,...In(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function Pn(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected target object.`);let n=t,r=n.target;return r&&typeof r==`object`&&!Array.isArray(r)?r:n}function Fn(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function In(e){return typeof e==`string`&&e.length>0?[e]:[]}function Ln(t){let n=Me(t);if(!n.ok)throw new e(n.code,n.message);return`ref`in n?{ref:n.ref,label:Vn(t.slice(1))}:{selector:n.selector}}function Rn(t){let n=Fe(t);if(!n.ok)throw new e(n.code,n.message);return n.format}function zn(t,n={}){let r=Le(t,n);if(!r)throw new e(`INVALID_ARGS`,Te);return r}function Bn(t,n){try{let e=JSON.parse(t);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}throw new e(`INVALID_ARGS`,`${n} must be a JSON object`)}function Vn(e){return e.join(` `).trim()||void 0}function y(...e){return new Set(e)}function b(e,t){return e!==void 0&&t.has(e)}function Hn(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function Un(t,n){if(t===void 0)return;let r=Number(t);if(Number.isFinite(r))return r;throw new e(`INVALID_ARGS`,`${n} must be a finite number.`)}function Wn(e){return e===void 0?void 0:Number(e)}function x(e){return e===void 0?[]:[e]}function S(e){return e===void 0?[]:[String(e)]}function C(t,n){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,n);return t}function w(t,n){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,n);return t}function Gn(e){return Jn(e.description,e.cliDetail)}function Kn(e){return Jn(e.description,e.mcpDetail)}function qn(e,t){return{...e,description:t}}function Jn(e,t){return t?`${e} ${t}`:e}function T(e){let t=qn(e.text,e.metadata.description),n=t.mcpDetail?{mcpDetail:t.mcpDetail}:{},r={...e.metadata,...n},i={name:r.name,description:r.description,inputSchema:r.inputSchema,...n,invoke:async(t,n)=>await e.run(t,r.readInput(n))};return{name:e.name,metadata:r,definition:i,cliSchema:{...e.cliSchema,text:t},cliReader:e.cliReader,daemonWriter:e.daemonWriter,cliOutputFormatter:e.cliOutputFormatter,text:t}}function E(e){let t={},n={},r={},i={};for(let a of e.commands)Yn(t,`CLI schema`,a.name,a.cliSchema),Yn(n,`CLI reader`,a.name,a.cliReader),a.daemonWriter&&Yn(r,`daemon writer`,a.name,a.daemonWriter),a.cliOutputFormatter&&Yn(i,`CLI output formatter`,a.name,a.cliOutputFormatter);return{name:e.name,clientSurface:e.clientSurface,metadata:e.commands.map(e=>e.metadata),definitions:e.commands.map(e=>e.definition),cliSchemas:t,cliReaders:n,daemonWriters:r,cliOutputFormatters:i}}function Yn(e,t,n,r){if(Object.hasOwn(e,n))throw Error(`Duplicate command family ${t}: ${n}`);e[n]=r}function D(e){return({result:t})=>e(t)}const O=D(k);function k(e){return{data:e,text:St(e)}}const Xn=D(e=>{let t=k(e),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):[];if(n.length===0)return t;let r=[t.text,...n.map(e=>`Warning: ${e}`)];return{data:t.data,text:r.filter(Boolean).join(`
1
+ import{C as e,S as t,_ as n,h as r,t as i,u as a,v as o}from"./sdk-contracts.js";import{d as s,f as c,i as ee,l as te,n as ne,p as re,t as ie,u as ae}from"./capture.js";import{D as oe,c as se,d as ce,f as le,g as l,l as ue,o as de,p as fe,s as pe,u as me}from"./sdk-batch-runner.js";import{t as he}from"./viewport.js";import{r as ge,t as _e}from"./sdk-device.js";import{i as ve,s as ye}from"./lease-scope.js";import{Dn as be,Nr as xe,Or as Se,Tn as Ce,Wr as we,ar as Te,fr as Ee,i as De,in as Oe,jn as ke,m as Ae,nn as je,or as Me,p as Ne,s as Pe,sr as Fe,ur as Ie,vr as Le}from"./sdk-batch.js";import{n as Re}from"./recording-export-quality.js";import{i as ze,r as Be,s as Ve,t as He}from"./back-mode.js";import{a as Ue,n as We,o as Ge,r as Ke,s as qe}from"./scroll-gesture.js";import{E as Je,T as Ye,b as Xe,v as Ze,w as Qe}from"./script.js";import{a as $e,i as et,r as tt}from"./vars.js";import{n as nt,r as rt,t as it}from"./format.js";import{n as u,t as at}from"./catalog.js";import{a as ot}from"./sdk-remote-config.js";import{t as st}from"./session.js";import{a as ct,c as lt,d as ut,f as dt,g as ft,h as pt,i as mt,l as ht,n as gt,o as _t,p as vt,s as yt,t as bt,u as xt}from"./observability.js";import{t as St}from"./success-text.js";import{t as Ct}from"./alert-contract.js";import{i as wt,t as Tt}from"./location-coordinates.js";import{t as Et}from"./snapshot-quality-backend-capabilities.js";import{a as Dt,d as Ot,f as kt,l as At,t as jt,u as Mt}from"./absence-observation-errors.js";import{t as Nt}from"./mobile-snapshot-semantics.js";import{t as Pt}from"./click-button.js";import{n as Ft}from"./scroll-command.js";import{n as It,t as Lt}from"./interaction-positionals.js";import{t as Rt}from"./app-inventory.js";import"./device.js";import{a as zt,t as Bt}from"./device-rotation.js";import"./app-inventory-contract.js";import{t as Vt}from"./prepare-kind.js";import{n as Ht,t as Ut}from"./path-resolution.js";import"./file.js";import{n as Wt,r as Gt,s as Kt,t as qt}from"./tv-remote.js";import d from"node:path";import f from"node:fs";const Jt=[`path`,`start`,`stop`,`doctor`,`mark`,`clear`],Yt=new Set(Be().map(e=>e.key));function Xt(e){let t=ve(e);return oe({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...ye(t),provider:e.provider,providerSessionId:e.providerSessionId,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerAppiumVersion:e.providerAppiumVersion,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,sessionIsolation:e.sessionIsolation,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,surface:e.surface,activity:e.activity,launchConsole:e.launchConsole,launchArgs:e.launchArgs,relaunch:e.relaunch,shutdown:e.shutdown,saveScript:e.saveScript,deviceHub:e.deviceHub,testIme:e.testIme,noRecord:e.noRecord,recordAs:e.recordAs,record:e.record,backMode:e.backMode,metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,launchUrl:e.launchUrl,...n(e,a),...te(e),appsFilter:e.appsFilter,kind:e.kind,out:e.out,count:e.count,fps:e.fps,quality:e.quality,hideTouches:e.hideTouches,recordingScope:e.recordingScope,intervalMs:e.intervalMs,delayMs:e.delayMs,durationMs:e.durationMs,holdMs:e.holdMs,jitterPx:e.jitterPx,pixels:e.pixels,until:e.until,doubleTap:e.doubleTap,verify:e.verify,settle:e.settle,settleQuietMs:e.settleQuietMs,clickButton:e.clickButton,pauseMs:e.pauseMs,pattern:e.pattern,headless:e.headless,restart:e.restart,replayUpdate:e.replayUpdate,replayBackend:e.replayBackend,replayEnv:e.replayEnv,replayShellEnv:e.replayShellEnv,replayScriptSource:e.replayScriptSource,replayScriptSources:e.replayScriptSources,replayFrom:e.replayFrom,replayPlanDigest:e.replayPlanDigest,replayKeepSession:e.replayKeepSession,failFast:e.failFast,timeoutMs:e.timeoutMs,retries:e.retries,recordVideo:e.recordVideo,artifactsDir:e.artifactsDir,shardAll:e.shardAll,shardSplit:e.shardSplit,findFirst:e.findFirst,findLast:e.findLast,networkInclude:e.networkInclude,batchOnError:e.batchOnError,batchMaxSteps:e.batchMaxSteps,batchSteps:e.batchSteps,verbose:e.debug})}function Zt(e,t){return{...Xt(e),...t}}function Qt(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!Yt.has(e))continue;let t=i[e];$t(t)&&(r[e]=t)}return r}function $t(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}function en(e){return{kind:`operator`,source:e}}function tn(e,t){return`${e} is not accepted as a tool argument. ${nn(e,t)}`}function nn(e,t){if(`operatorPath`in t)return t.operatorPath;let n=`for the process serving these tools.`,r=(t.envFlagKeys??[e]).map(ot).join(` or `);return r===``?`Set ${e} in ~/.agent-device/config.json ${n}`:`Set the ${r} environment variable${t.operatorConfig?` (or ${e} in ~/.agent-device/config.json)`:``} ${n}`}function rn(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function an(t,n){let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}function on(t,n){let r=t[n];if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}function sn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a string.`);return r}}function p(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}}function cn(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function ln(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`boolean`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a boolean.`);return r}}function un(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}function dn(t,n,r){let i=t[n];if(i!==void 0){if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}}function fn(t,n){let r=t[n];if(r!==void 0){if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}}function pn(t,n){let r=t[n];if(r!==void 0){if(!Array.isArray(r)||r.some(e=>typeof e!=`string`))throw new e(`INVALID_ARGS`,`Expected ${n} to be an array of strings.`);return r}}function mn(t,n,r,i){let a=new Set(n),o=Object.keys(t).filter(e=>!a.has(e));if(o.length>0)throw new e(`INVALID_ARGS`,`${r} has unknown field(s): ${o.join(`, `)}.`,i===void 0?void 0:{hint:i})}function m(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}const hn=en({operatorConfig:!0}),gn={session:{schema:{type:`string`,description:`Agent-device session name.`},read:e=>p(e,`session`),flagKey:`session`,flagIn:[`input`]},platform:{schema:{type:`string`,enum:ge,description:`Platform selector used to resolve a device.`},read:e=>dn(e,`platform`,ge),flagKey:`platform`,flagIn:[`input`,`selection`]},deviceTarget:{schema:{type:`string`,enum:_e,description:`Device target form. Maps to the CLI --target flag.`},read:Sn,clientKey:`target`,flagKey:`target`,flagIn:[`input`,`selection`]},target:{schema:{type:`string`,enum:_e,description:`Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element.`}},device:{schema:{type:`string`,description:`Device name selector (a UDID belongs in udid, a serial in serial).`},read:e=>p(e,`device`),flagKey:`device`,flagIn:[`input`,`selection`]},udid:{schema:{type:`string`,description:`Apple device or simulator UDID; the selector that pins one device when several share a name.`},read:e=>p(e,`udid`),flagKey:`udid`,flagIn:[`input`,`selection`]},serial:{schema:{type:`string`,description:`Android, HarmonyOS, or Vega VVD serial selector.`},read:e=>p(e,`serial`),flagKey:`serial`,flagIn:[`input`,`selection`]},iosSimulatorDeviceSet:{schema:{type:`string`,description:`iOS simulator device-set path used for device resolution.`},read:e=>p(e,`iosSimulatorDeviceSet`),audience:en({envFlagKeys:[],operatorConfig:!0}),flagKey:`iosSimulatorDeviceSet`,flagIn:[`input`,`selection`]},iosXctestrunFile:{schema:{type:`string`,description:`Externally built iOS XCTest runner .xctestrun artifact path.`},read:e=>p(e,`iosXctestrunFile`),audience:hn,flagKey:`iosXctestrunFile`,flagIn:[`input`]},iosXctestDerivedDataPath:{schema:{type:`string`,description:`Derived data path for external iOS XCTest runner execution.`},read:e=>p(e,`iosXctestDerivedDataPath`),audience:hn,flagKey:`iosXctestDerivedDataPath`,flagIn:[`input`]},iosXctestEnvDir:{schema:{type:`string`,description:`Writable directory for iOS XCTest runner env overlays.`},read:e=>p(e,`iosXctestEnvDir`),audience:hn,flagKey:`iosXctestEnvDir`,flagIn:[`input`]},androidDeviceAllowlist:{schema:{type:`string`,description:`Android serial allowlist used for device resolution.`},read:e=>p(e,`androidDeviceAllowlist`),flagKey:`androidDeviceAllowlist`,flagIn:[`input`,`selection`]},noRecord:{read:e=>ln(e,`noRecord`),flagKey:`noRecord`,flagIn:[`input`,`selection`]},daemonBaseUrl:{schema:{type:`string`,description:`Remote daemon base URL.`},read:e=>p(e,`daemonBaseUrl`),audience:hn},daemonAuthToken:{schema:{type:`string`,description:`Remote daemon auth token.`},read:e=>p(e,`daemonAuthToken`),audience:hn},tenant:{schema:{type:`string`,description:`Remote tenant identifier.`},read:e=>p(e,`tenant`)},runId:{schema:{type:`string`,description:`Lease run identifier.`},read:e=>p(e,`runId`)},leaseId:{schema:{type:`string`,description:`Existing lease identifier.`},read:e=>p(e,`leaseId`)},cwd:{schema:{type:`string`,description:`Working directory for command execution.`},read:e=>p(e,`cwd`),audience:en({operatorPath:`Start the process serving these tools in the desired working directory, or pass absolute paths.`})},debug:{schema:{type:`boolean`,description:`Enable debug diagnostics.`},read:e=>ln(e,`debug`)}},_n=Object.entries(gn),vn=Object.fromEntries(_n.flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]));function yn(){return Object.fromEntries(_n.flatMap(([e,t])=>t.schema?[[e,t.schema]]:[]))}function bn(e,t={}){let n={};for(let[r,i]of _n)i.read&&(n[r]=i.read(e,t));return n}function h(e){let t={};for(let[n,r]of _n)r.read&&(t[r.clientKey??n]=e[n]);return m(t)}function xn(e,t){let n={};for(let[r,i]of _n){if(i.flagIn===void 0||!i.flagIn.includes(t))continue;let a=t===`selection`?i.clientKey??r:r;n[a]=e[i.flagKey]}return n}function Sn(t,n){let r=dn(t,`deviceTarget`,_e);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=dn(t,`target`,_e);if(r!==void 0&&i!==r)throw new e(`INVALID_ARGS`,`Expected target alias to match deviceTarget when both are set.`);return r??i}function g(e,t){return n=>_(e,t?t(n):[],n)}function _(e,t,n,r){return{command:e,positionals:t,...r?{input:r}:{},options:Cn(n)}}function Cn(e){let t=wn(e.deviceTarget??e.target);if(t===void 0&&e.target===void 0)return e;let{target:n,...r}=e;return t===void 0?r:{...r,target:t}}function wn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function v(e){return m(xn(e,`input`))}function Tn(e){return m({record:e.record})}function En(e){return xn(e,`selection`)}function Dn(e){return m({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function On(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function kn(e){return m({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function An(e){return m({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function jn(e){if(`ref`in e&&e.ref!==void 0)return m({kind:`ref`,ref:e.ref,label:e.label});if(`selector`in e&&e.selector!==void 0)return{kind:`selector`,selector:e.selector};let t=e;return{kind:`point`,x:t.x,y:t.y}}function Mn(t){let n=Pn(t);if(typeof n.ref==`string`)return[n.ref,...In(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(Fn(n.x,`x`)),String(Fn(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function Nn(t){let n=Pn(t);if(typeof n.ref==`string`)return[n.ref,...In(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function Pn(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected target object.`);let n=t,r=n.target;return r&&typeof r==`object`&&!Array.isArray(r)?r:n}function Fn(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function In(e){return typeof e==`string`&&e.length>0?[e]:[]}function Ln(t){let n=Me(t);if(!n.ok)throw new e(n.code,n.message);return`ref`in n?{ref:n.ref,label:Vn(t.slice(1))}:{selector:n.selector}}function Rn(t){let n=Fe(t);if(!n.ok)throw new e(n.code,n.message);return n.format}function zn(t,n={}){let r=Le(t,n);if(!r)throw new e(`INVALID_ARGS`,Te);return r}function Bn(t,n){try{let e=JSON.parse(t);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}throw new e(`INVALID_ARGS`,`${n} must be a JSON object`)}function Vn(e){return e.join(` `).trim()||void 0}function y(...e){return new Set(e)}function b(e,t){return e!==void 0&&t.has(e)}function Hn(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function Un(t,n){if(t===void 0)return;let r=Number(t);if(Number.isFinite(r))return r;throw new e(`INVALID_ARGS`,`${n} must be a finite number.`)}function Wn(e){return e===void 0?void 0:Number(e)}function x(e){return e===void 0?[]:[e]}function S(e){return e===void 0?[]:[String(e)]}function C(t,n){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,n);return t}function w(t,n){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,n);return t}function Gn(e){return Jn(e.description,e.cliDetail)}function Kn(e){return Jn(e.description,e.mcpDetail)}function qn(e,t){return{...e,description:t}}function Jn(e,t){return t?`${e} ${t}`:e}function T(e){let t=qn(e.text,e.metadata.description),n=t.mcpDetail?{mcpDetail:t.mcpDetail}:{},r={...e.metadata,...n},i={name:r.name,description:r.description,inputSchema:r.inputSchema,...n,invoke:async(t,n)=>await e.run(t,r.readInput(n))};return{name:e.name,metadata:r,definition:i,cliSchema:{...e.cliSchema,text:t},cliReader:e.cliReader,daemonWriter:e.daemonWriter,cliOutputFormatter:e.cliOutputFormatter,text:t}}function E(e){let t={},n={},r={},i={};for(let a of e.commands)Yn(t,`CLI schema`,a.name,a.cliSchema),Yn(n,`CLI reader`,a.name,a.cliReader),a.daemonWriter&&Yn(r,`daemon writer`,a.name,a.daemonWriter),a.cliOutputFormatter&&Yn(i,`CLI output formatter`,a.name,a.cliOutputFormatter);return{name:e.name,clientSurface:e.clientSurface,metadata:e.commands.map(e=>e.metadata),definitions:e.commands.map(e=>e.definition),cliSchemas:t,cliReaders:n,daemonWriters:r,cliOutputFormatters:i}}function Yn(e,t,n,r){if(Object.hasOwn(e,n))throw Error(`Duplicate command family ${t}: ${n}`);e[n]=r}function D(e){return({result:t})=>e(t)}const O=D(k);function k(e){return{data:e,text:St(e)}}const Xn=D(e=>{let t=k(e),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):[];if(n.length===0)return t;let r=[t.text,...n.map(e=>`Warning: ${e}`)];return{data:t.data,text:r.filter(Boolean).join(`
2
2
  `)}});function Zn(e,t){if(typeof e==`string`&&e.length!==0&&typeof t==`number`)return`@${e.startsWith(`@`)?e.slice(1):e}~s${t}`}function Qn(e){let t=[`Batch completed: ${e.executed}/${e.total} steps in ${e.totalDurationMs}ms`];for(let n of e.results)t.push(er(n));return{data:e,text:t.join(`
3
3
  `)}}const $n={batch:D(Qn)};function er(e){let t=St(e.data)??e.command;return`${e.step}. OK ${t} (${e.durationMs}ms)`}function tr(e){return e}const nr=[`ref`,`selector`,`point`];function rr(e,t=[]){return{type:`object`,properties:{...yn(),...e},...t.length>0?{required:t}:{},additionalProperties:!1}}function ir(e){return{type:`object`,description:e,properties:{x:{type:`number`},y:{type:`number`}},required:[`x`,`y`],additionalProperties:!1}}function ar(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function A(e){return{type:`string`,...e?{description:e}:{}}}function or(e,t={}){return{type:`number`,...e?{description:e}:{},...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function sr(e){return{type:`integer`,...e?{description:e}:{}}}function cr(e){return{type:`boolean`,...e?{description:e}:{}}}function lr(e){return{type:`array`,items:{type:`string`},...e?{description:e}:{}}}function ur(e){return{type:`object`,additionalProperties:!0,...e?{description:e}:{}}}function j(e){return{...e,required:!0}}function M(e,t={}){return R(A(e),t.allowEmpty===!0?sn:p)}function dr(t){return{schema:{type:`null`},required:!1,audience:{kind:`retired`,message:t},read:(n,r)=>{if(Object.hasOwn(n,r))throw new e(`INVALID_ARGS`,t)}}}function fr(e,t){return{...e,audience:{kind:`operator`,source:t}}}function N(e,t={}){return R(or(e,t),(e,n)=>fe(e,n,t))}function P(e,t={}){return R(Pr(e,t),(e,n)=>le(e,n,t))}function F(e){return R(cr(e),ln)}function pr(e){return hr(mr(e))}function mr(e){let[t,...n]=ze(e).filter(e=>e.inputDescription!==void 0);if(!t)throw Error(`Flag ${e} declares no inputDescription; optionField cannot derive a field`);if(n.length>0)throw Error(`Flag ${e} declares inputDescription more than once`);return t}function hr(e){let t=e.inputDescription,n={min:e.min,max:e.max};switch(e.type){case`boolean`:return F(t);case`int`:return P(t,n);case`number`:return N(t,n);case`string`:return M(t);case`enum`:return I(gr(e),t);case`booleanOrString`:throw Error(`Flag ${e.key} is booleanOrString; declare its field shape explicitly with jsonSchemaField`)}}function gr(e){let t=e.enumValues;if(!t)throw Error(`Flag ${e.key} is an enum with no enumValues`);return t}function I(e,t){return R(ar(e,t),(t,n)=>dn(t,n,e))}function _r(e){return R(ur(e),fn)}function vr(e){return R(lr(e),pn)}function L(e){return R(e,(e,t)=>e[t])}function yr(e,t){return R(e,t)}function br(){return R(Rr(),(e,t)=>e[t]===void 0?void 0:Dr(e,t))}function xr(){return R(zr(),(e,t)=>e[t]===void 0?void 0:Or(e,t))}function Sr(e){return R(ir(e),(e,t)=>e[t]===void 0?void 0:kr(e,t))}function Cr(){return{depth:P(`Snapshot traversal depth.`,{min:0}),scope:M(`Snapshot scope selector used before resolution.`),raw:F(`Use raw snapshot data during selector resolution.`)}}function wr(){return{count:P(`Number of press/click repetitions.`,{min:1}),intervalMs:P(`Delay between repeated press/click actions.`,{min:0}),holdMs:P(`Hold duration for each action.`,{min:0}),jitterPx:P(`Randomization radius in pixels.`,{min:0}),doubleTap:F(`Request a double-tap action.`)}}function Tr(e){return rr(Fr(e),Ir(e))}function Er(t,n){let r=rn(t),i=Object.fromEntries(Object.entries(n).flatMap(([t,n])=>{let i=n.read(r,t);if(n.required&&i===void 0)throw new e(`INVALID_ARGS`,`Expected ${t} to be set.`);return i===void 0?[]:[[t,i]]})),a=bn(r,{readTargetAlias:!Object.hasOwn(n,`target`)});return m({...a,...h(a),...i})}function Dr(e,t){let n=an(e,t),r=un(n,`kind`,nr);switch(r){case`ref`:return{kind:r,ref:on(n,`ref`),label:p(n,`label`)};case`selector`:return{kind:r,selector:on(n,`selector`)};case`point`:return{kind:r,x:cn(n,`x`),y:cn(n,`y`)}}}function Or(e,t){let n=an(e,t),r=un(n,`kind`,[`ref`,`selector`]);return r===`ref`?{kind:r,ref:on(n,`ref`),label:p(n,`label`)}:{kind:r,selector:on(n,`selector`)}}function kr(e,t){let n=an(e,t);return{x:cn(n,`x`),y:cn(n,`y`)}}function Ar(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector};case`point`:return{x:e.x,y:e.y}}}function jr(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector}}}function Mr(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function Nr(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function R(e,t){return{schema:e,required:!1,read:t}}function Pr(e,t){return{...sr(e),...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function Fr(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e.audience?.kind!==`retired`).map(([e,t])=>[e,t.schema]))}function Ir(e){return Object.entries(e).flatMap(([e,t])=>t.required?[e]:[])}function Lr(e){return Object.fromEntries(Object.entries(e).flatMap(([e,t])=>t.audience?[[e,t.audience]]:[]))}function Rr(){return{oneOf:[...Br(),{type:`object`,properties:{kind:{type:`string`,const:`point`},x:{type:`number`},y:{type:`number`}},required:[`kind`,`x`,`y`],additionalProperties:!1}],description:`UI target. This is separate from deviceTarget, which selects the device form.`}}function zr(){return{oneOf:Br(),description:`UI element target by snapshot ref or selector expression.`}}function Br(){return[{type:`object`,properties:{kind:{type:`string`,const:`ref`},ref:{type:`string`,description:`Snapshot element ref such as @e12.`},label:{type:`string`,description:`Optional human label for the ref.`}},required:[`kind`,`ref`],additionalProperties:!1},{type:`object`,properties:{kind:{type:`string`,const:`selector`},selector:{type:`string`,description:`Agent-device selector expression.`}},required:[`kind`,`selector`],additionalProperties:!1}]}function z(e,t,n,r){return tr({name:e,description:t,inputSchema:Tr(n),readInput:r?.readInput??(e=>Er(e,n)),inputAudience:Lr(n)})}function Vr(e=De){let t=Hr(e);return z(`batch`,`Execute multiple commands in one daemon request.`,t,{readInput:e=>Wr(e,t)})}function Hr(e){return{steps:j(yr({type:`array`,description:`Structured batch steps. Each step uses a command name and the same input object as that command tool.`,items:Ur(e)},(t,n)=>Gr(t[n],e))),onError:I([`stop`],`Batch failure policy.`),maxSteps:P(`Maximum number of steps accepted for this batch.`,{min:1,max:1e3}),out:M(`Optional output path for command artifacts.`)}}function Ur(e){return{type:`object`,properties:{command:{type:`string`,enum:e,description:`Command name to run with structured input.`},input:{type:`object`,additionalProperties:!0,commandInputFor:`command`,description:`Structured command input for the nested command. Use the matching MCP tool schema for this object.`},runtime:{type:`object`,additionalProperties:!0,description:`Optional per-step runtime payload.`}},required:[`command`,`input`],additionalProperties:!1}}function Wr(t,n){let r=Er(t,n),i=r.maxSteps??100;if(!se(i))throw new e(`INVALID_ARGS`,`Invalid batch maxSteps: ${String(r.maxSteps)}`);return pe(r.steps.length,i),{...r}}function Gr(t,n){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected steps to be an array.`);return t.map((e,t)=>Kr(e,t+1,n))}function Kr(e,t,n){let r=ce(e,t);return mn(r,[`command`,`input`,`runtime`],`Batch step ${t}`,de),{command:qr(r,t,n),input:me(r,t),...Jr(r,t)}}function qr(t,n,r){if(r===De)return Pe(t.command,n);let i=t.command;if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected command to be one of: ${r.join(`, `)}.`);return i}function Jr(e,t){let n=ue(e.runtime,t);return n===void 0?{}:{runtime:n}}function Yr(e){return async t=>_(u.batch,[],{...t,batchSteps:await Xr(t.steps,e),batchOnError:t.onError,batchMaxSteps:t.maxSteps})}async function Xr(t,n){if(!Array.isArray(t)||t.length===0)throw new e(`INVALID_ARGS`,`batch requires a non-empty steps array.`);let r=[];for(let[e,i]of t.entries())r.push(await Zr(i,e+1,n));return r}async function Zr(e,t,n){let r=ce(e,t),i=Qr(r,t),a=me(r,t),o=ue(r.runtime,t),s=await n(i,a,t);return{command:s.command,positionals:s.positionals,...s.input?{input:s.input}:{},flags:Zt(s.options,s.metadataFlags),runtime:o??s.options.runtime}}function Qr(e,t){return Pe(e.command,t)}const $r=Vr(),ei={usageOverride:`batch [--steps <json> | --steps-file <path>]`,usageFlags:[],listUsageOverride:`batch --steps <json> | --steps-file <path>`,allowedFlags:[`steps`,`stepsFile`,`batchOnError`,`batchMaxSteps`,`out`]},ti=(e,t)=>({...v(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out}),ni=[{command:`snapshot`,input:{interactiveOnly:!0}},{command:`press`,input:{target:{kind:`ref`,ref:`@e12`},settle:!0}},{command:`fill`,input:{target:{kind:`selector`,selector:`id="field-email"`},text:`qa@example.com`}}];function ri(){return`${[`Each step is {"command":"<name>","input":{...}}, and input is that command's structured input object rather than its terminal spelling: a CLI positional becomes a named field (target, text, direction) and a CLI flag becomes a camelCase key (--settle -> "settle":true, -i -> "interactiveOnly":true). There is no positional step form; args, argv, positionals, and flags are not step fields. agent-device help <command> lists arguments in CLI spelling only. The examples below carry the structured spelling; over MCP, the command tool schema states it in full.`,`Steps run serially in one daemon request against the same session, in order. Mutating UI verbs are included (press, click, fill, longpress, scroll, back), which is where the round-trip saving is; --on-error stop halts at the first failing step.`,`Available through batch: ${[...De].sort().join(`, `)}.`,`Every other command is excluded: batch and replay never nest, and session, daemon, connection, and host tooling commands own lifecycle a batch request cannot carry. Run those on their own.`].join(` `)}\n\nExamples:\n${[` agent-device batch --steps '${JSON.stringify(ni)}'`,` agent-device batch --steps-file ./steps.json --json`].join(`
4
- `)}`}const ii=E({name:`batch`,clientSurface:!1,commands:[T({name:`batch`,text:{summary:`Run multiple commands`,cliDetail:ri()},metadata:$r,run:(e,t)=>e.batch.run(ai(t)),cliSchema:ei,cliReader:ti,cliOutputFormatter:$n.batch})]});function ai(e){return{...h(e),steps:e.steps,onError:e.onError,maxSteps:e.maxSteps,out:e.out}}const oi=`alert`,si=T({name:oi,text:{summary:`Inspect, accept, or dismiss a platform alert`},metadata:z(oi,`Inspect, wait for, accept, or dismiss a platform alert. Use get before acting when the alert content matters; accept and dismiss change the active alert state. Each iOS XCTest execution activates once, then only observes. Inspect again after an unconfirmed action; never assume a timeout means nothing happened.`,{action:I(Ct),timeoutMs:P()}),run:(e,t)=>e.command.alert(t),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...v(t),...li(e)}),daemonWriter:g(u.alert,e=>ci(e)),cliOutputFormatter:O});function ci(e){return[e.action??`get`,...S(e.timeoutMs)]}function li(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return m({action:ui(t[0]),timeoutMs:Un(t[1],`alert timeout`)})}function ui(t){let n=t?.toLowerCase();if(n===void 0||n===`get`||n===`accept`||n===`dismiss`||n===`wait`)return n;throw new e(`INVALID_ARGS`,`alert action must be get, accept, dismiss, or wait.`)}function B(...e){return e}const di=B(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),V=B(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),fi=B(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),pi=B(`metroHost`,`metroPort`,`bundleUrl`),mi=B(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),hi=B(`settle`,`settleQuietMs`,`timeoutMs`),gi=B(`replayUpdate`,`replayEnv`),_i=B(`remoteConfig`,`stateDir`,`daemonBaseUrl`,`daemonAuthToken`,`daemonTransport`,`daemonServerMode`,`tenant`,`sessionIsolation`,`runId`,`leaseId`,`leaseBackend`,`sessionLock`,`platform`,`target`,`device`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`providerDeviceOrientation`,`providerGeoLocation`,`providerTimezone`,`providerLanguage`,`providerLocale`,`providerNetworkProfile`,`providerCustomNetwork`,`providerNoResignApp`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`udid`,`serial`,`iosSimulatorDeviceSet`,`iosXctestrunFile`,`iosXctestDerivedDataPath`,`iosXctestEnvDir`,`androidDeviceAllowlist`,`session`,`noRecord`),vi=new Set([`platform`,`device`,`udid`,`serial`,`session`]),yi=new Set([`json`,`config`,`help`,`version`,`verbose`,`cost`,`responseLevel`]),bi=`diff`,xi=T({name:bi,text:{summary:`Diff snapshot or screenshot`,cliDetail:`Screenshot --threshold is a per-pixel RGB tolerance: 0 requires exact colors and 1 ignores color differences; image dimensions must still match. Live iOS simulator screenshot diffs normalize status-bar chrome by default; use screenshot --normalize-status-bar when capturing reusable baselines.`},metadata:z(bi,`Compare accessibility snapshots or screenshots to identify UI changes. Use snapshot comparisons for semantic tree changes and screenshot comparisons for pixel differences.`,{kind:j(L({type:`string`,const:`snapshot`})),out:M(),interactiveOnly:F(),depth:P(),scope:M(),raw:F()}),run:(e,t)=>e.capture.diff(t),cliSchema:{usageOverride:`diff snapshot | diff screenshot --baseline <path> [current.png] [--out <diff.png>] [--threshold <0-1>] [--overlay-refs]`,usageFlags:[],positionalArgs:[`kind`,`current?`],allowedFlags:[...di,`baseline`,`threshold`,`out`,`overlayRefs`]},cliReader:(t,n)=>{if(t[0]!==`snapshot`)throw new e(`INVALID_ARGS`,`Only diff snapshot is available through this parser.`);return{...v(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:g(u.diff,e=>[w(e.kind,`diff requires kind`)])}),Si=`screenshot`,Ci=T({name:Si,text:{summary:`Capture a screenshot`,cliDetail:`Web defaults to the viewport; use --fullscreen, --full, or -f for the entire page. iOS simulators default to 1x logical-point output; use --pixel-density to request a different screenshot density. macOS app sessions default to the app window; use --fullscreen for full desktop, --scale to downscale, --crop-on <selector> to crop the capture to the frame the selector resolves on the same screen (currently iOS simulators and Android emulators), --overlay-refs to annotate current refs, --normalize-status-bar for deterministic iOS simulator chrome, or --no-stabilize for low-latency Android capture loops.`},metadata:z(Si,`Capture a screenshot of the active app or web session. Choose the capture scope, density, size, or annotations through the corresponding input fields when needed.`,{path:M(`Output path.`),cropOn:M(`Selector expression; the capture is cropped to the frame the selector resolves on the same screen.`),overlayRefs:F(),pixelDensity:P(`Output screenshot pixel density in pixels per logical point.`,{min:1}),fullscreen:F(),scale:N(`Screenshot scale factor.`,ee),maxSize:dr(ie.migration.screenshot),stabilize:F(),normalizeStatusBar:F(),surface:I(st)}),run:(e,t)=>e.capture.screenshot(t),cliSchema:{positionalArgs:[`path?`],allowedFlags:ne},cliReader:(e,t)=>({...v(t),path:e[0]??t.out,...s(t)}),daemonWriter:e=>(c(`screenshot`,e),re(e),_(u.screenshot,x(e.path),{...e,...ae(e)}))}),wi=`settings`,Ti=T({name:wi,text:{summary:`Change OS settings and app permissions`,cliDetail:`macOS supports only settings appearance <light|dark|toggle> and settings permission <grant|reset> <accessibility|screen-recording|input-monitoring>; wifi|airplane|location|animations remain unsupported on macOS. Mobile permission actions use the active session app. On Android, deny|reset of a permission the app currently holds kills a running app; the response reports priorGrantState (granted|not_granted|unknown) and warns for granted and unknown, with open <app> --relaunch to restore it. Permission changes require a resolvable foreground user and fail without mutating if adb cannot report one. Android settings airplane on|off is applied by the connectivity service (Android 11+) and reports the airplaneMode that service holds; older builds fail without changing device state. settings reset-keychain clear is iOS-simulator-only and resets the whole simulator keychain, not just the selected app: simctl exposes no per-app keychain reset, so every app on that simulator loses its keychain-backed credentials (e.g. Firebase auth). clear-app-state does not touch the keychain, so a full fresh-install reset needs both; relaunch the app afterward to observe the signed-out state.`},metadata:z(wi,`Change supported operating-system settings, animation scales, appearance, or app permissions on the selected target. Platform support varies by setting and action.`,{setting:j(M()),state:j(M()),app:M(),latitude:N(),longitude:N(),permission:M(),mode:I([`full`,`limited`])}),run:(e,t)=>e.settings.update(t),cliSchema:{usageOverride:wt,listUsageOverride:`settings [area] [options]`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>Ei(e,t),daemonWriter:g(u.settings,e=>Di(e)),cliOutputFormatter:Xn});function Ei(t,n){let r=En(n),i=t[0],a=t[1];if(b(i,Ai)&&b(a,ji))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:Tt(t[2],`latitude`),longitude:Tt(t[3],`longitude`)};if(i===`appearance`&&b(a,Mi)||b(i,Ni)&&b(a,Pi)||i===`fingerprint`&&b(a,Fi))return{...r,setting:i,state:a};if(i===`permission`&&b(a,Ii))return{...r,setting:i,state:a,permission:Oi(t[2]),mode:ki(t[3])};if(i===`clear-app-state`){let e=a===`clear`?t[2]:a;return{...r,setting:i,state:`clear`,app:e}}if(i===`reset-keychain`&&a===`clear`&&t.length===2)return{...r,setting:i,state:a};throw new e(`INVALID_ARGS`,`Invalid settings arguments.`)}function Di(e){return e.setting===`clear-app-state`?[e.setting,...x(e.app)]:e.setting===`location`&&e.state===`set`?[e.setting,e.state,String(e.latitude),String(e.longitude)]:e.setting===`permission`?[e.setting,e.state,e.permission,...x(e.mode)]:[e.setting,e.state]}function Oi(t){if(b(t,Li))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function ki(t){if(t===void 0||t===`full`||t===`limited`)return t;throw new e(`INVALID_ARGS`,`settings permission mode must be full or limited.`)}const Ai=y(`wifi`,`airplane`,`location`,`animations`),ji=y(`on`,`off`),Mi=y(`light`,`dark`,`toggle`),Ni=y(`faceid`,`touchid`),Pi=y(`match`,`nonmatch`,`enroll`,`unenroll`),Fi=y(`match`,`nonmatch`),Ii=y(`grant`,`deny`,`reset`),Li=y(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function Ri(e){if(!Array.isArray(e)||e.length===0)return e;let t=xe(e);return e.map(e=>{let n=zi(e,t,e=>e.label),r=zi(e,t,e=>e.identifier),i=typeof e.label==`string`&&e.label.length>=24&&e.label===n,a=typeof e.identifier==`string`&&e.identifier.length>=24&&e.identifier===r;if(!i&&!a)return e;let o={...e};return i&&(delete o.label,o.inheritsLabel=!0),a&&(delete o.identifier,o.inheritsIdentifier=!0),o})}function zi(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0;for(;r;){let e=n(r);if(typeof e==`string`&&e.length>0)return e;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}}function Bi(e){return e.width>0&&e.height>0}function Vi(e,t){return!e||!t?!1:e.x>=t.x-2&&e.y>=t.y-2&&e.x+e.width<=t.x+t.width+2&&e.y+e.height<=t.y+t.height+2}function Hi(e,t){if(!e||!t)return!0;let n=e.y+e.height/2,r=t.y+t.height/2;return Math.abs(n-r)<=Math.max(e.height,t.height,1)}function Ui(e){return typeof e.parentIndex!=`number`}function Wi(e){let t=(e.type??``).toLowerCase(),n=(e.identifier??``).trim().toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)||n===`composer`}function Gi(e){let t=(e.type??``).toLowerCase();return t.includes(`scroll`)||t.includes(`list`)||t.includes(`recyclerview`)}function H(e){let t=Se(e);if(!t||t!==e.identifier?.trim()||!qi(t))return t;let n=(e.type??``).toLowerCase();return n.includes(`view`)||n.includes(`layout`)||n.includes(`image`)||n.includes(`list`)||n.includes(`recyclerview`)||n.includes(`collection`)?``:t}function Ki(e){let t=e.trim().replaceAll(/\s+/g,` `).toLowerCase();return!t||/^(true|false|\d+)$/.test(t)?null:t}function qi(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function Ji(e,t,n){let r=e;for(;typeof r.parentIndex==`number`;){let e=t.get(r.parentIndex);if(!e)return null;if(n(e))return e;r=e}return null}function Yi(e,t){let n=[],r=[t];for(;r.length>0;){let t=r.pop();for(let i of e)i.parentIndex===t&&(n.push(i),r.push(i.index))}return n}function Xi(e,t,n){let r=[t];for(;r.length>0;){let t=r.pop();if(!n.has(t)){n.add(t);for(let i of e)i.parentIndex!==t||n.has(i.index)||r.push(i.index)}}}const Zi=[`button`,`switch`,`checkbox`,`radio`],Qi=[`button`,`image`,`textview`,`view`];function $i(e,t,n){for(let r of e){if(t.has(r.index)||!na(r))continue;let i=ra(Yi(e,r.index),r,t);if(i.label){n.set(r.index,{...r,...n.get(r.index),label:i.label});for(let n of i.removableIndexes)Xi(e,n,t)}}}function ea(e,t,n){let r=new Map;for(let i of e){if(t.has(i.index)||!da(i))continue;let a=Ki(H(i));if(!a)continue;let o=r.get(a);if(o&&ca(o,i,t)){let s=la(e,o,i,t,n);r.set(a,s);continue}r.set(a,i)}}function ta(e,t){for(let n of e){if(t.has(n.index)||!oa(n))continue;let r=Ki(H(n));if(!r)continue;let i=Yi(e,n.index).filter(e=>!t.has(e.index)&&sa(n,e,r));for(let n of i.filter(aa))Xi(e,n.index,t);let a=i.filter(e=>!aa(e)),o=new Set(a.map(e=>Ki(H(e))).filter(e=>!!e));if(!(a.length<2||o.size<2))for(let n of a)Xi(e,n.index,t)}}function na(e){return e.hittable===!0&&!Wi(e)&&!!(e.rect&&Bi(e.rect))&&H(e).trim().length===0}function ra(e,t,n){let r=[],i=[],a=new Set;for(let o of e){if(n.has(o.index)||!ia(o,e)||!Vi(o.rect,t.rect))continue;let s=H(o).trim().replaceAll(/\s+/g,` `),c=Ki(s);i.push(o.index),!(!s||!c||a.has(c))&&(a.add(c),r.push(s))}return{label:r.join(`, `),removableIndexes:i}}function ia(e,t){if(aa(e))return!0;let n=(e.type??``).toLowerCase();return e.hittable!==!0&&!Wi(e)&&n.includes(`view`)&&H(e).trim().length>0&&!t.some(t=>t.parentIndex===e.index)}function aa(e){if(e.hittable===!0||Wi(e))return!1;let t=(e.type??``).toLowerCase();return t.includes(`text`)||t.includes(`image`)||t.includes(`icon`)}function oa(e){return e.hittable===!0&&!Wi(e)&&!!(e.rect&&Bi(e.rect))&&!!Ki(H(e))}function sa(e,t,n){if(!da(t)||!Vi(t.rect,e.rect))return!1;let r=Ki(H(t));return!!(r&&n!==r&&n.includes(r))}function ca(e,t,n){return!n.has(e.index)&&Hi(e.rect,t.rect)&&(ga(e,t)||ha(e,t))}function la(e,t,n,r,i){let a=fa(t,n),o=a.index===t.index?n:t,s=(o.type??``).toLowerCase().includes(`image`)?`has image`:null,c=i.get(a.index)??a,ee=i.get(o.index)?.presentationHints??o.presentationHints;return i.set(a.index,{...c,presentationHints:ua(c.presentationHints,ee,s)}),Xi(e,o.index,r),i.get(a.index)??a}function ua(e,t,n){return[...new Set([...Array.isArray(e)?e:[],...Array.isArray(t)?t:[],...n?[n]:[]])]}function da(e){if(!e.rect||!Bi(e.rect)||Ui(e)||Wi(e))return!1;let t=(e.type??``).toLowerCase();return t===`text`||ma(t,Qi)}function fa(e,t){let n=pa(e);return pa(t)>n?t:e}function pa(e){let t=(e.type??``).toLowerCase(),n=0;return ma(t,Zi)?n+=100:t.includes(`image`)?n+=30:t.includes(`textview`)||t===`text`?n+=20:t.includes(`view`)&&(n+=10),e.hittable===!0&&(n+=20),e.enabled!==!1&&(n+=5),n}function ma(e,t){return t.some(t=>e.includes(t))}function ha(e,t){let n=e.parentIndex===t.index?t:t.parentIndex===e.index?e:null,r=n?.index===e.index?t:n?.index===t.index?e:null;return!n||!r?!1:fa(n,r).index===n.index}function ga(e,t){return e.parentIndex===t.parentIndex?Math.abs(e.index-t.index)<=3:e.parentIndex===t.index||t.parentIndex===e.index?!1:Math.abs((e.depth??0)-(t.depth??0))<=1&&Math.abs(e.index-t.index)<=2}function _a(e,t,n){if(n.raw||!va(e))return{nodes:t,filteredCount:0};let r=ya(t);return{nodes:r,filteredCount:t.length-r.length}}function va(e){let t=e.androidSnapshot;return!t||typeof t!=`object`?!1:t.backend===`android-helper`}function ya(e){if(e.length===0)return e;let t=new Set,n=new Map,r=new Map(e.map(e=>[e.index,e]));return ba(e,t),xa(e,r,t,n),$i(e,t,n),ta(e,t),ea(e,t,n),e.filter(e=>!t.has(e.index)).map(e=>n.get(e.index)??e)}function ba(e,t){for(let n of e)!n.rect||Bi(n.rect)||Ui(n)||Xi(e,n.index,t)}function xa(e,t,n,r){for(let i of e){if(n.has(i.index)||i.rect||Ui(i))continue;let a=Ji(i,t,Gi);a&&Ca(r,a,Sa(i,e)),Xi(e,i.index,n)}}function Sa(e,t){let n=t.filter(t=>t.parentIndex===e.parentIndex&&t.rect&&Bi(t.rect)).map(e=>e.index);return n.length===0?null:e.index<Math.min(...n)?`above`:e.index>Math.max(...n)?`below`:null}function Ca(e,t,n){if(!n)return;let r=e.get(t.index)??t;e.set(t.index,{...r,hiddenContentAbove:r.hiddenContentAbove===!0||n===`above`||void 0,hiddenContentBelow:r.hiddenContentBelow===!0||n===`below`||void 0})}function wa(e){if(e.length<20)return!1;let t=new Map;for(let n of e){let e=(n.type??``).toLowerCase(),r=Ta(Se(n));if(!r)continue;let i=`${e}|${r}`,a=t.get(i)??[];a.push(n),t.set(i,a)}let n=0;for(let e of t.values())e.length<=1||!Da(e)||(n+=e.length);return n>=8}function Ta(e){let t=e.trim().replaceAll(/\s+/g,` `).toLowerCase();return!t||Ea(t)?null:t}function Ea(e){return/\S+@\S+\.\S+/.test(e)}function Da(e){for(let t=0;t<e.length;t+=1)for(let n=t+1;n<e.length;n+=1)if(Oa(e[t]?.rect,e[n]?.rect))return!0;return!1}function Oa(e,t){if(!e||!t)return!0;let n=.5;return!(e.x+e.width<=t.x+n||t.x+t.width<=e.x+n||e.y+e.height<=t.y+n||t.y+t.height<=e.y+n)}function ka(e,n={}){let i=e.nodes,a=Array.isArray(i)?i:[],o=r(e.backend)?e.backend:void 0,s=t(o),c=_a(e,a,n),ee=Na(e),te=Ha(e,a,n,c),ne=te.length>0?`${te.join(`
4
+ `)}`}const ii=E({name:`batch`,clientSurface:!1,commands:[T({name:`batch`,text:{summary:`Run multiple commands`,cliDetail:ri()},metadata:$r,run:(e,t)=>e.batch.run(ai(t)),cliSchema:ei,cliReader:ti,cliOutputFormatter:$n.batch})]});function ai(e){return{...h(e),steps:e.steps,onError:e.onError,maxSteps:e.maxSteps,out:e.out}}const oi=`alert`,si=T({name:oi,text:{summary:`Inspect, accept, or dismiss a platform alert`},metadata:z(oi,`Inspect, wait for, accept, or dismiss a platform alert. Use get before acting when the alert content matters; accept and dismiss change the active alert state. Each iOS XCTest execution activates once, then only observes. Inspect again after an unconfirmed action; never assume a timeout means nothing happened.`,{action:I(Ct),timeoutMs:P()}),run:(e,t)=>e.command.alert(t),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...v(t),...li(e)}),daemonWriter:g(u.alert,e=>ci(e)),cliOutputFormatter:O});function ci(e){return[e.action??`get`,...S(e.timeoutMs)]}function li(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return m({action:ui(t[0]),timeoutMs:Un(t[1],`alert timeout`)})}function ui(t){let n=t?.toLowerCase();if(n===void 0||n===`get`||n===`accept`||n===`dismiss`||n===`wait`)return n;throw new e(`INVALID_ARGS`,`alert action must be get, accept, dismiss, or wait.`)}function B(...e){return e}const di=B(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),V=B(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),fi=B(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),pi=B(`metroHost`,`metroPort`,`bundleUrl`),mi=B(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),hi=B(`settle`,`settleQuietMs`,`timeoutMs`),gi=B(`replayUpdate`,`replayEnv`),_i=B(`remoteConfig`,`stateDir`,`daemonBaseUrl`,`daemonAuthToken`,`daemonTransport`,`daemonServerMode`,`tenant`,`sessionIsolation`,`runId`,`leaseId`,`leaseBackend`,`sessionLock`,`platform`,`target`,`device`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`providerDeviceOrientation`,`providerGeoLocation`,`providerTimezone`,`providerAppiumVersion`,`providerLanguage`,`providerLocale`,`providerNetworkProfile`,`providerCustomNetwork`,`providerNoResignApp`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`udid`,`serial`,`iosSimulatorDeviceSet`,`iosXctestrunFile`,`iosXctestDerivedDataPath`,`iosXctestEnvDir`,`androidDeviceAllowlist`,`session`,`noRecord`),vi=new Set([`platform`,`device`,`udid`,`serial`,`session`]),yi=new Set([`json`,`config`,`help`,`version`,`verbose`,`cost`,`responseLevel`]),bi=`diff`,xi=T({name:bi,text:{summary:`Diff snapshot or screenshot`,cliDetail:`Screenshot --threshold is a per-pixel RGB tolerance: 0 requires exact colors and 1 ignores color differences; image dimensions must still match. Live iOS simulator screenshot diffs normalize status-bar chrome by default; use screenshot --normalize-status-bar when capturing reusable baselines.`},metadata:z(bi,`Compare accessibility snapshots or screenshots to identify UI changes. Use snapshot comparisons for semantic tree changes and screenshot comparisons for pixel differences.`,{kind:j(L({type:`string`,const:`snapshot`})),out:M(),interactiveOnly:F(),depth:P(),scope:M(),raw:F()}),run:(e,t)=>e.capture.diff(t),cliSchema:{usageOverride:`diff snapshot | diff screenshot --baseline <path> [current.png] [--out <diff.png>] [--threshold <0-1>] [--overlay-refs]`,usageFlags:[],positionalArgs:[`kind`,`current?`],allowedFlags:[...di,`baseline`,`threshold`,`out`,`overlayRefs`]},cliReader:(t,n)=>{if(t[0]!==`snapshot`)throw new e(`INVALID_ARGS`,`Only diff snapshot is available through this parser.`);return{...v(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:g(u.diff,e=>[w(e.kind,`diff requires kind`)])}),Si=`screenshot`,Ci=T({name:Si,text:{summary:`Capture a screenshot`,cliDetail:`Web defaults to the viewport; use --fullscreen, --full, or -f for the entire page. iOS simulators default to 1x logical-point output; use --pixel-density to request a different screenshot density. macOS app sessions default to the app window; use --fullscreen for full desktop, --scale to downscale, --crop-on <selector> to crop the capture to the frame the selector resolves on the same screen (currently iOS simulators and Android emulators), --overlay-refs to annotate current refs, --normalize-status-bar for deterministic iOS simulator chrome, or --no-stabilize for low-latency Android capture loops.`},metadata:z(Si,`Capture a screenshot of the active app or web session. Choose the capture scope, density, size, or annotations through the corresponding input fields when needed.`,{path:M(`Output path.`),cropOn:M(`Selector expression; the capture is cropped to the frame the selector resolves on the same screen.`),overlayRefs:F(),pixelDensity:P(`Output screenshot pixel density in pixels per logical point.`,{min:1}),fullscreen:F(),scale:N(`Screenshot scale factor.`,ee),maxSize:dr(ie.migration.screenshot),stabilize:F(),normalizeStatusBar:F(),surface:I(st)}),run:(e,t)=>e.capture.screenshot(t),cliSchema:{positionalArgs:[`path?`],allowedFlags:ne},cliReader:(e,t)=>({...v(t),path:e[0]??t.out,...s(t)}),daemonWriter:e=>(c(`screenshot`,e),re(e),_(u.screenshot,x(e.path),{...e,...ae(e)}))}),wi=`settings`,Ti=T({name:wi,text:{summary:`Change OS settings and app permissions`,cliDetail:`macOS supports only settings appearance <light|dark|toggle> and settings permission <grant|reset> <accessibility|screen-recording|input-monitoring>; wifi|airplane|location|animations remain unsupported on macOS. Mobile permission actions use the active session app. On Android, deny|reset of a permission the app currently holds kills a running app; the response reports priorGrantState (granted|not_granted|unknown) and warns for granted and unknown, with open <app> --relaunch to restore it. Permission changes require a resolvable foreground user and fail without mutating if adb cannot report one. Android settings airplane on|off is applied by the connectivity service (Android 11+) and reports the airplaneMode that service holds; older builds fail without changing device state. settings reset-keychain clear is iOS-simulator-only and resets the whole simulator keychain, not just the selected app: simctl exposes no per-app keychain reset, so every app on that simulator loses its keychain-backed credentials (e.g. Firebase auth). clear-app-state does not touch the keychain, so a full fresh-install reset needs both; relaunch the app afterward to observe the signed-out state.`},metadata:z(wi,`Change supported operating-system settings, animation scales, appearance, or app permissions on the selected target. Platform support varies by setting and action.`,{setting:j(M()),state:j(M()),app:M(),latitude:N(),longitude:N(),permission:M(),mode:I([`full`,`limited`])}),run:(e,t)=>e.settings.update(t),cliSchema:{usageOverride:wt,listUsageOverride:`settings [area] [options]`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>Ei(e,t),daemonWriter:g(u.settings,e=>Di(e)),cliOutputFormatter:Xn});function Ei(t,n){let r=En(n),i=t[0],a=t[1];if(b(i,Ai)&&b(a,ji))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:Tt(t[2],`latitude`),longitude:Tt(t[3],`longitude`)};if(i===`appearance`&&b(a,Mi)||b(i,Ni)&&b(a,Pi)||i===`fingerprint`&&b(a,Fi))return{...r,setting:i,state:a};if(i===`permission`&&b(a,Ii))return{...r,setting:i,state:a,permission:Oi(t[2]),mode:ki(t[3])};if(i===`clear-app-state`){let e=a===`clear`?t[2]:a;return{...r,setting:i,state:`clear`,app:e}}if(i===`reset-keychain`&&a===`clear`&&t.length===2)return{...r,setting:i,state:a};throw new e(`INVALID_ARGS`,`Invalid settings arguments.`)}function Di(e){return e.setting===`clear-app-state`?[e.setting,...x(e.app)]:e.setting===`location`&&e.state===`set`?[e.setting,e.state,String(e.latitude),String(e.longitude)]:e.setting===`permission`?[e.setting,e.state,e.permission,...x(e.mode)]:[e.setting,e.state]}function Oi(t){if(b(t,Li))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function ki(t){if(t===void 0||t===`full`||t===`limited`)return t;throw new e(`INVALID_ARGS`,`settings permission mode must be full or limited.`)}const Ai=y(`wifi`,`airplane`,`location`,`animations`),ji=y(`on`,`off`),Mi=y(`light`,`dark`,`toggle`),Ni=y(`faceid`,`touchid`),Pi=y(`match`,`nonmatch`,`enroll`,`unenroll`),Fi=y(`match`,`nonmatch`),Ii=y(`grant`,`deny`,`reset`),Li=y(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function Ri(e){if(!Array.isArray(e)||e.length===0)return e;let t=xe(e);return e.map(e=>{let n=zi(e,t,e=>e.label),r=zi(e,t,e=>e.identifier),i=typeof e.label==`string`&&e.label.length>=24&&e.label===n,a=typeof e.identifier==`string`&&e.identifier.length>=24&&e.identifier===r;if(!i&&!a)return e;let o={...e};return i&&(delete o.label,o.inheritsLabel=!0),a&&(delete o.identifier,o.inheritsIdentifier=!0),o})}function zi(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0;for(;r;){let e=n(r);if(typeof e==`string`&&e.length>0)return e;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}}function Bi(e){return e.width>0&&e.height>0}function Vi(e,t){return!e||!t?!1:e.x>=t.x-2&&e.y>=t.y-2&&e.x+e.width<=t.x+t.width+2&&e.y+e.height<=t.y+t.height+2}function Hi(e,t){if(!e||!t)return!0;let n=e.y+e.height/2,r=t.y+t.height/2;return Math.abs(n-r)<=Math.max(e.height,t.height,1)}function Ui(e){return typeof e.parentIndex!=`number`}function Wi(e){let t=(e.type??``).toLowerCase(),n=(e.identifier??``).trim().toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)||n===`composer`}function Gi(e){let t=(e.type??``).toLowerCase();return t.includes(`scroll`)||t.includes(`list`)||t.includes(`recyclerview`)}function H(e){let t=Se(e);if(!t||t!==e.identifier?.trim()||!qi(t))return t;let n=(e.type??``).toLowerCase();return n.includes(`view`)||n.includes(`layout`)||n.includes(`image`)||n.includes(`list`)||n.includes(`recyclerview`)||n.includes(`collection`)?``:t}function Ki(e){let t=e.trim().replaceAll(/\s+/g,` `).toLowerCase();return!t||/^(true|false|\d+)$/.test(t)?null:t}function qi(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function Ji(e,t,n){let r=e;for(;typeof r.parentIndex==`number`;){let e=t.get(r.parentIndex);if(!e)return null;if(n(e))return e;r=e}return null}function Yi(e,t){let n=[],r=[t];for(;r.length>0;){let t=r.pop();for(let i of e)i.parentIndex===t&&(n.push(i),r.push(i.index))}return n}function Xi(e,t,n){let r=[t];for(;r.length>0;){let t=r.pop();if(!n.has(t)){n.add(t);for(let i of e)i.parentIndex!==t||n.has(i.index)||r.push(i.index)}}}const Zi=[`button`,`switch`,`checkbox`,`radio`],Qi=[`button`,`image`,`textview`,`view`];function $i(e,t,n){for(let r of e){if(t.has(r.index)||!na(r))continue;let i=ra(Yi(e,r.index),r,t);if(i.label){n.set(r.index,{...r,...n.get(r.index),label:i.label});for(let n of i.removableIndexes)Xi(e,n,t)}}}function ea(e,t,n){let r=new Map;for(let i of e){if(t.has(i.index)||!da(i))continue;let a=Ki(H(i));if(!a)continue;let o=r.get(a);if(o&&ca(o,i,t)){let s=la(e,o,i,t,n);r.set(a,s);continue}r.set(a,i)}}function ta(e,t){for(let n of e){if(t.has(n.index)||!oa(n))continue;let r=Ki(H(n));if(!r)continue;let i=Yi(e,n.index).filter(e=>!t.has(e.index)&&sa(n,e,r));for(let n of i.filter(aa))Xi(e,n.index,t);let a=i.filter(e=>!aa(e)),o=new Set(a.map(e=>Ki(H(e))).filter(e=>!!e));if(!(a.length<2||o.size<2))for(let n of a)Xi(e,n.index,t)}}function na(e){return e.hittable===!0&&!Wi(e)&&!!(e.rect&&Bi(e.rect))&&H(e).trim().length===0}function ra(e,t,n){let r=[],i=[],a=new Set;for(let o of e){if(n.has(o.index)||!ia(o,e)||!Vi(o.rect,t.rect))continue;let s=H(o).trim().replaceAll(/\s+/g,` `),c=Ki(s);i.push(o.index),!(!s||!c||a.has(c))&&(a.add(c),r.push(s))}return{label:r.join(`, `),removableIndexes:i}}function ia(e,t){if(aa(e))return!0;let n=(e.type??``).toLowerCase();return e.hittable!==!0&&!Wi(e)&&n.includes(`view`)&&H(e).trim().length>0&&!t.some(t=>t.parentIndex===e.index)}function aa(e){if(e.hittable===!0||Wi(e))return!1;let t=(e.type??``).toLowerCase();return t.includes(`text`)||t.includes(`image`)||t.includes(`icon`)}function oa(e){return e.hittable===!0&&!Wi(e)&&!!(e.rect&&Bi(e.rect))&&!!Ki(H(e))}function sa(e,t,n){if(!da(t)||!Vi(t.rect,e.rect))return!1;let r=Ki(H(t));return!!(r&&n!==r&&n.includes(r))}function ca(e,t,n){return!n.has(e.index)&&Hi(e.rect,t.rect)&&(ga(e,t)||ha(e,t))}function la(e,t,n,r,i){let a=fa(t,n),o=a.index===t.index?n:t,s=(o.type??``).toLowerCase().includes(`image`)?`has image`:null,c=i.get(a.index)??a,ee=i.get(o.index)?.presentationHints??o.presentationHints;return i.set(a.index,{...c,presentationHints:ua(c.presentationHints,ee,s)}),Xi(e,o.index,r),i.get(a.index)??a}function ua(e,t,n){return[...new Set([...Array.isArray(e)?e:[],...Array.isArray(t)?t:[],...n?[n]:[]])]}function da(e){if(!e.rect||!Bi(e.rect)||Ui(e)||Wi(e))return!1;let t=(e.type??``).toLowerCase();return t===`text`||ma(t,Qi)}function fa(e,t){let n=pa(e);return pa(t)>n?t:e}function pa(e){let t=(e.type??``).toLowerCase(),n=0;return ma(t,Zi)?n+=100:t.includes(`image`)?n+=30:t.includes(`textview`)||t===`text`?n+=20:t.includes(`view`)&&(n+=10),e.hittable===!0&&(n+=20),e.enabled!==!1&&(n+=5),n}function ma(e,t){return t.some(t=>e.includes(t))}function ha(e,t){let n=e.parentIndex===t.index?t:t.parentIndex===e.index?e:null,r=n?.index===e.index?t:n?.index===t.index?e:null;return!n||!r?!1:fa(n,r).index===n.index}function ga(e,t){return e.parentIndex===t.parentIndex?Math.abs(e.index-t.index)<=3:e.parentIndex===t.index||t.parentIndex===e.index?!1:Math.abs((e.depth??0)-(t.depth??0))<=1&&Math.abs(e.index-t.index)<=2}function _a(e,t,n){if(n.raw||!va(e))return{nodes:t,filteredCount:0};let r=ya(t);return{nodes:r,filteredCount:t.length-r.length}}function va(e){let t=e.androidSnapshot;return!t||typeof t!=`object`?!1:t.backend===`android-helper`}function ya(e){if(e.length===0)return e;let t=new Set,n=new Map,r=new Map(e.map(e=>[e.index,e]));return ba(e,t),xa(e,r,t,n),$i(e,t,n),ta(e,t),ea(e,t,n),e.filter(e=>!t.has(e.index)).map(e=>n.get(e.index)??e)}function ba(e,t){for(let n of e)!n.rect||Bi(n.rect)||Ui(n)||Xi(e,n.index,t)}function xa(e,t,n,r){for(let i of e){if(n.has(i.index)||i.rect||Ui(i))continue;let a=Ji(i,t,Gi);a&&Ca(r,a,Sa(i,e)),Xi(e,i.index,n)}}function Sa(e,t){let n=t.filter(t=>t.parentIndex===e.parentIndex&&t.rect&&Bi(t.rect)).map(e=>e.index);return n.length===0?null:e.index<Math.min(...n)?`above`:e.index>Math.max(...n)?`below`:null}function Ca(e,t,n){if(!n)return;let r=e.get(t.index)??t;e.set(t.index,{...r,hiddenContentAbove:r.hiddenContentAbove===!0||n===`above`||void 0,hiddenContentBelow:r.hiddenContentBelow===!0||n===`below`||void 0})}function wa(e){if(e.length<20)return!1;let t=new Map;for(let n of e){let e=(n.type??``).toLowerCase(),r=Ta(Se(n));if(!r)continue;let i=`${e}|${r}`,a=t.get(i)??[];a.push(n),t.set(i,a)}let n=0;for(let e of t.values())e.length<=1||!Da(e)||(n+=e.length);return n>=8}function Ta(e){let t=e.trim().replaceAll(/\s+/g,` `).toLowerCase();return!t||Ea(t)?null:t}function Ea(e){return/\S+@\S+\.\S+/.test(e)}function Da(e){for(let t=0;t<e.length;t+=1)for(let n=t+1;n<e.length;n+=1)if(Oa(e[t]?.rect,e[n]?.rect))return!0;return!1}function Oa(e,t){if(!e||!t)return!0;let n=.5;return!(e.x+e.width<=t.x+n||t.x+t.width<=e.x+n||e.y+e.height<=t.y+n||t.y+t.height<=e.y+n)}function ka(e,n={}){let i=e.nodes,a=Array.isArray(i)?i:[],o=r(e.backend)?e.backend:void 0,s=t(o),c=_a(e,a,n),ee=Na(e),te=Ha(e,a,n,c),ne=te.length>0?`${te.join(`
5
5
  `)}\n`:``,re=n.raw?null:Aa(e);if(re)return`${ee}${ne}${ja(re)}\n`;let ie=n.raw||!s?null:Nt(c.nodes),ae=!!e.truncated,oe=ie?.nodes??a,se=n.raw||!s?null:za(e,ie,oe.length,a.length,c.filteredCount),ce=Pa(a.length,se,ae);return a.length===0?`${ee}${ce}\n${ne}`:n.raw?`${ee}${ce}\n${ne}${Fa(a)}\n`:n.flatten?`${ee}${ce}\n${ne}${Ia(oe)}${Ra(ie)}\n`:`${ee}${ce}\n${ne}${La(oe)}${Ra(ie)}\n`}function Aa(e){let t=e.unchanged;if(!t||typeof t!=`object`)return null;let n=t;return typeof n.ageMs!=`number`||typeof n.nodeCount!=`number`?null:{ageMs:n.ageMs,nodeCount:n.nodeCount,interactiveOnly:n.interactiveOnly===!0||void 0,scope:typeof n.scope==`string`?n.scope:void 0}}function ja(e){let t=Ma(e.ageMs);return e.scope?[`Scoped snapshot unchanged for scope "${e.scope}" since previous read ${t} ago.`,`Previous refs in this scope remain valid. Use find/get/is for a targeted query, or --force-full to re-emit.`].join(`
6
6
  `):e.interactiveOnly?[`Interactive snapshot unchanged since previous read ${t} ago.`,`${e.nodeCount} visible nodes are unchanged. Previous @e refs are still valid. Use find/get/is for a targeted query, or --force-full to re-emit.`].join(`
7
7
  `):[`Snapshot unchanged since previous read ${t} ago.`,`Refs from the previous snapshot are still valid. Use --force-full to re-emit the tree, or use find/get/is for a targeted query.`].join(`
@@ -47,7 +47,7 @@ import{C as e,S as t,_ as n,h as r,t as i,u as a,v as o}from"./sdk-contracts.js"
47
47
 
48
48
  Aggregate perf was removed in 0.21. Use one of the explicit forms above.`,usageFlags:[],listUsageOverride:`perf`,positionalArgs:[`area`,`subjectOrAction?`,`action?`],allowedFlags:[`kind`,`perfTemplate`,`out`]},cliReader:(e,t)=>({...v(t),...Od(e,{kind:Pd(t.kind),template:t.perfTemplate,out:t.out})}),daemonWriter:g(wd,e=>Ed(e)),cliOutputFormatter:qu.perf})]});function Ed(e){let t=e.area;return t===`cpu`?Dd([...x(t),...x(e.subject),...x(e.action),...x(e.kind)],e):t===`trace`?Dd([...x(t),...x(e.action),...x(e.kind)],e):[...x(t),...x(e.action)]}function Dd(e,t){let n=[...e];return(t.template||t.out||t.tracePath)&&n.push(t.template??``),(t.out||t.tracePath)&&n.push(t.out??``),t.tracePath&&n.push(t.tracePath),n}function Od(e,t={}){let n=Ad(e[0]);if(n===`cpu`)return{area:n,subject:Md(e[1]),action:jd(e[2]),kind:Nd(t.kind),template:t.template,out:t.out};if(n===`trace`)return{area:n,action:jd(e[1]),kind:Nd(t.kind),template:t.template,out:t.out};let r=jd(e[1]),i=Nd(t.kind);return kd(n,r,i,t.out),{area:n,action:r,kind:i,out:t.out}}function kd(t,n,r,i){if(t===`frames`){if(r!==void 0)throw new e(`INVALID_ARGS`,`--kind is only supported with perf memory snapshot`);if(i!==void 0)throw new e(`INVALID_ARGS`,`--out is only supported with perf memory snapshot, perf cpu profile, or perf trace`)}if(t===`memory`){if(n!==`snapshot`&&r!==void 0)throw new e(`INVALID_ARGS`,`--kind is only supported with perf memory snapshot`);if(n!==`snapshot`&&i!==void 0)throw new e(`INVALID_ARGS`,`--out is only supported with perf memory snapshot`)}}function Ad(t){let n=t?.toLowerCase();if(ft(n))throw new e(`INVALID_ARGS`,mt);if(dt(n))return n;throw new e(`INVALID_ARGS`,ct)}function jd(t){if(t===void 0)return;let n=t.toLowerCase();if(ut(n))return n;throw new e(`INVALID_ARGS`,bt)}function Md(t){let n=t?.toLowerCase();if(n!==void 0&&pt(n))return n;throw new e(`INVALID_ARGS`,ht)}function Nd(t){if(t===void 0)return;let n=t.toLowerCase();if(vt(n))return n;throw new e(`INVALID_ARGS`,yt)}function Pd(e){return typeof e==`string`?Nd(e):void 0}const Fd=`react-native`,Id=E({name:`react-native`,commands:[T({name:Fd,text:{summary:`Run React Native automation helpers`},metadata:z(Fd,`Run supported React Native automation helpers. Use dismiss-overlay to close a visible development error overlay before continuing normal UI automation.`,{action:j(I([`dismiss-overlay`]))}),run:(e,t)=>e.command.reactNative(t),cliSchema:{usageOverride:`react-native dismiss-overlay`,listUsageOverride:`react-native dismiss-overlay`,positionalArgs:[`dismiss-overlay`]},cliReader:(e,t)=>({...v(t),action:Ld(e[0])}),daemonWriter:g(Fd,e=>[w(e.action,`react-native requires action`)])})]});function Ld(t){if(t===`dismiss-overlay`)return t;throw new e(`INVALID_ARGS`,`react-native supports only: dismiss-overlay`)}function Rd(e){let t=e,n=typeof t.outPath==`string`?t.outPath:``,r=Vd(t);if(r.length<=1)return{data:t,text:Bd(t,n)};let i=[`Recording chunks:`];for(let e of r)i.push(` ${e.index}: ${e.path}`);return typeof t.telemetryPath==`string`&&i.push(`Telemetry: ${t.telemetryPath}`),typeof t.warning==`string`&&i.push(`Warning: ${t.warning}`),typeof t.overlayWarning==`string`&&i.push(`Overlay warning: ${t.overlayWarning}`),{data:t,text:i.join(`
49
49
  `)}}const zd={record:D(Rd)};function Bd(e,t){let n=[];return t&&n.push(t),typeof e.sessionStateDir==`string`&&n.push(`Session state: ${e.sessionStateDir}`),typeof e.warning==`string`&&n.push(`Warning: ${e.warning}`),typeof e.overlayWarning==`string`&&n.push(`Overlay warning: ${e.overlayWarning}`),n.join(`
50
- `)}function Vd(e){let t=e.chunks;return Array.isArray(t)?t.flatMap(e=>{if(!e||typeof e!=`object`)return[];let t=e;return typeof t.index!=`number`||typeof t.path!=`string`?[]:[{index:t.index,path:t.path}]}):[]}const Hd=`record`,Ud=`trace`,Wd=[`start`,`stop`],Gd=z(Hd,`Start or stop a screen recording for the active app session or, where supported, the selected device. Long Android recordings can return multiple video artifacts; HarmonyOS supports whole-screen recording on physical devices.`,{action:j(I(Wd)),path:M(),fps:P(),maxSize:dr(ie.migration.record),quality:I(Re),hideTouches:F(),recordingScope:I(Ve)}),Kd=z(Ud,`Start or stop trace-log capture and return the resulting artifact when capture ends. Use the same artifact path for the matching start and stop requests when an explicit path is required.`,{action:j(I(Wd)),path:M()}),qd={usageOverride:`record start [path] [--scope <app|device|system>] [--fps <n>] [--quality <medium|high>] [--hide-touches] | record stop`,usageFlags:[],listUsageOverride:`record start [path] | record stop`,positionalArgs:[`start|stop`,`path?`],allowedFlags:[`recordingScope`,`fps`,`quality`,`hideTouches`]},Jd={usageOverride:`trace start <path> | trace stop <path>`,listUsageOverride:`trace start <path> | trace stop <path>`,positionalArgs:[`start|stop`,`path?`]},Yd=(e,t)=>({...v(t),action:nf(e[0],Hd),path:e[1],fps:t.fps,quality:t.quality,hideTouches:t.hideTouches,recordingScope:t.recordingScope}),Xd=(e,t)=>({...v(t),action:nf(e[0],Ud),path:e[1]}),Zd=g(Hd,e=>tf(e)),Qd=e=>(c(`record`,e),Zd(e)),$d=g(Ud,e=>tf(e)),ef=E({name:`recording`,commands:[T({name:Hd,text:{summary:`Start or stop screen recording`,cliDetail:`The default --scope app requires an active app session from open <app>; use --scope device/system to explicitly request whole-screen recording where the selected backend supports it. Android record start publishes a durable device manifest, recordings longer than the 180s adb screenrecord limit are returned as multiple MP4 chunks while the daemon stays alive, and daemon-restart recovery uses only manifest-owned chunks. Android screenrecord encodes a frame only when the screen changes, so a clip can end at the last frame the recorder encoded instead of at record stop; durationMs is host wall clock from record start until the export finished, and capturedDurationMs reports the video timeline when it can be measured, with a warning naming how much of the window that video covers. An Android manifest left by an unreachable recording is retired on the next start once its recorders are proven gone; one still owned refuses with non-retriable DEVICE_IN_USE and reason native_recovery_evidence_open naming the session to run record stop for, and a recorder that is still writing an artifact refuses with DEVICE_IN_USE and reason native_recording_artifact_claimed, which clears itself once that recorder ends at the 180s limit. HarmonyOS supports whole-screen recording on physical devices only: use --scope device/system; --fps, --quality, and --hide-touches are unsupported. Use --quality to choose medium or high export quality on supported backends. An iOS simulator host recording lock returns non-retriable DEVICE_IN_USE with reason apple_simulator_recording_busy. Stop the recording in its owning session; if a dead recorder left the host locked, ask the host operator to restart the CoreSimulator stream service.`},metadata:Gd,run:(e,t)=>e.recording.record(t),cliSchema:qd,cliReader:Yd,daemonWriter:Qd,cliOutputFormatter:zd.record}),T({name:Ud,text:{summary:`Start or stop trace capture`,cliDetail:`Pass that path as the same positional argument to start and stop.`},metadata:Kd,run:(e,t)=>e.recording.trace(t),cliSchema:Jd,cliReader:Xd,daemonWriter:$d})]});function tf(e){return[e.action,...x(e.path)]}function nf(t,n){if(t===`start`||t===`stop`)return t;throw new e(`INVALID_ARGS`,`${n} requires start|stop`)}const rf=2097152;async function af(e){let t=Ht(e.inputPath,{cwd:e.cwd}),n=sf(t,e.inputPath);if(rt(t,e.replayBackend)!==`maestro`)return of(t,{[t]:n},e.inputPath);let{collectMaestroFlowSources:r}=await import(`./src8.js`).then(e=>e.t);return of(t,r({entryPath:t,entrySource:n,env:e.env,readSource:cf}),e.inputPath)}function of(e,t,n){return lf(t,n),{entry:e,files:t}}function sf(t,n){try{return f.readFileSync(t,`utf8`)}catch(r){throw new e(`INVALID_ARGS`,`replay script not found on this machine: ${n}`,{path:t,hint:`Replay scripts are read by the client and sent to the daemon, so the path must resolve where you ran the command.`},r instanceof Error?r:void 0)}}function cf(e){try{return f.readFileSync(e,`utf8`)}catch{return}}function lf(t,n){let r=Object.values(t).reduce((e,t)=>e+Buffer.byteLength(t,`utf8`),0);if(!(r<=2097152))throw new e(`INVALID_ARGS`,`replay script sources for ${n} total ${r} bytes, over the ${rf}-byte limit; split the flow or drop unused runFlow includes.`,{limitBytes:rf,totalBytes:r})}const uf=/[*?[\]{}]/;function df(e){let t=e.replayBackend===`maestro`?new Set([`.yaml`,`.yml`,`.ad`]):new Set([`.ad`]),n=[],r=[];for(let i of e.inputs){let a=ff(i,e.cwd,t);if(a.source===`file`){n.push(...a.paths);continue}r.push(a.source===`directory`?_f(a.paths):hf(a.paths))}return _f([...n,...r.flat()])}function ff(t,n,r){let i=Ht(t,{cwd:n});if(f.existsSync(i)){let e=f.statSync(i);return e.isDirectory()?{paths:mf(i,r),source:`directory`}:e.isFile()?(pf(t,i,r),{paths:[i],source:`file`}):{paths:[],source:`file`}}if(!vf(t))throw new e(`INVALID_ARGS`,`test input not found: ${t}`);return{source:`glob`,paths:f.globSync(Ut(t),{cwd:n}).map(e=>d.isAbsolute(e)?e:d.resolve(n,e)).filter(e=>r.has(d.extname(e).toLowerCase())&&yf(e))}}function pf(t,n,r){if(!r.has(d.extname(n).toLowerCase()))throw it(n)&&!r.has(`.yaml`)?new e(`INVALID_ARGS`,nt(`test`,t)):new e(`INVALID_ARGS`,`test does not support this file type: ${t}`)}function mf(e,t){let n=[],r=f.opendirSync(e);try{let i;for(;(i=r.readSync())!==null;){let r=d.join(e,i.name);i.isDirectory()?n.push(...mf(r,t)):i.isFile()&&t.has(d.extname(i.name).toLowerCase())&&n.push(r)}}finally{r.closeSync()}return n}function hf(e){return e.map(e=>d.normalize(e)).sort((e,t)=>{let n=gf(e)-gf(t);return n===0?e.localeCompare(t):n})}function gf(e){return+(d.extname(e).toLowerCase()===`.ad`)}function _f(e){return[...new Set(e.map(e=>d.normalize(e)))]}function vf(e){return uf.test(e)}function yf(e){try{return f.statSync(e).isFile()}catch{return!1}}const bf=`replay`,xf=`test`,Sf=z(bf,`Run a recorded automation script, including compatible Maestro YAML flows. A script without a terminal close leaves its session active for subsequent automation.`,{path:j(M()),update:F(),backend:M(),maestro:F(),env:vr(),metroHost:M(`Metro/debug host hint inherited by replay-opened sessions.`),metroPort:P(`Metro/debug port hint inherited by replay-opened sessions.`),bundleUrl:M(`Bundle URL hint inherited by replay-opened sessions.`),resumeFrom:P(),resumePlanDigest:M(),keepSession:F(`Leave the session active by suppressing exactly an authored terminal close in native .ad.`),timeoutMs:P(`Maximum wall-clock duration for the replay request.`),saveScript:L({oneOf:[cr(),A()]}),force:F()}),Cf=z(xf,`Run one or more replay scripts as a serial test suite`,{paths:j(vr()),update:F(),backend:M(),maestro:F(),env:vr(),metroHost:M(`Metro/debug host hint inherited by each test session.`),metroPort:P(`Metro/debug port hint inherited by each test session.`),bundleUrl:M(`Bundle URL hint inherited by each test session.`),failFast:F(),timeoutMs:P(),retries:P(),recordVideo:F(),artifactsDir:M(),shardAll:P(),shardSplit:P()}),wf={usageOverride:`replay <path> | replay export <file.ad> [--out <path>]`,usageFlags:[],positionalArgs:[`path`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...gi,...pi,`replayFrom`,`replayPlanDigest`,`replayKeepSession`,`timeoutMs`,`out`,`saveScript`,`force`],flagDescriptionOverrides:{saveScript:`Arm a repair transaction from this replay (ADR 0012): recording starts at step 1, and the healed script commits when the repair-armed session tears down (close, close --save-script, or idle-reap). Independent of the open/close authoring arm-on-open. Optional custom output path.`}},Tf={usageOverride:`test <path-or-glob>...`,usageFlags:[],listUsageOverride:`test <path-or-glob>...`,positionalArgs:[`pathOrGlob`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...gi,...pi,`failFast`,`timeoutMs`,`retries`,`recordVideo`,`artifactsDir`,`reporter`,`reportJunit`,`shardAll`,`shardSplit`]},Ef=E({name:`replay`,commands:[T({name:bf,text:{summary:`Replay a recorded session or Maestro flow`,cliDetail:`For Maestro YAML compatibility flows, use replay <flow.yaml> --maestro and keep the target binding such as --platform ios on the replay command. A script with no terminal close leaves its session (and daemon) running until you close it or it idle-reaps — no different from a session opened interactively. For native .ad scripts, --keep-session suppresses exactly an authored terminal close so you can continue interactively. replay export <file.ad> converts compatible actions to Maestro YAML locally, including app switches with explicit launchApp.appId targets, deep links (including tel: and mailto:) as openLink, and home as pressKey: Home.`},metadata:Sf,run:(e,t)=>e.replay.run(mc(t)),cliSchema:wf,cliReader:(e,t)=>({...v(t),path:C(e[0],`replay requires path`),update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,resumeFrom:t.replayFrom,resumePlanDigest:t.replayPlanDigest,keepSession:t.replayKeepSession,timeoutMs:t.timeoutMs,saveScript:t.saveScript,force:t.force}),daemonWriter:async e=>{let t=w(e.path,`replay requires path`),n=kf(e),r=jf(process.env);return _(bf,[t],{...e,replayUpdate:e.update,replayBackend:n,replayEnv:e.env,replayShellEnv:r,replayScriptSource:await af({inputPath:t,cwd:Of(e),replayBackend:n,env:Df(e,r)}),replayFrom:e.resumeFrom,replayPlanDigest:e.resumePlanDigest,replayKeepSession:e.keepSession,saveScript:e.saveScript})}}),T({name:xf,text:{summary:`Run replay test suites`,cliDetail:`Relative globs are expanded on the caller from its working directory, whose name is treated literally. Quote glob inputs to defer expansion to test. Copied diagnostic artifacts receive numbered filenames when needed to preserve other artifacts, replay sources, timing traces, and attempt manifests. JUnit reports (--reporter junit:<path>) replace characters forbidden by XML 1.0 with U+FFFD and preserve legal Unicode and whitespace. JSON and other reporters retain the original suite values. Custom reporter getExitCode hooks must return an integer from 0 to 255 or undefined; the highest valid code wins and cannot lower a failing suite's exit code.`},metadata:Cf,run:(e,t)=>e.replay.test(mc(t)),cliSchema:Tf,cliReader:(e,t)=>({...v(t),paths:e,update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,recordVideo:t.recordVideo,artifactsDir:t.artifactsDir,shardAll:t.shardAll,shardSplit:t.shardSplit}),daemonWriter:async e=>{let t=e.paths??[],n=kf(e),r=Of(e),i=jf(process.env),a=Df(e,i);return _(xf,t,{...Af(e),replayUpdate:e.update,replayBackend:n,replayEnv:e.env,replayShellEnv:i,replayScriptSources:await Promise.all(df({inputs:t,cwd:r,replayBackend:n}).map(async e=>await af({inputPath:e,cwd:r,replayBackend:n,env:a})))})}})]});function Df(e,t){return{...tt(t),...et($e(e.env))}}function Of(e){return typeof e.cwd==`string`&&e.cwd.length>0?e.cwd:process.cwd()}function kf(e){return e.backend??(e.maestro===!0?`maestro`:void 0)}function Af(e){let t={...e};return delete t.reporter,delete t.reportJunit,t}function jf(e){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&n.startsWith(`AD_VAR_`)&&(t[n]=r);return t}function Mf(e){return{data:e,text:Ff(e)}}function Nf(e){if(e.platform===`android`&&e.action===`status`){let t=[`Keyboard visible: ${e.visible===!0?`yes`:`no`}`,`Input type: ${e.type??e.inputType??`unknown`}`,`Input owner: ${e.inputOwner??`unknown`}`];return e.inputMethodPackage&&t.push(`Input method: ${e.inputMethodPackage}`),e.focusedPackage&&t.push(`Focused package: ${e.focusedPackage}`),e.focusedResourceId&&t.push(`Focused resource: ${e.focusedResourceId}`),t.push(`Next action: ${If(e.visible,e.inputOwner)}`),{data:e,text:t.join(`
50
+ `)}function Vd(e){let t=e.chunks;return Array.isArray(t)?t.flatMap(e=>{if(!e||typeof e!=`object`)return[];let t=e;return typeof t.index!=`number`||typeof t.path!=`string`?[]:[{index:t.index,path:t.path}]}):[]}const Hd=`record`,Ud=`trace`,Wd=[`start`,`stop`],Gd=z(Hd,`Start or stop a screen recording for the active app session or, where supported, the selected device. Long Android recordings can return multiple video artifacts; HarmonyOS supports whole-screen recording on physical devices.`,{action:j(I(Wd)),path:M(),fps:P(),maxSize:dr(ie.migration.record),quality:I(Re),hideTouches:F(),recordingScope:I(Ve)}),Kd=z(Ud,`Start or stop trace-log capture and return the resulting artifact when capture ends. Use the same artifact path for the matching start and stop requests when an explicit path is required.`,{action:j(I(Wd)),path:M()}),qd={usageOverride:`record start [path] [--scope <app|device|system>] [--fps <n>] [--quality <medium|high>] [--hide-touches] | record stop`,usageFlags:[],listUsageOverride:`record start [path] | record stop`,positionalArgs:[`start|stop`,`path?`],allowedFlags:[`recordingScope`,`fps`,`quality`,`hideTouches`]},Jd={usageOverride:`trace start <path> | trace stop <path>`,listUsageOverride:`trace start <path> | trace stop <path>`,positionalArgs:[`start|stop`,`path?`]},Yd=(e,t)=>({...v(t),action:nf(e[0],Hd),path:e[1],fps:t.fps,quality:t.quality,hideTouches:t.hideTouches,recordingScope:t.recordingScope}),Xd=(e,t)=>({...v(t),action:nf(e[0],Ud),path:e[1]}),Zd=g(Hd,e=>tf(e)),Qd=e=>(c(`record`,e),Zd(e)),$d=g(Ud,e=>tf(e)),ef=E({name:`recording`,commands:[T({name:Hd,text:{summary:`Start or stop screen recording`,cliDetail:`The default --scope app requires an active app session from open <app>; use --scope device/system to explicitly request whole-screen recording where the selected backend supports it. Android record start publishes a durable device manifest, recordings longer than the 180s adb screenrecord limit are returned as multiple MP4 chunks while the daemon stays alive, and daemon-restart recovery uses only manifest-owned chunks. Android screenrecord encodes a frame only when the screen changes, so a clip can end at the last frame the recorder encoded instead of at record stop; durationMs is host wall clock from record start until the export finished, and capturedDurationMs reports the video timeline when it can be measured, with a warning naming how much of the window that video covers. An Android manifest left by an unreachable recording is retired on the next start once its recorders are proven gone; one still owned refuses with non-retriable DEVICE_IN_USE and reason native_recovery_evidence_open naming the session to run record stop for, and a recorder that is still writing an artifact refuses with DEVICE_IN_USE and reason native_recording_artifact_claimed, which clears itself once that recorder ends at the 180s limit. HarmonyOS supports whole-screen recording on physical devices only: use --scope device/system; --fps, --quality, and --hide-touches are unsupported. Use --quality to choose medium or high export quality on supported backends. An iOS simulator host recording lock returns non-retriable DEVICE_IN_USE with reason apple_simulator_recording_busy. Stop the recording in its owning session; if a dead recorder left the host locked, ask the host operator to restart the CoreSimulator stream service. A record stop that cannot produce its export keeps what a retry reads back — on Android the device-side artifact and the native manifest — leaves the recording manifest of that session open, and returns its own error, so retry record stop in that session; only closing the session disposes them.`},metadata:Gd,run:(e,t)=>e.recording.record(t),cliSchema:qd,cliReader:Yd,daemonWriter:Qd,cliOutputFormatter:zd.record}),T({name:Ud,text:{summary:`Start or stop trace capture`,cliDetail:`Pass that path as the same positional argument to start and stop.`},metadata:Kd,run:(e,t)=>e.recording.trace(t),cliSchema:Jd,cliReader:Xd,daemonWriter:$d})]});function tf(e){return[e.action,...x(e.path)]}function nf(t,n){if(t===`start`||t===`stop`)return t;throw new e(`INVALID_ARGS`,`${n} requires start|stop`)}const rf=2097152;async function af(e){let t=Ht(e.inputPath,{cwd:e.cwd}),n=sf(t,e.inputPath);if(rt(t,e.replayBackend)!==`maestro`)return of(t,{[t]:n},e.inputPath);let{collectMaestroFlowSources:r}=await import(`./src8.js`).then(e=>e.t);return of(t,r({entryPath:t,entrySource:n,env:e.env,readSource:cf}),e.inputPath)}function of(e,t,n){return lf(t,n),{entry:e,files:t}}function sf(t,n){try{return f.readFileSync(t,`utf8`)}catch(r){throw new e(`INVALID_ARGS`,`replay script not found on this machine: ${n}`,{path:t,hint:`Replay scripts are read by the client and sent to the daemon, so the path must resolve where you ran the command.`},r instanceof Error?r:void 0)}}function cf(e){try{return f.readFileSync(e,`utf8`)}catch{return}}function lf(t,n){let r=Object.values(t).reduce((e,t)=>e+Buffer.byteLength(t,`utf8`),0);if(!(r<=2097152))throw new e(`INVALID_ARGS`,`replay script sources for ${n} total ${r} bytes, over the ${rf}-byte limit; split the flow or drop unused runFlow includes.`,{limitBytes:rf,totalBytes:r})}const uf=/[*?[\]{}]/;function df(e){let t=e.replayBackend===`maestro`?new Set([`.yaml`,`.yml`,`.ad`]):new Set([`.ad`]),n=[],r=[];for(let i of e.inputs){let a=ff(i,e.cwd,t);if(a.source===`file`){n.push(...a.paths);continue}r.push(a.source===`directory`?_f(a.paths):hf(a.paths))}return _f([...n,...r.flat()])}function ff(t,n,r){let i=Ht(t,{cwd:n});if(f.existsSync(i)){let e=f.statSync(i);return e.isDirectory()?{paths:mf(i,r),source:`directory`}:e.isFile()?(pf(t,i,r),{paths:[i],source:`file`}):{paths:[],source:`file`}}if(!vf(t))throw new e(`INVALID_ARGS`,`test input not found: ${t}`);return{source:`glob`,paths:f.globSync(Ut(t),{cwd:n}).map(e=>d.isAbsolute(e)?e:d.resolve(n,e)).filter(e=>r.has(d.extname(e).toLowerCase())&&yf(e))}}function pf(t,n,r){if(!r.has(d.extname(n).toLowerCase()))throw it(n)&&!r.has(`.yaml`)?new e(`INVALID_ARGS`,nt(`test`,t)):new e(`INVALID_ARGS`,`test does not support this file type: ${t}`)}function mf(e,t){let n=[],r=f.opendirSync(e);try{let i;for(;(i=r.readSync())!==null;){let r=d.join(e,i.name);i.isDirectory()?n.push(...mf(r,t)):i.isFile()&&t.has(d.extname(i.name).toLowerCase())&&n.push(r)}}finally{r.closeSync()}return n}function hf(e){return e.map(e=>d.normalize(e)).sort((e,t)=>{let n=gf(e)-gf(t);return n===0?e.localeCompare(t):n})}function gf(e){return+(d.extname(e).toLowerCase()===`.ad`)}function _f(e){return[...new Set(e.map(e=>d.normalize(e)))]}function vf(e){return uf.test(e)}function yf(e){try{return f.statSync(e).isFile()}catch{return!1}}const bf=`replay`,xf=`test`,Sf=z(bf,`Run a recorded automation script, including compatible Maestro YAML flows. A script without a terminal close leaves its session active for subsequent automation.`,{path:j(M()),update:F(),backend:M(),maestro:F(),env:vr(),metroHost:M(`Metro/debug host hint inherited by replay-opened sessions.`),metroPort:P(`Metro/debug port hint inherited by replay-opened sessions.`),bundleUrl:M(`Bundle URL hint inherited by replay-opened sessions.`),resumeFrom:P(),resumePlanDigest:M(),keepSession:F(`Leave the session active by suppressing exactly an authored terminal close in native .ad.`),timeoutMs:P(`Maximum wall-clock duration for the replay request.`),saveScript:L({oneOf:[cr(),A()]}),force:F()}),Cf=z(xf,`Run one or more replay scripts as a serial test suite`,{paths:j(vr()),update:F(),backend:M(),maestro:F(),env:vr(),metroHost:M(`Metro/debug host hint inherited by each test session.`),metroPort:P(`Metro/debug port hint inherited by each test session.`),bundleUrl:M(`Bundle URL hint inherited by each test session.`),failFast:F(),timeoutMs:P(),retries:P(),recordVideo:F(),artifactsDir:M(),shardAll:P(),shardSplit:P()}),wf={usageOverride:`replay <path> | replay export <file.ad> [--out <path>]`,usageFlags:[],positionalArgs:[`path`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...gi,...pi,`replayFrom`,`replayPlanDigest`,`replayKeepSession`,`timeoutMs`,`out`,`saveScript`,`force`],flagDescriptionOverrides:{saveScript:`Arm a repair transaction from this replay (ADR 0012): recording starts at step 1, and the healed script commits when the repair-armed session tears down (close, close --save-script, or idle-reap). Independent of the open/close authoring arm-on-open. Optional custom output path.`}},Tf={usageOverride:`test <path-or-glob>...`,usageFlags:[],listUsageOverride:`test <path-or-glob>...`,positionalArgs:[`pathOrGlob`],allowsExtraPositionals:!0,allowedFlags:[`replayMaestro`,...gi,...pi,`failFast`,`timeoutMs`,`retries`,`recordVideo`,`artifactsDir`,`reporter`,`reportJunit`,`shardAll`,`shardSplit`]},Ef=E({name:`replay`,commands:[T({name:bf,text:{summary:`Replay a recorded session or Maestro flow`,cliDetail:`For Maestro YAML compatibility flows, use replay <flow.yaml> --maestro and keep the target binding such as --platform ios on the replay command. A script with no terminal close leaves its session (and daemon) running until you close it or it idle-reaps — no different from a session opened interactively. For native .ad scripts, --keep-session suppresses exactly an authored terminal close so you can continue interactively. replay export <file.ad> converts compatible actions to Maestro YAML locally, including app switches with explicit launchApp.appId targets, deep links (including tel: and mailto:) as openLink, and home as pressKey: Home.`},metadata:Sf,run:(e,t)=>e.replay.run(mc(t)),cliSchema:wf,cliReader:(e,t)=>({...v(t),path:C(e[0],`replay requires path`),update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,resumeFrom:t.replayFrom,resumePlanDigest:t.replayPlanDigest,keepSession:t.replayKeepSession,timeoutMs:t.timeoutMs,saveScript:t.saveScript,force:t.force}),daemonWriter:async e=>{let t=w(e.path,`replay requires path`),n=kf(e),r=jf(process.env);return _(bf,[t],{...e,replayUpdate:e.update,replayBackend:n,replayEnv:e.env,replayShellEnv:r,replayScriptSource:await af({inputPath:t,cwd:Of(e),replayBackend:n,env:Df(e,r)}),replayFrom:e.resumeFrom,replayPlanDigest:e.resumePlanDigest,replayKeepSession:e.keepSession,saveScript:e.saveScript})}}),T({name:xf,text:{summary:`Run replay test suites`,cliDetail:`Relative globs are expanded on the caller from its working directory, whose name is treated literally. Quote glob inputs to defer expansion to test. Copied diagnostic artifacts receive numbered filenames when needed to preserve other artifacts, replay sources, timing traces, and attempt manifests. JUnit reports (--reporter junit:<path>) replace characters forbidden by XML 1.0 with U+FFFD and preserve legal Unicode and whitespace. JSON and other reporters retain the original suite values. Custom reporter getExitCode hooks must return an integer from 0 to 255 or undefined; the highest valid code wins and cannot lower a failing suite's exit code.`},metadata:Cf,run:(e,t)=>e.replay.test(mc(t)),cliSchema:Tf,cliReader:(e,t)=>({...v(t),paths:e,update:t.replayUpdate,backend:t.replayMaestro?`maestro`:void 0,env:t.replayEnv,metroHost:t.metroHost,metroPort:t.metroPort,bundleUrl:t.bundleUrl,failFast:t.failFast,timeoutMs:t.timeoutMs,retries:t.retries,recordVideo:t.recordVideo,artifactsDir:t.artifactsDir,shardAll:t.shardAll,shardSplit:t.shardSplit}),daemonWriter:async e=>{let t=e.paths??[],n=kf(e),r=Of(e),i=jf(process.env),a=Df(e,i);return _(xf,t,{...Af(e),replayUpdate:e.update,replayBackend:n,replayEnv:e.env,replayShellEnv:i,replayScriptSources:await Promise.all(df({inputs:t,cwd:r,replayBackend:n}).map(async e=>await af({inputPath:e,cwd:r,replayBackend:n,env:a})))})}})]});function Df(e,t){return{...tt(t),...et($e(e.env))}}function Of(e){return typeof e.cwd==`string`&&e.cwd.length>0?e.cwd:process.cwd()}function kf(e){return e.backend??(e.maestro===!0?`maestro`:void 0)}function Af(e){let t={...e};return delete t.reporter,delete t.reportJunit,t}function jf(e){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&n.startsWith(`AD_VAR_`)&&(t[n]=r);return t}function Mf(e){return{data:e,text:Ff(e)}}function Nf(e){if(e.platform===`android`&&e.action===`status`){let t=[`Keyboard visible: ${e.visible===!0?`yes`:`no`}`,`Input type: ${e.type??e.inputType??`unknown`}`,`Input owner: ${e.inputOwner??`unknown`}`];return e.inputMethodPackage&&t.push(`Input method: ${e.inputMethodPackage}`),e.focusedPackage&&t.push(`Focused package: ${e.focusedPackage}`),e.focusedResourceId&&t.push(`Focused resource: ${e.focusedResourceId}`),t.push(`Next action: ${If(e.visible,e.inputOwner)}`),{data:e,text:t.join(`
51
51
  `)}}return k(e)}function Pf(e){return e.action===`read`?{data:e,text:e.text}:k(e)}const $=ss({appstate:D(Mf),back:O,home:O,orientation:O,"app-switcher":O,keyboard:D(Nf),clipboard:D(Pf),"tv-remote":O});function Ff(e){if(e.platform===`ios`){let t=[`Foreground app: ${e.appName??e.appBundleId??`unknown`}`];return e.appBundleId&&t.push(`Bundle: ${e.appBundleId}`),e.source&&t.push(`Source: ${e.source}`),t.join(`
52
52
  `)}if(e.platform===`android`){let t=[`Foreground app: ${e.package??`unknown`}`];return e.activity&&t.push(`Activity: ${e.activity}`),t.join(`
53
53
  `)}return null}function If(e,t){return t===`ime`?`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`:e===!0?`Keyboard is visible and focused input appears app-owned; fill/type can proceed.`:`Keyboard is hidden; focus an app field before type, or use fill with a concrete target.`}const Lf=`appstate`,Rf=`back`,zf=`home`,Bf=`orientation`,Vf=`app-switcher`,Hf=`keyboard`,Uf=`clipboard`,Wf=`tv-remote`,Gf=[`read`,`write`],Kf=[`status`,`dismiss`,`enter`,`return`],qf=z(Lf,`Show foreground app/activity`,{}),Jf=z(Rf,`Navigate back in the app or through system navigation. Use in-app for the app navigation stack and system when the platform back behavior is required.`,{mode:I(He),...U(Rf)}),Yf=z(zf,`Send the selected device to its home screen. This leaves the app session open but moves the foreground away from the app.`,{}),Xf=z(Bf,`Set device orientation on iOS and Android`,{orientation:j(I(Bt))}),Zf=z(Vf,`Open the device app switcher to inspect or change foreground apps. This changes the visible system UI and may move focus away from the current app.`,{}),Qf=z(Hf,`Inspect Android keyboard visibility/type or press/dismiss the device keyboard. To hide the keyboard, use keyboard dismiss. It taps the keyboard dismiss/hide key when one is exposed, verifies the keyboard closed, and reports UNSUPPORTED_OPERATION when no dismiss key exists — background taps are never attempted.`,{action:I(Kf)}),$f=z(Uf,`Read the current device clipboard text, or replace its contents with the given text.`,{action:j(I(Gf)),text:M()}),ep=z(Wf,`Press or long-press a TV remote or D-pad button on Android TV, tvOS, or Vega OS. Choose the button and optional hold duration through the input fields. The aliases ok, center, and enter all map to select.`,{button:j(I(qt)),durationMs:P(`Press duration in milliseconds. tvOS and Vega OS use the exact hold duration; Android TV maps any positive value to an ADB longpress (${Kt(`android`)}).`,{min:0})}),tp={},np={usageOverride:`back [--in-app|--system] [--settle]`,usageFlags:[],allowedFlags:[`backMode`,...W(Rf)]},rp={},ip={},ap={usageOverride:`orientation <portrait|portrait-upside-down|landscape-left|landscape-right>`,positionalArgs:[`orientation`]},op={usageOverride:`keyboard [status|get|dismiss|enter|return]`,positionalArgs:[`action?`]},sp={usageOverride:`clipboard read | clipboard write <text>`,listUsageOverride:`clipboard read | clipboard write <text>`,positionalArgs:[`read|write`,`text?`],allowsExtraPositionals:!0},cp={usageOverride:`tv-remote [press|longpress] ${Wt}`,listUsageOverride:`tv-remote press|longpress <button> [--duration-ms <ms>]`,positionalArgs:[`press|longpress?`,`button`],allowedFlags:[`durationMs`]},lp=(e,t)=>v(t),up=(e,t)=>v(t),dp=(e,t)=>v(t),fp=(e,t)=>({...v(t),mode:t.backMode}),pp=(e,t)=>({...v(t),orientation:zt(e[0])}),mp=(e,t)=>({...v(t),...Op(e)}),hp=(e,t)=>({...v(t),...kp(e)}),gp=(e,t)=>({...v(t),...Ap(e,t.durationMs)}),_p=g(Lf),vp=e=>_(Rf,[],{...e,backMode:Ep(e.mode)}),yp=g(zf),bp=g(Bf,e=>[w(e.orientation,`orientation requires orientation`)]),xp=g(Vf),Sp=g(Hf,e=>x(e.action)),Cp=g(Uf,e=>Dp(e)),wp=g(Wf,e=>[w(e.button,`tv-remote requires button`)]),Tp=E({name:`system`,commands:[T({name:Lf,text:{summary:`Show the foreground app and activity`},metadata:qf,run:(e,t)=>e.command.appState(t),cliSchema:tp,cliReader:lp,daemonWriter:_p,cliOutputFormatter:$.appstate}),T({name:Rf,text:{summary:`Navigate back in the app or system`},metadata:Jf,run:(e,t)=>e.command.back(t),cliSchema:np,cliReader:fp,daemonWriter:vp,cliOutputFormatter:$.back}),T({name:zf,text:{summary:`Go to the device home screen`},metadata:Yf,run:(e,t)=>e.command.home(t),cliSchema:rp,cliReader:up,daemonWriter:yp,cliOutputFormatter:$.home}),T({name:Bf,text:{summary:`Set device orientation`},metadata:Xf,run:(e,t)=>e.command.orientation(t),cliSchema:ap,cliReader:pp,daemonWriter:bp,cliOutputFormatter:$.orientation}),T({name:Vf,text:{summary:`Open the device app switcher`},metadata:Zf,run:(e,t)=>e.command.appSwitcher(t),cliSchema:ip,cliReader:dp,daemonWriter:xp,cliOutputFormatter:$[`app-switcher`]}),T({name:Hf,text:{summary:`Inspect, press, or dismiss the device keyboard`},metadata:Qf,run:(e,t)=>e.command.keyboard(t),cliSchema:op,cliReader:mp,daemonWriter:Sp,cliOutputFormatter:$.keyboard}),T({name:Uf,text:{summary:`Read or write device clipboard text`},metadata:$f,run:(e,t)=>e.command.clipboard(t),cliSchema:sp,cliReader:hp,daemonWriter:Cp,cliOutputFormatter:$.clipboard}),T({name:Wf,text:{summary:`Press a TV remote/D-pad button`,cliDetail:`longpress holds for 500ms by default; --duration-ms overrides the preset.`},metadata:ep,run:(e,t)=>e.command.tvRemote(t),cliSchema:cp,cliReader:gp,daemonWriter:wp,cliOutputFormatter:$[`tv-remote`]})]});function Ep(e){return e===`in-app`||e===`system`?e:void 0}function Dp(e){return e.action===`read`?[`read`]:[`write`,e.text]}function Op(t){if(t.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one action argument.`);return m({action:jp(t[0])})}function kp(t){let n=t[0]?.toLowerCase();if(n!==`read`&&n!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write.`);if(n===`read`){if(t.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments.`);return{action:n}}if(t.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text.`);return{action:n,text:t.slice(1).join(` `)}}function Ap(t,n){let r=t[0]?.toLowerCase(),i=r===`press`||r===`longpress`?t.slice(1):t;if(i.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button: ${qt.join(`, `)}.`);let a=n??(r===`longpress`?500:void 0);return m({button:Gt(i[0]),durationMs:a})}function jp(t){let n=t?.toLowerCase();if(n===`get`)return`status`;if(n===void 0||n===`status`||n===`dismiss`||n===`enter`||n===`return`)return n;throw new e(`INVALID_ARGS`,`keyboard action must be status, get, dismiss, enter, or return.`)}const Mp=[Ms,Rl,So,Tp,Id,Ef,Fu,Td,Do,ef,Hl,ii];function Np(){return Mp.flatMap(e=>[...e.metadata])}function Pp(){return Mp.flatMap(e=>[...e.definitions])}function Fp(){return zp(`cliSchemas`)}function Ip(){return zp(`cliReaders`)}function Lp(){return zp(`daemonWriters`)}function Rp(){return zp(`cliOutputFormatters`)}function zp(e){let t={};for(let n of Mp){let r=n[e];if(r)for(let[n,i]of Object.entries(r)){if(Object.hasOwn(t,n))throw Error(`Duplicate ${String(e)} command family entry: ${n}`);t[n]=i}}return t}export{tn as C,en as S,Qt as T,A as _,Pp as a,vn as b,jo as c,vi as d,yi as f,ur as g,cr as h,Lp as i,qa as l,Yr as m,Ip as n,Np as o,fi as p,Fp as r,Xc as s,Rp as t,_i as u,Gn as v,Zt as w,mn as x,Kn as y};
@@ -1 +1 @@
1
- import"./process.js";import{t as e}from"./platform-runtime-android-mechanics.js";import{r as t,t as n}from"./register-builtins.js";function r(e={}){let t=e.providers??{},n=s(t);return Object.freeze({hasConfiguredResolvers:n,run:async(n,r)=>{let a=o(await i(t,e.defaultWebProvider,n),n),s={androidAdbExecutor:a.androidAdb?.executor};return await d(await l(a),async()=>await r(s))}})}async function i(e,t,n){if(e.webProvider||!n.useDefaultWebProvider||!t)return e;let{createAgentBrowserWebProvider:r}=await import(`./src6.js`).then(e=>e.i),i=await r({session:n.session?.name??n.requestedSession,stateDir:t.stateDir,openWebSessionNames:t.openWebSessionNames,ownedProcessRecords:t.ownedProcessRecords});return{...e,webProvider:()=>i}}const a=[{resolverKey:`androidAdbProvider`,resolve(e,t){let n=e.androidAdbProvider;if(!n||!c(`androidAdbProvider`,t.device))return{};let r=n(t);return{androidAdb:{provider:r,executor:typeof r==`function`?r:r?.exec,serial:t.device.id}}},async appendWrapper(t,n){if(!t.androidAdb?.provider)return;let{withAndroidAdbProvider:r}=await e();u(n,t.androidAdb,(e,n)=>r(e,{serial:t.androidAdb?.serial??``},n))}},{resolverKey:`appleRunnerProvider`,resolve(e,t){let n=e.appleRunnerProvider;return!n||!c(`appleRunnerProvider`,t.device)?{}:{appleRunner:{provider:n(t),deviceId:t.device.id,requestId:t.requestId}}},async appendWrapper(e,t){if(!e.appleRunner?.provider)return;let{withAppleRunnerProvider:n}=await import(`./runner.js`).then(e=>e.t),r=e.appleRunner;t.push(async e=>await n(r.provider,{deviceId:r.deviceId??``,requestId:r.requestId},e))}},{resolverKey:`appleToolProvider`,resolve(e,t){let n=e.appleToolProvider;return!n||!c(`appleToolProvider`,t.device)?{}:{appleTool:{provider:n(t)}}},async appendWrapper(e,t){if(!e.appleTool?.provider)return;let{withAppleToolProvider:n}=await import(`./tool-provider-facade.js`);u(t,e.appleTool,n)}},{resolverKey:`vegaToolProvider`,resolve(e,t){let n=e.vegaToolProvider;return!n||!c(`vegaToolProvider`,t.device)?{}:{vegaTool:{provider:n(t)}}},async appendWrapper(e,t){if(!e.vegaTool?.provider)return;let{withVegaToolProvider:n}=await import(`./src4.js`).then(e=>e.r);u(t,e.vegaTool,n)}},{resolverKey:`linuxToolProvider`,resolve(e,t){let n=e.linuxToolProvider;return!n||!c(`linuxToolProvider`,t.device)?{}:{linuxTool:{provider:n(t)}}},async appendWrapper(e,t){if(!e.linuxTool?.provider)return;let{withLinuxToolProvider:n}=await import(`./src5.js`).then(e=>e.y);u(t,e.linuxTool,n)}},{resolverKey:`webProvider`,resolve(e,t){let n=e.webProvider;return!n||!c(`webProvider`,t.device)?{}:{web:{provider:n(t)}}},async appendWrapper(e,t){if(!e.web?.provider)return;let{withWebProvider:n}=await import(`./src6.js`).then(e=>e.i);u(t,e.web,n)}},{resolverKey:`appleRunnerScreenRecordingTransport`,resolve(e,t){let n=e.appleRunnerScreenRecordingTransport;return n?{appleRunnerScreenRecording:{provider:n(t)}}:{}},async appendWrapper(e,t){let n=e.appleRunnerScreenRecording?.provider;if(!n&&!e.appleRunner?.provider)return;let{withAppleRunnerScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-runner-transport.js`);t.push(async e=>await r(n,e))}},{resolverKey:`appleSimulatorScreenRecordingTransport`,resolve(e,t){let n=e.appleSimulatorScreenRecordingTransport;return n?{appleSimulatorScreenRecording:{provider:n(t)}}:{}},async appendWrapper(e,t){let n=e.appleSimulatorScreenRecording?.provider;if(!n&&!e.appleRunner?.provider)return;let{withAppleSimulatorScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-transport.js`);t.push(async e=>await r(n,e))}}];function o(e,t){return a.reduce((n,r)=>({...n,...r.resolve(e,t)}),{})}function s(e){return a.some(t=>!!e[t.resolverKey])}function c(e,n){return t(n.platform)?.providers?.platformGatedResolvers.includes(e)??!1}n();async function l(e){let t=[];for(let n of a)await n.appendWrapper(e,t);return t}function u(e,t,n){let r=t?.provider;r&&e.push(async e=>await n(r,e))}async function d(e,t){let n=t;for(let t of[...e].reverse()){let e=n;n=async()=>await t(e)}return await n()}export{r as createComposedRequestPlatformProviders};
1
+ import"./process.js";import{t as e}from"./platform-runtime-android-mechanics.js";import{r as t,t as n}from"./register-builtins.js";function r(e={}){let t=e.providers??{},n=s(t);return Object.freeze({hasConfiguredResolvers:n,run:async(n,r)=>{let a=o(await i(t,e.defaultWebProvider,n),n),s={androidAdbExecutor:a.androidAdb?.executor};return await d(await l(a),async()=>await r(s))}})}async function i(e,t,n){if(e.webProvider||!n.useDefaultWebProvider||!t)return e;let{createAgentBrowserWebProvider:r}=await import(`./src6.js`).then(e=>e.i),i=await r({session:n.session?.name??n.requestedSession,stateDir:t.stateDir,openWebSessionNames:t.openWebSessionNames,ownedProcessRecords:t.ownedProcessRecords});return{...e,webProvider:()=>i}}const a=[{resolverKey:`androidAdbProvider`,resolve(e,t){let n=e.androidAdbProvider;if(!n||!c(`androidAdbProvider`,t.device))return{};let r=n(t);return{androidAdb:{provider:r,executor:typeof r==`function`?r:r?.exec,serial:t.device.id}}},async appendWrapper(t,n){if(!t.androidAdb?.provider)return;let{withAndroidAdbProvider:r}=await e();u(n,t.androidAdb,(e,n)=>r(e,{serial:t.androidAdb?.serial??``},n))}},{resolverKey:`appleRunnerProvider`,resolve(e,t){let n=e.appleRunnerProvider;return!n||!c(`appleRunnerProvider`,t.device)?{}:{appleRunner:{provider:n(t),deviceId:t.device.id,requestId:t.requestId}}},async appendWrapper(e,t){if(!e.appleRunner?.provider)return;let{withAppleRunnerProvider:n}=await import(`./runner.js`).then(e=>e.t),r=e.appleRunner;t.push(async e=>await n(r.provider,{deviceId:r.deviceId??``,requestId:r.requestId},e))}},{resolverKey:`appleToolProvider`,resolve(e,t){let n=e.appleToolProvider;return!n||!c(`appleToolProvider`,t.device)?{}:{appleTool:{provider:n(t)}}},async appendWrapper(e,t){if(!e.appleTool?.provider)return;let{withAppleToolProvider:n}=await import(`./tool-provider-facade.js`);u(t,e.appleTool,n)}},{resolverKey:`vegaToolProvider`,resolve(e,t){let n=e.vegaToolProvider;return!n||!c(`vegaToolProvider`,t.device)?{}:{vegaTool:{provider:n(t)}}},async appendWrapper(e,t){if(!e.vegaTool?.provider)return;let{withVegaToolProvider:n}=await import(`./src3.js`).then(e=>e.r);u(t,e.vegaTool,n)}},{resolverKey:`linuxToolProvider`,resolve(e,t){let n=e.linuxToolProvider;return!n||!c(`linuxToolProvider`,t.device)?{}:{linuxTool:{provider:n(t)}}},async appendWrapper(e,t){if(!e.linuxTool?.provider)return;let{withLinuxToolProvider:n}=await import(`./src5.js`).then(e=>e.y);u(t,e.linuxTool,n)}},{resolverKey:`webProvider`,resolve(e,t){let n=e.webProvider;return!n||!c(`webProvider`,t.device)?{}:{web:{provider:n(t)}}},async appendWrapper(e,t){if(!e.web?.provider)return;let{withWebProvider:n}=await import(`./src6.js`).then(e=>e.i);u(t,e.web,n)}},{resolverKey:`appleRunnerScreenRecordingTransport`,resolve(e,t){let n=e.appleRunnerScreenRecordingTransport;return n?{appleRunnerScreenRecording:{provider:n(t)}}:{}},async appendWrapper(e,t){let n=e.appleRunnerScreenRecording?.provider;if(!n&&!e.appleRunner?.provider)return;let{withAppleRunnerScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-runner-transport.js`);t.push(async e=>await r(n,e))}},{resolverKey:`appleSimulatorScreenRecordingTransport`,resolve(e,t){let n=e.appleSimulatorScreenRecordingTransport;return n?{appleSimulatorScreenRecording:{provider:n(t)}}:{}},async appendWrapper(e,t){let n=e.appleSimulatorScreenRecording?.provider;if(!n&&!e.appleRunner?.provider)return;let{withAppleSimulatorScreenRecordingTransport:r}=await import(`./platform-runtime-screen-recording-apple-transport.js`);t.push(async e=>await r(n,e))}}];function o(e,t){return a.reduce((n,r)=>({...n,...r.resolve(e,t)}),{})}function s(e){return a.some(t=>!!e[t.resolverKey])}function c(e,n){return t(n.platform)?.providers?.platformGatedResolvers.includes(e)??!1}n();async function l(e){let t=[];for(let n of a)await n.appendWrapper(e,t);return t}function u(e,t,n){let r=t?.provider;r&&e.push(async e=>await n(r,e))}async function d(e,t){let n=t;for(let t of[...e].reverse()){let e=n;n=async()=>await t(e)}return await n()}export{r as createComposedRequestPlatformProviders};