agent-device 0.20.0 → 0.20.1

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 (98) hide show
  1. package/README.md +3 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.apk → agent-device-android-ime-helper-0.20.1.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.manifest.json → agent-device-android-ime-helper-0.20.1.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.apk → agent-device-android-snapshot-helper-0.20.1.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.manifest.json → agent-device-android-snapshot-helper-0.20.1.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +54 -6
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +15 -4
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +8 -3
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +4 -2
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
  15. package/dist/src/agent-device-client.js +2 -2
  16. package/dist/src/android-input-method-overlays.js +1 -1
  17. package/dist/src/android-system-chrome.js +1 -1
  18. package/dist/src/android.js +1 -1
  19. package/dist/src/app-log-request-scope.js +1 -1
  20. package/dist/src/app-resolution.js +1 -1
  21. package/dist/src/apple-multitouch-support.js +1 -1
  22. package/dist/src/apps.js +5 -5
  23. package/dist/src/boot-diagnostics.js +2 -2
  24. package/dist/src/cli-config.js +1 -1
  25. package/dist/src/cli-help.js +76 -19
  26. package/dist/src/cli-runner.js +1 -1
  27. package/dist/src/cli.js +14 -14
  28. package/dist/src/command-metadata.js +1 -1
  29. package/dist/src/command-schema.js +1 -1
  30. package/dist/src/compatibility-policy.js +1 -0
  31. package/dist/src/context.js +1 -1
  32. package/dist/src/contracts.d.ts +2 -2
  33. package/dist/src/debug-symbols.js +1 -1
  34. package/dist/src/devices2.js +1 -1
  35. package/dist/src/devices4.js +1 -0
  36. package/dist/src/find.js +1 -1
  37. package/dist/src/finders.js +1 -1
  38. package/dist/src/generic.js +1 -1
  39. package/dist/src/index.d.ts +144 -9
  40. package/dist/src/input-actions.js +2 -2
  41. package/dist/src/interaction-snapshot.js +1 -1
  42. package/dist/src/interaction.d.ts +2 -2
  43. package/dist/src/interaction.js +1 -1
  44. package/dist/src/interactor.js +2 -2
  45. package/dist/src/interactor2.js +1 -0
  46. package/dist/src/internal/bin.js +1 -1
  47. package/dist/src/internal/daemon.js +20 -20
  48. package/dist/src/lease-context.js +1 -1
  49. package/dist/src/lease.js +1 -1
  50. package/dist/src/linux.js +1 -1
  51. package/dist/src/method-scope.js +1 -0
  52. package/dist/src/metro-types.d.ts +52 -0
  53. package/dist/src/metro.d.ts +2 -2
  54. package/dist/src/react-native.js +1 -1
  55. package/dist/src/recording-export-quality.js +15 -0
  56. package/dist/src/register-builtins.js +1 -1
  57. package/dist/src/registry.js +24 -24
  58. package/dist/src/remote-config.d.ts +1 -1
  59. package/dist/src/reporting.js +4 -4
  60. package/dist/src/runner-client.js +1 -1
  61. package/dist/src/runner-disposal.js +2 -2
  62. package/dist/src/runner-lease.js +1 -1
  63. package/dist/src/runner-provider.js +1 -1
  64. package/dist/src/runtime.js +3 -3
  65. package/dist/src/runtime2.js +1 -1
  66. package/dist/src/sdk-android-adb.d.ts +2 -24
  67. package/dist/src/sdk-android-adb.js +4 -4
  68. package/dist/src/sdk-batch-runner.js +3 -2
  69. package/dist/src/sdk-contracts.d.ts +4 -90
  70. package/dist/src/sdk-device.js +1 -1
  71. package/dist/src/sdk-finders.d.ts +3 -2
  72. package/dist/src/sdk-finders.js +1 -1
  73. package/dist/src/sdk-remote-config.d.ts +18 -103
  74. package/dist/src/sdk-selectors.js +1 -1
  75. package/dist/src/selector-runtime.js +1 -1
  76. package/dist/src/selector-vocabulary.js +1 -1
  77. package/dist/src/selectors.d.ts +1 -1
  78. package/dist/src/selectors.js +1 -1
  79. package/dist/src/server.js +2 -2
  80. package/dist/src/session-target-evidence.js +1 -1
  81. package/dist/src/session.js +8 -8
  82. package/dist/src/simctl.js +1 -0
  83. package/dist/src/simulator.js +1 -1
  84. package/dist/src/snapshot-diagnostics.js +4 -4
  85. package/dist/src/snapshot-quality.js +1 -1
  86. package/dist/src/snapshot2.js +1 -1
  87. package/dist/src/tool-provider3.js +1 -0
  88. package/dist/src/unsupported-interactor.js +1 -0
  89. package/dist/src/web.js +1 -1
  90. package/package.json +8 -6
  91. package/server.json +2 -2
  92. package/skills/agent-device/SKILL.md +5 -3
  93. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +0 -1
  94. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +0 -1
  95. package/dist/src/config.js +0 -1
  96. package/dist/src/daemon-shutdown-report.js +0 -1
  97. package/dist/src/sdk-batch.js +0 -2
  98. package/dist/src/tv-remote.js +0 -15
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{F as t,N as n,j as r}from"./sdk-android-adb.js";import{l as i,s as a}from"./sdk-batch.js";import{Ct as o,Dt as s,Jn as c,Ot as l,St as u,Ut as d,at as f,bt as p,c as m,ct as h,er as ee,ot as te,p as g,qn as _,r as ne,st as re,tr as ie,wt as ae}from"./tv-remote.js";import{_ as v,c as y,d as oe,g as se,m as b,o as ce,s as x}from"./sdk-device.js";import{t as le}from"./timeouts.js";import{m as ue,p as de}from"./runtime.js";import{d as S}from"./logcat.js";import{a as fe,o as pe}from"./boot-diagnostics.js";import{i as me}from"./lease-context.js";import{a as he,i as ge,r as _e,t as C}from"./register-builtins.js";import{t as ve}from"./apple-multitouch-support.js";import{n as ye,t as be}from"./launch-console.js";import{AsyncLocalStorage as w}from"node:async_hooks";import xe,{promises as T}from"node:fs";import Se from"node:path";let Ce=[];const E=new w;async function we(e,t){return await E.run([...e],t)}function Te(e){for(let t of O()){if(!t.ownsDevice(e))continue;let n=t.getInteractor(e);if(n)return n}}function D(e){return O().some(t=>t.ownsDevice(e))}async function Ee(e,t,n,r){for(let i of O()){if(!i.ownsDevice(e))continue;if(!i.installApp)throw j(i,e,`install`);let a=await i.installApp?.(e,t,n,r);if(a)return a;throw j(i,e,`install`)}}async function De(e,t,n){for(let r of O()){if(!r.ownsDevice(e))continue;if(!r.installInstallablePath)throw j(r,e,`install_from_source`);let i=await r.installInstallablePath?.(e,t,n);if(i)return i;throw j(r,e,`install_from_source`)}}async function Oe(e){for(let t of O()){if(!A(t,e.provider))continue;let n=await t.configurePortReverse?.(e);if(n)return n}}function O(){return E.getStore()??Ce}function ke(e,t={}){let n=e.map(e=>e.provider);return{providerRuntimeIds:n,providerRuntimeRequiredIds:je([...n,...t.providerRuntimeRequiredIds??[]]),leaseLifecycleProvider:Ne(e),recoverableProviderIds:e.filter(e=>e.recoverExpiredLease!==void 0).map(e=>e.provider),recoverExpiredLease:Ae(e),cloudArtifactProvider:Pe(e),deviceInventoryProvider:Fe(e),providerDeviceRuntimeScope:async t=>await we(e,t)}}function Ae(t){if(t.some(e=>e.recoverExpiredLease!==void 0))return async n=>{let r=t.find(e=>A(e,n.leaseProvider));if(!r?.recoverExpiredLease)throw new e(`UNSUPPORTED_OPERATION`,`Provider ${n.leaseProvider??`unknown`} cannot recover an expired lease.`,{provider:n.leaseProvider,leaseId:n.leaseId});await r.recoverExpiredLease(n)}}function je(e){return[...new Set(e)]}function Me(...e){let t=e.filter(e=>e!==void 0);if(t.length!==0)return{listCloudArtifacts:async e=>{for(let n of t){let t=await n.listCloudArtifacts?.(e);if(t)return t}}}}function Ne(e){if(e.length!==0)return{allocate:async(t,n)=>await k(e,`allocate`,t,n),heartbeat:async(t,n)=>await k(e,`heartbeat`,t,n),release:async(t,n)=>await k(e,`release`,t,n)}}function Pe(e){if(e.length!==0)return{listCloudArtifacts:async t=>await Ie(e,t)}}function Fe(e){if(e.length!==0)return async t=>{for(let n of e){if(!A(n,t.leaseProvider))continue;let e=await n.deviceInventoryProvider(t);if(e)return e}return null}}async function Ie(e,t){for(let n of e){if(!A(n,t.provider))continue;let e=await n.cloudArtifacts?.listCloudArtifacts?.(t);if(e)return e}}async function k(e,t,n,r){for(let i of e){if(!A(i,n.leaseProvider))continue;let e=i.leaseLifecycle[t],a=e?await e(n,r):void 0;if(a)return a}}function A(e,t){return e.provider===t}function j(t,n,r){throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime ${t.provider} does not support ${r} for this device.`,{provider:t.provider,deviceId:n.id,platform:b(n)})}const M=new w,Le=new w;async function Re(t,n,r){let i=await ze(t,n,r);if(r.allowLocalSimulatorFallback!==!1&&Ve(n,i)){let{findBootableIosSimulator:e}=await import(`./devices2.js`),t=await e({simulatorSetPath:r.simulatorSetPath,target:n.target});if(t)return t}if(i)return i;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function ze(e,t,n){try{return await v(e,t,n)}catch(e){if(Be(e,t))return;throw e}}function Be(t,n){return!N(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function Ve(e,t){return!N(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}function N(e){return!!(e.udid||e.serial||e.deviceName)}async function He(e,n={}){let r=P(e),{iosSimulatorSetPath:i,...a}=r,o=Je(r,n),s={simulatorSetPath:i,allowStoppedAndroidAvdPlaceholders:n.allowStoppedAndroidAvdPlaceholders},c={platform:r.platform,target:e.target,cacheHit:!1};return await t(`resolve_target_device`,async()=>{let e=qe(o);if(e)return c.cacheHit=!0,e;let t=await F(r);if(t)return I(a)?L(o,await Re(t,a,{simulatorSetPath:i,allowLocalSimulatorFallback:r.leaseProvider===void 0})):L(o,await v(t,a,s));let n=await he(r);return I(a)?L(o,await Re(n,a,{simulatorSetPath:i})):L(o,await v(n,a,s))},c)}function P(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|linux|apple with --target mobile|tv|desktop.`);let r=se({simulatorSetPath:pe(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=fe(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function Ue(e){return M.getStore()?await e():await M.run(new Map,e)}async function We(e,t){return e?await Le.run(e,t):await t()}async function Ge(e,t){return await We(e,async()=>await Ue(t))}async function Ke(e){return await F(e)??await he(e)}async function F(e){let t=Le.getStore();if(!t)return null;let n=await t(e);return n==null?null:n.map(e=>({...e}))}function I(e){return ce(e.platform)}function qe(e){let t=M.getStore()?.get(e);if(t)return{...t}}function L(e,t){return M.getStore()?.set(e,{...t}),t}function Je(e,t){return JSON.stringify({request:e,options:t})}C();const Ye={device:!0},Xe=[`open`,`close`],Ze=[`record`],Qe=[`audio`,`find`,`get`,`is`,`network`,`screenshot`,`snapshot`,`wait`],$e=[`click`,`fill`,`focus`,`press`,`scroll`,`type`],et=[`viewport`],R=new Set([...Xe,...Ze,...Qe,...$e,...et]),z=tt(a(i));function tt(e){let t={};for(let[n,r]of Object.entries(e))t[n]=R.has(n)?{...r,web:Ye}:r;for(let t of R)if(!(t in e))throw Error(`Web command "${t}" missing from capability matrix`);return t}function B(e,t){let n=z[e];if(!n)return!0;let r=ge(t.platform);if(!r)return!1;let i=n[r.capability.bucket];if(!i)return!1;let a=r.capability.supportsByDefault?.[e];return a&&!a(t)?!1:i[t.kind??`unknown`]===!0}function nt(e,t){return ge(t.platform)?.capability.unsupportedHintByDefault?.[e]?.(t)}function rt(){return Object.keys(z).sort()}function it(e){let t=z[e];if(!t)return[];let n=[`apple`,`android`,`linux`,`web`],r=[];for(let e of n){let n=t[e];n&&Object.values(n).some(e=>e===!0)&&r.push(e)}return r}function at(e,t){if(t.platform===`web`||t.appleOs===`watchos`)throw H(e,V(e,t));if(ot(e)){st(e,t);return}if(t.appleOs===`visionos`)throw H(e,V(e,t));if(e.intent===`fling`&&`direction`in e&&t.platform===`linux`)throw H(e,`gesture fling is not supported on Linux`)}function ot(e){return e.intent===`pan`?(`pointerCount`in e?e.pointerCount:1)===2:e.intent===`pinch`||e.intent===`rotate`||e.intent===`transform`}function st(e,t){if(t.platform===`android`){if(t.target!==`tv`)return;throw H(e,`gesture ${e.intent} is not supported on Android TV`,`Android TV has no touch input — this gesture is supported on Android phones, tablets, and the iOS simulator only.`)}if(t.platform!==`apple`)throw H(e,V(e,t));ve(t,e.intent)}function V(e,t){return`gesture ${e.intent} is not supported on ${t.appleOs??t.platform}`}function H(t,n,r){return new e(`UNSUPPORTED_OPERATION`,n,{gesture:t.intent,...r?{hint:r}:{}})}const U=`No active session. Run open first.`;function W(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function ct(){return W(`SESSION_NOT_FOUND`,U)}function lt(e,t,n){if(B(e,t))return null;let r=n?.hint?nt(e,t):void 0;return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:n?.message??`${e} is not supported on this device`,...r?{hint:r}:{}}}}C();async function G(t,n){if(D(t)){let n=Te(t);if(n)return n;throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime does not have an active interactor for this device.`,{deviceId:t.id,platform:b(t)})}return await _e(t.platform).createInteractor(t,n)}const ut=/^[A-Za-z0-9_.:-]{1,64}$/,K=8*1024,q=4*1024;function dt(t){let n=t[0]?.trim(),r=t[1]?.trim();if(!n)throw new e(`INVALID_ARGS`,`trigger-app-event requires <event> [payloadJson]`);if(!ut.test(n))throw new e(`INVALID_ARGS`,`Invalid trigger-app-event event name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});if(t.length>2)throw new e(`INVALID_ARGS`,`trigger-app-event accepts at most two arguments: <event> [payloadJson]`);return{eventName:n,payload:pt(r,n)}}function ft(t,n,r){let i=b(t),a=mt(t);if(!a)throw new e(`UNSUPPORTED_OPERATION`,`No app event URL template configured for ${i}.`,{hint:`Set AGENT_DEVICE_${i.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):``,s=a.replaceAll(`{event}`,encodeURIComponent(n)).replaceAll(`{payload}`,encodeURIComponent(o)).replaceAll(`{platform}`,encodeURIComponent(i));if(s.length>q)throw new e(`INVALID_ARGS`,`trigger-app-event URL exceeds maximum supported length`,{hint:`Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.`,length:s.length,maxLength:q});return s}function pt(t,n){if(t)try{let r=JSON.parse(t);if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" must be a JSON object`);let i=JSON.stringify(r);if(Buffer.byteLength(i,`utf8`)>K)throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" exceeds ${K} bytes`);return r}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid trigger-app-event payload JSON: ${t}`)}}function mt(e){return((x(e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:y(e)?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE)?.trim()||void 0}const J=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function ht(e,t){return ce(e.platform)&&t>1}function gt(e,t,n=2e4){if(e.length===0)return[];let r=t>0?t:e.length,i=[],a=[],o=0;for(let t of e){let e=(t.durationMs??0)+(t.pauseMs??0)+250,s=a.length>0&&o+e>n,c=a.length>=r;(s||c)&&(i.push(a),a=[],o=0),a.push(t),o+=e}return a.length>0&&i.push(a),i}function _t(e,t){if(t<=0)return[0,0];let[n,r]=J[e%J.length];return[n*t,r*t]}async function vt(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await le(t)}async function yt(e,t){let{x:n,y:r}=Y(t,`longpress requires x y [durationMs]`,{hint:`Direct platform longpress requires coordinates. In an open daemon session, use agent-device longpress @ref|selector [durationMs]; otherwise run snapshot -i, use the target rect center as x y, then retry longpress x y durationMs.`}),i=t[2]?Number(t[2]):void 0;return await e.longPress(n,r,i),{x:n,y:r,durationMs:i,..._(`Long pressed (${n}, ${r})`)}}async function bt(e,t){let{x:n,y:r}=Y(t,`focus requires x y`);return await e.focus(n,r),{x:n,y:r,..._(`Focused (${n}, ${r})`)}}async function xt(t,n,r){let i=Kt(n);if(i)throw new e(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});let a=n.join(` `);if(!a)throw new e(`INVALID_ARGS`,`type requires text`);let o=h(r?.delayMs??0,`delay-ms`,0,1e4);return await t.type(a,o),{text:a,delayMs:o,..._(Q(`Typed`,a))}}async function St(t,n,r){if(r?.directElementSelector)return await Ct(t,r.directElementSelector,n,r);let i=Number(n[0]),a=Number(n[1]),o=n.slice(2).join(` `);if(Number.isNaN(i)||Number.isNaN(a)||!o)throw new e(`INVALID_ARGS`,`fill requires x y text`);let s=h(r?.delayMs??0,`delay-ms`,0,1e4);return await t.fill(i,a,o,s),{x:i,y:a,text:o,delayMs:s,..._(Q(`Filled`,o))}}async function Ct(t,n,r,i){if(!t.fillElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector fill is not supported`);let a=r.join(` `);if(!a)throw new e(`INVALID_ARGS`,`fill requires text`);let o=h(i.delayMs??0,`delay-ms`,0,1e4),s=await t.fillElementSelector(n,a,o);return{selector:n.raw,text:a,delayMs:o,...s??{},..._(Q(`Filled`,a))}}async function wt(e,t,n,r){if(r?.directElementSelector&&x(e))return await Tt(t,r.directElementSelector);let{x:i,y:a}=Y(n,`press requires x y`);if(y(e)&&r?.surface&&r.surface!==`app`)return await Et(i,a,r);let o=l(r);if(o!==`primary`)return await Dt(e,i,a,o,r);let s=At(r);return jt(s),ht(e,s.count)?await Nt(e,i,a,s,r):await It(t,i,a,s)}async function Tt(t,n){if(!t.tapElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector tap is not supported`);let r=await t.tapElementSelector(n),i=r?.maestroNonHittableCoordinateFallbackUsed===!0;return{selector:n.raw,...r??{},..._(i?`tapped via non-hittable coordinate fallback`:`Tapped ${n.raw}`)}}function Y(t,n,r){let i=Number(t[0]),a=Number(t[1]);if(Number.isNaN(i)||Number.isNaN(a))throw new e(`INVALID_ARGS`,n,r);return{x:i,y:a}}async function Et(t,n,r){let i=l(r);if(i!==`primary`)throw new e(`UNSUPPORTED_OPERATION`,`${i} click is not supported on macOS ${r.surface} sessions.`);let{runMacOsPressAction:a}=await import(`./helper.js`).then(e=>e.t);return await a(t,n,{bundleId:r.appBundleId,surface:r.surface}),{x:t,y:n,..._(Z({x:t,y:n}))}}async function Dt(e,t,n,r,i){if(Ot(e,r,i),e.platform===`linux`)return await kt(t,n,r);let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o);return await a(e,{command:`mouseClick`,x:t,y:n,button:r,appBundleId:i?.appBundleId},Lt(i)),{x:t,y:n,button:r,..._(Z({x:t,y:n,button:r}))}}function Ot(e,t,n){let r=s({commandLabel:`click`,platform:b(e),button:t,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap});if(r)throw r}async function kt(e,t,n){if(n===`secondary`){let{rightClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}else{let{middleClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}return{x:e,y:t,button:n,..._(Z({x:e,y:t,button:n}))}}function At(e){return{count:X(e?.count,1,`count`,1,200),intervalMs:X(e?.intervalMs,0,`interval-ms`,0,1e4),holdMs:X(e?.holdMs,0,`hold-ms`,0,1e4),jitterPx:X(e?.jitterPx,0,`jitter-px`,0,100),doubleTap:!!e?.doubleTap}}function X(e,t,n,r,i){return h(e===void 0?t:e,n,r,i)}function jt({doubleTap:t,holdMs:n,jitterPx:r}){if(t&&n>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with hold-ms`);if(t&&r>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with jitter-px`)}async function Mt(e,t,n){let{runAppleRunnerCommand:r}=await import(`./runner-client.js`).then(e=>e.o),{MAX_RUNNER_SEQUENCE_STEPS:i,buildRunnerSequenceCommand:a,parseRunnerSequenceResult:o}=await import(`./runner-sequence.js`).then(e=>e.r),s=gt(t,i),c,l,u=0,d=[],f=0;for(let t of s){let i=await r(e,a(t,n?.appBundleId),Lt(n));c??=i,l=i;let s;try{s=o(i)}catch(e){throw Ft(e,f)}u+=s.completedSteps,d.push(...s.results),f+=t.length}return{...c??{},completedSteps:u,sequenceResults:d,...l?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:l.gestureEndUptimeMs}}}async function Nt(e,t,n,r,i){let a=await Mt(e,Pt(e,t,n,r),i);return{x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,timingMode:`runner-sequence`,...a,..._(Z({x:t,y:n}))}}function Pt(e,t,n,r){let i=r.doubleTap?`doubleTap`:r.holdMs>0?`longPress`:`tap`,a=i===`tap`&&x(e)&&!oe(e);return Array.from({length:r.count},(e,o)=>{let[s,c]=_t(o,r.jitterPx),l=o===r.count-1;return{kind:i,x:t+s,y:n+c,...a?{synthesized:!0}:{},...r.holdMs>0?{durationMs:r.holdMs}:{},...!l&&r.intervalMs>0?{pauseMs:r.intervalMs}:{}}})}function Ft(t,n){if(n===0||!(t instanceof e)||!t.details)return t;let r=t.details.failedStepIndex;if(typeof r!=`number`)return t;let i=t.details.completedSteps;return new e(t.code,t.message,{...t.details,failedStepIndex:r+n,chunkStepIndex:r,...typeof i==`number`?{completedSteps:n+i}:{}},t.cause)}async function It(e,t,n,r){let i;return await vt(r.count,r.intervalMs,async a=>{let[o,s]=_t(a,r.jitterPx),c=t+o,l=n+s;if(r.doubleTap){let t=await e.doubleTap(c,l);i??=t??void 0;return}if(r.holdMs>0){let t=await e.longPress(c,l,r.holdMs);i??=t??void 0}else{let t=await e.tap(c,l);i??=t??void 0}}),c({x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,...i},Z({x:t,y:n}))}function Lt(e){return{verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,requestId:e?.requestId,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir}}async function Rt(t,n,r){let i=n[0],a=n[1]?Number(n[1]):void 0,o=r?.pixels,s=r?.durationMs;if(!i)throw new e(`INVALID_ARGS`,`scroll requires direction`);zt(a,o,s);let l=Wt(i),u={amount:a,pixels:o,durationMs:s},{interactionResult:d,completedPasses:f}=await Vt(t,r,l,u);return c(Ht(l,u,f,d),te(l.direction,l.edge,f,a,o))}function zt(e,t,n){Bt(e),ae(n),u({amount:e,pixels:t})}function Bt(t){if(t!==void 0&&!Number.isFinite(t))throw new e(`INVALID_ARGS`,`scroll amount must be a number`)}async function Vt(e,t,n,r){if(n.edge){let i=n.edge,a=await re({edge:i,captureState:async n=>await Ut(e,t,i,n),scroll:async()=>await e.scroll(n.direction,r)});return{interactionResult:a.result??{},completedPasses:a.passes}}return{interactionResult:await e.scroll(n.direction,r)??{},completedPasses:1}}function Ht(e,t,n,r){let i=o(r);return{direction:e.direction,...e.edge?{edge:e.edge,passes:n}:{},...t.amount===void 0?{}:{amount:t.amount},...t.pixels===void 0?{}:{pixels:t.pixels},...i===void 0?{}:{durationMs:i},...r}}async function Ut(t,n,r,i){if(typeof t.snapshot!=`function`)throw new e(`UNSUPPORTED_OPERATION`,`scroll ${r} requires snapshot support to verify hidden content before scrolling`);let a=t.snapshot;return await f({edge:r,scope:i,captureNodes:async e=>(await a({appBundleId:n?.appBundleId,scope:e})).nodes??[]})}function Wt(e){return e===`bottom`?{direction:`down`,edge:`bottom`}:e===`top`?{direction:`up`,edge:`top`}:{direction:p(e)}}async function Gt(e,t,n){let{x:r,y:i}=Y(t,`read requires x y`);if(e.platform===`android`){let{readAndroidTextAtPoint:t}=await import(`./input-actions.js`).then(e=>e.s);return{action:`read`,text:await t(e,r,i)??``}}if(e.platform===`linux`){let{readLinuxTextAtPoint:e}=await import(`./snapshot.js`).then(e=>e.n);return{action:`read`,text:await e(r,i,n?.surface)}}if(y(e)&&n?.surface&&n.surface!==`app`){let{runMacOsReadTextAction:e}=await import(`./helper.js`).then(e=>e.t);return{action:`read`,text:(await e(r,i,{bundleId:n.appBundleId,surface:n.surface})).text}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(e,{command:`readText`,x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId,iosXctestrunFile:n?.iosXctestrunFile,iosXctestDerivedDataPath:n?.iosXctestDerivedDataPath,iosXctestEnvDir:n?.iosXctestEnvDir});return{action:`read`,text:typeof o.text==`string`?o.text:typeof o.message==`string`?o.message:``}}function Kt(e){return de(e[0])}function Z(e){return e.button&&e.button!==`primary`?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function Q(e,t){return`${e} ${Array.from(t).length} chars`}function qt(e){let t=e.trim();return t.startsWith(`{`)&&t.endsWith(`}`)||t.startsWith(`[`)&&t.endsWith(`]`)}function Jt(t,n){let r=n?.subject??`Payload`,i=t.trim();if(!i)throw new e(`INVALID_ARGS`,`${r} cannot be empty`);let a=n?.expandPath?n.expandPath(i,n.cwd):i;try{if(!xe.statSync(a).isFile())throw new e(`INVALID_ARGS`,`${r} path is not a file: ${a}`);return{kind:`file`,path:a}}catch(t){if(t instanceof e)throw t;let n=t.code;if(n===`EACCES`||n===`EPERM`)throw new e(`INVALID_ARGS`,`${r} file is not readable: ${a}`);if(n&&n!==`ENOENT`)throw new e(`COMMAND_FAILED`,`Unable to read ${r} file: ${a}`,{cause:String(t)})}if(qt(i))return{kind:`inline`,text:i};throw new e(`INVALID_ARGS`,`${r} file not found: ${a}`)}async function Yt(t){let n=Jt(t,{subject:`Push payload`}),r=n.kind===`inline`?n.text:await Xt(n.path);try{let t=JSON.parse(r);if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`push payload must be a JSON object`);return t}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid push payload JSON: ${t}`)}}async function Xt(t){try{return await T.readFile(t,`utf8`)}catch(n){let r=n.code;throw r===`ENOENT`?new e(`INVALID_ARGS`,`Push payload file not found: ${t}`):r===`EISDIR`?new e(`INVALID_ARGS`,`Push payload path is not a file: ${t}`):r===`EACCES`||r===`EPERM`?new e(`INVALID_ARGS`,`Push payload file is not readable: ${t}`):new e(`COMMAND_FAILED`,`Unable to read push payload file: ${t}`,{cause:String(n)})}}async function Zt(e,n,i,a,o){let s=$(o),c=await G(e,s);return r({level:`debug`,phase:`platform_command_prepare`,data:{command:n,platform:e.platform,kind:e.kind}}),await t(`platform_command`,async()=>await tn(e,c,n,i,a,o,s),{command:n,platform:e.platform})}async function Qt(t,n,r){let i=await G(t,$(r));if(!i.performGesture)throw new e(`UNSUPPORTED_OPERATION`,`Gesture execution is unavailable`);return await i.performGesture(n)}async function $t(e,t){return await(await G(e,$(t))).gestureViewport?.()}function $(e){return{requestId:e?.requestId,appBundleId:e?.appBundleId,verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir,runnerLeaseContext:e?.runnerLeaseContext}}const en={open:({device:e,interactor:t,positionals:n,context:r})=>nn(e,t,n,r),close:async({device:e,interactor:t,positionals:n})=>{let r=n[0];return r?(await t.close(r),{app:r,..._(`Closed: ${r}`)}):(e.platform===`web`&&await t.close(``),{closed:`session`,..._(`Closed session`)})},press:({device:e,interactor:t,positionals:n,context:r})=>wt(e,t,n,r),longpress:({interactor:e,positionals:t})=>yt(e,t),focus:({interactor:e,positionals:t})=>bt(e,t),type:({interactor:e,positionals:t,context:n})=>xt(e,t,n),fill:({interactor:e,positionals:t,context:n})=>St(e,t,n),scroll:({interactor:e,positionals:t,context:n})=>Rt(e,t,n),"trigger-app-event":({device:e,interactor:t,positionals:n,context:r})=>rn(e,t,n,r),screenshot:({interactor:e,positionals:t,outPath:n,context:r})=>an(e,t,n,r),viewport:({interactor:e,positionals:t})=>on(e,t),back:async({interactor:e,context:t})=>(await e.back(t?.backMode),{action:`back`,mode:t?.backMode??`in-app`,..._(`Back`)}),home:async({interactor:e})=>(await e.home(),{action:`home`,..._(`Home`)}),orientation:async({interactor:e,positionals:t})=>{let n=m(t[0]);return await e.setOrientation(n),{action:`orientation`,orientation:n,..._(`Rotated to ${n}`)}},"app-switcher":async({interactor:e})=>(await e.appSwitcher(),{action:`app-switcher`,..._(`Opened app switcher`)}),clipboard:({interactor:e,positionals:t})=>sn(e,t),keyboard:({device:e,positionals:t,context:n,runnerCtx:r})=>ln(e,t,n,r),"tv-remote":({device:e,interactor:t,positionals:n,context:r})=>cn(e,t,n,r),settings:({device:e,interactor:t,positionals:n,context:r})=>fn(e,t,n,r),push:({device:e,positionals:t,context:n})=>pn(e,t,n),snapshot:({interactor:e,context:t})=>mn(e,t),read:({device:e,positionals:t,context:n})=>Gt(e,t,n)};async function tn(t,n,r,i,a,o,s){let c=Object.hasOwn(en,r)?en[r]:void 0;if(!c)throw new e(`INVALID_ARGS`,`Unknown command: ${r}`);return await c({device:t,interactor:n,positionals:i,outPath:a,context:o,runnerCtx:s})}async function nn(t,n,r,i){let a=r[0],o=r[1],s=i?.launchConsole,c=i?.launchArgs;if(r.length>2)throw new e(`INVALID_ARGS`,`open accepts at most two arguments: <app|url> [url]`);if(!a){if(s)throw new e(`INVALID_ARGS`,`--launch-console requires an app target`);if(c&&c.length>0)throw new e(`INVALID_ARGS`,`--launch-args requires an app target`);return await n.openDevice(),{app:null,..._(`Opened device`)}}if(s&&(!x(t)||t.kind!==`simulator`))throw new e(`UNSUPPORTED_OPERATION`,ye);if(t.platform===`linux`&&c&&c.length>0)throw new e(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on Linux.`);if(o!==void 0){if(S(a))throw new e(`INVALID_ARGS`,`open <app> <url> requires an app target as the first argument`);if(!S(o))throw new e(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(s)throw new e(`INVALID_ARGS`,be);return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchArgs:c,url:o}),{app:a,url:o,..._(`Opened: ${a}`)}}if(s&&S(a))throw new e(`INVALID_ARGS`,be);if(i?.clearAppState){if(S(a))throw new e(`INVALID_ARGS`,`Clearing app state requires an app target, not a deep link.`);await n.setSetting(`clear-app-state`,`clear`,a)}return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchConsole:s,launchArgs:c,terminateRunningApp:i?.terminateRunningApp}),{app:a,...s?{launchConsole:s}:{},..._(`Opened: ${a}`)}}async function rn(e,t,n,r){let{eventName:i,payload:a}=dt(n),o=ft(e,i,a);return await t.open(o,{appBundleId:r?.appBundleId}),{event:i,eventUrl:o,transport:`deep-link`,..._(`Triggered app event: ${i}`)}}async function an(e,t,n,r){let i=t[0]??n??`./screenshot-${Date.now()}.png`;await T.mkdir(Se.dirname(i),{recursive:!0});let a=ie(r);return await e.screenshot(i,{appBundleId:r?.appBundleId,pixelDensity:a.pixelDensity,fullscreen:a.fullscreen,normalizeStatusBar:a.normalizeStatusBar,stabilize:a.stabilize,surface:r?.surface,skipIosSimulatorBootCheck:r?.skipIosSimulatorBootCheck,captureBackend:r?.screenshotCaptureBackend}),{path:i,..._(`Saved screenshot: ${i}`)}}async function on(t,n){if(n.length!==2)throw new e(`INVALID_ARGS`,`viewport requires exactly two arguments: <width> <height>`);let r=g(n[0],`width`),i=g(n[1],`height`);if(!t.setViewport)throw new e(`UNSUPPORTED_OPERATION`,`viewport is not supported by this backend`);return await t.setViewport(r,i),{width:r,height:i,..._(`Viewport set: ${r}x${i}`)}}async function sn(t,n){let r=(n[0]??``).toLowerCase();if(r!==`read`&&r!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write`);if(r===`read`){if(n.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments`);return{action:r,text:await t.readClipboard()}}if(n.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text (use "" to clear clipboard)`);let i=n.slice(1).join(` `);return await t.writeClipboard(i),{action:r,textLength:Array.from(i).length,..._(`Clipboard updated`)}}async function cn(t,n,r,i){if(t.target!==`tv`)throw new e(`UNSUPPORTED_OPERATION`,`tv-remote is supported only on TV targets`,{hint:`Select an Android TV or tvOS target with --target tv.`});if(r.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button`);let a=ne(r[0]),o=i?.durationMs===void 0?void 0:h(i.durationMs,`durationMs`,0,1e4);return await n.tvRemote(a,o),{action:`tv-remote`,button:a,...o===void 0?{}:{durationMs:o},..._(`Pressed TV remote ${a}`)}}async function ln(t,n,r,i){let a=(n[0]??`status`).toLowerCase();if(!ue(a))throw new e(`INVALID_ARGS`,`keyboard requires a subcommand: status, get, dismiss, enter, or return`);if(n.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one subcommand argument`);if(t.platform===`android`)return await un(t,a);if(x(t))return await dn(t,a,r,i);throw new e(`UNSUPPORTED_OPERATION`,`keyboard is supported only on Android and iOS`)}async function un(e,t){if(t===`enter`||t===`return`){let{pressAndroidEnter:t}=await import(`./input-actions.js`).then(e=>e.s);return await t(e),{platform:`android`,action:`enter`,..._(`Keyboard enter pressed`)}}if(t===`dismiss`){let{dismissAndroidKeyboard:t}=await import(`./device-input-state.js`).then(e=>e.t),n=await t(e);return{platform:`android`,action:`dismiss`,attempts:n.attempts,wasVisible:n.wasVisible,dismissed:n.dismissed,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}let{getAndroidKeyboardState:n}=await import(`./device-input-state.js`).then(e=>e.t),r=await n(e);return{platform:`android`,action:`status`,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}async function dn(t,n,r,i){if(n!==`dismiss`&&n!==`enter`&&n!==`return`)throw new e(`UNSUPPORTED_OPERATION`,`keyboard status/get is currently supported only on Android; use keyboard dismiss or enter on iOS`);if(n===`enter`||n===`return`){let{runAppleRunnerCommand:e}=await import(`./runner-client.js`).then(e=>e.o),n=await e(t,{command:`keyboardReturn`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`enter`,visible:n.visible,wasVisible:n.wasVisible,..._(`Keyboard enter pressed`)}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(t,{command:`keyboardDismiss`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`dismiss`,wasVisible:o.wasVisible,dismissed:o.dismissed,visible:o.visible,..._(o.dismissed?`Keyboard dismissed`:`Keyboard already hidden`)}}async function fn(t,n,i,a){let[o,s,l,u]=i;if(!o||!s&&o!==`clear-app-state`)throw new e(`INVALID_ARGS`,`settings requires setting state`);if(o===`clear-app-state`){let i=(s===`clear`?l:s)??a?.appBundleId;if(!i)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);r({level:`debug`,phase:`settings_apply`,data:{setting:o,state:`clear`,appBundleId:i,platform:t.platform}});let u=await n.setSetting(o,`clear`,i);return u&&typeof u==`object`?c({setting:o,state:`clear`,...u},hn(u)??`Cleared user data for ${i}`):{setting:o,state:`clear`,..._(`Cleared user data for ${i}`)}}if(!s)throw new e(`INVALID_ARGS`,`settings requires setting state`);let f=o===`location`&&s===`set`,p=(o===`permission`||f?i[4]:i[2])??a?.appBundleId,m=o===`permission`?{permissionTarget:l,permissionMode:u}:f?{latitude:d(l,`latitude`),longitude:d(u,`longitude`)}:void 0;r({level:`debug`,phase:`settings_apply`,data:f?{setting:o,state:s,latitude:l,longitude:u,platform:t.platform}:o===`permission`?{setting:o,state:s,permissionTarget:l,permissionMode:u,platform:t.platform}:{setting:o,state:s,appBundleId:p,platform:t.platform}});let h=await n.setSetting(o,s,p,m);return h&&typeof h==`object`?c({setting:o,state:s,...h},hn(h)??`Updated setting: ${o}`):{setting:o,state:s,..._(`Updated setting: ${o}`)}}async function pn(t,n,r){let i=n[0]?.trim(),a=n[1]?.trim();if(!i||!a)throw new e(`INVALID_ARGS`,`push requires <bundle|package> <payload.json|inline-json>`);let o=await Yt(a);if(x(t)){let{pushIosNotification:e}=await import(`./apps.js`).then(e=>e.t);return await e(t,i,o),{platform:`ios`,bundleId:i,..._(`Pushed notification to ${i}`)}}let{pushAndroidNotification:s}=await import(`./notifications.js`),c=await s(t,i,o);return{platform:`android`,package:i,action:c.action,extrasCount:c.extrasCount,..._(`Pushed notification to ${i}`)}}async function mn(e,t){return await e.snapshot({appBundleId:t?.appBundleId,interactiveOnly:t?.snapshotInteractiveOnly,depth:t?.snapshotDepth,scope:t?.snapshotScope,raw:t?.snapshotRaw,includeRects:t?.snapshotIncludeRects,includeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,surface:t?.surface})}function hn(e){return typeof e.message==`string`&&e.message.length>0?e.message:void 0}function gn(e,t,r,i,a,o){return{requestId:a??n().requestId,appBundleId:r,runnerLeaseContext:me({meta:o}),activity:t?.activity,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,clearAppState:t?.clearAppState,verbose:t?.verbose,logPath:e,traceLogPath:i,iosXctestrunFile:t?.iosXctestrunFile,iosXctestDerivedDataPath:t?.iosXctestDerivedDataPath,iosXctestEnvDir:t?.iosXctestEnvDir,screenshotCaptureBackend:t?.maestro?.screenshotCaptureBackend,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,snapshotIncludeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,...ee(t),count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,durationMs:t?.durationMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:l(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}export{D as C,De as S,Ge as _,Jt as a,ke as b,ct as c,rt as d,at as f,He as g,Ke as h,$t as i,lt as l,P as m,Zt as n,U as o,it as p,Qt as r,W as s,gn as t,B as u,Me as v,Ee as x,Oe as y};
1
+ import{_ as e}from"./sdk-contracts.js";import{I as t,N as n,j as r}from"./sdk-android-adb.js";import{E as i,a}from"./sdk-batch-runner.js";import{$n as o,Mn as s,On as c,Qn as l,Sn as u,St as d,Wn as f,a as p,ar as m,at as h,et as g,jn as ee,nt as te,or as ne,ot as re,rt as _,st as ie,tt as ae}from"./recording-export-quality.js";import{L as oe}from"./snapshot-diagnostics.js";import{_ as se,c as v,f as ce,h as y,o as le,p as ue,s as b,v as x}from"./sdk-device.js";import{t as de}from"./timeouts.js";import{d as fe}from"./runtime.js";import{d as S}from"./logcat.js";import{a as pe,o as me}from"./boot-diagnostics.js";import{i as he}from"./lease-context.js";import{a as C,i as ge,r as _e,t as ve}from"./register-builtins.js";import{t as ye}from"./apple-multitouch-support.js";import{n as be,t as xe}from"./launch-console.js";import{AsyncLocalStorage as w}from"node:async_hooks";import Se,{promises as T}from"node:fs";import Ce from"node:path";let we=[];const E=new w;async function Te(e,t){return await E.run([...e],t)}function Ee(e,t){for(let n of O()){if(!n.ownsDevice(e))continue;let r=n.getInteractor(e,t);if(r)return r}}function D(e){return O().some(t=>t.ownsDevice(e))}async function De(e,t,n,r){for(let i of O()){if(!i.ownsDevice(e))continue;if(!i.installApp)throw j(i,e,`install`);let a=await i.installApp?.(e,t,n,r);if(a)return a;throw j(i,e,`install`)}}async function Oe(e,t,n){for(let r of O()){if(!r.ownsDevice(e))continue;if(!r.installInstallablePath)throw j(r,e,`install_from_source`);let i=await r.installInstallablePath?.(e,t,n);if(i)return i;throw j(r,e,`install_from_source`)}}async function ke(e){for(let t of O()){if(!A(t,e.provider))continue;let n=await t.configurePortReverse?.(e);if(n)return n}}function O(){return E.getStore()??we}function Ae(e,t={}){let n=e.map(e=>e.provider);return{providerRuntimeIds:n,providerRuntimeRequiredIds:Ne([...n,...t.providerRuntimeRequiredIds??[]]),leaseLifecycleProvider:Fe(e),recoverableProviderIds:e.filter(e=>e.recoverExpiredLease!==void 0).map(e=>e.provider),recoverExpiredLease:Me(e),cloudArtifactProvider:Ie(e),deviceInventoryProvider:Le(e),appleRunnerProvider:je(e),providerDeviceRuntimeScope:async t=>await Te(e,t)}}function je(e){if(e.some(e=>e.getAppleRunnerProvider!==void 0))return t=>{for(let n of e){if(!n.ownsDevice(t.device))continue;let e=n.getAppleRunnerProvider?.(t.device);if(e)return e}}}function Me(t){if(t.some(e=>e.recoverExpiredLease!==void 0))return async n=>{let r=t.find(e=>A(e,n.leaseProvider));if(!r?.recoverExpiredLease)throw new e(`UNSUPPORTED_OPERATION`,`Provider ${n.leaseProvider??`unknown`} cannot recover an expired lease.`,{provider:n.leaseProvider,leaseId:n.leaseId});await r.recoverExpiredLease(n)}}function Ne(e){return[...new Set(e)]}function Pe(...e){let t=e.filter(e=>e!==void 0);if(t.length!==0)return{listCloudArtifacts:async e=>{for(let n of t){let t=await n.listCloudArtifacts?.(e);if(t)return t}}}}function Fe(e){if(e.length!==0)return{allocate:async(t,n)=>await k(e,`allocate`,t,n),heartbeat:async(t,n)=>await k(e,`heartbeat`,t,n),release:async(t,n)=>await k(e,`release`,t,n)}}function Ie(e){if(e.length!==0)return{listCloudArtifacts:async t=>await Re(e,t)}}function Le(e){if(e.length!==0)return async t=>{for(let n of e){if(!A(n,t.leaseProvider))continue;let e=await n.deviceInventoryProvider(t);if(e)return e}return null}}async function Re(e,t){for(let n of e){if(!A(n,t.provider))continue;let e=await n.cloudArtifacts?.listCloudArtifacts?.(t);if(e)return e}}async function k(e,t,n,r){for(let i of e){if(!A(i,n.leaseProvider))continue;let e=i.leaseLifecycle[t],a=e?await e(n,r):void 0;if(a)return a}}function A(e,t){return e.provider===t}function j(t,n,r){throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime ${t.provider} does not support ${r} for this device.`,{provider:t.provider,deviceId:n.id,platform:y(n)})}const M=new w,ze=new w;async function Be(t,n,r){let i=await Ve(t,n,r);if(i)return i;let a=await He(t,n,r);if(r.allowLocalSimulatorFallback!==!1&&We(n,a)){let{findBootableIosSimulator:e}=await import(`./devices2.js`),t=await e({simulatorSetPath:r.simulatorSetPath,target:n.target});if(t)return t}if(a)return a;throw new e(`DEVICE_NOT_FOUND`,`No devices found`,{selector:n})}async function Ve(t,n,r){let i=r.appleSimulatorAppTarget?.trim();if(!i||N(n)||r.allowLocalSimulatorFallback===!1)return;let a=t.filter(e=>ue(e,n)&&b(e)&&e.kind===`simulator`&&e.booted===!0);if(a.length<2)return;let{findIosSimulatorInstalledApp:o}=await import(`./apps.js`).then(e=>e.t),s=(await Promise.all(a.map(async e=>await o(e,i)?e:void 0))).filter(e=>e!==void 0);if(s.length===1)return s[0];let c=a.map(e=>({id:e.id,name:e.name}));throw s.length===0?new e(`APP_NOT_INSTALLED`,`No booted iOS simulator has ${i} installed`,{appTarget:i,candidates:c,hint:`Install the app on a booted simulator, or pass --udid to select the intended device explicitly.`}):new e(`AMBIGUOUS_MATCH`,`Multiple booted iOS simulators have ${i} installed`,{appTarget:i,candidates:s.map(e=>({id:e.id,name:e.name})),hint:`Pass --udid to select the intended simulator explicitly.`})}async function He(e,t,n){try{return await x(e,t,n)}catch(e){if(Ue(e,t))return;throw e}}function Ue(t,n){return!N(n)&&t instanceof e&&t.code===`DEVICE_NOT_FOUND`}function We(e,t){return!N(e)&&(!e.platform||e.platform===`apple`||e.platform===`ios`)&&e.target!==`desktop`&&(!t||t.kind===`device`)}function N(e){return!!(e.udid||e.serial||e.deviceName)}async function Ge(e,n={}){let r=Ke(e),{iosSimulatorSetPath:i,...a}=r,o=$e(r,n),s={simulatorSetPath:i,allowStoppedAndroidAvdPlaceholders:n.allowStoppedAndroidAvdPlaceholders},c={platform:r.platform,target:e.target,cacheHit:!1};return await t(`resolve_target_device`,async()=>{let e=Qe(o);if(e)return c.cacheHit=!0,e;let t=await P(r);if(t)return F(a)?I(o,await Be(t,a,{simulatorSetPath:i,allowLocalSimulatorFallback:r.leaseProvider===void 0,appleSimulatorAppTarget:n.appleSimulatorAppTarget})):I(o,await x(t,a,s));let l=await C(r);return F(a)?I(o,await Be(l,a,{simulatorSetPath:i,appleSimulatorAppTarget:n.appleSimulatorAppTarget})):I(o,await x(l,a,s))},c)}function Ke(t){let n=t.platform;if(t.target&&!n)throw new e(`INVALID_ARGS`,`Device target selector requires --platform. Use --platform ios|macos|android|vega|linux|apple with --target mobile|tv|desktop.`);let r=se({simulatorSetPath:me(t.iosSimulatorDeviceSet),platform:n,target:t.target}),i=pe(t.androidDeviceAllowlist);return{platform:n,target:t.target,deviceName:t.device,udid:t.udid,serial:t.serial,leaseId:t.leaseId,leaseProvider:t.leaseProvider,deviceKey:t.deviceKey,clientId:t.clientId,iosSimulatorSetPath:r,androidSerialAllowlist:i?Array.from(i).sort():void 0}}async function qe(e){return M.getStore()?await e():await M.run(new Map,e)}async function Je(e,t){return e?await ze.run(e,t):await t()}async function Ye(e,t){return await Je(e,async()=>await qe(t))}async function Xe(e){return await P(e)??await C(e)}async function P(e){let t=ze.getStore();if(!t)return null;let n=await t(e);return n==null?null:n.map(e=>({...e}))}function Ze(e){return le(e.platform)}function F(e){return Ze(e)}function Qe(e){let t=M.getStore()?.get(e);if(t)return{...t}}function I(e,t){return M.getStore()?.set(e,{...t}),t}function $e(e,t){let{appleSimulatorAppTarget:n,...r}=t;return JSON.stringify({request:e,options:r})}ve();const et={device:!0},tt=[`open`,`close`],nt=[`record`],rt=[`audio`,`find`,`get`,`is`,`network`,`screenshot`,`snapshot`,`wait`],it=[`click`,`fill`,`focus`,`press`,`scroll`,`type`],at=[`viewport`],L=new Set([...tt,...nt,...rt,...it,...at]),R=ot(a(i));function ot(e){let t={};for(let[n,r]of Object.entries(e))t[n]=L.has(n)?{...r,web:et}:r;for(let t of L)if(!(t in e))throw Error(`Web command "${t}" missing from capability matrix`);return t}function z(e,t){let n=R[e];if(!n)return!0;let r=ge(t.platform);if(!r)return!1;let i=n[r.capability.bucket];if(!i)return!1;let a=r.capability.supportsByDefault?.[e];return a&&!a(t)?!1:i[t.kind??`unknown`]===!0}function st(e,t){return ge(t.platform)?.capability.unsupportedHintByDefault?.[e]?.(t)}function ct(){return Object.keys(R).sort()}function lt(e){let t=R[e];if(!t)return[];let n=[`apple`,`android`,`vega`,`linux`,`web`],r=[];for(let e of n){let n=t[e];n&&Object.values(n).some(e=>e===!0)&&r.push(e)}return r}function ut(e,t){if(t.platform===`web`||t.appleOs===`watchos`)throw V(e,B(e,t));if(dt(e)){ft(e,t);return}if(t.appleOs===`visionos`)throw V(e,B(e,t));if(e.intent===`fling`&&`direction`in e&&t.platform===`linux`)throw V(e,`gesture fling is not supported on Linux`)}function dt(e){return e.intent===`pan`?(`pointerCount`in e?e.pointerCount:1)===2:e.intent===`pinch`||e.intent===`rotate`||e.intent===`transform`}function ft(e,t){if(t.platform===`android`){if(t.target!==`tv`)return;throw V(e,`gesture ${e.intent} is not supported on Android TV`,`Android TV has no touch input — this gesture is supported on Android phones, tablets, and the iOS simulator only.`)}if(t.platform!==`apple`)throw V(e,B(e,t));ye(t,e.intent)}function B(e,t){return`gesture ${e.intent} is not supported on ${t.appleOs??t.platform}`}function V(t,n,r){return new e(`UNSUPPORTED_OPERATION`,n,{gesture:t.intent,...r?{hint:r}:{}})}const H=`No active session. Run open first.`;function U(e,t,n){return{ok:!1,error:{code:e,message:t,...n?{details:n}:{}}}}function pt(){return U(`SESSION_NOT_FOUND`,H)}function mt(e,t,n){if(z(e,t))return null;let r=n?.hint?st(e,t):void 0;return{ok:!1,error:{code:`UNSUPPORTED_OPERATION`,message:n?.message??`${e} is not supported on this device`,...r?{hint:r}:{}}}}ve();async function W(t,n){if(D(t)){let r=Ee(t,n);if(r)return r;throw new e(`UNSUPPORTED_OPERATION`,`Provider device runtime does not have an active interactor for this device.`,{deviceId:t.id,platform:y(t)})}return await _e(t.platform).createInteractor(t,n)}const ht=/^[A-Za-z0-9_.:-]{1,64}$/,G=8*1024,K=4*1024;function gt(t){let n=t[0]?.trim(),r=t[1]?.trim();if(!n)throw new e(`INVALID_ARGS`,`trigger-app-event requires <event> [payloadJson]`);if(!ht.test(n))throw new e(`INVALID_ARGS`,`Invalid trigger-app-event event name: ${n}`,{hint:`Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash.`});if(t.length>2)throw new e(`INVALID_ARGS`,`trigger-app-event accepts at most two arguments: <event> [payloadJson]`);return{eventName:n,payload:vt(r,n)}}function _t(t,n,r){let i=y(t),a=yt(t);if(!a)throw new e(`UNSUPPORTED_OPERATION`,`No app event URL template configured for ${i}.`,{hint:`Set AGENT_DEVICE_${i.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let o=r?JSON.stringify(r):``,s=a.replaceAll(`{event}`,encodeURIComponent(n)).replaceAll(`{payload}`,encodeURIComponent(o)).replaceAll(`{platform}`,encodeURIComponent(i));if(s.length>K)throw new e(`INVALID_ARGS`,`trigger-app-event URL exceeds maximum supported length`,{hint:`Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.`,length:s.length,maxLength:K});return s}function vt(t,n){if(t)try{let r=JSON.parse(t);if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" must be a JSON object`);let i=JSON.stringify(r);if(Buffer.byteLength(i,`utf8`)>G)throw new e(`INVALID_ARGS`,`trigger-app-event payload for "${n}" exceeds ${G} bytes`);return r}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid trigger-app-event payload JSON: ${t}`)}}function yt(e){return((b(e)?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:v(e)?process.env.AGENT_DEVICE_MACOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE)?.trim()||void 0}const q=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function bt(e,t){return le(e.platform)&&t>1}function xt(e,t,n=2e4){if(e.length===0)return[];let r=t>0?t:e.length,i=[],a=[],o=0;for(let t of e){let e=(t.durationMs??0)+(t.pauseMs??0)+250,s=a.length>0&&o+e>n,c=a.length>=r;(s||c)&&(i.push(a),a=[],o=0),a.push(t),o+=e}return a.length>0&&i.push(a),i}function St(e,t){if(t<=0)return[0,0];let[n,r]=q[e%q.length];return[n*t,r*t]}async function Ct(e,t,n){for(let r=0;r<e;r+=1)await n(r),r<e-1&&t>0&&await de(t)}async function wt(e,t){let{x:n,y:r}=J(t,`longpress requires x y [durationMs]`,{hint:`Direct platform longpress requires coordinates. In an open daemon session, use agent-device longpress @ref|selector [durationMs]; otherwise run snapshot -i, use the target rect center as x y, then retry longpress x y durationMs.`}),i=t[2]?Number(t[2]):void 0;return await e.longPress(n,r,i),{x:n,y:r,durationMs:i,...l(`Long pressed (${n}, ${r})`)}}async function Tt(e,t){let{x:n,y:r}=J(t,`focus requires x y`);return await e.focus(n,r),{x:n,y:r,...l(`Focused (${n}, ${r})`)}}async function Et(t,n,r){let i=Zt(n);if(i)throw new e(`INVALID_ARGS`,`type does not accept a target ref like "${i}"`,{hint:`Use fill ${i} "text" to target that field, or press ${i} then type "text" to append.`});let a=n.join(` `);if(!a)throw new e(`INVALID_ARGS`,`type requires text`);let o=_(r?.delayMs??0,`delay-ms`,0,1e4);return await t.type(a,o),{text:a,delayMs:o,...l(Z(`Typed`,a))}}async function Dt(t,n,r){if(r?.directElementSelector)return await Ot(t,r.directElementSelector,n,r);let i=Number(n[0]),a=Number(n[1]),o=n.slice(2).join(` `);if(Number.isNaN(i)||Number.isNaN(a)||!o)throw new e(`INVALID_ARGS`,`fill requires x y text`);let s=_(r?.delayMs??0,`delay-ms`,0,1e4);return await t.fill(i,a,o,s),{x:i,y:a,text:o,delayMs:s,...l(Z(`Filled`,o))}}async function Ot(t,n,r,i){if(!t.fillElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector fill is not supported`);let a=r.join(` `);if(!a)throw new e(`INVALID_ARGS`,`fill requires text`);let o=_(i.delayMs??0,`delay-ms`,0,1e4),s=await t.fillElementSelector(n,a,o);return{selector:n.raw,text:a,delayMs:o,...s??{},...l(Z(`Filled`,a))}}async function kt(e,t,n,r){if(r?.directElementSelector&&b(e))return await At(t,r.directElementSelector);let{x:i,y:a}=J(n,`press requires x y`);if(v(e)&&r?.surface&&r.surface!==`app`)return await jt(i,a,r);let o=s(r);if(o!==`primary`)return await Mt(e,i,a,o,r);let c=Ft(r);return It(c),bt(e,c.count)?await Rt(e,i,a,c,r):await Vt(t,i,a,c)}async function At(t,n){if(!t.tapElementSelector)throw new e(`UNSUPPORTED_OPERATION`,`direct element selector tap is not supported`);let r=await t.tapElementSelector(n),i=r?.maestroNonHittableCoordinateFallbackUsed===!0;return{selector:n.raw,...r??{},...l(i?`tapped via non-hittable coordinate fallback`:`Tapped ${n.raw}`)}}function J(t,n,r){let i=Number(t[0]),a=Number(t[1]);if(Number.isNaN(i)||Number.isNaN(a))throw new e(`INVALID_ARGS`,n,r);return{x:i,y:a}}async function jt(t,n,r){let i=s(r);if(i!==`primary`)throw new e(`UNSUPPORTED_OPERATION`,`${i} click is not supported on macOS ${r.surface} sessions.`);let{runMacOsPressAction:a}=await import(`./helper.js`).then(e=>e.t);return await a(t,n,{bundleId:r.appBundleId,surface:r.surface}),{x:t,y:n,...l(X({x:t,y:n}))}}async function Mt(e,t,n,r,i){if(Nt(e,r,i),e.platform===`linux`)return await Pt(t,n,r);let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o);return await a(e,{command:`mouseClick`,x:t,y:n,button:r,appBundleId:i?.appBundleId},Ht(i)),{x:t,y:n,button:r,...l(X({x:t,y:n,button:r}))}}function Nt(e,t,n){let r=ee({commandLabel:`click`,platform:y(e),button:t,count:n?.count,intervalMs:n?.intervalMs,holdMs:n?.holdMs,jitterPx:n?.jitterPx,doubleTap:n?.doubleTap});if(r)throw r}async function Pt(e,t,n){if(n===`secondary`){let{rightClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}else{let{middleClickLinux:n}=await import(`./input-actions2.js`);await n(e,t)}return{x:e,y:t,button:n,...l(X({x:e,y:t,button:n}))}}function Ft(e){return{count:Y(e?.count,1,`count`,1,200),intervalMs:Y(e?.intervalMs,0,`interval-ms`,0,1e4),holdMs:Y(e?.holdMs,0,`hold-ms`,0,1e4),jitterPx:Y(e?.jitterPx,0,`jitter-px`,0,100),doubleTap:!!e?.doubleTap}}function Y(e,t,n,r,i){return _(e===void 0?t:e,n,r,i)}function It({doubleTap:t,holdMs:n,jitterPx:r}){if(t&&n>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with hold-ms`);if(t&&r>0)throw new e(`INVALID_ARGS`,`double-tap cannot be combined with jitter-px`)}async function Lt(e,t,n){let{runAppleRunnerCommand:r}=await import(`./runner-client.js`).then(e=>e.o),{MAX_RUNNER_SEQUENCE_STEPS:i,buildRunnerSequenceCommand:a,parseRunnerSequenceResult:o}=await import(`./runner-sequence.js`).then(e=>e.r),s=xt(t,i),c,l,u=0,d=[],f=0;for(let t of s){let i=await r(e,a(t,n?.appBundleId),Ht(n));c??=i,l=i;let s;try{s=o(i)}catch(e){throw Bt(e,f)}u+=s.completedSteps,d.push(...s.results),f+=t.length}return{...c??{},completedSteps:u,sequenceResults:d,...l?.gestureEndUptimeMs===void 0?{}:{gestureEndUptimeMs:l.gestureEndUptimeMs}}}async function Rt(e,t,n,r,i){let a=await Lt(e,zt(e,t,n,r),i);return{x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,timingMode:`runner-sequence`,...a,...l(X({x:t,y:n}))}}function zt(e,t,n,r){let i=r.doubleTap?`doubleTap`:r.holdMs>0?`longPress`:`tap`,a=i===`tap`&&b(e)&&!ce(e);return Array.from({length:r.count},(e,o)=>{let[s,c]=St(o,r.jitterPx),l=o===r.count-1;return{kind:i,x:t+s,y:n+c,...a?{synthesized:!0}:{},...r.holdMs>0?{durationMs:r.holdMs}:{},...!l&&r.intervalMs>0?{pauseMs:r.intervalMs}:{}}})}function Bt(t,n){if(n===0||!(t instanceof e)||!t.details)return t;let r=t.details.failedStepIndex;if(typeof r!=`number`)return t;let i=t.details.completedSteps;return new e(t.code,t.message,{...t.details,failedStepIndex:r+n,chunkStepIndex:r,...typeof i==`number`?{completedSteps:n+i}:{}},t.cause)}async function Vt(e,t,n,r){let i;return await Ct(r.count,r.intervalMs,async a=>{let[o,s]=St(a,r.jitterPx),c=t+o,l=n+s;if(r.doubleTap){let t=await e.doubleTap(c,l);i??=t??void 0;return}if(r.holdMs>0){let t=await e.longPress(c,l,r.holdMs);i??=t??void 0}else{let t=await e.tap(c,l);i??=t??void 0}}),o({x:t,y:n,count:r.count,intervalMs:r.intervalMs,holdMs:r.holdMs,jitterPx:r.jitterPx,doubleTap:r.doubleTap,...i},X({x:t,y:n}))}function Ht(e){return{verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,requestId:e?.requestId,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir}}async function Ut(t,n,r){let i=n[0],a=n[1]?Number(n[1]):void 0,s=r?.pixels,c=r?.durationMs;if(!i)throw new e(`INVALID_ARGS`,`scroll requires direction`);Wt(a,s,c);let l=Yt(i),u={amount:a,pixels:s,durationMs:c},{interactionResult:d,completedPasses:f}=await Kt(t,r,l,u);return o(qt(l,u,f,d),ae(l.direction,l.edge,f,a,s))}function Wt(e,t,n){Gt(e),ie(n),h({amount:e,pixels:t})}function Gt(t){if(t!==void 0&&!Number.isFinite(t))throw new e(`INVALID_ARGS`,`scroll amount must be a number`)}async function Kt(e,t,n,r){if(n.edge){let i=n.edge,a=await te({edge:i,captureState:async n=>await Jt(e,t,i,n),scroll:async()=>await e.scroll(n.direction,r)});return{interactionResult:a.result??{},completedPasses:a.passes}}return{interactionResult:await e.scroll(n.direction,r)??{},completedPasses:1}}function qt(e,t,n,r){let i=re(r);return{direction:e.direction,...e.edge?{edge:e.edge,passes:n}:{},...t.amount===void 0?{}:{amount:t.amount},...t.pixels===void 0?{}:{pixels:t.pixels},...i===void 0?{}:{durationMs:i},...r}}async function Jt(t,n,r,i){if(typeof t.snapshot!=`function`)throw new e(`UNSUPPORTED_OPERATION`,`scroll ${r} requires snapshot support to verify hidden content before scrolling`);let a=t.snapshot;return await g({edge:r,scope:i,captureNodes:async e=>(await a({appBundleId:n?.appBundleId,scope:e})).nodes??[]})}function Yt(e){return e===`bottom`?{direction:`down`,edge:`bottom`}:e===`top`?{direction:`up`,edge:`top`}:{direction:f(e)}}async function Xt(e,t,n){let{x:r,y:i}=J(t,`read requires x y`);if(e.platform===`android`){let{readAndroidTextAtPoint:t}=await import(`./input-actions.js`).then(e=>e.s);return{action:`read`,text:await t(e,r,i)??``}}if(e.platform===`linux`){let{readLinuxTextAtPoint:e}=await import(`./snapshot.js`).then(e=>e.n);return{action:`read`,text:await e(r,i,n?.surface)}}if(v(e)&&n?.surface&&n.surface!==`app`){let{runMacOsReadTextAction:e}=await import(`./helper.js`).then(e=>e.t);return{action:`read`,text:(await e(r,i,{bundleId:n.appBundleId,surface:n.surface})).text}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(e,{command:`readText`,x:r,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId,iosXctestrunFile:n?.iosXctestrunFile,iosXctestDerivedDataPath:n?.iosXctestDerivedDataPath,iosXctestEnvDir:n?.iosXctestEnvDir});return{action:`read`,text:typeof o.text==`string`?o.text:typeof o.message==`string`?o.message:``}}function Zt(e){return fe(e[0])}function X(e){return e.button&&e.button!==`primary`?`Clicked ${e.button} (${e.x}, ${e.y})`:`Tapped (${e.x}, ${e.y})`}function Z(e,t){return`${e} ${Array.from(t).length} chars`}function Qt(e){let t=e.trim();return t.startsWith(`{`)&&t.endsWith(`}`)||t.startsWith(`[`)&&t.endsWith(`]`)}function $t(t,n){let r=n?.subject??`Payload`,i=t.trim();if(!i)throw new e(`INVALID_ARGS`,`${r} cannot be empty`);let a=n?.expandPath?n.expandPath(i,n.cwd):i;try{if(!Se.statSync(a).isFile())throw new e(`INVALID_ARGS`,`${r} path is not a file: ${a}`);return{kind:`file`,path:a}}catch(t){if(t instanceof e)throw t;let n=t.code;if(n===`EACCES`||n===`EPERM`)throw new e(`INVALID_ARGS`,`${r} file is not readable: ${a}`);if(n&&n!==`ENOENT`)throw new e(`COMMAND_FAILED`,`Unable to read ${r} file: ${a}`,{cause:String(t)})}if(Qt(i))return{kind:`inline`,text:i};throw new e(`INVALID_ARGS`,`${r} file not found: ${a}`)}async function en(t){let n=$t(t,{subject:`Push payload`}),r=n.kind===`inline`?n.text:await tn(n.path);try{let t=JSON.parse(r);if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`push payload must be a JSON object`);return t}catch(n){throw n instanceof e?n:new e(`INVALID_ARGS`,`Invalid push payload JSON: ${t}`)}}async function tn(t){try{return await T.readFile(t,`utf8`)}catch(n){let r=n.code;throw r===`ENOENT`?new e(`INVALID_ARGS`,`Push payload file not found: ${t}`):r===`EISDIR`?new e(`INVALID_ARGS`,`Push payload path is not a file: ${t}`):r===`EACCES`||r===`EPERM`?new e(`INVALID_ARGS`,`Push payload file is not readable: ${t}`):new e(`COMMAND_FAILED`,`Unable to read push payload file: ${t}`,{cause:String(n)})}}async function nn(e,n,i,a,o){let s=Q(o),c=await W(e,s);return r({level:`debug`,phase:`platform_command_prepare`,data:{command:n,platform:e.platform,kind:e.kind}}),await t(`platform_command`,async()=>await on(e,c,n,i,a,o,s),{command:n,platform:e.platform})}async function rn(t,n,r){let i=await W(t,Q(r));if(!i.performGesture)throw new e(`UNSUPPORTED_OPERATION`,`Gesture execution is unavailable`);return await i.performGesture(n)}async function an(e,t){return await(await W(e,Q(t))).gestureViewport?.()}function Q(e){return{requestId:e?.requestId,appBundleId:e?.appBundleId,verbose:e?.verbose,logPath:e?.logPath,traceLogPath:e?.traceLogPath,iosXctestrunFile:e?.iosXctestrunFile,iosXctestDerivedDataPath:e?.iosXctestDerivedDataPath,iosXctestEnvDir:e?.iosXctestEnvDir,runnerLeaseContext:e?.runnerLeaseContext}}const $={open:({device:e,interactor:t,positionals:n,context:r})=>sn(e,t,n,r),close:async({device:e,interactor:t,positionals:n})=>{let r=n[0];return r?(await t.close(r),{app:r,...l(`Closed: ${r}`)}):(e.platform===`web`&&await t.close(``),{closed:`session`,...l(`Closed session`)})},press:({device:e,interactor:t,positionals:n,context:r})=>kt(e,t,n,r),longpress:({interactor:e,positionals:t})=>wt(e,t),focus:({interactor:e,positionals:t})=>Tt(e,t),type:({interactor:e,positionals:t,context:n})=>Et(e,t,n),fill:({interactor:e,positionals:t,context:n})=>Dt(e,t,n),scroll:({interactor:e,positionals:t,context:n})=>Ut(e,t,n),"trigger-app-event":({device:e,interactor:t,positionals:n,context:r})=>cn(e,t,n,r),screenshot:({interactor:e,positionals:t,outPath:n,context:r})=>ln(e,t,n,r),viewport:({interactor:e,positionals:t})=>un(e,t),back:async({interactor:e,context:t})=>(await e.back(t?.backMode),{action:`back`,mode:t?.backMode??`in-app`,...l(`Back`)}),home:async({interactor:e})=>(await e.home(),{action:`home`,...l(`Home`)}),orientation:async({interactor:e,positionals:t})=>{let n=c(t[0]),r=(await e.setOrientation(n))?.orientation??n;return{action:`orientation`,orientation:r,...l(`Rotated to ${r}`)}},"app-switcher":async({interactor:e})=>(await e.appSwitcher(),{action:`app-switcher`,...l(`Opened app switcher`)}),clipboard:({interactor:e,positionals:t})=>dn(e,t),keyboard:({device:e,positionals:t,context:n,runnerCtx:r})=>pn(e,t,n,r),"tv-remote":({device:e,interactor:t,positionals:n,context:r})=>fn(e,t,n,r),settings:({device:e,interactor:t,positionals:n,context:r})=>gn(e,t,n,r),push:({device:e,positionals:t,context:n})=>_n(e,t,n),snapshot:({interactor:e,context:t})=>vn(e,t),read:({device:e,positionals:t,context:n})=>Xt(e,t,n)};async function on(t,n,r,i,a,o,s){let c=Object.hasOwn($,r)?$[r]:void 0;if(!c)throw new e(`INVALID_ARGS`,`Unknown command: ${r}`);return await c({device:t,interactor:n,positionals:i,outPath:a,context:o,runnerCtx:s})}async function sn(t,n,r,i){let a=r[0],o=r[1],s=i?.launchConsole,c=i?.launchArgs;if(r.length>2)throw new e(`INVALID_ARGS`,`open accepts at most two arguments: <app|url> [url]`);if(!a){if(s)throw new e(`INVALID_ARGS`,`--launch-console requires an app target`);if(c&&c.length>0)throw new e(`INVALID_ARGS`,`--launch-args requires an app target`);return await n.openDevice(),{app:null,...l(`Opened device`)}}if(s&&(!b(t)||t.kind!==`simulator`))throw new e(`UNSUPPORTED_OPERATION`,be);if(t.platform===`linux`&&c&&c.length>0)throw new e(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on Linux.`);if(o!==void 0){if(S(a))throw new e(`INVALID_ARGS`,`open <app> <url> requires an app target as the first argument`);if(!S(o))throw new e(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(s)throw new e(`INVALID_ARGS`,xe);return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchArgs:c,url:o}),{app:a,url:o,...l(`Opened: ${a}`)}}if(s&&S(a))throw new e(`INVALID_ARGS`,xe);if(i?.clearAppState){if(S(a))throw new e(`INVALID_ARGS`,`Clearing app state requires an app target, not a deep link.`);await n.setSetting(`clear-app-state`,`clear`,a)}return await n.open(a,{activity:i?.activity,appBundleId:i?.appBundleId,launchConsole:s,launchArgs:c,terminateRunningApp:i?.terminateRunningApp}),{app:a,...s?{launchConsole:s}:{},...l(`Opened: ${a}`)}}async function cn(e,t,n,r){let{eventName:i,payload:a}=gt(n),o=_t(e,i,a);return await t.open(o,{appBundleId:r?.appBundleId}),{event:i,eventUrl:o,transport:`deep-link`,...l(`Triggered app event: ${i}`)}}async function ln(e,t,n,r){let i=t[0]??n??`./screenshot-${Date.now()}.png`;await T.mkdir(Ce.dirname(i),{recursive:!0});let a=ne(r);return await e.screenshot(i,{appBundleId:r?.appBundleId,pixelDensity:a.pixelDensity,fullscreen:a.fullscreen,normalizeStatusBar:a.normalizeStatusBar,stabilize:a.stabilize,surface:r?.surface,skipIosSimulatorBootCheck:r?.skipIosSimulatorBootCheck,captureBackend:r?.screenshotCaptureBackend}),{path:i,...l(`Saved screenshot: ${i}`)}}async function un(t,n){if(n.length!==2)throw new e(`INVALID_ARGS`,`viewport requires exactly two arguments: <width> <height>`);let r=p(n[0],`width`),i=p(n[1],`height`);if(!t.setViewport)throw new e(`UNSUPPORTED_OPERATION`,`viewport is not supported by this backend`);return await t.setViewport(r,i),{width:r,height:i,...l(`Viewport set: ${r}x${i}`)}}async function dn(t,n){let r=(n[0]??``).toLowerCase();if(r!==`read`&&r!==`write`)throw new e(`INVALID_ARGS`,`clipboard requires a subcommand: read or write`);if(r===`read`){if(n.length!==1)throw new e(`INVALID_ARGS`,`clipboard read does not accept additional arguments`);return{action:r,text:await t.readClipboard()}}if(n.length<2)throw new e(`INVALID_ARGS`,`clipboard write requires text (use "" to clear clipboard)`);let i=n.slice(1).join(` `);return await t.writeClipboard(i),{action:r,textLength:Array.from(i).length,...l(`Clipboard updated`)}}async function fn(t,n,r,i){if(t.target!==`tv`)throw new e(`UNSUPPORTED_OPERATION`,`tv-remote is supported only on TV targets`,{hint:`Select an Android TV, tvOS, or Vega OS target with --target tv.`});if(r.length!==1)throw new e(`INVALID_ARGS`,`tv-remote requires exactly one button`);let a=u(r[0]),o=i?.durationMs===void 0?void 0:_(i.durationMs,`durationMs`,0,1e4);return await n.tvRemote(a,o),{action:`tv-remote`,button:a,...o===void 0?{}:{durationMs:o},...l(`Pressed TV remote ${a}`)}}async function pn(t,n,r,i){let a=(n[0]??`status`).toLowerCase();if(!oe(a))throw new e(`INVALID_ARGS`,`keyboard requires a subcommand: status, get, dismiss, enter, or return`);if(n.length>1)throw new e(`INVALID_ARGS`,`keyboard accepts at most one subcommand argument`);if(t.platform===`android`)return await mn(t,a);if(b(t))return await hn(t,a,r,i);throw new e(`UNSUPPORTED_OPERATION`,`keyboard is supported only on Android and iOS`)}async function mn(e,t){if(t===`enter`||t===`return`){let{pressAndroidEnter:t}=await import(`./input-actions.js`).then(e=>e.s);return await t(e),{platform:`android`,action:`enter`,...l(`Keyboard enter pressed`)}}if(t===`dismiss`){let{dismissAndroidKeyboard:t}=await import(`./device-input-state.js`).then(e=>e.t),n=await t(e);return{platform:`android`,action:`dismiss`,attempts:n.attempts,wasVisible:n.wasVisible,dismissed:n.dismissed,visible:n.visible,inputType:n.inputType,type:n.type,inputMethodPackage:n.inputMethodPackage,focusedPackage:n.focusedPackage,focusedResourceId:n.focusedResourceId,inputOwner:n.inputOwner}}let{getAndroidKeyboardState:n}=await import(`./device-input-state.js`).then(e=>e.t),r=await n(e);return{platform:`android`,action:`status`,visible:r.visible,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,inputOwner:r.inputOwner}}async function hn(t,n,r,i){if(n!==`dismiss`&&n!==`enter`&&n!==`return`)throw new e(`UNSUPPORTED_OPERATION`,`keyboard status/get is currently supported only on Android; use keyboard dismiss or enter on iOS`);if(n===`enter`||n===`return`){let{runAppleRunnerCommand:e}=await import(`./runner-client.js`).then(e=>e.o),n=await e(t,{command:`keyboardReturn`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`enter`,visible:n.visible,wasVisible:n.wasVisible,...l(`Keyboard enter pressed`)}}let{runAppleRunnerCommand:a}=await import(`./runner-client.js`).then(e=>e.o),o=await a(t,{command:`keyboardDismiss`,appBundleId:r?.appBundleId},i);return{platform:`ios`,action:`dismiss`,wasVisible:o.wasVisible,dismissed:o.dismissed,visible:o.visible,...l(o.dismissed?`Keyboard dismissed`:`Keyboard already hidden`)}}async function gn(t,n,i,a){let[s,c,u,f]=i;if(!s||!c&&s!==`clear-app-state`)throw new e(`INVALID_ARGS`,`settings requires setting state`);if(s===`clear-app-state`){let i=(c===`clear`?u:c)??a?.appBundleId;if(!i)throw new e(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);r({level:`debug`,phase:`settings_apply`,data:{setting:s,state:`clear`,appBundleId:i,platform:t.platform}});let d=await n.setSetting(s,`clear`,i);return d&&typeof d==`object`?o({setting:s,state:`clear`,...d},yn(d)??`Cleared user data for ${i}`):{setting:s,state:`clear`,...l(`Cleared user data for ${i}`)}}if(!c)throw new e(`INVALID_ARGS`,`settings requires setting state`);let p=s===`location`&&c===`set`,m=(s===`permission`||p?i[4]:i[2])??a?.appBundleId,h=s===`permission`?{permissionTarget:u,permissionMode:f}:p?{latitude:d(u,`latitude`),longitude:d(f,`longitude`)}:void 0;r({level:`debug`,phase:`settings_apply`,data:p?{setting:s,state:c,latitude:u,longitude:f,platform:t.platform}:s===`permission`?{setting:s,state:c,permissionTarget:u,permissionMode:f,platform:t.platform}:{setting:s,state:c,appBundleId:m,platform:t.platform}});let g=await n.setSetting(s,c,m,h);return g&&typeof g==`object`?o({setting:s,state:c,...g},yn(g)??`Updated setting: ${s}`):{setting:s,state:c,...l(`Updated setting: ${s}`)}}async function _n(t,n,r){let i=n[0]?.trim(),a=n[1]?.trim();if(!i||!a)throw new e(`INVALID_ARGS`,`push requires <bundle|package> <payload.json|inline-json>`);let o=await en(a);if(b(t)){let{pushIosNotification:e}=await import(`./apps.js`).then(e=>e.t);return await e(t,i,o),{platform:`ios`,bundleId:i,...l(`Pushed notification to ${i}`)}}let{pushAndroidNotification:s}=await import(`./notifications.js`),c=await s(t,i,o);return{platform:`android`,package:i,action:c.action,extrasCount:c.extrasCount,...l(`Pushed notification to ${i}`)}}async function vn(e,t){return await e.snapshot({appBundleId:t?.appBundleId,interactiveOnly:t?.snapshotInteractiveOnly,depth:t?.snapshotDepth,scope:t?.snapshotScope,raw:t?.snapshotRaw,includeRects:t?.snapshotIncludeRects,includeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,surface:t?.surface})}function yn(e){return typeof e.message==`string`&&e.message.length>0?e.message:void 0}function bn(e,t,r,i,a,o){return{requestId:a??n().requestId,appBundleId:r,runnerLeaseContext:he({meta:o}),activity:t?.activity,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,clearAppState:t?.clearAppState,verbose:t?.verbose,logPath:e,traceLogPath:i,iosXctestrunFile:t?.iosXctestrunFile,iosXctestDerivedDataPath:t?.iosXctestDerivedDataPath,iosXctestEnvDir:t?.iosXctestEnvDir,screenshotCaptureBackend:t?.maestro?.screenshotCaptureBackend,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,snapshotIncludeHiddenContentHints:t?.snapshotIncludeHiddenContentHints,...m(t),count:t?.count,intervalMs:t?.intervalMs,delayMs:t?.delayMs,durationMs:t?.durationMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,pixels:t?.pixels,doubleTap:t?.doubleTap,clickButton:s(t),backMode:t?.backMode,pauseMs:t?.pauseMs,pattern:t?.pattern}}export{D as C,Oe as S,Ye as _,$t as a,Ae as b,pt as c,ct as d,ut as f,Ge as g,Xe as h,an as i,mt as l,Ke as m,nn as n,H as o,lt as p,rn as r,U as s,bn as t,z as u,Pe as v,De as x,ke as y};
@@ -1,2 +1,2 @@
1
- import { E as defaultHintForCode, R as centerOfRect, c as DaemonResponseData, d as JsonRpcId, f as JsonRpcRequestEnvelope, g as LeaseReleasePayload, h as LeaseHeartbeatPayload, i as DaemonInstallSource, k as normalizeError, m as LeaseBackend, o as DaemonRequest, p as LeaseAllocatePayload, r as DaemonError, s as DaemonResponse, x as SessionRuntimeHints } from "./sdk-contracts.js";
2
- export { type DaemonError, type DaemonInstallSource, type DaemonRequest, type DaemonResponse, type DaemonResponseData, type JsonRpcId, type JsonRpcRequestEnvelope, type LeaseAllocatePayload, type LeaseBackend, type LeaseHeartbeatPayload, type LeaseReleasePayload, type SessionRuntimeHints, centerOfRect, defaultHintForCode, normalizeError };
1
+ import { N as centerOfRect, c as DaemonResponseData, d as JsonRpcId, f as JsonRpcRequestEnvelope, i as DaemonInstallSource, o as DaemonRequest, p as LeaseBackend, r as DaemonError, s as DaemonResponse, v as SessionRuntimeHints, w as normalizeError, x as defaultHintForCode } from "./sdk-contracts.js";
2
+ export { type DaemonError, type DaemonInstallSource, type DaemonRequest, type DaemonResponse, type DaemonResponseData, type JsonRpcId, type JsonRpcRequestEnvelope, type LeaseBackend, type SessionRuntimeHints, centerOfRect, defaultHintForCode, normalizeError };
@@ -1,4 +1,4 @@
1
- import{_ as e}from"./sdk-contracts.js";import{h as t,v as n}from"./sdk-android-adb.js";import{u as r}from"./sdk-batch-runner.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let t=JSON.parse(e);return r(t)?t:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
1
+ import{_ as e}from"./sdk-contracts.js";import{h as t,v as n}from"./sdk-android-adb.js";import{m as r}from"./sdk-batch-runner.js";import i from"node:path";import a from"node:fs/promises";const o=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(!(!e||!o.test(e)))return e.replaceAll(`-`,``).toUpperCase()}function c(e,t){return`${e.uuid}:${l(t)}`}function l(e){return`0x${e.toString(16)}`}function u(e){return typeof e==`string`&&e.length>0?e:void 0}function d(...e){for(let t of e){let e=u(t);if(e)return e}}function f(e){let t=e.filter(e=>!!e);return t.length>0?t.join(` `):void 0}function p(e){try{let t=JSON.parse(e);return r(t)?t:null}catch{return null}}function m(e){if(typeof e==`number`&&Number.isSafeInteger(e))return e;if(typeof e==`string`){let t=e.startsWith(`0x`)?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function h(e,t,n){if(!Object.hasOwn(e,t))return;let r=m(e[t]);if(r!==void 0)return r;v(n,t)}function g(e,t,n){if(!Object.hasOwn(e,t))return;let r=_(e[t]);if(r!==void 0)return r;v(n,t)}function _(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isSafeInteger(e)||typeof e==`string`&&/^(?:0x[0-9a-fA-F]+|\d+)$/.test(e))return BigInt(e)}function v(t,n){throw new e(`INVALID_ARGS`,`Invalid ${t} numeric field: ${n}`,{hint:`Crash artifact numeric fields must be integer numbers or integer numeric strings.`})}function y(e){return e.length===1?e[0]:void 0}function b(e){return[...new Set(e)]}function x(e){let t=e.match(/^(.*) \+ (\d+)$/);return t?{symbol:t[1],location:Number(t[2])}:{symbol:e}}const S=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;function ee(e){return te(e)??w(e)}function te(e){let t=ne(e);if(!t)return null;let n=(Array.isArray(t.payload.usedImages)?t.payload.usedImages:[]).flatMap((e,t)=>C(e,t));if(n.length===0)return null;let r=re(Array.isArray(t.payload.threads)?t.payload.threads:[],n);return{format:`ips`,images:n,addresses:r.map(({frame:e,...t})=>t),document:t,frameMatches:r,write:e=>oe(t,r,e)}}function ne(e){let t=p(e);if(t)return{payload:t};let n=e.indexOf(`
2
2
  `);if(n===-1)return null;let r=e.slice(0,n),i=p(e.slice(n+1));return i?{header:r,payload:i}:null}function re(e,t){let n=new Map(t.map(e=>[e.index,e]));return e.flatMap((e,t)=>ie(e).flatMap((e,r)=>ae(e,n,t,r)))}function ie(e){return!r(e)||!Array.isArray(e.frames)?[]:e.frames.filter(r)}function ae(e,t,n,r){let i=h(e,`imageIndex`,`IPS frame`),a=g(e,`imageOffset`,`IPS frame`);if(i===void 0||a===void 0)return[];let o=t.get(i);return o?[{frame:e,frameIndex:r,threadIndex:n,image:o,address:o.base+a}]:[]}function oe(e,t,n){for(let e of t){let t=n.get(c(e.image,e.address))?.text;t&&se(e.frame,t)}e.payload.agentDeviceSymbolication={tool:`agent-device debug symbols`,symbolicatedFrames:[...n.values()].filter(e=>e.text).length};let r=`${JSON.stringify(e.payload,null,2)}\n`;return e.header?`${e.header}\n${r}`:r}function se(e,t){let n=x(t);e.symbol=n.symbol,n.location!==void 0&&(e.symbolLocation=n.location)}function C(e,t){if(!r(e))return[];let n=s(u(e.uuid)),a=g(e,`base`,`IPS usedImages`);if(!n||a===void 0)return[];let o=u(e.path);return[{index:t,name:u(e.name)??(o?i.basename(o):`image-${t}`),uuid:n,arch:u(e.arch),base:a,path:o}]}function w(e){let t=e.split(`
3
3
  `),n=T(t);if(n.length===0)return null;let r=O(t,n);return{format:`text`,images:n,addresses:r,lines:t,frameMatches:r,write(e){let n=new Map(r.map(e=>[e.lineIndex,e]));return t.map((t,r)=>{let i=n.get(r);if(!i)return t;let a=e.get(c(i.image,i.address))?.text;return!a||t.includes(a)?t:`${t} // ${a}`}).join(`
4
4
  `)}}}function T(e){let t=[],n=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(n===-1)return t;for(let r of e.slice(n+1)){let e=E(r);e&&t.push(e)}return t}function E(e){let t=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!t)return null;let n=s(t[4]);if(!n)return null;let r=D(t[3].trim(),t[5].trim());return{name:r.name,arch:r.arch,uuid:n,base:BigInt(t[1]),end:BigInt(t[2]),path:t[5].trim()}}function D(e,t){let n=e.split(/\s+/),r=n.at(-1);if(r&&S.test(r))return{name:n.slice(0,-1).join(` `).trim(),arch:r};let a=i.basename(t);return{name:e.startsWith(a)?a:e}}function O(e,t){let n=[],r;for(let[i,a]of e.entries()){let e=a.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(a.trim().length===0||/^Thread\s+\d+/.test(a))&&(r=void 0);let o=k(a,t),s=a.match(/^\s*(\d+)/);o&&s&&n.push({...o,frameIndex:Number(s[1]),lineIndex:i,threadIndex:r})}return n}function k(e,t){let n=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!n)return null;let r=n[1].trim(),i=BigInt(n[2]),a=A(t,r,i);return a?{image:a,address:i}:null}function A(e,t,n){let r=e.filter(e=>e.name===t);return r.find(e=>j(e,n))??y(r)}function j(e,t){return e.end!==void 0&&e.base<=t&&t<=e.end}const M=1e4;async function N(e){return e.dsym&&e.searchPath?[H(e.cwd,e.dsym),...await P(H(e.cwd,e.searchPath))]:e.dsym?[H(e.cwd,e.dsym)]:e.searchPath?await P(H(e.cwd,e.searchPath)):[]}async function P(t){let n=[],r=0;async function o(s){if(n.length>=200)return;if(r+=1,r>M)throw new e(`COMMAND_FAILED`,`debug symbols search-path scan exceeded bounds.`,{searchPath:t,maxEntries:M,hint:`Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory.`});if(!(await F(s,t)).isDirectory()){s===t&&I(t);return}if(s.endsWith(`.dSYM`)){n.push(s);return}let c=await a.readdir(s,{withFileTypes:!0});for(let e of c)e.isDirectory()&&await o(i.join(s,e.name))}return await o(t),n}async function F(t,n){try{return await a.stat(t)}catch{throw new e(`INVALID_ARGS`,`debug symbols search path does not exist: ${n}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}}function I(t){throw new e(`INVALID_ARGS`,`debug symbols search path is not a directory: ${t}`,{hint:`Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly.`})}async function L(t,n){let r=(await Promise.all(b(t).map(e=>R(e,n)))).flat();if(r.length===0)throw new e(`COMMAND_FAILED`,`No UUIDs found in dSYM bundle.`,{hint:`Verify the path points to a built .dSYM bundle with DWARF contents.`});return r}async function R(e,r){return await z(e),B(e,t(await n(r,[`--uuid`,e],{timeoutMs:15e3,allowFailure:!0}),`Failed to inspect dSYM UUIDs: ${e}`,{hint:`Verify the dSYM bundle is valid and readable.`}).stdout)}async function z(t){if(!((await a.stat(t).catch(()=>null))?.isDirectory()&&t.endsWith(`.dSYM`)))throw new e(`INVALID_ARGS`,`Not a .dSYM bundle: ${t}`,{hint:`Pass the .dSYM bundle path, not the DWARF executable inside it.`})}function B(e,t){return t.split(`
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{s as t,y as n}from"./sdk-device.js";import{o as r}from"./boot-diagnostics.js";import{j as i}from"./runner-disposal.js";import{a,r as o}from"./tool-provider.js";import{r as s}from"./simulator.js";import{buildHostMacDevice as c}from"./devices.js";import{promises as l}from"node:fs";import u from"node:os";import d from"node:path";const f=/^(iphone|ipad|ipod|appletv|realitydevice)/i,p=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,h=/\b(iphone|ipad|ipod)\b/i,g=/^appletv/i,_=[`apple tv`,`appletv`,`tvos`],v=/^==\s*(.+?)\s*==$/,y=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function b(e){return(e??``).trim().toLowerCase()}function x(e){return b(e)}function S(e){return b(e.hardwareProperties?.platform)}function C(e){return e.includes(`tvos`)}function w(e){return e.includes(`xros`)||e.includes(`visionos`)}function T(e){return C(x(e))?`tv`:`mobile`}function E(e){let t=x(e);return t.includes(`ios`)||t.includes(`tvos`)||t.includes(`xros`)||t.includes(`visionos`)}function D(e){let t=b(e);return _.some(e=>t.includes(e))}function O(e){return h.test(e.trim())}function k(e){return D(e)?`tv`:O(e)||m.test(e)?`mobile`:null}function A(e,t){return e===`tv`?`tvos`:t.some(e=>m.test(e))?`visionos`:t.some(e=>p.test(e))?`ipados`:`ios`}function j(e){return f.test(e.trim())}function M(e){return g.test(e.trim())}function N(e){return[e.name??``,e.deviceProperties?.name??``,e.deviceProperties?.deviceType??``]}function P(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??``}function F(e){return C(S(e))||M(P(e))||N(e).some(D)?`tv`:`mobile`}function I(e){let t=S(e);return t.includes(`ios`)||t.includes(`tvos`)||w(t)||j(P(e))?!0:N(e).some(D)}async function L(e={}){let t=r(e.simulatorSetPath),o=e.target,s;try{s=await a(i([`list`,`devices`,`-j`],{simulatorSetPath:t}))}catch{return null}let c;try{c=JSON.parse(s.stdout)}catch{return null}return n(R(c,t)).find(e=>!o||e.target===o)??null}function R(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(E(r))for(let e of i){if(!e.isAvailable)continue;let i=T(r),a={platform:`apple`,id:e.udid,name:e.name,kind:`simulator`,target:i,appleOs:A(i,[e.deviceTypeIdentifier??``,e.name]),booted:e.state===`Booted`,...t?{simulatorSetPath:t}:{}};a.booted&&s(a),n.push(a)}return n}function z(e){let t=[];for(let n of e.result?.devices??[]){if(!I(n))continue;let e=n.hardwareProperties?.udid??n.identifier??``,r=n.name??n.deviceProperties?.name??e;if(!e)continue;let i=F(n);t.push({platform:`apple`,id:e,name:r,kind:`device`,target:i,appleOs:A(i,[P(n),...N(n)]),booted:!0})}return t}function B(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=v.exec(e);if(i){n=i[1]?.trim()??null;continue}if(n!==`Devices`)continue;let a=y.exec(e),o=a?.groups?.id?.trim()??``,s=a?.groups?.name?.trim()??``;if(!o||!s)continue;let c=k(s);c&&t.push({platform:`apple`,id:o,name:s,kind:`device`,target:c,appleOs:A(c,[s]),booted:!0})}return t}function V(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function H(){let e=null;try{if(e=d.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),(await a([`devicectl`,`list`,`devices`,`--json-output`,e],{allowFailure:!0,timeoutMs:8e3})).exitCode!==0)return[];let t=await l.readFile(e,`utf8`);return z(JSON.parse(t))}catch{return[]}finally{e&&await l.rm(e,{force:!0}).catch(()=>{})}}async function U(){try{let e=await a([`xctrace`,`list`,`devices`],{allowFailure:!0});return e.exitCode===0?B(e.stdout):[]}catch{return[]}}async function W(s={}){if(process.platform!==`darwin`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple tools are only available on macOS`);if(!await o().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await a(i([`list`,`devices`,`-j`],{simulatorSetPath:l})),d=[];try{d=R(JSON.parse(u.stdout),l)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse simctl devices JSON`,void 0,t)}if(d.push(c()),s.udid&&d.some(e=>t(e)&&e.id===s.udid))return d;if(l)return n(d);let[f,p]=await Promise.all([H(),U()]);return d=V(d,f),n(V(d,p))}export{L as findBootableIosSimulator,W as listAppleDevices};
1
+ import{_ as e}from"./sdk-contracts.js";import{b as t,s as n}from"./sdk-device.js";import{o as r}from"./boot-diagnostics.js";import{a as i,r as a}from"./tool-provider.js";import{t as o}from"./simctl.js";import{r as s}from"./simulator.js";import{buildHostMacDevice as c}from"./devices.js";import{promises as l}from"node:fs";import u from"node:os";import d from"node:path";const f=/^(iphone|ipad|ipod|appletv|realitydevice)/i,p=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,h=/\b(iphone|ipad|ipod)\b/i,g=/^appletv/i,_=[`apple tv`,`appletv`,`tvos`],v=/^==\s*(.+?)\s*==$/,y=/^(?<name>.+?)\s+(?:\[(?<idBracket>[^[\]]+)\]|\((?<osVersion>[^)]+)\)\s+\((?<idParen>[^)]+)\))\s*$/;function b(e){return(e??``).trim().toLowerCase()}function x(e){return b(e)}function S(e){return b(e.hardwareProperties?.platform)}function C(e){return e.includes(`tvos`)}function w(e){return e.includes(`xros`)||e.includes(`visionos`)}function T(e){return C(x(e))?`tv`:`mobile`}function E(e){let t=x(e);return t.includes(`ios`)||t.includes(`tvos`)||t.includes(`xros`)||t.includes(`visionos`)}function D(e){let t=b(e);return _.some(e=>t.includes(e))}function O(e){return h.test(e.trim())}function k(e){return D(e)?`tv`:O(e)||m.test(e)?`mobile`:null}function A(e,t){return e===`tv`?`tvos`:t.some(e=>m.test(e))?`visionos`:t.some(e=>p.test(e))?`ipados`:`ios`}function j(e){return f.test(e.trim())}function M(e){return g.test(e.trim())}function N(e){return[e.name??``,e.deviceProperties?.name??``,e.deviceProperties?.deviceType??``]}function P(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??``}function F(e){return C(S(e))||M(P(e))||N(e).some(D)?`tv`:`mobile`}function I(e){let t=S(e);return t.includes(`ios`)||t.includes(`tvos`)||w(t)||j(P(e))?!0:N(e).some(D)}async function L(e={}){let n=r(e.simulatorSetPath),a=e.target,s;try{s=await i(o([`list`,`devices`,`-j`],{simulatorSetPath:n}))}catch{return null}let c;try{c=JSON.parse(s.stdout)}catch{return null}return t(R(c,n)).find(e=>!a||e.target===a)??null}function R(e,t){let n=[];for(let[r,i]of Object.entries(e.devices))if(E(r))for(let e of i){if(!e.isAvailable)continue;let i=T(r),a={platform:`apple`,id:e.udid,name:e.name,kind:`simulator`,target:i,appleOs:A(i,[e.deviceTypeIdentifier??``,e.name]),booted:e.state===`Booted`,...t?{simulatorSetPath:t}:{}};a.booted&&s(a),n.push(a)}return n}function z(e){let t=[];for(let n of e.result?.devices??[]){if(!I(n))continue;let e=n.hardwareProperties?.udid??n.identifier??``,r=n.name??n.deviceProperties?.name??e;if(!e)continue;let i=F(n);t.push({platform:`apple`,id:e,name:r,kind:`device`,target:i,appleOs:A(i,[P(n),...N(n)]),iosPhysicalDeviceBackend:`coredevice`,booted:!0})}return t}function B(e){let t=y.exec(e);if(!t?.groups)return null;let n=t.groups.name?.trim()??``,r=t.groups.idBracket?.trim()??t.groups.idParen?.trim()??``,i=t.groups.osVersion?.trim();return!n||!r?null:{name:n,id:r,osVersion:i}}function V(e,t,n){let r=k(e);return r?{platform:`apple`,id:t,name:e,kind:`device`,target:r,appleOs:A(r,n?[e,n]:[e]),iosPhysicalDeviceBackend:`xctest`,booted:!0}:null}function H(e){let t=[],n=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let i=v.exec(e);if(i){n=i[1]?.trim()??null;continue}if(n!==`Devices`)continue;let a=B(e);if(!a)continue;let o=V(a.name,a.id,a.osVersion);o&&t.push(o)}return t}function U(e,t){let n=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)n.has(e.id)||(n.add(e.id),r.push(e));return r}async function W(){let e=null;try{if(e=d.join(u.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),(await i([`devicectl`,`list`,`devices`,`--json-output`,e],{allowFailure:!0,timeoutMs:8e3})).exitCode!==0)return[];let t=await l.readFile(e,`utf8`);return z(JSON.parse(t))}catch{return[]}finally{e&&await l.rm(e,{force:!0}).catch(()=>{})}}async function G(){try{let e=await i([`xctrace`,`list`,`devices`],{allowFailure:!0});return e.exitCode===0?H(e.stdout):[]}catch{return[]}}async function K(s={}){if(process.platform!==`darwin`)throw new e(`UNSUPPORTED_PLATFORM`,`Apple tools are only available on macOS`);if(!await a().whichCommand(`xcrun`))throw new e(`TOOL_MISSING`,`xcrun not found in PATH`);let l=r(s.simulatorSetPath),u=await i(o([`list`,`devices`,`-j`],{simulatorSetPath:l})),d=[];try{d=R(JSON.parse(u.stdout),l)}catch(t){throw new e(`COMMAND_FAILED`,`Failed to parse simctl devices JSON`,void 0,t)}if(d.push(c()),s.udid&&d.some(e=>n(e)&&e.id===s.udid))return d;if(l)return t(d);let[f,p]=await Promise.all([W(),G()]);return d=U(d,f),t(U(d,p))}export{L as findBootableIosSimulator,K as listAppleDevices};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";import{h as t}from"./sdk-android-adb.js";import{t as n}from"./tool-provider3.js";const r=`VirtualDevice`;async function i(){let r=n();if(!await r.isAvailable())throw new e(`TOOL_MISSING`,`Vega CLI not found in PATH`,{hint:`Install Vega Developer Tools, source ~/vega/env, and retry devices.`});let i=t(await r.listDevices({allowFailure:!0,timeoutMs:1e4}),`Failed to list Vega devices`),o=a(i.stdout),c=s(i.stdout);if(o.length===0&&c.length>0)throw new e(`DEVICE_NOT_FOUND`,`Vega CLI found devices, but no supported Vega Virtual Device is running.`,{listedSerials:c,hint:`Start the Vega Virtual Device, then retry with --platform vega --target tv.`});return o}function a(e){return s(e).some(o)?[{platform:`vega`,id:r,name:`Vega Virtual Device (${r})`,kind:`emulator`,target:`tv`,booted:!0}]:[]}function o(e){return e.toLowerCase()===`virtualdevice`}function s(e){let t=new Set;for(let n of e.split(/\r?\n/)){let e=/^\s*([^\s:]+)\s*:\s*\S/.exec(n)?.[1]?.trim();e&&t.add(e)}return[...t]}export{i as listVegaDevices,a as parseVegaDeviceList};
package/dist/src/find.js CHANGED
@@ -1 +1 @@
1
- import{u as e}from"./sdk-contracts.js";import{C as t,D as n,E as r,w as i}from"./sdk-batch.js";import{K as a,Kn as o,q as s,qn as c}from"./tv-remote.js";import"./snapshot-diagnostics.js";import{D as l,m as u}from"./sdk-selectors.js";import{t as d}from"./snapshot-quality.js";import{r as f}from"./android-input-method-overlays.js";import{c as p,n as m,s as h,t as g}from"./context.js";import{$t as _,h as v,un as y}from"./internal/daemon.js";import{a as b,t as x,w as S}from"./selector-runtime.js";async function C(e){let{req:t,sessionName:a,logPath:o,sessionStore:s,invoke:c}=e,l=t.command;if(l!==`find`)return null;let u=t.positionals??[];if(u.length===0)return h(`INVALID_ARGS`,`find requires a locator or text`);let{locator:f,query:m,action:g,value:_}=r(u);if(!m)return h(`INVALID_ARGS`,`find requires a value`);if(t.flags?.findFirst&&t.flags?.findLast)return h(`INVALID_ARGS`,`find accepts only one of --first or --last`);if(t.flags?.record&&!i(g))return h(`INVALID_ARGS`,`find ${g} is a mutating action and is always recorded; --record only applies to a read-only find (exists, wait, get text, get attrs).`);let v=await x({req:t,sessionName:a,logPath:o,sessionStore:s});if(v)return v;let y=s.get(a);if(!y)return p();let b=y.device,C=n(f,m),O=T({device:b,session:y,req:t,logPath:o,locator:f,query:m,sessionStore:s,sessionName:a}),k={req:t,sessionName:a,logPath:o,sessionStore:s,invoke:c,session:y,device:b,command:l,locator:f,query:m,publicFlags:W(t.flags)},A=await O();if(d(A.snapshotQuality))return E(A.snapshotQuality);let{nodes:j}=A,M=D({nodes:j,locator:f,query:m,selectorChain:C,flags:t.flags,platform:b.platform});if(!M.ok)return S(M.response,A);let N=M.node,F=P(j,N),I=await w(k,{node:N,resolvedNode:F,ref:`@${F.ref}`,nodes:j,actionFlags:{...t.flags??{},noRecord:!0}},g,_);return I&&S(I,A)}async function w(e,t,n,r){let i={click:()=>L(e,t),fill:()=>R(e,t,r),focus:()=>z(e,t),type:()=>B(e,t,r)}[n];return i?await i():null}function T(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o}=e,{sessionStore:s,sessionName:c}=e,l=b({device:t,session:n,sessionStore:s,sessionName:c,req:r,logPath:i});return async()=>{let{snapshot:e}=await l.capture({flags:{...r.flags,snapshotInteractiveOnly:!0},recovery:{legacyIosSparse:{query:o,shouldScope:K(a)},sparseVerdictQueryScope:{query:o,shouldScope:K(a)}}});return{nodes:e.nodes,snapshotQuality:e.snapshotQuality,systemSurfaceOnly:e.systemSurfaceOnly}}}function E(e){return h(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function D(e){let{nodes:n,locator:r,query:i,selectorChain:a,flags:o,platform:s}=e,c=n.filter(e=>!F(e,n[0]));if(a){let e=u(c,a,{platform:s,requireRect:!0,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}let l=t(c,r,i,{requireRect:!0});if(l.matches=k(l.matches,n),l.matches.length>1){let e=O(l.matches,o);if(!e)return{ok:!1,response:G(l.matches,r,i)};l.matches=e}let d=l.matches[0]??null;return d?{ok:!0,node:d}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}function O(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function k(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return A(i.length>0?i:t,n)}function A(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:j(e,t)})).sort((e,t)=>t.score===e.score?N(e.node)-N(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function j(e,t){let n=s(t,e);if(n.reason===`covered`)return 0;let r=M(n,t[0]);return r>0?r:e.hittable&&e.rect&&!F(e,t[0])?3:+!!e.rect}function M(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!F(e.node,t)?2:0:0}function N(e){return e.rect?e.rect.width*e.rect.height:1/0}function P(e,t){let n=a(e,t);return F(n,e[0])&&t.rect?t:n}function F(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:I(e.rect,t.rect)}function I(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function L(t,n){let{req:r,sessionName:i,sessionStore:a,session:s,invoke:l,command:u,locator:d,query:f,publicFlags:p}=t,m=await l({token:r.token,session:i,command:`click`,positionals:[n.ref],flags:n.actionFlags,internal:{findResolvedTarget:!0}});if(!m.ok)return m;let h=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,g={ref:n.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let _=o(m.data)??`Tapped ${n.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,c(_)),v(a,s,r,u,{ref:n.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function R(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return h(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags,internal:{findResolvedTarget:!0}});return u.ok&&v(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function z(e,t){let n=await V(e,t);return n.ok&&U(e,t,`focus`),n}async function B(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return h(`INVALID_ARGS`,`find type requires text`);let s=await V(e,t);if(!s.ok)return s;_(o);let c=await m(i,`type`,[n],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)});return U(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function V(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=H(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?(_(o),{ok:!0,data:await m(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)})??{ref:n.ref}}):h(`COMMAND_FAILED`,`matched element has no bounds`)}function H(e,t){let n=[e.resolvedNode,e.node].find(f);return n?h(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function U(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;v(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function W(e){return{...y(e)??{}}}function G(e,t,n){let r=e.slice(0,8).map(e=>{let t=l(e)||e.label||e.identifier||e.type||``;return`@${e.ref}${t?`(${t})`:``}`});return h(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,matches:e.length,candidates:r})}function K(e){return e!==`role`}export{C as handleFindCommands};
1
+ import{u as e}from"./sdk-contracts.js";import{H as t,U as n,W as r,q as i}from"./sdk-batch-runner.js";import{B as a,Qn as o,V as s,Zn as c}from"./recording-export-quality.js";import"./snapshot-diagnostics.js";import{M as l,h as u}from"./sdk-selectors.js";import{t as d}from"./snapshot-quality.js";import{r as f}from"./android-input-method-overlays.js";import{c as p,n as m,s as h,t as g}from"./context.js";import{h as _,mn as v,rn as y}from"./internal/daemon.js";import{a as b,t as x,w as S}from"./selector-runtime.js";async function C(e){let{req:n,sessionName:a,logPath:o,sessionStore:s,invoke:c}=e,l=n.command;if(l!==`find`)return null;let u=t(n.positionals??[],n.flags);if(!u.ok)return h(u.code,u.message);let{locator:f,query:m,action:g,value:_}=u.parsed;if(n.flags?.record&&!r(g))return h(`INVALID_ARGS`,`find ${g} is a mutating action and is always recorded; --record only applies to a read-only find (exists, wait, get text, get attrs).`);let v=await x({req:n,sessionName:a,logPath:o,sessionStore:s});if(v)return v;let y=s.get(a);if(!y)return p();let b=y.device,C=i(f,m),O=T({device:b,session:y,req:n,logPath:o,locator:f,query:m,sessionStore:s,sessionName:a}),k={req:n,sessionName:a,logPath:o,sessionStore:s,invoke:c,session:y,device:b,command:l,locator:f,query:m,publicFlags:W(n.flags)},A=await O();if(d(A.snapshotQuality))return E(A.snapshotQuality);let{nodes:j}=A,M=D({nodes:j,locator:f,query:m,selectorChain:C,flags:n.flags,platform:b.platform});if(!M.ok)return S(M.response,A);let N=M.node,F=P(j,N),I=await w(k,{node:N,resolvedNode:F,ref:`@${F.ref}`,nodes:j,actionFlags:{...n.flags??{},noRecord:!0}},g,_);return I&&S(I,A)}async function w(e,t,n,r){let i={click:()=>L(e,t),fill:()=>R(e,t,r),focus:()=>z(e,t),type:()=>B(e,t,r)}[n];return i?await i():null}function T(e){let{device:t,session:n,req:r,logPath:i,locator:a,query:o}=e,{sessionStore:s,sessionName:c}=e,l=b({device:t,session:n,sessionStore:s,sessionName:c,req:r,logPath:i});return async()=>{let{snapshot:e}=await l.capture({flags:{...r.flags,snapshotInteractiveOnly:!0},recovery:{legacyIosSparse:{query:o,shouldScope:K(a)},sparseVerdictQueryScope:{query:o,shouldScope:K(a)}}});return{nodes:e.nodes,snapshotQuality:e.snapshotQuality,systemSurfaceOnly:e.systemSurfaceOnly}}}function E(e){return h(`COMMAND_FAILED`,`find could not read the current accessibility tree`,{reason:e.reason,hint:`The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen.`})}function D(e){let{nodes:t,locator:r,query:i,selectorChain:a,flags:o,platform:s}=e,c=t.filter(e=>!F(e,t[0]));if(a){let e=u(c,a,{platform:s,requireRect:!0,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}let l=n(c,r,i,{requireRect:!0});if(l.matches=k(l.matches,t),l.matches.length>1){let e=O(l.matches,o);if(!e)return{ok:!1,response:G(l.matches,r,i)};l.matches=e}let d=l.matches[0]??null;return d?{ok:!0,node:d}:{ok:!1,response:h(`COMMAND_FAILED`,`find did not match any element`)}}function O(e,t){return t?.findFirst?[e[0]]:t?.findLast?[e[e.length-1]]:null}function k(t,n){let r=n[0]?.rect;if(!r)return t;let i=t.filter(t=>{if(!t.rect)return!1;let n=e(t.rect);return n.x>=r.x&&n.x<=r.x+r.width&&n.y>=r.y&&n.y<=r.y+r.height});return A(i.length>0?i:t,n)}function A(e,t){return e.length<2?e:e.map((e,n)=>({node:e,index:n,score:j(e,t)})).sort((e,t)=>t.score===e.score?N(e.node)-N(t.node)||e.index-t.index:t.score-e.score).map(e=>e.node)}function j(e,t){let n=s(t,e);if(n.reason===`covered`)return 0;let r=M(n,t[0]);return r>0?r:e.hittable&&e.rect&&!F(e,t[0])?3:+!!e.rect}function M(e,t){return e.node.rect?e.reason===`semantic-target`||e.reason===`same-rect-descendant`?4:e.reason===`hittable-ancestor`&&!F(e.node,t)?2:0:0}function N(e){return e.rect?e.rect.width*e.rect.height:1/0}function P(e,t){let n=a(e,t);return F(n,e[0])&&t.rect?t:n}function F(e,t){if(!t?.rect||!e.rect)return!1;let n=e.type?.toLowerCase()??``;return!n.includes(`application`)&&!n.includes(`window`)?!1:I(e.rect,t.rect)}function I(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}async function L(t,n){let{req:r,sessionName:i,sessionStore:a,session:s,invoke:l,command:u,locator:d,query:f,publicFlags:p}=t,m=await l({token:r.token,session:i,command:`click`,positionals:[n.ref],flags:n.actionFlags,internal:{findResolvedTarget:!0}});if(!m.ok)return m;let h=n.resolvedNode.rect?e(n.resolvedNode.rect):n.node.rect?e(n.node.rect):null,g={ref:n.ref,locator:d,query:f};h&&(g.x=h.x,g.y=h.y);let v=c(m.data)??`Tapped ${n.ref}${h?` (${h.x}, ${h.y})`:``}`;return Object.assign(g,o(v)),_(a,s,r,u,{ref:n.ref,action:`click`,locator:d,query:f},{flags:p}),{ok:!0,data:g}}async function R(e,t,n){let{req:r,sessionName:i,sessionStore:a,session:o,invoke:s,command:c,publicFlags:l}=e;if(!n)return h(`INVALID_ARGS`,`find fill requires text`);let u=await s({token:r.token,session:i,command:`fill`,positionals:[t.ref,n],flags:t.actionFlags,internal:{findResolvedTarget:!0}});return u.ok&&_(a,o,r,c,{ref:t.ref,action:`fill`},{flags:l}),u}async function z(e,t){let n=await V(e,t);return n.ok&&U(e,t,`focus`),n}async function B(e,t,n){let{req:r,device:i,logPath:a,session:o}=e;if(!n)return h(`INVALID_ARGS`,`find type requires text`);let s=await V(e,t);if(!s.ok)return s;y(o);let c=await m(i,`type`,[n],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)});return U(e,t,`type`),{ok:!0,data:c??{ref:t.ref}}}async function V(t,n){let{req:r,device:i,logPath:a,session:o}=t,s=H(n,`be focused`);if(s)return s;let c=n.resolvedNode.rect?e(n.resolvedNode.rect):null;return c?(y(o),{ok:!0,data:await m(i,`focus`,[String(c.x),String(c.y)],r.flags?.out,{...g(a,r.flags,o.appBundleId,o.trace?.outPath)})??{ref:n.ref}}):h(`COMMAND_FAILED`,`matched element has no bounds`)}function H(e,t){let n=[e.resolvedNode,e.node].find(f);return n?h(`COMMAND_FAILED`,`Matched element ${e.ref} is covered by another visible element and cannot ${t} safely`,{ref:`@${n.ref}`,interactionBlocked:n.interactionBlocked,hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`}):null}function U(e,t,n){let{req:r,sessionStore:i,session:a,command:o,publicFlags:s}=e;_(i,a,r,o,{ref:t.ref,action:n},{flags:s})}function W(e){return{...v(e)??{}}}function G(e,t,n){let r=e.slice(0,8).map(e=>{let t=l(e)||e.label||e.identifier||e.type||``;return`@${e.ref}${t?`(${t})`:``}`});return h(`AMBIGUOUS_MATCH`,`find matched ${e.length} elements for ${t} "${n}". Use a more specific locator or selector.`,{locator:t,query:n,matches:e.length,candidates:r})}function K(e){return e!==`role`}export{G as buildAmbiguousMatchError,C as handleFindCommands};
@@ -1 +1 @@
1
- import{E as e}from"./sdk-batch.js";import{t}from"./sdk-finders.js";export{t as findBestMatchesByLocator,e as parseFindArgs};
1
+ import{K as e}from"./sdk-batch-runner.js";import{t}from"./sdk-finders.js";export{t as findBestMatchesByLocator,e as parseFindArgs};
@@ -1 +1 @@
1
- import{a as e}from"./sdk-contracts.js";import{Kn as t}from"./tv-remote.js";import{i as n,n as r}from"./cli-runner.js";async function i({command:t,positionals:i,flags:s,client:c,debug:l,replayTestReporterRuntime:u}){let{result:d,cliOutput:f}=await r({client:c,command:t,positionals:i,flags:s});if(e(s.responseLevel))return n(s,d,()=>JSON.stringify(d,null,2)),!0;if(f)o(s,f);else{let e=await a(t,s,d,{debug:l,replayTestReporterRuntime:u});e!==0&&process.exit(e)}return!0}function a(e,r,i,a={}){return e===`test`?import(`./reporting.js`).then(({renderReplayTestResponse:e})=>e({suite:i,debug:a.debug,verbose:r.verbose,json:r.json,reporter:r.reporter,reportJunit:r.reportJunit,reporterRuntime:a.replayTestReporterRuntime})):(n(r,i,()=>t(i)),0)}function o(e,t){!e.json&&t.stderr&&process.stderr.write(t.stderr),n(e,e.json?t.jsonData??t.data:t.data,()=>t.text)}export{i as runGenericClientBackedCommand};
1
+ import{a as e}from"./sdk-contracts.js";import{Zn as t}from"./recording-export-quality.js";import{i as n,n as r}from"./cli-runner.js";async function i({command:t,positionals:i,flags:s,client:c,debug:l,replayTestReporterRuntime:u}){let{result:d,cliOutput:f}=await r({client:c,command:t,positionals:i,flags:s});if(e(s.responseLevel))return n(s,d,()=>JSON.stringify(d,null,2)),!0;if(f)o(s,f);else{let e=await a(t,s,d,{debug:l,replayTestReporterRuntime:u});e!==0&&process.exit(e)}return!0}function a(e,r,i,a={}){return e===`test`?import(`./reporting.js`).then(({renderReplayTestResponse:e})=>e({suite:i,debug:a.debug,verbose:r.verbose,json:r.json,reporter:r.reporter,reportJunit:r.reportJunit,reporterRuntime:a.replayTestReporterRuntime})):(n(r,i,()=>t(i)),0)}function o(e,t){!e.json&&t.stderr&&process.stderr.write(t.stderr),n(e,e.json?t.jsonData??t.data:t.data,()=>t.text)}export{i as runGenericClientBackedCommand};
@@ -1,12 +1,35 @@
1
- import { B as DeviceKind, C as DebugSymbolsResult, D as isAgentDeviceError, I as SnapshotUnchanged, L as SnapshotVisibility, M as ScreenshotOverlayRef, N as SnapshotNode, O as normalizeAgentDeviceError, P as SnapshotQualityVerdict, R as centerOfRect, S as DebugSymbolsOptions, T as NormalizedError, U as PlatformSelector, V as DeviceTarget, W as PublicPlatform, _ as NetworkIncludeMode, a as DaemonLockPolicy, b as SessionIsolationMode, c as DaemonResponseData, i as DaemonInstallSource, m as LeaseBackend, n as DaemonArtifactType, o as DaemonRequest, r as DaemonError, s as DaemonResponse, t as DaemonArtifact, w as AppError, x as SessionRuntimeHints, y as ResponseLevel, z as AppleOS } from "./sdk-contracts.js";
2
- import { a as GesturePointerCount, c as SwipePreset, l as TransformGestureParams, o as ScrollDirection, s as SwipePattern, u as AndroidSnapshotBackendMetadata } from "./sdk-android-adb.js";
1
+ import { C as normalizeAgentDeviceError, D as ScreenshotOverlayRef, F as DeviceKind, I as DeviceTarget, M as SnapshotVisibility, N as centerOfRect, O as SnapshotNode, P as AppleOS, R as PlatformSelector, S as isAgentDeviceError, _ as SessionIsolationMode, a as DaemonLockPolicy, b as NormalizedError, c as DaemonResponseData, g as ResponseLevel, i as DaemonInstallSource, j as SnapshotUnchanged, k as SnapshotQualityVerdict, m as NetworkIncludeMode, n as DaemonArtifactType, o as DaemonRequest, p as LeaseBackend, r as DaemonError, s as DaemonResponse, t as DaemonArtifact, v as SessionRuntimeHints, y as AppError, z as PublicPlatform } from "./sdk-contracts.js";
2
+ import { a as GesturePointerCount, c as SwipePreset, d as AndroidSnapshotHelperInstallReason, f as AndroidSnapshotHelperTransport, l as TransformGestureParams, o as ScrollDirection, s as SwipePattern, u as AndroidSnapshotCaptureMode } from "./sdk-android-adb.js";
3
3
  import { t as AppsFilter } from "./sdk-app-inventory.js";
4
4
  import { t as BatchRunResult } from "./sdk-batch-runner.js";
5
5
  import { r as FindLocator } from "./sdk-finders.js";
6
6
  import { a as LongPressCommandResponseData, i as FindCommandResponseData, o as PressCommandResponseData, r as FillCommandResponseData, s as ClickButton, t as ClickCommandResponseData } from "./interaction.js";
7
7
  import { p as createLocalArtifactAdapter } from "./sdk-io.js";
8
- import { a as PrepareMetroRuntimeResult, c as MetroBridgeScope, i as MetroPrepareKind, o as ReloadMetroResult, r as RemoteConnectionProfileFields, t as CloudProviderProfileFields } from "./sdk-remote-config.js";
9
- //#region src/snapshot-capture-annotations.d.ts
8
+ import { i as MetroPrepareKind, n as RemoteConnectionProfileFields, r as CloudProviderProfileFields } from "./sdk-remote-config.js";
9
+ import { n as MetroBridgeResult, r as MetroRuntimeHints } from "./metro-types.js";
10
+ //#region src/platforms/android/snapshot-types.d.ts
11
+ type AndroidSnapshotBackendMetadata = {
12
+ backend: 'android-helper';
13
+ helperVersion?: string;
14
+ helperApiVersion?: string;
15
+ helperTransport?: AndroidSnapshotHelperTransport;
16
+ helperSessionReused?: boolean;
17
+ installReason?: AndroidSnapshotHelperInstallReason;
18
+ waitForIdleTimeoutMs?: number;
19
+ waitForIdleQuietMs?: number;
20
+ timeoutMs?: number;
21
+ maxDepth?: number;
22
+ maxNodes?: number;
23
+ rootPresent?: boolean;
24
+ captureMode?: AndroidSnapshotCaptureMode;
25
+ systemSurfaceOnly?: boolean;
26
+ windowCount?: number;
27
+ nodeCount?: number;
28
+ helperTruncated?: boolean;
29
+ elapsedMs?: number;
30
+ };
31
+ //#endregion
32
+ //#region src/contracts/snapshot-capture-annotations.d.ts
10
33
  type SnapshotCaptureAnalysis = {
11
34
  rawNodeCount: number;
12
35
  maxDepth: number;
@@ -28,7 +51,7 @@ type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androi
28
51
  snapshotQuality?: SnapshotQualityVerdict;
29
52
  };
30
53
  //#endregion
31
- //#region src/snapshot-diagnostics.d.ts
54
+ //#region src/contracts/snapshot-diagnostics.d.ts
32
55
  type SnapshotTimingStats = {
33
56
  count: number;
34
57
  p50Ms: number;
@@ -57,41 +80,49 @@ declare const TV_REMOTE_BUTTON_DEFINITIONS: {
57
80
  readonly aliases: readonly [];
58
81
  readonly androidKeyevent: 'KEYCODE_DPAD_UP';
59
82
  readonly appleRemoteButton: 'up';
83
+ readonly vegaKey: 'KEY_UP';
60
84
  };
61
85
  readonly down: {
62
86
  readonly aliases: readonly [];
63
87
  readonly androidKeyevent: 'KEYCODE_DPAD_DOWN';
64
88
  readonly appleRemoteButton: 'down';
89
+ readonly vegaKey: 'KEY_DOWN';
65
90
  };
66
91
  readonly left: {
67
92
  readonly aliases: readonly [];
68
93
  readonly androidKeyevent: 'KEYCODE_DPAD_LEFT';
69
94
  readonly appleRemoteButton: 'left';
95
+ readonly vegaKey: 'KEY_LEFT';
70
96
  };
71
97
  readonly right: {
72
98
  readonly aliases: readonly [];
73
99
  readonly androidKeyevent: 'KEYCODE_DPAD_RIGHT';
74
100
  readonly appleRemoteButton: 'right';
101
+ readonly vegaKey: 'KEY_RIGHT';
75
102
  };
76
103
  readonly select: {
77
104
  readonly aliases: readonly ["ok", "center", "enter"];
78
105
  readonly androidKeyevent: 'KEYCODE_DPAD_CENTER';
79
106
  readonly appleRemoteButton: 'select';
107
+ readonly vegaKey: 'KEY_ENTER';
80
108
  };
81
109
  readonly menu: {
82
110
  readonly aliases: readonly [];
83
111
  readonly androidKeyevent: 'KEYCODE_MENU';
84
112
  readonly appleRemoteButton: 'menu';
113
+ readonly vegaKey: 'KEY_MENU';
85
114
  };
86
115
  readonly home: {
87
116
  readonly aliases: readonly [];
88
117
  readonly androidKeyevent: 'KEYCODE_HOME';
89
118
  readonly appleRemoteButton: 'home';
119
+ readonly vegaKey: 'KEY_HOMEPAGE';
90
120
  };
91
121
  readonly back: {
92
122
  readonly aliases: readonly [];
93
123
  readonly androidKeyevent: 'KEYCODE_BACK';
94
124
  readonly appleRemoteButton: 'menu';
125
+ readonly vegaKey: 'KEY_BACK';
95
126
  };
96
127
  };
97
128
  declare const TV_REMOTE_BUTTONS: (keyof typeof TV_REMOTE_BUTTON_DEFINITIONS)[];
@@ -148,7 +179,7 @@ type TvRemoteCommandResult = {
148
179
  message: string;
149
180
  };
150
181
  //#endregion
151
- //#region src/core/recording-export-quality.d.ts
182
+ //#region src/contracts/recording-export-quality.d.ts
152
183
  declare const RECORDING_EXPORT_QUALITIES: readonly ['medium', 'high'];
153
184
  type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number];
154
185
  //#endregion
@@ -156,7 +187,7 @@ type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number];
156
187
  declare const RECORDING_SCOPE_VALUES: readonly ['app', 'device', 'system'];
157
188
  type RecordingScope = (typeof RECORDING_SCOPE_VALUES)[number];
158
189
  //#endregion
159
- //#region src/alert-contract.d.ts
190
+ //#region src/contracts/alert-contract.d.ts
160
191
  declare const ALERT_ACTIONS: readonly ['get', 'accept', 'dismiss', 'wait'];
161
192
  type AlertAction = (typeof ALERT_ACTIONS)[number];
162
193
  //#endregion
@@ -238,7 +269,46 @@ type ProjectedNavigationCommandClient<BaseOptions> = { [Name in NavigationComman
238
269
  declare const LOG_ACTION_VALUES: readonly ['path', 'start', 'stop', 'doctor', 'mark', 'clear'];
239
270
  type LogAction = (typeof LOG_ACTION_VALUES)[number];
240
271
  //#endregion
241
- //#region src/target-shutdown-contract.d.ts
272
+ //#region src/client/client-companion-tunnel-contract.d.ts
273
+ type CompanionTunnelScope = {
274
+ tenantId: string;
275
+ runId: string;
276
+ leaseId: string;
277
+ };
278
+ type MetroBridgeScope = CompanionTunnelScope;
279
+ //#endregion
280
+ //#region src/metro/client-metro.d.ts
281
+ type ResolvedMetroKind = Exclude<MetroPrepareKind, 'auto'>;
282
+ type PrepareMetroRuntimeResult = {
283
+ projectRoot: string;
284
+ kind: ResolvedMetroKind;
285
+ dependenciesInstalled: boolean;
286
+ packageManager: string | null;
287
+ started: boolean;
288
+ reused: boolean;
289
+ pid: number;
290
+ logPath: string;
291
+ statusUrl: string;
292
+ runtimeFilePath: string | null;
293
+ iosRuntime: MetroRuntimeHints;
294
+ androidRuntime: MetroRuntimeHints;
295
+ bridge: MetroBridgeResult | null;
296
+ };
297
+ /**
298
+ * `transport` says which channel delivered the reload: `http` for the classic GET /reload route,
299
+ * `message-socket` for the /message websocket broadcast used when the server has no HTTP reload
300
+ * route (Expo). `status`/`body` always describe the HTTP probe; on the websocket path `reloadUrl`
301
+ * is the ws(s) message-socket URL.
302
+ */
303
+ type ReloadMetroResult = {
304
+ reloaded: true;
305
+ reloadUrl: string;
306
+ status: number;
307
+ body: string;
308
+ transport: 'http' | 'message-socket';
309
+ };
310
+ //#endregion
311
+ //#region src/contracts/target-shutdown-contract.d.ts
242
312
  type TargetShutdownResult = {
243
313
  success: boolean;
244
314
  exitCode: number;
@@ -257,6 +327,55 @@ type PerfAction = (typeof PERF_ACTION_VALUES)[number];
257
327
  type PerfSubject = (typeof PERF_SUBJECT_VALUES)[number];
258
328
  type PerfKind = (typeof PERF_KIND_VALUES)[number];
259
329
  //#endregion
330
+ //#region src/contracts/debug-symbols.d.ts
331
+ type DebugSymbolsOptions = {
332
+ action?: 'symbols';
333
+ artifact: string;
334
+ dsym?: string;
335
+ searchPath?: string;
336
+ out?: string;
337
+ cwd?: string;
338
+ };
339
+ type DebugSymbolsImage = {
340
+ name: string;
341
+ uuid: string;
342
+ arch?: string;
343
+ dsymPath: string;
344
+ binaryPath: string;
345
+ };
346
+ type DebugSymbolsCrashFrame = {
347
+ index: number;
348
+ image: string;
349
+ address: string;
350
+ symbol?: string;
351
+ };
352
+ type DebugSymbolsCrashSummary = {
353
+ format: 'ips' | 'text';
354
+ appName?: string;
355
+ bundleId?: string;
356
+ version?: string;
357
+ incident?: string;
358
+ timestamp?: string;
359
+ exceptionType?: string;
360
+ exceptionCodes?: string;
361
+ terminationReason?: string;
362
+ crashedThread?: number;
363
+ topFrames: DebugSymbolsCrashFrame[];
364
+ findings: string[];
365
+ };
366
+ type DebugSymbolsResult = {
367
+ kind: 'debugSymbols';
368
+ platform: 'apple';
369
+ artifactPath: string;
370
+ outPath: string;
371
+ crash: DebugSymbolsCrashSummary;
372
+ matchedImages: DebugSymbolsImage[];
373
+ symbolicatedFrames: number;
374
+ skippedImages: number;
375
+ warnings?: string[];
376
+ message: string;
377
+ };
378
+ //#endregion
260
379
  //#region src/contracts/device.d.ts
261
380
  /**
262
381
  * Closed result of the `boot` command. Mirrors the daemon handler's only
@@ -574,6 +693,14 @@ type ReplayCommandResult = {
574
693
  replayed: number;
575
694
  healed: number;
576
695
  session: string;
696
+ /**
697
+ * True iff `session` still exists in the daemon's session store when the
698
+ * response is built — i.e. the replayed script had no terminal `close`
699
+ * (ADR 0016's consumption contract). The client uses this, not script
700
+ * parsing, to decide whether an owned one-shot daemon must stay alive so
701
+ * the caller can keep addressing this session.
702
+ */
703
+ sessionActive: boolean;
577
704
  artifactPaths: string[];
578
705
  warnings?: string[];
579
706
  snapshotDiagnostics?: SnapshotDiagnosticsSummary;
@@ -698,7 +825,7 @@ interface CommandResultMap {
698
825
  */
699
826
  type CommandResult<N extends string> = N extends keyof CommandResultMap ? CommandResultMap[N] : Record<string, unknown>;
700
827
  //#endregion
701
- //#region src/cloud-artifacts.d.ts
828
+ //#region src/contracts/cloud-artifacts.d.ts
702
829
  declare const CLOUD_ARTIFACT_KINDS: readonly ['video', 'appium-log', 'device-log', 'automation-log', 'provider-session', 'raw'];
703
830
  type CloudArtifactKind = (typeof CLOUD_ARTIFACT_KINDS)[number];
704
831
  type CloudArtifactAvailability = 'ready' | 'pending' | 'unavailable' | 'expired';
@@ -802,6 +929,9 @@ type AgentDeviceDevice = {
802
929
  android?: {
803
930
  serial: string;
804
931
  };
932
+ vega?: {
933
+ serial: string;
934
+ };
805
935
  };
806
936
  type AgentDeviceCapabilitiesResult = {
807
937
  device: AgentDeviceDevice;
@@ -825,6 +955,9 @@ type AgentDeviceSessionDevice = {
825
955
  android?: {
826
956
  serial: string;
827
957
  };
958
+ vega?: {
959
+ serial: string;
960
+ };
828
961
  };
829
962
  type AgentDeviceSession = {
830
963
  name: string;
@@ -1295,6 +1428,8 @@ type TypeTextOptions = DeviceCommandBaseOptions & {
1295
1428
  type FillOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & InteractionTarget & SettleCommandOptions & {
1296
1429
  text: string;
1297
1430
  delayMs?: number;
1431
+ /** Publish this fill value as `${VAR}` when script recording is armed. */
1432
+ recordAs?: string;
1298
1433
  verify?: boolean;
1299
1434
  };
1300
1435
  type ScrollOptions = DeviceCommandBaseOptions & {