agent-device 0.19.3 → 0.20.0

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 (168) hide show
  1. package/README.md +61 -70
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.manifest.json +10 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +1 -0
  7. package/{android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.manifest.json → android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.manifest.json} +6 -6
  8. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +2 -0
  9. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +5 -0
  10. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +5 -10
  11. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +74 -174
  12. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +113 -19
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +82 -0
  14. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +272 -118
  15. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -2
  16. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +134 -101
  17. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +56 -2
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +73 -0
  19. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +44 -24
  20. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -2
  21. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -107
  22. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +126 -11
  23. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +51 -8
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +24 -0
  25. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +1 -1
  26. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +43 -35
  27. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +14 -0
  28. package/dist/src/agent-browser-tool.js +1 -1
  29. package/dist/src/agent-device-client.js +3 -0
  30. package/dist/src/android-adb.d.ts +1 -1
  31. package/dist/src/android-adb.js +1 -1
  32. package/dist/src/android-input-method-overlays.js +1 -0
  33. package/dist/src/android-input-ownership.js +1 -6
  34. package/dist/src/android-system-chrome.js +1 -0
  35. package/dist/src/android.js +1 -1
  36. package/dist/src/app-lifecycle.js +5 -5
  37. package/dist/src/app-log-request-scope.js +1 -0
  38. package/dist/src/app-resolution.js +1 -0
  39. package/dist/src/apple-multitouch-support.js +1 -0
  40. package/dist/src/apps.js +5 -5
  41. package/dist/src/boot-diagnostics.js +2 -0
  42. package/dist/src/cli-config.js +1 -0
  43. package/dist/src/cli-help.js +61 -27
  44. package/dist/src/cli-runner.js +1 -1
  45. package/dist/src/cli.js +15 -11
  46. package/dist/src/command-schema.js +3 -3
  47. package/dist/src/config.js +1 -0
  48. package/dist/src/context.js +1 -0
  49. package/dist/src/contracts.d.ts +1 -1
  50. package/dist/src/daemon-shutdown-report.js +1 -0
  51. package/dist/src/debug-symbols.js +1 -1
  52. package/dist/src/device-input-state.js +1 -1
  53. package/dist/src/devices2.js +1 -1
  54. package/dist/src/find.js +1 -1
  55. package/dist/src/finders.js +1 -1
  56. package/dist/src/generic.js +1 -1
  57. package/dist/src/helper.js +1 -1
  58. package/dist/src/index.d.ts +412 -293
  59. package/dist/src/index.js +1 -1
  60. package/dist/src/input-actions.js +4 -3
  61. package/dist/src/install-artifact.js +1 -0
  62. package/dist/src/install-source.d.ts +5 -1
  63. package/dist/src/install-source.js +1 -1
  64. package/dist/src/install-source2.js +1 -1
  65. package/dist/src/interaction-snapshot.js +1 -1
  66. package/dist/src/interaction.d.ts +230 -0
  67. package/dist/src/interaction.js +1 -1
  68. package/dist/src/interactor.js +2 -2
  69. package/dist/src/internal/bin.js +1 -1
  70. package/dist/src/internal/daemon.js +42 -20
  71. package/dist/src/internal/png-worker.d.ts +22 -0
  72. package/dist/src/internal/png-worker.js +1 -1
  73. package/dist/src/launch-console.js +1 -0
  74. package/dist/src/lease-context.js +1 -0
  75. package/dist/src/lease.js +1 -1
  76. package/dist/src/linux.js +1 -1
  77. package/dist/src/logcat.js +5 -0
  78. package/dist/src/metro.d.ts +2 -2
  79. package/dist/src/notifications.js +1 -1
  80. package/dist/src/png-worker-contract.js +1 -1
  81. package/dist/src/process-lock.js +1 -0
  82. package/dist/src/react-native.js +1 -1
  83. package/dist/src/record-trace.js +1 -1
  84. package/dist/src/register-builtins.js +1 -0
  85. package/dist/src/registry.js +24 -24
  86. package/dist/src/reporting.js +8 -7
  87. package/dist/src/runner-client.js +1 -1
  88. package/dist/src/runner-disposal.js +2 -0
  89. package/dist/src/runner-lease.js +1 -0
  90. package/dist/src/runner-sequence.js +1 -1
  91. package/dist/src/runtime.js +3 -3
  92. package/dist/src/runtime2.js +1 -0
  93. package/dist/src/sdk-android-adb.d.ts +119 -33
  94. package/dist/src/sdk-android-adb.js +2 -2
  95. package/dist/src/sdk-batch-runner.d.ts +2 -1
  96. package/dist/src/sdk-batch-runner.js +2 -2
  97. package/dist/src/sdk-batch.js +2 -2
  98. package/dist/src/sdk-contracts.d.ts +105 -98
  99. package/dist/src/sdk-contracts.js +1 -1
  100. package/dist/src/sdk-device.js +1 -1
  101. package/dist/src/sdk-finders.d.ts +3 -3
  102. package/dist/src/sdk-finders.js +1 -1
  103. package/dist/src/sdk-io.d.ts +1 -1
  104. package/dist/src/sdk-remote-config.d.ts +9 -1
  105. package/dist/src/sdk-remote-config.js +1 -1
  106. package/dist/src/sdk-selectors.js +1 -1
  107. package/dist/src/selector-runtime.js +1 -1
  108. package/dist/src/selector-vocabulary.js +1 -0
  109. package/dist/src/selectors.d.ts +12 -3
  110. package/dist/src/selectors.js +1 -1
  111. package/dist/src/server.js +3 -3
  112. package/dist/src/session-target-evidence.js +1 -0
  113. package/dist/src/session.js +8 -10
  114. package/dist/src/simulator.js +1 -1
  115. package/dist/src/snapshot-diagnostics.js +5 -2
  116. package/dist/src/snapshot.js +1 -1
  117. package/dist/src/snapshot2.js +1 -2
  118. package/dist/src/tv-remote.js +13 -12
  119. package/dist/src/url.js +1 -1
  120. package/dist/src/web.js +1 -1
  121. package/package.json +28 -23
  122. package/server.json +2 -2
  123. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk +0 -0
  124. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk.sha256 +0 -1
  125. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.manifest.json +0 -10
  126. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk +0 -0
  127. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk.sha256 +0 -1
  128. package/dist/src/apple-runner-options.js +0 -1
  129. package/dist/src/cli-output.js +0 -1
  130. package/dist/src/client.js +0 -3
  131. package/dist/src/handler-utils.js +0 -1
  132. package/dist/src/output-path.js +0 -1
  133. package/dist/src/points.js +0 -4
  134. package/dist/src/provider.js +0 -1
  135. package/dist/src/providers.js +0 -1
  136. package/dist/src/record-trace-recording.js +0 -23
  137. package/dist/src/recording-provider.js +0 -1
  138. package/dist/src/selectors2.js +0 -1
  139. package/dist/src/simctl.js +0 -1
  140. package/dist/src/ttl-memo.js +0 -1
  141. package/dist/src/xml.js +0 -2
  142. /package/{macos-helper → apple/macos-helper}/Package.swift +0 -0
  143. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +0 -0
  144. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +0 -0
  145. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/main.swift +0 -0
  146. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
  147. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
  148. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  149. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  150. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  151. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  152. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  153. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  154. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -0
  155. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +0 -0
  156. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  157. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  158. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -0
  159. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +0 -0
  160. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  161. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -0
  162. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
  163. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  164. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  165. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  166. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  167. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
  168. /package/{src/platforms/linux → linux}/atspi-dump.py +0 -0
package/dist/src/index.js CHANGED
@@ -1 +1 @@
1
- import{_ as e,b as t,u as n,x as r}from"./sdk-contracts.js";import{n as i}from"./client.js";import{t as a}from"./sdk-io.js";export{e as AppError,n as centerOfRect,i as createAgentDeviceClient,a as createLocalArtifactAdapter,t as isAgentDeviceError,r as normalizeAgentDeviceError};
1
+ import{_ as e,b as t,u as n,x as r}from"./sdk-contracts.js";import{n as i}from"./agent-device-client.js";import{t as a}from"./sdk-io.js";export{e as AppError,n as centerOfRect,i as createAgentDeviceClient,a as createLocalArtifactAdapter,t as isAgentDeviceError,r as normalizeAgentDeviceError};
@@ -1,3 +1,4 @@
1
- import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,u as r}from"./sdk-android-adb.js";import{i,st as a}from"./tv-remote.js";import{t as o}from"./timeouts.js";import{p as s,r as c}from"./android-input-ownership.js";import{r as l}from"./device-input-state.js";import{Et as u,Mt as d}from"./internal/daemon.js";function ee(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=h(t),r={failureReason:t.reason??`text_mismatch`,targetInput:m(t.targetInput),actualInput:m(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function f(e){return e?e.password?!0:p(e.text):!1}function p(e){return e?Array.from(e).every(te):!1}function m(e){if(!e)return null;let t=f(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function te(e){return e===`•`||e===`*`||e===`●`}function h(e){return e.masked===!0||f(e.targetInput)||f(e.actualInput)}async function g(e,t,n,r){let i=[0,150,350],a=null,s=null,c=await ae(e);for(let l of i){l>0&&await o(l);let i=await S(e,t,n,r,c);if(a=i,i.reason===`ime_capture`)return i;s=i.ok?i:null}return s??a??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function _(e,t,n){return y(await u(e),t,n)}function v(e,t,n,r,i={}){let a=C(e,t,n,i);return w(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:T(a,r)??E(a,r)}function y(e,t,n){return C(e,t,n).actualInput?.text??null}function b(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function x(e,t){let n=ee(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function S(e,t,n,r,i){return v(await u(e),t,n,r,i)}function C(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of d(e)){let e=ie(a,r);e&&oe(i,e,t,n)}return ce(i)}function w(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function T(e,t){let n=e.actualInput;if(!n||!A(n))return null;let r=n.text??null,i=Array.from(r??``).length,a=Array.from(t).length,o=r!==null&&i>0&&a>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function E(e,t){let n=e.actualInput?.text??null;return{ok:ne(n,t),actual:n,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:e.actualInput}}function ne(e,t){if(e===t)return!0;let n=D(e),r=D(t);return!n||!r?!1:!!(n===r||re(n,r))}function D(e){return(e??``).replace(/\s+/g,` `).trim()}function re(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function ie(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:c({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:k(e.className??``)}}async function ae(e){try{return{activeInputMethodPackage:(await l(e)).inputMethodPackage}}catch(e){return n({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function oe(e,t,n,r){let i=se(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=O(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=O(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=O(e.anyAtPoint,t))}function se(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function O(e,t){return e&&e.area<t.area?e:t}function ce(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function k(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function A(e){return f(e)}var j=e({appSwitcherAndroid:()=>z,backAndroid:()=>F,fillAndroid:()=>U,focusAndroid:()=>H,getAndroidScreenSize:()=>q,homeAndroid:()=>I,longPressAndroid:()=>B,pressAndroid:()=>M,pressAndroidEnter:()=>L,pressAndroidTvRemote:()=>N,readAndroidTextAtPoint:()=>_,rotateAndroid:()=>R,scrollAndroid:()=>G,swipeAndroid:()=>P,typeAndroid:()=>V});async function M(e,t,n){await s(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function N(e,t,n){let r=i(t);await s(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function P(e,t,n,r,i,a=250){await s(e,[`shell`,`input`,`swipe`,String(t),String(n),String(r),String(i),String(a)])}async function F(e){await s(e,[`shell`,`input`,`keyevent`,`4`])}async function I(e){await s(e,[`shell`,`input`,`keyevent`,`3`])}async function L(e){await s(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function R(e,t){let n=le(t);await s(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await s(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n])}async function z(e){await s(e,[`shell`,`input`,`keyevent`,`187`])}async function B(e,t,n,r=800){await s(e,[`shell`,`input`,`swipe`,String(t),String(n),String(t),String(n),String(r)])}async function V(e,t,n=0){let i=r(e);if(i){await i({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}if(X(t),await K(e,`type`),n>0&&Array.from(t).length>1){await Y(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Y(e,{action:`type`,text:t,chunkSize:J,delayMs:0})}async function H(e,t,n){await M(e,t,n)}async function U(e,t,n,i,a=0){let o=r(e);if(o){await o({action:`fill`,target:{x:t,y:n},text:i,delayMs:a}),$(`fill`,`provider-native`,i);let r=await g(e,t,n,i);if(r.ok)return;W(i,r)}X(i);let s=Array.from(i).length,c=[{clearPadding:12,minClear:8,maxClear:48,chunkSize:a>0?1:J,inputDelayMs:a},{clearPadding:24,minClear:16,maxClear:96,chunkSize:a>0?1:4,inputDelayMs:a>0?a:15}],l=null;for(let r of c){await H(e,t,n),await K(e,`fill`),await me(e,he(s+r.clearPadding,r.minClear,r.maxClear)),await Y(e,{action:`fill`,text:i,chunkSize:r.chunkSize,delayMs:r.inputDelayMs});let a=await g(e,t,n,i);if(l=a,a.ok)return;a.reason===`ime_capture`&&W(i,a)}W(i,l)}function W(e,n){throw new t(`COMMAND_FAILED`,b(n),x(e,n))}async function G(e,t,n){let r=await q(e),i=a({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height}),o=n?.durationMs??300;return await s(e,[`shell`,`input`,`swipe`,String(i.x1),String(i.y1),String(i.x2),String(i.y2),String(o)]),{...i,...n?.durationMs===void 0?{}:{durationMs:n.durationMs}}}function le(e){switch(e){case`portrait`:return`0`;case`landscape-left`:return`1`;case`portrait-upside-down`:return`2`;case`landscape-right`:return`3`;default:throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`)}}async function K(e,r){let i;try{i=await l(e)}catch(e){n({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:r,error:e instanceof Error?e.message:String(e)}});return}if(i.inputOwner===`ime`)throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:r,inputOwner:i.inputOwner,inputType:i.inputType,type:i.type,inputMethodPackage:i.inputMethodPackage,focusedPackage:i.focusedPackage,focusedResourceId:i.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}async function q(e){let n=(await s(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}const J=8;async function Y(e,t){let n=t.text.split(`
2
- `);for(let[r,i]of n.entries()){let a=pe(i,t.chunkSize);for(let[i,s]of a.entries())await ue(e,s),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await o(t.delayMs);r+1<n.length&&await s(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function ue(e,t){if(t)try{await s(e,[`shell`,`input`,`text`,Z(t)])}catch(e){throw fe(e)?Q(t,e):e}}function X(e){if(!de(e))throw Q(e)}function de(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
3
- `&&(e<32||e>126))return!1}return!0}function Z(e){return e.replace(/ /g,`%s`)}function fe(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function Q(e,n){return new t(`COMMAND_FAILED`,`Android text input requires provider-native text injection for non-ASCII/control characters; the current adb-shell fallback supports ASCII text only.`,{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function pe(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,r){n({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(r).length}})}async function me(e,t){let n=Math.max(0,t);await s(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await s(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}function he(e,t,n){return Math.max(t,Math.min(n,e))}export{q as a,B as c,R as d,G as f,H as i,M as l,V as m,F as n,I as o,P as p,U as r,j as s,z as t,N as u};
1
+ import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{F as n,c as r,j as i,l as a,p as o,s,u as c}from"./sdk-android-adb.js";import{gt as l,i as ee}from"./tv-remote.js";import{t as u}from"./timeouts.js";import{r as te}from"./android-input-ownership.js";import{i as ne}from"./runtime.js";import{s as d}from"./logcat.js";import{r as f}from"./device-input-state.js";import{Bt as p,D as m,E as re,Gt as ie,Ht as ae,It as oe,Lt as se,Mt as h,O as g,Rt as ce,Ut as le,Vt as ue,Wt as _,w as v,zt as y}from"./internal/daemon.js";function de(e,t){if(!t)return{expected:e,actual:null,failureReason:`text_mismatch`,targetInput:null,actualInput:null};let n=me(t),r={failureReason:t.reason??`text_mismatch`,targetInput:x(t.targetInput),actualInput:x(t.actualInput)};return n?{...r,expectedLength:Array.from(e).length,actual:null,masked:!0,actualLength:Array.from(t.actual??``).length}:{...r,expected:e,actual:t.actual}}function b(e){return e?e.password?!0:fe(e.text):!1}function fe(e){return e?Array.from(e).every(pe):!1}function x(e){if(!e)return null;let t=b(e);return{...e,text:t?null:e.text,...t?{textRedacted:!0}:{}}}function pe(e){return e===`•`||e===`*`||e===`●`}function me(e){return e.masked===!0||b(e.targetInput)||b(e.actualInput)}async function S(e,t,n,r){let i=[0,150,350],a=null,o=null,s=await De(e);for(let c of i){c>0&&await u(c);let i=await be(e,t,n,r,s);if(a=i,i.reason===`ime_capture`)return i;o=i.ok?i:null}return o??a??{ok:!1,actual:null,reason:`text_mismatch`,targetInput:null,actualInput:null}}async function he(e,t,n){return _e(await h(e),t,n)}function ge(e,t,n,r,i={}){let a=C(e,t,n,i);return xe(a)?{ok:!1,actual:a.actualInput?.text??null,reason:`ime_capture`,targetInput:a.targetInput,actualInput:a.actualInput}:Se(a,r)??Ce(a,r)}function _e(e,t,n){return C(e,t,n).actualInput?.text??null}function ve(e){return e?.reason===`ime_capture`?`Android fill input was captured by the active keyboard instead of the app field`:e?.reason===`masked_unverified`?`Android fill verification could not confirm masked text value`:`Android fill verification failed`}function ye(e,t){let n=de(e,t);return t?.reason===`ime_capture`&&(n.hint=`The focused input belongs to the Android keyboard/IME, not the app field. Disable handwriting/stylus input or switch to a standard IME, then retry fill.`),n}async function be(e,t,n,r,i){return ge(await h(e),t,n,r,i)}function C(e,t,n,r={}){let i={focusedEdit:null,editAtPoint:null,anyAtPoint:null};for(let a of ie(e)){let e=Ee(a,r);e&&Oe(i,e,t,n)}return Ae(i)}function xe(e){let{targetInput:t,actualInput:n}=e;return!t||!n||n===t?!1:n.inputMethodOwned&&!t.inputMethodOwned}function Se(e,t){let n=e.actualInput;if(!n||!Me(n))return null;let r=n.text??null,i=Array.from(r??``).length,a=Array.from(t).length,o=r!==null&&i>0&&a>0&&i===a;return{ok:o,actual:r,reason:o?void 0:`masked_unverified`,masked:!0,targetInput:e.targetInput,actualInput:n}}function Ce(e,t){let n=e.actualInput?.text??null;return{ok:we(n,t),actual:n,reason:`text_mismatch`,targetInput:e.targetInput,actualInput:e.actualInput}}function we(e,t){if(e===t)return!0;let n=w(e),r=w(t);return!n||!r?!1:!!(n===r||Te(n,r))}function w(e){return(e??``).replace(/\s+/g,` `).trim()}function Te(e,t){if(e.length!==t.length||e.length===0||e.slice(1)!==t.slice(1))return!1;let n=e[0],r=t[0];return!n||!r?!1:r.toLowerCase()===r&&n===r.toUpperCase()}function Ee(e,t){if(!e.rect)return null;let n=e.text??``,r=Math.max(1,e.rect.width*e.rect.height);return{text:n||null,className:e.className,resourceId:e.resourceId,packageName:e.packageName,rect:e.rect,focused:e.focused??!1,password:e.password===!0,inputMethodOwned:te({packageName:e.packageName,resourceId:e.resourceId,activeInputMethodPackage:t.activeInputMethodPackage}),area:r,editText:je(e.className??``)}}async function De(e){try{return{activeInputMethodPackage:(await f(e)).inputMethodPackage}}catch(e){return i({level:`warn`,phase:`android_fill_verification_input_method_probe_failed`,data:{error:e instanceof Error?e.message:String(e)}}),{}}}function Oe(e,t,n,r){let i=ke(t.rect,n,r);if(i&&t.editText&&(e.editAtPoint=T(e.editAtPoint,t)),t.focused&&t.editText){e.focusedEdit=T(e.focusedEdit,t);return}i&&t.text&&(e.anyAtPoint=T(e.anyAtPoint,t))}function ke(e,t,n){return t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height}function T(e,t){return e&&e.area<t.area?e:t}function Ae(e){let t=e.editAtPoint??e.anyAtPoint;return{targetInput:t,actualInput:(e.focusedEdit?.text?e.focusedEdit:null)??t}}function je(e){let t=e.toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)}function Me(e){return b(e)}function E(e){if(!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.width)||!Number.isFinite(e.height)||e.width<=0||e.height<=0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return e}const D=45e3,O=`ANDROID_TOUCH_HELPER_NO_FINAL_RESULT`,k=`ANDROID_TOUCH_HELPER_REPORTED_FAILURE`;async function Ne(e,t){let r=await j(e),i=Ie(t),a=Math.max(45e3,i.durationMs+15e3),o=Buffer.from(JSON.stringify({protocol:`android-touch-plan-v1`,...i})).toString(`base64`),s=await n(`android_touch_helper_gesture`,async()=>{let e=await y({deviceKey:r.deviceKey,action:`gesture`,helper:A(r.artifact),payloadBase64:o,timeoutMs:a});return e?{...N(e),helperTransport:`persistent-session`}:{...await M({adb:r.adb,runner:r.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`gesture`,`-e`,`payloadBase64`,o],timeoutMs:a,readResult:N}),helperTransport:`instrumentation`}},{packageName:r.artifact.manifest.packageName,version:r.artifact.manifest.version});return{backend:`android-helper`,helperVersion:r.artifact.manifest.version,installReason:r.install.reason,...s}}async function Pe(e){let t=await j(e);try{let e=await y({deviceKey:t.deviceKey,action:`viewport`,helper:A(t.artifact),timeoutMs:D});if(e)return ze(e)}catch(e){await p(t.deviceKey),i({level:`warn`,phase:`android_touch_helper_viewport_session_fallback`,data:{reason:e instanceof Error?e.message:String(e)}})}return await M({adb:t.adb,runner:t.artifact.manifest.instrumentationRunner,extraArgs:[`-e`,`mode`,`viewport`],timeoutMs:D,readResult:ze})}function A(e){return{packageName:e.manifest.packageName,runner:e.manifest.instrumentationRunner,helperVersion:e.manifest.version,helperVersionCode:e.manifest.versionCode,sha256:e.manifest.sha256}}async function j(e){let t=r(e),a=t.snapshotHelperArtifact??await Fe(),o=ce(e),s=await n(`android_touch_helper_install`,async()=>await oe({adb:t.exec,adbProvider:t,artifact:a,deviceKey:o,timeoutMs:3e4}),{packageName:a.manifest.packageName,versionCode:a.manifest.versionCode});return i({phase:`android_touch_helper_install_decision`,data:s}),s.installed&&await p(o),{adb:t.exec,artifact:a,install:s,deviceKey:o}}async function Fe(){return await se({helperDirName:`snapshot-helper`,manifestFileName:e=>`agent-device-android-snapshot-helper-${e}.manifest.json`,parseManifest:e=>{let t=ue(e);return{...t,assetName:t.assetName??`agent-device-android-snapshot-helper-${t.version}.apk`}},unavailableMessage:`Android touch gestures require the bundled Android automation helper artifact, but it was not found or could not be read`})}function Ie(e){return{kind:e.topology===`single`?`swipe`:`transform`,durationMs:e.durationMs,pointers:e.pointers.map(Le)}}function Le(e){return{pointerId:e.pointerId,samples:e.samples.map(({offsetMs:e,point:t})=>({offsetMs:e,x:t.x,y:t.y}))}}async function M(e){let n=await e.adb([`shell`,`am`,`instrument`,`-w`,...e.extraArgs,e.runner],{allowFailure:!0,timeoutMs:e.timeoutMs}),r;try{r=Re(`${n.stdout}\n${n.stderr}`)}catch(e){if(e instanceof t){if(e.code===k)throw new t(`COMMAND_FAILED`,e.message,e.details,e);if(e.code!==O)throw e}throw new t(`COMMAND_FAILED`,n.exitCode===0?`Android automation helper output could not be parsed`:`Android automation helper failed before returning parseable output`,o(n),e)}if(n.exitCode!==0)throw new t(`COMMAND_FAILED`,`Android automation helper failed`,o(n,{helper:r}));return e.readResult(r)}function Re(e){let n=le(e).results.find(e=>e.agentDeviceProtocol===ae);if(!n)throw new t(O,`Android automation helper did not return a final result`);if(n.ok!==`true`)throw new t(k,n.message&&n.message!==`null`?n.message:n.errorType||`Android automation helper returned an error`,{errorType:n.errorType,helper:n});return n}function N(e){return{helperKind:e.kind,helperApiVersion:e.helperApiVersion,injectedEvents:_(e.injectedEvents),elapsedMs:_(e.elapsedMs)}}function ze(e){let n=_(e.x),r=_(e.y),i=_(e.width),a=_(e.height);if(n===void 0||r===void 0||i===void 0||a===void 0)throw new t(`COMMAND_FAILED`,`Android helper returned an invalid gesture viewport`);return E({x:n,y:r,width:i,height:a})}async function P(e,t){let n=c(e);if(n){let e=t.intent===`longPress`?{...t,viewport:E(await n.gestureViewport())}:t;return{backend:`provider-native-touch`,...await n.touch(e)??{}}}return await Ne(e,t)}async function F(e){let t=c(e);return t?E(await t.gestureViewport()):await Pe(e)}var Be=e({appSwitcherAndroid:()=>V,backAndroid:()=>R,fillAndroid:()=>G,focusAndroid:()=>W,getAndroidScreenSize:()=>Y,homeAndroid:()=>z,longPressAndroid:()=>H,pressAndroid:()=>I,pressAndroidEnter:()=>Ve,pressAndroidTvRemote:()=>L,readAndroidTextAtPoint:()=>he,scrollAndroid:()=>q,setAndroidOrientation:()=>B,typeAndroid:()=>U});async function I(e,t,n){await d(e,[`shell`,`input`,`tap`,String(t),String(n)])}async function L(e,t,n){let r=ee(t);await d(e,[`shell`,`input`,...n&&n>0?[`keyevent`,`--longpress`]:[`keyevent`],r])}async function R(e){await d(e,[`shell`,`input`,`keyevent`,`4`])}async function z(e){await d(e,[`shell`,`input`,`keyevent`,`3`])}async function Ve(e){await d(e,[`shell`,`input`,`keyevent`,`ENTER`])}async function B(e,t){let n=We(t);await d(e,[`shell`,`settings`,`put`,`system`,`accelerometer_rotation`,`0`]),await d(e,[`shell`,`settings`,`put`,`system`,`user_rotation`,n])}async function V(e){await d(e,[`shell`,`input`,`keyevent`,`187`])}async function H(e,t,n,r=800){let i={x:t,y:n};return await P(e,{topology:`single`,intent:`longPress`,durationMs:r,pointers:[{pointerId:0,samples:[{offsetMs:0,point:i},{offsetMs:r,point:i}]}]})}async function U(e,t,n=0){let r=a(e);if(r){await r({action:`type`,text:t,delayMs:n}),$(`type`,`provider-native`,t);return}if(v(e)){await He(e,t,n);return}if(Q(t),await J(e,`type`),n>0&&Array.from(t).length>1){await Z(e,{action:`type`,text:t,chunkSize:1,delayMs:n});return}await Z(e,{action:`type`,text:t,chunkSize:X,delayMs:0})}async function W(e,t,n){await I(e,t,n)}async function G(e,t,n,r,i=0){let o=a(e);if(o){await o({action:`fill`,target:{x:t,y:n},text:r,delayMs:i}),$(`fill`,`provider-native`,r);let a=await S(e,t,n,r);if(a.ok)return;K(r,a)}if(v(e)){let i=await Ue(e,t,n,r);if(i.ok)return;K(r,i)}Q(r);let s=Array.from(r).length,c=[{clearPadding:12,minClear:8,maxClear:48,chunkSize:i>0?1:X,inputDelayMs:i},{clearPadding:24,minClear:16,maxClear:96,chunkSize:i>0?1:4,inputDelayMs:i>0?i:15}],l=null;for(let i of c){await W(e,t,n),await J(e,`fill`),await Ze(e,Qe(s+i.clearPadding,i.minClear,i.maxClear)),await Z(e,{action:`fill`,text:r,chunkSize:i.chunkSize,delayMs:i.inputDelayMs});let a=await S(e,t,n,r);if(l=a,a.ok)return;a.reason===`ime_capture`&&K(r,a)}K(r,l)}async function He(e,t,n){let r=s(e),i=(await m()).manifest.packageName,a=t.split(`
2
+ `);for(let[t,o]of a.entries()){let s=n>0?Xe(o,1):[o];for(let[e,o]of s.entries())o&&await g(r,i,o),n>0&&(e+1<s.length||t+1<a.length)&&await u(n);t+1<a.length&&await d(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(`type`,`test-ime`,t)}async function Ue(e,t,n,r){let i=s(e),a=(await m()).manifest.packageName,o=null;for(let s=0;s<2;s+=1){await W(e,t,n),await re(i,a),r&&await g(i,a,r);let s=await S(e,t,n,r);if(o=s,s.ok)break}return $(`fill`,`test-ime`,r),o}function K(e,n){throw new t(`COMMAND_FAILED`,ve(n),ye(e,n))}async function q(e,t,n){let r=await F(e),i=l({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:r.width,referenceHeight:r.height}),a={...i,referenceWidth:r.x+r.width,referenceHeight:r.y+r.height,x1:r.x+i.x1,y1:r.y+i.y1,x2:r.x+i.x2,y2:r.y+i.y2},o=Math.max(n?.durationMs??300,16),s=await P(e,ne({intent:`pan`,origin:{x:a.x1,y:a.y1},delta:{x:a.x2-a.x1,y:a.y2-a.y1},durationMs:o},r,`android`));return{...a,...n?.durationMs===void 0?{}:{durationMs:o},...s}}function We(e){switch(e){case`portrait`:return`0`;case`landscape-left`:return`1`;case`portrait-upside-down`:return`2`;case`landscape-right`:return`3`;default:throw new t(`INVALID_ARGS`,`Unsupported Android rotation: ${e}`)}}async function J(e,n){let r;try{r=await f(e)}catch(e){i({level:`warn`,phase:`android_input_ownership_probe_failed`,data:{action:n,error:e instanceof Error?e.message:String(e)}});return}if(r.inputOwner===`ime`)throw new t(`COMMAND_FAILED`,`KEYBOARD_OVERLAY_BLOCKING: Android text input is blocked because the focused input belongs to the active keyboard/IME.`,{failureReason:`ime_capture`,action:n,inputOwner:r.inputOwner,inputType:r.inputType,type:r.type,inputMethodPackage:r.inputMethodPackage,focusedPackage:r.focusedPackage,focusedResourceId:r.focusedResourceId,nextAction:`Focused input appears to be owned by the keyboard/IME; dismiss or change the IME before retrying text entry.`})}async function Y(e){let n=(await d(e,[`shell`,`wm`,`size`])).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!n)throw new t(`COMMAND_FAILED`,`Unable to read screen size`);return{width:Number(n[1]),height:Number(n[2])}}const X=8;async function Z(e,t){let n=t.text.split(`
3
+ `);for(let[r,i]of n.entries()){let a=Xe(i,t.chunkSize);for(let[i,o]of a.entries())await Ge(e,o),t.delayMs>0&&(i+1<a.length||r+1<n.length)&&await u(t.delayMs);r+1<n.length&&await d(e,[`shell`,`input`,`keyevent`,`ENTER`])}$(t.action,`adb-shell`,t.text)}async function Ge(e,t){if(t)try{await d(e,[`shell`,`input`,`text`,qe(t)])}catch(e){throw Je(e)?Ye(t,e):e}}function Q(e){if(!Ke(e))throw Ye(e)}function Ke(e){for(let t of e){let e=t.codePointAt(0);if(e!==void 0&&t!==`
4
+ `&&(e<32||e>126))return!1}return!0}function qe(e){return e.replace(/ /g,`%s`)}function Je(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details?.stderr,r=(typeof n==`string`?n:``).toLowerCase();return!!(r.includes(`exception occurred while executing 'text'`)||r.includes(`nullpointerexception`)&&r.includes(`inputshellcommand.sendtext`))}function Ye(e,n){return new t(`COMMAND_FAILED`,"Android text input requires provider-native text injection or the bundled test IME helper for non-ASCII/control characters; the adb-shell fallback supports ASCII text only. On emulators the test IME activates automatically; on real devices pass `open --test-ime` to enable it (see `agent-device doctor` for the current IME state).",{backend:`adb-shell`,textLength:Array.from(e).length,textPreview:e.slice(0,32)},n instanceof Error?n:void 0)}function Xe(e,t){let n=Math.max(1,Math.floor(t)),r=[],i=Array.from(e);for(let e=0;e<i.length;e+=n)r.push(i.slice(e,e+n).join(``));return r.length>0?r:[``]}function $(e,t,n){i({phase:`android_text_injection`,data:{action:e,backend:t,textLength:Array.from(n).length}})}async function Ze(e,t){let n=Math.max(0,t);await d(e,[`shell`,`input`,`keyevent`,`KEYCODE_MOVE_END`],{allowFailure:!0});for(let t=0;t<n;t+=24){let r=Math.min(24,n-t);await d(e,[`shell`,`input`,`keyevent`,...Array(r).fill(`KEYCODE_DEL`)],{allowFailure:!0})}}function Qe(e,t,n){return Math.max(t,Math.min(n,e))}export{Y as a,H as c,q as d,B as f,F as h,W as i,I as l,P as m,R as n,z as o,U as p,G as r,Be as s,V as t,L as u};
@@ -0,0 +1 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{v as n}from"./sdk-android-adb.js";import{n as r,r as i}from"./install-source2.js";import{it as a}from"./internal/daemon.js";import{promises as o}from"node:fs";import s from"node:os";import c from"node:path";var l=e({prepareIosInstallArtifact:()=>u,readIosBundleInfo:()=>d});async function u(e,n){if(e.kind===`url`&&!r(e.url))throw new t(`INVALID_ARGS`,`iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.`);let a=await i({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(`.app`)||t.isFile()&&e.toLowerCase().endsWith(`.ipa`),installableLabel:`iOS installable (.app or .ipa)`,allowArchiveExtraction:e.kind!==`url`||r(e.url),signal:n?.signal}),o;try{o=await f(a.installablePath,n);let e=o,t=await d(e.installPath);return{archivePath:a.archivePath??(a.installablePath.toLowerCase().endsWith(`.ipa`)?a.installablePath:void 0),installablePath:e.installPath,bundleId:t.bundleId,appName:t.appName,cleanup:async()=>{await e.cleanup(),await a.cleanup()}}}catch(e){try{await o?.cleanup()}finally{await a.cleanup()}throw e}}async function d(e){let t=c.join(e,`Info.plist`),[n,r,i]=await Promise.all([a(t,`CFBundleIdentifier`),a(t,`CFBundleDisplayName`),a(t,`CFBundleName`)]);return{bundleId:n,appName:r??i}}async function f(e,r){if(!e.toLowerCase().endsWith(`.ipa`))return{installPath:e,cleanup:async()=>{}};let i=await o.mkdtemp(c.join(s.tmpdir(),`agent-device-ios-ipa-`)),a=async()=>{await o.rm(i,{recursive:!0,force:!0})};try{await n(`unzip`,[`-q`,e,`-d`,i]);let s=c.join(i,`Payload`),l=(await o.readdir(s,{withFileTypes:!0}).catch(()=>{throw new t(`INVALID_ARGS`,`Invalid IPA: missing Payload directory`)})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(`.app`)).map(e=>({installPath:c.join(s,e.name),bundleName:e.name.replace(/\.app$/i,``)})),u=l[0];if(u!==void 0&&l.length===1)return{installPath:u.installPath,cleanup:a};if(l.length===0)throw new t(`INVALID_ARGS`,`Invalid IPA: expected at least one .app under Payload, found 0`);await p(l);let d=r?.appIdentifierHint?.trim();if(d){let e=m(l,d);if(e)return{installPath:e.installPath,cleanup:a};throw new t(`INVALID_ARGS`,`Invalid IPA: found ${l.length} .app bundles under Payload and none matched "${d}". Available bundles: ${l.map(h).join(`, `)}`)}throw new t(`INVALID_ARGS`,`Invalid IPA: found ${l.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${l.map(h).join(`, `)}`)}catch(e){throw await a(),e}}async function p(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await d(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function m(e,n){let r=n.toLowerCase(),i=e.filter(e=>e.bundleName.toLowerCase()===r);if(i.length===1)return i[0];if(i.length>1)throw new t(`INVALID_ARGS`,`Invalid IPA: multiple app bundles matched "${n}" by name. Use a bundle id hint instead.`);if(n.includes(`.`)){let t=e.filter(e=>e.bundleId?.toLowerCase()===r);if(t.length===1)return t[0]}}function h(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}export{u as n,l as t};
@@ -7,7 +7,11 @@ type MaterializeInstallSource = {
7
7
  kind: 'path';
8
8
  path: string;
9
9
  };
10
+ /**
11
+ * @public Archive extensions accepted by install-source resolution.
12
+ */
13
+ declare const ARCHIVE_EXTENSIONS: readonly [".zip", ".tar", ".tar.gz", ".tgz"];
10
14
  declare function validateDownloadSourceUrl(parsedUrl: URL): Promise<void>;
11
15
  declare function isTrustedInstallSourceUrl(sourceUrl: string | URL): boolean;
12
16
  //#endregion
13
- export { type MaterializeInstallSource, isTrustedInstallSourceUrl, validateDownloadSourceUrl };
17
+ export { ARCHIVE_EXTENSIONS, type MaterializeInstallSource, isTrustedInstallSourceUrl, validateDownloadSourceUrl };
@@ -1 +1 @@
1
- import{r as e,t}from"./install-source2.js";export{t as isTrustedInstallSourceUrl,e as validateDownloadSourceUrl};
1
+ import{i as e,n as t,t as n}from"./install-source2.js";export{n as ARCHIVE_EXTENSIONS,t as isTrustedInstallSourceUrl,e as validateDownloadSourceUrl};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{v as t}from"./sdk-android-adb.js";import{t as n}from"./path-resolution.js";import{createWriteStream as r,promises as i}from"node:fs";import a from"node:os";import o from"node:path";import{pipeline as s}from"node:stream/promises";import{Readable as c}from"node:stream";import l from"node:net";import u from"node:dns/promises";const d=[`.zip`,`.tar`,`.tar.gz`,`.tgz`];Object.freeze([...d]);async function f(e){let t=[];try{let n=await m(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(n.cleanup);let r=await T(n.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,allowArchiveExtraction:e.allowArchiveExtraction!==!1,registerCleanup:e=>{t.push(e)}});return{archivePath:r.archivePath,installablePath:r.installablePath,cleanup:async()=>{await A(t)}}}catch(e){throw await A(t),e}}function p(e){return n(e)}async function m(e,t){if(e.kind===`path`)return{localPath:p(e.path),cleanup:async()=>{}};let n=await i.mkdtemp(o.join(a.tmpdir(),`agent-device-source-`));try{return{localPath:await h(n,e.url,e.headers,t),cleanup:async()=>{await i.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await i.rm(n,{recursive:!0,force:!0}),e}}async function h(t,n,i,a){let l;try{l=new URL(n)}catch{throw new e(`INVALID_ARGS`,`Invalid source URL: ${n}`)}await g(l);let u=a?.signal;if(u?.aborted)throw new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});let d=a?.downloadTimeoutMs??12e4,f=AbortSignal.timeout(d),p=u?AbortSignal.any([u,f]):f;try{let n=await fetch(l,{headers:i,redirect:`follow`,signal:p});if(!n.ok)throw new e(`COMMAND_FAILED`,`Failed to download app source: ${n.status} ${n.statusText}`,{status:n.status,statusText:n.statusText,url:l.toString()});let a=b(n,l),u=o.join(t,a),d=n.body;if(!d)throw new e(`COMMAND_FAILED`,`Download response body was empty`,{url:l.toString()});return await s(c.fromWeb(d),r(u)),u}catch(t){throw u?.aborted?new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`},t):f.aborted?new e(`COMMAND_FAILED`,`App source download timed out after ${d}ms`,{timeoutMs:d,url:l.toString()},t):t}}async function g(t){if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new e(`INVALID_ARGS`,`Unsupported source URL protocol: ${t.protocol}`);if(x(t.hostname.toLowerCase()))throw new e(`INVALID_ARGS`,`Source URL host is not allowed: ${t.hostname}`,{hint:`Use a public artifact URL.`});if((await u.lookup(t.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>S(e.address)))throw new e(`INVALID_ARGS`,`Source URL host resolved to a private or loopback address: ${t.hostname}`,{hint:`Use a public artifact URL.`})}function _(e){let t=e instanceof URL?e:new URL(e),n=t.hostname.toLowerCase();if(!n)return!1;let r=t.pathname;return v(n,r)||y(n,r)}function v(e,t){return e===`api.github.com`?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(t):e===`github.com`?/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(t):!1}function y(e,t){return e!==`expo.dev`&&!e.endsWith(`.expo.dev`)?!1:/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(t)}function b(e,t){let n=(e.headers.get(`content-disposition`)?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i))?.[1]?.trim();return n?o.basename(n):o.basename(t.pathname)||`downloaded-artifact.bin`}function x(e){return!e||e===`localhost`||e.endsWith(`.localhost`)?!0:S(e)}function S(e){let t=l.isIP(e);return t===4?C(e):t===6?w(e):!1}function C(e){let t=e.split(`.`).map(e=>Number.parseInt(e,10));if(t.length!==4||t.some(e=>Number.isNaN(e)||e<0||e>255))return!1;let n=t[0],r=t[1];return n===void 0||r===void 0?!1:n===10||n===127||n===169&&r===254||n===172&&r>=16&&r<=31||n===192&&r===168}function w(e){let t=e.toLowerCase();return!!(t===`::1`||t.startsWith(`fc`)||t.startsWith(`fd`)||t.startsWith(`fe80:`))}async function T(t,n){let r=await i.stat(t).catch(()=>null);if(!r)throw new e(`INVALID_ARGS`,`App source not found: ${t}`);if(n.isInstallablePath(t,r))return{archivePath:n.archivePath,installablePath:t};if(r.isFile()&&k(t)){if(!n.allowArchiveExtraction)throw new e(`INVALID_ARGS`,`URL sources must point directly to a ${n.installableLabel}; archive extraction is not allowed`,{path:t});let r=await D(t);return n.registerCleanup(r.cleanup),await T(r.outputPath,{...n,archivePath:n.archivePath??t})}if(r.isDirectory()){let r=await E(t,n.isInstallablePath),i=r[0];if(i!==void 0&&r.length===1)return{archivePath:n.archivePath,installablePath:i};if(r.length>1)throw new e(`INVALID_ARGS`,`Found multiple ${n.installableLabel} candidates under ${t}`,{matches:r});let a=await E(t,(e,t)=>t.isFile()&&k(e)),o=a[0];if(o!==void 0&&a.length===1){if(!n.allowArchiveExtraction)throw new e(`INVALID_ARGS`,`URL sources must point directly to a ${n.installableLabel}; nested archives are not allowed`,{path:o});let t=await D(o);return n.registerCleanup(t.cleanup),await T(t.outputPath,{...n,archivePath:n.archivePath??o})}if(a.length>1)throw new e(`INVALID_ARGS`,`Found multiple nested archives under ${t}; expected one ${n.installableLabel} source`,{matches:a})}throw new e(`INVALID_ARGS`,`Expected ${n.installableLabel} source, but got ${t}`)}async function E(e,t){let n=[],r=[{path:e,depth:0}];for(;r.length>0;){let e=r.shift();if(!e)continue;let a=await i.readdir(e.path,{withFileTypes:!0});a.sort((e,t)=>e.name.localeCompare(t.name));for(let i of a){let a=o.join(e.path,i.name);if(t(a,i)){n.push(a);continue}i.isDirectory()&&e.depth<5&&r.push({path:a,depth:e.depth+1})}}return n}async function D(e){let n=await i.mkdtemp(o.join(a.tmpdir(),`agent-device-archive-`));try{return e.toLowerCase().endsWith(`.zip`)?await O(e,n):e.toLowerCase().endsWith(`.tar.gz`)||e.toLowerCase().endsWith(`.tgz`)?await t(`tar`,[`-xzf`,e,`-C`,n]):await t(`tar`,[`-xf`,e,`-C`,n]),{outputPath:n,cleanup:async()=>{await i.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await i.rm(n,{recursive:!0,force:!0}),e}}async function O(e,n){await t(`unzip`,[`-q`,e,`-d`,n])}function k(e){let t=e.toLowerCase();return d.some(e=>t.endsWith(e))}async function A(e){for(let t of[...e].reverse())await t()}export{f as n,g as r,_ as t};
1
+ import{_ as e}from"./sdk-contracts.js";import{v as t}from"./sdk-android-adb.js";import{t as n}from"./path-resolution.js";import{createWriteStream as r,promises as i}from"node:fs";import a from"node:os";import o from"node:path";import{pipeline as s}from"node:stream/promises";import{Readable as c}from"node:stream";import l from"node:net";import u from"node:dns/promises";const d=[`.zip`,`.tar`,`.tar.gz`,`.tgz`],f=Object.freeze([...d]);async function p(e){let t=[];try{let n=await h(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(n.cleanup);let r=await E(n.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,allowArchiveExtraction:e.allowArchiveExtraction!==!1,registerCleanup:e=>{t.push(e)}});return{archivePath:r.archivePath,installablePath:r.installablePath,cleanup:async()=>{await j(t)}}}catch(e){throw await j(t),e}}function m(e){return n(e)}async function h(e,t){if(e.kind===`path`)return{localPath:m(e.path),cleanup:async()=>{}};let n=await i.mkdtemp(o.join(a.tmpdir(),`agent-device-source-`));try{return{localPath:await g(n,e.url,e.headers,t),cleanup:async()=>{await i.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await i.rm(n,{recursive:!0,force:!0}),e}}async function g(t,n,i,a){let l;try{l=new URL(n)}catch{throw new e(`INVALID_ARGS`,`Invalid source URL: ${n}`)}await _(l);let u=a?.signal;if(u?.aborted)throw new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});let d=a?.downloadTimeoutMs??12e4,f=AbortSignal.timeout(d),p=u?AbortSignal.any([u,f]):f;try{let n=await fetch(l,{headers:i,redirect:`follow`,signal:p});if(!n.ok)throw new e(`COMMAND_FAILED`,`Failed to download app source: ${n.status} ${n.statusText}`,{status:n.status,statusText:n.statusText,url:l.toString()});let a=x(n,l),u=o.join(t,a),d=n.body;if(!d)throw new e(`COMMAND_FAILED`,`Download response body was empty`,{url:l.toString()});return await s(c.fromWeb(d),r(u)),u}catch(t){throw u?.aborted?new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`},t):f.aborted?new e(`COMMAND_FAILED`,`App source download timed out after ${d}ms`,{timeoutMs:d,url:l.toString()},t):t}}async function _(t){if(t.protocol!==`http:`&&t.protocol!==`https:`)throw new e(`INVALID_ARGS`,`Unsupported source URL protocol: ${t.protocol}`);if(S(t.hostname.toLowerCase()))throw new e(`INVALID_ARGS`,`Source URL host is not allowed: ${t.hostname}`,{hint:`Use a public artifact URL.`});if((await u.lookup(t.hostname,{all:!0,verbatim:!0}).catch(()=>[])).some(e=>C(e.address)))throw new e(`INVALID_ARGS`,`Source URL host resolved to a private or loopback address: ${t.hostname}`,{hint:`Use a public artifact URL.`})}function v(e){let t=e instanceof URL?e:new URL(e),n=t.hostname.toLowerCase();if(!n)return!1;let r=t.pathname;return y(n,r)||b(n,r)}function y(e,t){return e===`api.github.com`?/^\/repos\/[^/]+\/[^/]+\/actions\/artifacts\/\d+\/zip$/i.test(t):e===`github.com`?/^\/[^/]+\/[^/]+\/(?:actions\/runs\/\d+\/artifacts\/\d+|suites\/\d+\/artifacts\/\d+)$/i.test(t):!1}function b(e,t){return e!==`expo.dev`&&!e.endsWith(`.expo.dev`)?!1:/^\/(?:artifacts\/eas\/|accounts\/[^/]+\/projects\/[^/]+\/builds\/)/i.test(t)}function x(e,t){let n=(e.headers.get(`content-disposition`)?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i))?.[1]?.trim();return n?o.basename(n):o.basename(t.pathname)||`downloaded-artifact.bin`}function S(e){return!e||e===`localhost`||e.endsWith(`.localhost`)?!0:C(e)}function C(e){let t=l.isIP(e);return t===4?w(e):t===6?T(e):!1}function w(e){let t=e.split(`.`).map(e=>Number.parseInt(e,10));if(t.length!==4||t.some(e=>Number.isNaN(e)||e<0||e>255))return!1;let n=t[0],r=t[1];return n===void 0||r===void 0?!1:n===10||n===127||n===169&&r===254||n===172&&r>=16&&r<=31||n===192&&r===168}function T(e){let t=e.toLowerCase();return!!(t===`::1`||t.startsWith(`fc`)||t.startsWith(`fd`)||t.startsWith(`fe80:`))}async function E(t,n){let r=await i.stat(t).catch(()=>null);if(!r)throw new e(`INVALID_ARGS`,`App source not found: ${t}`);if(n.isInstallablePath(t,r))return{archivePath:n.archivePath,installablePath:t};if(r.isFile()&&A(t)){if(!n.allowArchiveExtraction)throw new e(`INVALID_ARGS`,`URL sources must point directly to a ${n.installableLabel}; archive extraction is not allowed`,{path:t});let r=await O(t);return n.registerCleanup(r.cleanup),await E(r.outputPath,{...n,archivePath:n.archivePath??t})}if(r.isDirectory()){let r=await D(t,n.isInstallablePath),i=r[0];if(i!==void 0&&r.length===1)return{archivePath:n.archivePath,installablePath:i};if(r.length>1)throw new e(`INVALID_ARGS`,`Found multiple ${n.installableLabel} candidates under ${t}`,{matches:r});let a=await D(t,(e,t)=>t.isFile()&&A(e)),o=a[0];if(o!==void 0&&a.length===1){if(!n.allowArchiveExtraction)throw new e(`INVALID_ARGS`,`URL sources must point directly to a ${n.installableLabel}; nested archives are not allowed`,{path:o});let t=await O(o);return n.registerCleanup(t.cleanup),await E(t.outputPath,{...n,archivePath:n.archivePath??o})}if(a.length>1)throw new e(`INVALID_ARGS`,`Found multiple nested archives under ${t}; expected one ${n.installableLabel} source`,{matches:a})}throw new e(`INVALID_ARGS`,`Expected ${n.installableLabel} source, but got ${t}`)}async function D(e,t){let n=[],r=[{path:e,depth:0}];for(;r.length>0;){let e=r.shift();if(!e)continue;let a=await i.readdir(e.path,{withFileTypes:!0});a.sort((e,t)=>e.name.localeCompare(t.name));for(let i of a){let a=o.join(e.path,i.name);if(t(a,i)){n.push(a);continue}i.isDirectory()&&e.depth<5&&r.push({path:a,depth:e.depth+1})}}return n}async function O(e){let n=await i.mkdtemp(o.join(a.tmpdir(),`agent-device-archive-`));try{return e.toLowerCase().endsWith(`.zip`)?await k(e,n):e.toLowerCase().endsWith(`.tar.gz`)||e.toLowerCase().endsWith(`.tgz`)?await t(`tar`,[`-xzf`,e,`-C`,n]):await t(`tar`,[`-xf`,e,`-C`,n]),{outputPath:n,cleanup:async()=>{await i.rm(n,{recursive:!0,force:!0})}}}catch(e){throw await i.rm(n,{recursive:!0,force:!0}),e}}async function k(e,n){await t(`unzip`,[`-q`,e,`-d`,n])}function A(e){let t=e.toLowerCase();return d.some(e=>t.endsWith(e))}async function j(e){for(let t of[...e].reverse())await t()}export{_ as i,v as n,p as r,f as t};
@@ -1 +1 @@
1
- import{j as e}from"./sdk-android-adb.js";import{t}from"./snapshot-quality.js";import{Ht as n,Jt as r,Lt as i,St as a,Ut as o,Vt as s,Yt as c,xt as l,zt as u}from"./internal/daemon.js";import{a as d}from"./input-actions.js";function f(e){let{session:t,sessionStore:i,command:a,positionals:u,retryPositionals:d,flags:f,result:p,responseData:m,actionStartedAt:h,actionFinishedAt:g,androidFreshnessBaseline:_}=e,v=o(f);return i.recordAction(t,{command:a,positionals:u,flags:v??{},result:p}),n({session:t,command:a,positionals:d??u,flags:f,preSnapshot:t.snapshot}),r(a)&&c(t,a,_??t.snapshot),s(t,a,d??u,f),l(t,a,u,p,v??{},h,g),{ok:!0,data:m}}async function p(e){let{session:t,flags:n,sessionStore:r,contextFromFlags:i,captureSnapshotForSession:o}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if(t.device.platform===`android`){let e=await d(t.device),n={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=n),n}let s=a(t.snapshot);if(s)return t.recording&&(t.recording.touchReferenceFrame=s),s;if(!t.recording)return;let c=a(await o(t,n,r,i,{interactiveOnly:!0}));return c&&t.recording&&(t.recording.touchReferenceFrame=c),c}async function m(t){try{return await p(t)}catch(n){e({level:`warn`,phase:`touch_reference_frame_resolve_failed`,data:{platform:t.session.device.platform,error:n instanceof Error?n.message:String(n)}});return}}function h(e){return a({nodes:e,createdAt:0})}async function g(e,n,r,a,o){let s={...n??{},snapshotInteractiveOnly:o.interactiveOnly},c=a(s,e.appBundleId,e.trace?.outPath),{snapshot:l}=await u({device:e.device,session:e,flags:s,outPath:s.out,logPath:c.logPath??``,includeRects:o.includeRects,androidFreshnessMode:o.androidFreshnessMode});return t(l.snapshotQuality)||(i(e,l),r.set(e.name,e)),l}export{f as i,h as n,m as r,g as t};
1
+ import{j as e}from"./sdk-android-adb.js";import"./snapshot-diagnostics.js";import{t}from"./snapshot-quality.js";import{Dt as n,Ot as r,Xt as i,cn as a,fn as o,ln as s,nn as c,pn as l,un as u}from"./internal/daemon.js";import{a as d}from"./input-actions.js";import{o as f}from"./session-target-evidence.js";function p(e){let{session:t,sessionStore:r,command:i,positionals:c,actionCommand:d=i,retryPositionals:p,flags:m,result:h,responseData:g,recordedTarget:_,actionStartedAt:v,actionFinishedAt:y,androidFreshnessBaseline:b}=e,x=u(m),S=t.recordSession&&_?f(_):void 0;return r.recordAction(t,{command:i,positionals:c,flags:x??{},result:h,...S?{targetEvidence:S}:{}}),s({session:t,command:i,positionals:p??c,flags:m,preSnapshot:t.snapshot}),o(d)&&l(t,d,b??t.snapshot),a(t,d,p??c,m),n(t,d,c,h,x??{},v,y),{ok:!0,data:g}}async function m(e){let{session:t,flags:n,sessionStore:i,contextFromFlags:a,captureSnapshotForSession:o}=e;if(!t.recording)return;if(t.recording.touchReferenceFrame)return t.recording.touchReferenceFrame;if(t.device.platform===`android`){let e=await d(t.device),n={referenceWidth:e.width,referenceHeight:e.height};return t.recording&&(t.recording.touchReferenceFrame=n),n}let s=r(t.snapshot);if(s)return t.recording&&(t.recording.touchReferenceFrame=s),s;if(!t.recording)return;let c=r(await o(t,n,i,a,{interactiveOnly:!0}));return c&&t.recording&&(t.recording.touchReferenceFrame=c),c}async function h(t){try{return await m(t)}catch(n){e({level:`warn`,phase:`touch_reference_frame_resolve_failed`,data:{platform:t.session.device.platform,error:n instanceof Error?n.message:String(n)}});return}}function g(e){return r({nodes:e,createdAt:0})}async function _(e,n,r,a,o){let s={...n??{},snapshotInteractiveOnly:o.interactiveOnly},l=a(s,e.appBundleId,e.trace?.outPath),{snapshot:u}=await c({device:e.device,session:e,flags:s,outPath:s.out,logPath:l.logPath??``,includeRects:o.includeRects,androidFreshnessMode:o.androidFreshnessMode});return t(u.snapshotQuality)||(i(e,u),r.set(e.name,e)),u}export{p as i,g as n,h as r,_ as t};
@@ -0,0 +1,230 @@
1
+ import { N as SnapshotNode, v as ResponseCost } from "./sdk-contracts.js";
2
+ //#region src/core/click-button.d.ts
3
+ declare const CLICK_BUTTONS: readonly ['primary', 'secondary', 'middle'];
4
+ type ClickButton = (typeof CLICK_BUTTONS)[number];
5
+ //#endregion
6
+ //#region src/contracts/interaction.d.ts
7
+ /** The decisive criterion separating a resolveSelectorChain winner from its strongest runner-up (ADR 0012). */
8
+ type DisambiguationTiebreak = 'visible' | 'deepest' | 'smallest-area';
9
+ /**
10
+ * A disambiguation winner or losing alternative. `diagnosticRef` is an opaque,
11
+ * non-`@` token — never a snapshot ref, never issued via `refsGeneration`,
12
+ * never pinnable or usable as an `@ref` target. Strings are UTF-8 truncated
13
+ * to 256 bytes.
14
+ */
15
+ type ResolutionDiagnosticEntry = {
16
+ diagnosticRef: string;
17
+ role?: string;
18
+ label?: string;
19
+ };
20
+ /**
21
+ * ADR 0012 decision 2: pre-action disclosure of how the acting path resolved
22
+ * its target, on every press/click/fill/longpress response. Never ref-issuing.
23
+ * `direct-ios`/`not-observed` = the XCTest fast path has no daemon tree to
24
+ * report from; `ref`/`label-fallback` = a stale `@ref` recovered via
25
+ * first-match label lookup, never exact ref provenance; `alternatives` holds
26
+ * at most 5 losing candidates, winner excluded.
27
+ */
28
+ type ResolutionDisclosure = {
29
+ source: 'runtime';
30
+ phase: 'pre-action';
31
+ kind: 'unique';
32
+ } | {
33
+ source: 'runtime';
34
+ phase: 'pre-action';
35
+ kind: 'disambiguated';
36
+ matchCount: number;
37
+ winnerDiagnostic: ResolutionDiagnosticEntry;
38
+ tiebreak: DisambiguationTiebreak;
39
+ alternatives: ResolutionDiagnosticEntry[];
40
+ } | {
41
+ source: 'ref';
42
+ phase: 'pre-action';
43
+ kind: 'exact';
44
+ } | {
45
+ source: 'ref';
46
+ phase: 'pre-action';
47
+ kind: 'label-fallback';
48
+ } | {
49
+ source: 'direct-ios';
50
+ kind: 'not-observed';
51
+ };
52
+ /**
53
+ * Opt-in (`--verify`) cheap post-condition evidence for mutating interaction
54
+ * commands (#1047). `digest`/`nodeCount`/`interactiveNodeCount` describe a single
55
+ * interactive-only capture taken right after the action; `changedFromBefore`
56
+ * compares that digest against the pre-action capture the resolution path already
57
+ * held, so no extra device round trip is spent beyond the one verify capture.
58
+ * `changedFromBefore: false` is evidence, not failure — the command still
59
+ * succeeded.
60
+ */
61
+ type InteractionEvidence = {
62
+ foregroundApp?: string;
63
+ nodeCount: number;
64
+ interactiveNodeCount: number;
65
+ digest: string;
66
+ changedFromBefore: boolean;
67
+ };
68
+ type SettleDiffLine = {
69
+ kind: 'added' | 'removed';
70
+ text: string;
71
+ /**
72
+ * Plain ref body (`e12`) for ADDED lines: minted from the settled tree that
73
+ * became the stored session snapshot, so it is immediately actionable and
74
+ * lets the MCP layer pin it at `refsGeneration`. Removed lines never carry
75
+ * one — their refs name nodes of the replaced tree.
76
+ */
77
+ ref?: string;
78
+ };
79
+ /**
80
+ * One still-present, actionable element on the settled tree, surfaced by the
81
+ * unchanged-interactive tail (see `SettleObservation.tail`).
82
+ */
83
+ type SettleTailEntry = {
84
+ ref: string;
85
+ role: string;
86
+ label?: string;
87
+ };
88
+ type SettleObservation = {
89
+ settled: boolean;
90
+ waitedMs: number;
91
+ captures: number;
92
+ quietMs: number;
93
+ timeoutMs: number;
94
+ /**
95
+ * The session's snapshot generation after the settled tree became the stored
96
+ * snapshot (#1076 versioned refs). Attached by the daemon response layer
97
+ * when `diff` is present: added lines carry refs minted from that tree, so
98
+ * the response is ref-issuing — the MCP layer merges per-ref pins from it
99
+ * exactly like snapshot/find responses.
100
+ */
101
+ refsGeneration?: number;
102
+ /**
103
+ * Digest response view only: capped added-line refs preserved without the
104
+ * verbose diff line text, so MCP can still pin refs when `diff.lines` is
105
+ * intentionally omitted.
106
+ */
107
+ refs?: Array<{
108
+ ref: string;
109
+ }>;
110
+ /** Present only for `settled: true` observations that stored the settled tree. */
111
+ diff?: {
112
+ summary: {
113
+ additions: number;
114
+ removals: number;
115
+ unchanged: number;
116
+ };
117
+ lines: SettleDiffLine[];
118
+ /** Present (true) when lines were capped to the response bound. */
119
+ truncated?: boolean;
120
+ };
121
+ /**
122
+ * Unchanged interactive refs tail: benchmarks (July 2026) showed 27% of
123
+ * `--settle` actions were followed by a fallback `snapshot -i` because a
124
+ * change-only diff omits refs for elements that did not change — after a
125
+ * modal dismiss the diff shows only removals, and the next button to press
126
+ * (already on screen, untouched) is absent from the response. `tail` lists
127
+ * the settled tree's remaining uncovered interactive elements (excluding
128
+ * structural application/window chrome and the keyboard window's chrome)
129
+ * so the response stays actionable without that extra round trip. Attached
130
+ * ONLY when `diff` carries zero added-line refs naming a NEW target (the
131
+ * modal-dismiss/toast-only/fill signature) — a diff whose added refs hand
132
+ * the next target already pays its way, so the tail would be pure byte
133
+ * cost. Keyboard-chrome refs and self-echo refs (added lines whose node
134
+ * contains the action point: the acted-on element re-describing itself,
135
+ * e.g. a filled field re-labeled with its new value) do not count as new
136
+ * targets. Refs already present on `diff`'s added lines are excluded.
137
+ * Capped; `tailTruncated` marks when candidates exceeded the cap.
138
+ */
139
+ tail?: SettleTailEntry[];
140
+ tailTruncated?: true;
141
+ hint?: string;
142
+ };
143
+ /**
144
+ * Public daemon response data shared by press/click/fill/longpress.
145
+ * `buildInteractionResponseData` emits this shape (ADR 0011 Layer 2):
146
+ * `targetKind` discriminates the resolved target, identity fields are FLAT
147
+ * (`ref`, `selector`, `x`, `y`), and per-command extras ride alongside.
148
+ */
149
+ type TouchResponseDataBase = {
150
+ message?: string;
151
+ warning?: string;
152
+ x?: number;
153
+ y?: number;
154
+ referenceWidth?: number;
155
+ referenceHeight?: number;
156
+ evidence?: InteractionEvidence;
157
+ settle?: SettleObservation;
158
+ resolution?: ResolutionDisclosure;
159
+ cost?: ResponseCost;
160
+ /** Direct iOS Maestro coordinate-fallback signals. */
161
+ maestroNonHittableCoordinateFallbackAllowed?: boolean;
162
+ maestroNonHittableCoordinateFallbackUsed?: boolean;
163
+ maestroFallbackReason?: 'non-hittable-coordinate';
164
+ };
165
+ type TouchResponsePoint = TouchResponseDataBase & {
166
+ targetKind: 'point';
167
+ x: number;
168
+ y: number;
169
+ };
170
+ type TouchResponseRef = TouchResponseDataBase & {
171
+ targetKind: 'ref';
172
+ ref: string;
173
+ refLabel?: string;
174
+ selectorChain?: string[];
175
+ targetHittable?: boolean;
176
+ hint?: string;
177
+ };
178
+ type TouchResponseSelector = TouchResponseDataBase & {
179
+ targetKind: 'selector';
180
+ selector: string;
181
+ selectorChain?: string[];
182
+ refLabel?: string;
183
+ targetHittable?: boolean;
184
+ hint?: string;
185
+ };
186
+ type TouchPressExtras = {
187
+ button?: ClickButton;
188
+ count?: number;
189
+ intervalMs?: number;
190
+ holdMs?: number;
191
+ jitterPx?: number;
192
+ doubleTap?: boolean;
193
+ };
194
+ type PressCommandResponseData = (TouchResponsePoint & TouchPressExtras) | (TouchResponseRef & TouchPressExtras) | (TouchResponseSelector & TouchPressExtras);
195
+ type ClickCommandResponseData = PressCommandResponseData;
196
+ type TouchFillExtras = {
197
+ text: string;
198
+ delayMs?: number;
199
+ };
200
+ type FillCommandResponseData = (TouchResponsePoint & TouchFillExtras) | (TouchResponseRef & TouchFillExtras) | (TouchResponseSelector & TouchFillExtras);
201
+ type TouchLongPressExtras = {
202
+ durationMs?: number;
203
+ gesture: 'longpress';
204
+ };
205
+ type LongPressCommandResponseData = (TouchResponsePoint & TouchLongPressExtras) | (TouchResponseRef & TouchLongPressExtras) | (TouchResponseSelector & TouchLongPressExtras);
206
+ /**
207
+ * Daemon response data for the `find` command. Read-only actions (`exists`,
208
+ * `wait`, `get_text`, `get_attrs`) may issue a pinnable ref with
209
+ * `refsGeneration`; mutating actions (`click`, `fill`, `focus`, `type`) carry
210
+ * `ref` as diagnostic pre-action identity and intentionally omit `refsGeneration`
211
+ * (ADR 0014). The shape is intentionally a flat, optional-field record because
212
+ * the action positional changes which fields are present.
213
+ */
214
+ type FindCommandResponseData = {
215
+ ref?: string;
216
+ refsGeneration?: number;
217
+ found?: true;
218
+ waitedMs?: number;
219
+ text?: string;
220
+ node?: SnapshotNode;
221
+ locator?: string;
222
+ query?: string;
223
+ x?: number;
224
+ y?: number;
225
+ message?: string;
226
+ settle?: SettleObservation;
227
+ cost?: ResponseCost;
228
+ };
229
+ //#endregion
230
+ export { LongPressCommandResponseData as a, FindCommandResponseData as i, DisambiguationTiebreak as n, PressCommandResponseData as o, FillCommandResponseData as r, ClickButton as s, ClickCommandResponseData as t };
@@ -1 +1 @@
1
- import{S as e,_ as t,v as n}from"./sdk-contracts.js";import{j as r}from"./sdk-android-adb.js";import{d as i,f as a,h as o,u as s}from"./sdk-batch.js";import{Sn as c,Xn as l,bt as u,xt as d,yt as ee}from"./tv-remote.js";import{c as f,m as p,o as m}from"./sdk-device.js";import{t as h}from"./runtime.js";import{It as g,Lt as _,Nt as v,Pt as y,Qt as b,Tt as x,Xt as S,an as C,in as w,on as T,qt as te,rn as ne,wt as E}from"./internal/daemon.js";import{n as re}from"./provider.js";import{_ as D,c as O,d as ie,f as ae,g as k,h as oe,l as se,m as ce,n as le,o as ue,p as de,r as fe,s as pe,u as me,v as he,y as A}from"./selector-runtime.js";import{i as j,n as M,r as N,t as P}from"./interaction-snapshot.js";const F=new Set(a());function I(e){return R({fields:L(e.command),input:e.input??{},data:e.data,controlledFields:F})}function L(e){let t=o(e);if(!t)throw Error(`Missing response data transform descriptor for ${e}`);return t.fields}function R(e){let t=Object.fromEntries(Object.entries(e.data??{}).filter(([t])=>!e.controlledFields.has(t)));for(let[n,r]of Object.entries(e.fields)){let i=e.input[n]===void 0?r.defaultValue:e.input[n];if(i===void 0||r.omitDefault===!0&&i===r.defaultValue){delete t[n];continue}t[n]=i}return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}const ge=new Set([`currentUptimeMs`,`gestureEndUptimeMs`,`gestureStartUptimeMs`,`sequenceResults`]);function _e(e){if(e)return Object.fromEntries(Object.entries(e).filter(([e])=>!ge.has(e)))}function z(e){let{source:t,referenceFrame:n,extra:r}=e;if(t.kind===`runner-payload`){let e={targetKind:t.targetKind,...r??{}};return{result:B({data:t.data,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e}),responseData:B({data:t.publicData,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e})}}let{result:i}=t,a=ae(i),o={targetKind:i.kind,...a,...ve(i.settle,e.settleRefsGeneration),...r??{}},s=B({data:i.backendResult,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),c=B({data:t.publicData,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),l=ye(`warning`in i?i.warning:void 0,e.staleRefsWarning);return l&&(s.warning=l,c.warning=l),{result:s,responseData:c}}function ve(e,t){return!e?.diff||t===void 0?{}:{settle:{...e,refsGeneration:t}}}function ye(e,t){return t?e?`${e} ${t}`:t:e}function B(e){let{data:t,fallbackX:n,fallbackY:r,referenceFrame:i,extra:a}=e,o=xe(a,n,r)??(typeof t?.message==`string`?t.message:void 0);return be({...t??{},...n===void 0||r===void 0?{}:{x:n,y:r},...i??{},...a??{},...c(o)})}function be(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function xe(e,t,n){let r=V(e,`text`);if(r!==void 0)return`Filled ${Array.from(r).length} chars`;let i=Se(t,n),a=Ce(e);if(a)return Te(a,e??{},i);if(i)return we(e,i)}function V(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function Se(e,t){return e===void 0||t===void 0?``:` (${e}, ${t})`}function Ce(e){let t=V(e,`ref`);return t===void 0?V(e,`selector`):`@${t}`}function we(e,t){return e?.gesture===`longpress`?`Long pressed${t}`:`Tapped${t}`}function Te(e,t,n){let r=typeof t.button==`string`?t.button:void 0;return t.gesture===`longpress`?`Long pressed ${e}${n}`:r&&r!==`primary`?`Clicked ${r} ${e}${n}`:`Tapped ${e}${n}`}function H(e,t){return!f(e.device)||e.surface!==`desktop`&&e.surface!==`menubar`||e.surface===`menubar`&&(t===`click`||t===`press`)?null:w(`UNSUPPORTED_OPERATION`,`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function U(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new t(`SESSION_NOT_FOUND`,ne);return h({backend:Ee({...e,session:n}),...ue(`interaction commands`,{plural:!0}),sessions:v({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0},setRecord:t=>{t.snapshot&&(_(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function Ee(e){let{req:t,session:n}=e,r=De(n);return{platform:p(n.device),captureSnapshot:async(r,i)=>({snapshot:await e.captureSnapshotForSession(n,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0,includeRects:i?.includeRects===!0})}),tap:async(r,i)=>W(await S(n.device,`press`,[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),tapTarget:r?.clickRef?async(e,t)=>(await r.clickRef?.(t.ref),{ref:k(t.ref)}):void 0,fill:async(r,i,a)=>W(await S(n.device,`fill`,[String(i.x),String(i.y),a],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),fillTarget:r?.fillRef?async(e,t,n,i)=>(await r.fillRef?.(t.ref,n,i),{ref:k(t.ref),text:n,delayMs:i?.delayMs??0}):void 0,longPress:async(r,i,a)=>W(await S(n.device,`longpress`,[String(i.x),String(i.y),...a?.durationMs===void 0?[]:[String(a.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))),typeText:async(r,i)=>W(await S(n.device,`type`,[i],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))}}function De(e){if(e.device.platform!==`web`)return;let t=re();return t.clickRef||t.fillRef?t:void 0}function W(e){return e&&typeof e==`object`?e:void 0}async function Oe(e){switch(e.req.command){case`press`:return await G(e,`press`);case`click`:return await G(e,`click`);case`longpress`:return await G(e,`longpress`);case`fill`:return await ze(e);default:return null}}async function G(e,t){let{req:n,sessionName:r,sessionStore:i}=e,a=i.get(r);if(!a)return C();let o=t===`click`?`click`:t,s=t===`longpress`?`longpress`:`press`,c=H(a,o);if(c)return c;let l=T(s,a.device);if(l)return l;let f=A(t,n.flags);if(f)return f;let m=d(n.flags),h=ee(m);if(t!==`longpress`&&m!==`primary`){let e=u({commandLabel:o,platform:p(a.device),button:m,count:n.flags?.count,intervalMs:n.flags?.intervalMs,holdMs:n.flags?.holdMs,jitterPx:n.flags?.jitterPx,doubleTap:n.flags?.doubleTap});if(e)return w(e.code,e.message,e.details)}let _=t===`longpress`?ce(n.positionals??[]):oe(n.positionals??[],o);if(!_.ok)return _.response;let v=_.target.kind===`ref`?g({session:a,ref:_.target.ref,mintedGeneration:_.refGeneration}):void 0,y;if(_.target.kind===`ref`){let r=e.refSnapshotFlagGuardResponse(t===`longpress`?`longpress`:`press`,n.flags);if(r)return r;y=await Z(e,a)}let b=Me({session:a,commandLabel:o,target:_.target,flags:n.flags});if(b){let t=await Pe(e,a,b);if(t)return t}let x=t===`longpress`?_.durationMs:void 0;return await X(e,{androidFreshnessBaseline:y,run:async e=>await ke({runtime:e,command:t,target:_.target,sessionName:r,requestId:n.meta?.requestId,clickButton:m,flags:n.flags,durationMs:x}),afterRun:async e=>{a.lease?.leaseProvider||await se(a,ie(_.target,e))},buildPayloads:async r=>{let i=je(r);return await Ae({params:e,session:a,result:r,staleRefsWarning:v,publicData:Y({session:a,command:t===`longpress`?void 0:t,flags:n.flags,data:r.backendResult}),extra:t===`longpress`?{...i===void 0?{}:{durationMs:i},gesture:`longpress`}:h})}})}async function ke(e){let{runtime:t,command:n,target:r,sessionName:i,requestId:a,flags:o}=e,s=D(o);if(n===`longpress`)return await t.interactions.longPress(r,{session:i,requestId:a,durationMs:e.durationMs,settle:s});let c={session:i,requestId:a,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap,verify:o?.verify,settle:s};return n===`click`?await t.interactions.click(r,c):await t.interactions.press(r,c)}async function Ae(e){let{params:t,session:n,result:r,publicData:i,extra:a}=e,o=r.kind===`point`?await N({session:n,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):M(n.snapshot?.nodes??[]);return z({source:{kind:`runtime`,result:r,publicData:i},referenceFrame:o,extra:a,staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:K(n,r)})}function K(e,t){if(t.settle?.diff)return y(e),e.snapshotGeneration}function je(e){return`durationMs`in e?e.durationMs:void 0}function Me(e){let{session:t,commandLabel:n,target:r,flags:a}=e;return n!==`click`||r.kind!==`selector`||Ne(a)||i(n)&&a?.verify===!0||s(n)&&a?.settle===!0?null:q(t,r.selector,a)}function q(e,t,n){let r=O({session:e,selectorExpression:t});return r?{...r,...n?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{}}:null}function Ne(e){return e?.count!==void 0||e?.intervalMs!==void 0||e?.holdMs!==void 0||e?.jitterPx!==void 0||e?.doubleTap!==void 0||e?.clickButton!==void 0&&e.clickButton!==`primary`}async function Pe(e,t,n){return await J({params:e,session:t,selector:n,command:`press`,positionals:[],extra:{selector:n.raw},fallbackPhase:`ios_direct_selector_tap_fallback`})}async function J(t){let{params:n,session:i,selector:a,command:o,positionals:s,extra:c,fallbackPhase:l}=t,u=Date.now();try{let e=await S(i.device,o,s,n.req.flags?.out,{...n.contextFromFlags(n.req.flags,i.appBundleId,i.trace?.outPath),directElementSelector:a,surface:i.surface})??{},t=Date.now(),r=Le(e),{result:l,responseData:d}=z({source:{kind:`runner-payload`,targetKind:`selector`,data:e,publicData:Y({session:i,command:Fe(n.req.command,o),flags:n.req.flags,data:e}),point:r},referenceFrame:Re(e),extra:{...c,...Ie(a,e)}});return j({session:i,sessionStore:n.sessionStore,command:n.req.command,positionals:n.req.positionals??[],retryPositionals:$(r),flags:n.req.flags,result:l,responseData:d,actionStartedAt:u,actionFinishedAt:t})}catch(t){return pe(t,{delegateSemanticFailures:a.allowNonHittableCoordinateFallback!==!0})?(r({level:`debug`,phase:l,data:{selector:a.raw,error:t instanceof Error?t.message:String(t)}}),null):{ok:!1,error:e(t)}}}function Y(e){let t=m(e.session.device.platform)?_e(e.data):e.data;return e.command?I({command:e.command,input:e.flags,data:t}):t}function Fe(e,t){return e===`click`||e===`press`||e===`fill`?e:t}function Ie(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let n=t.message===b;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:n,...n?{maestroFallbackReason:`non-hittable-coordinate`}:{}}}function Le(e){let t=typeof e.x==`number`?e.x:void 0,n=typeof e.y==`number`?e.y:void 0;return t!==void 0&&n!==void 0?{x:t,y:n}:{x:0,y:0}}function Re(e){return typeof e.referenceWidth==`number`&&typeof e.referenceHeight==`number`?{referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight}:void 0}async function ze(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n);if(i){let e=H(i,`fill`);if(e)return e;let t=T(`fill`,i.device);if(t)return t}if(!i)return C();let a=A(`fill`,t.flags);if(a)return a;let o=de(t.positionals??[]);if(!o.ok)return o.response;let s=await Be(e,i,o.target,o.refGeneration);if(s.response)return s.response;let{staleRefsWarning:c}=s;return await Ve(e,i,o.target,o.text)||await X(e,{run:async e=>await e.interactions.fill(o.target,o.text,{session:n,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs,verify:t.flags?.verify,settle:D(t.flags)}),buildPayloads:e=>He({session:i,result:e,text:o.text,flags:t.flags,staleRefsWarning:c})})}async function Be(e,t,n,r){if(n.kind!==`ref`)return{};let i=g({session:t,ref:n.ref,mintedGeneration:r}),a=e.refSnapshotFlagGuardResponse(`fill`,e.req.flags);return a?{response:a,staleRefsWarning:i}:(await Z(e,t),{staleRefsWarning:i})}async function Ve(e,t,n,r){let i=Ue({session:t,target:n,flags:e.req.flags});return i?await We(e,t,i,r):null}function He(e){let{session:t,result:n}=e,r=n.kind===`point`?void 0:M(t.snapshot?.nodes??[]);return z({source:{kind:`runtime`,result:n,publicData:Y({session:t,command:`fill`,flags:e.flags,data:n.backendResult})},referenceFrame:r,extra:{text:e.text},staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:K(t,n)})}function Ue(e){let{session:t,target:n,flags:r}=e;return n.kind!==`selector`||i(`fill`)&&r?.verify===!0||s(`fill`)&&r?.settle===!0?null:q(t,n.selector,r)}async function We(e,t,n,r){return await J({params:e,session:t,selector:n,command:`fill`,positionals:[r],extra:{selector:n.raw,text:r},fallbackPhase:`ios_direct_selector_fill_fallback`})}async function X(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return C();let i=U(e),a=Date.now();try{let{readiness:n,runtimeResult:o}=await Ge(r,e.req.command,async()=>{let e=await t.run(i);return await t.afterRun?.(e),e}),s=Date.now(),{result:c,responseData:l}=await t.buildPayloads(o);if(n.status===`recovered`){let e=typeof l.warning==`string`?`${l.warning} ${n.warning}`:n.warning;c.warning=e,l.warning=e}return j({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:Ke(e.req.command,o),flags:e.req.flags,result:c,responseData:l,actionStartedAt:a,actionFinishedAt:s,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(e){let t=n(e);if(me(t))throw t;return Q(e)}}async function Ge(e,t,n){if(e.lease?.leaseProvider)return{readiness:{status:`clear`},runtimeResult:await n()};let r=await E({session:e,command:t,phase:`before-command`}),i=await n();return await E({session:e,command:t,phase:`after-command`}),{readiness:r,runtimeResult:i}}async function Z(e,t){if(!te(t))return;let n=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:`ref-refresh`})}catch(t){r({level:`warn`,phase:`android_ref_snapshot_refresh_failed`,data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return n}function Q(t){return{ok:!1,error:e(t)}}function Ke(e,t){if(!(t.kind===`ref`&&!t.node)&&(e===`click`||e===`press`))return t.point?$(t.point):void 0}function $(e){return[String(e.x),String(e.y)]}async function qe(e){let t=await Oe({...e,captureSnapshotForSession:P,refSnapshotFlagGuardResponse:he});if(t)return t;switch(e.req.command){case l.type:return await Je({...e,captureSnapshotForSession:P});case`get`:return await le(e);case`is`:return await fe(e);default:return null}}async function Je(e){let{sessionName:t,sessionStore:n}=e,r=n.get(t);return r?T(l.type,r.device)||await Ye(r)||await Xe(e,r):C()}async function Ye(e){return e.device.platform===`android`&&e.recording&&(await x({session:e})).status===`failed`?w(`COMMAND_FAILED`,`Android system dialog blocked the recording session`):null}async function Xe(t,n){let{req:r,sessionName:i,sessionStore:a}=t,o=(r.positionals??[]).join(` `),s=U(t),l=Date.now();try{let e=await E({session:n,command:r.command,phase:`before-command`}),t=await s.interactions.typeText(o,{session:i,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await E({session:n,command:r.command,phase:`after-command`});let u=Date.now(),d={...t.backendResult??{},text:t.text,delayMs:t.delayMs,...c(t.message??`Typed ${Array.from(t.text).length} chars`)};return e.status===`recovered`&&(d.warning=e.warning),j({session:n,sessionStore:a,command:r.command,positionals:r.positionals??[],flags:r.flags,result:d,responseData:d,actionStartedAt:l,actionFinishedAt:u})}catch(t){return{ok:!1,error:e(t)}}}export{qe as handleInteractionCommands};
1
+ import{S as e,_ as t,v as n}from"./sdk-contracts.js";import{j as r}from"./sdk-android-adb.js";import{_ as i,d as a,f as o,u as s}from"./sdk-batch.js";import{Dt as c,Et as l,Ot as u,S as d,_ as f,_n as p,dt as m,pt as h,qn as g,rr as _,v,y}from"./tv-remote.js";import{c as b,m as x,o as S}from"./sdk-device.js";import{t as ee}from"./timeouts.js";import{t as te}from"./runtime.js";import{C as ne,c as C,f as w,i as re,l as T,n as E,o as ie,r as ae,s as D}from"./context.js";import{$t as O,At as k,Kt as oe,Qt as se,Xt as ce,Yt as A,dn as le,en as ue,jt as de,m as fe,qt as pe,tn as me}from"./internal/daemon.js";import{_ as j,c as he,d as ge,f as _e,g as M,h as ve,l as ye,m as be,n as xe,o as Se,p as Ce,r as we,s as Te,u as Ee,v as De,y as N}from"./selector-runtime.js";import{i as P,n as F,r as Oe,t as I}from"./interaction-snapshot.js";const ke=new Set(o());function Ae(e){return Me({fields:je(e.command),input:e.input??{},data:e.data,controlledFields:ke})}function je(e){let t=i(e);if(!t)throw Error(`Missing response data transform descriptor for ${e}`);return t.fields}function Me(e){let t=Object.fromEntries(Object.entries(e.data??{}).filter(([t])=>!e.controlledFields.has(t)));for(let[n,r]of Object.entries(e.fields)){let i=e.input[n]===void 0?r.defaultValue:e.input[n];if(i===void 0||r.omitDefault===!0&&i===r.defaultValue){delete t[n];continue}t[n]=i}return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0))}const Ne=new Set([`currentUptimeMs`,`gestureEndUptimeMs`,`gestureStartUptimeMs`,`sequenceResults`]);function Pe(e){if(e)return Object.fromEntries(Object.entries(e).filter(([e])=>!Ne.has(e)))}const Fe={source:`direct-ios`,kind:`not-observed`};function L(e){let{source:t,referenceFrame:n,extra:r}=e;if(t.kind===`runner-payload`){let e={targetKind:t.targetKind,...t.maestroFallbackUsed?{}:{resolution:Fe},...r??{}};return{result:z({data:t.data,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e}),responseData:z({data:t.publicData,fallbackX:t.point.x,fallbackY:t.point.y,referenceFrame:n,extra:e})}}let{result:i}=t,a=_e(i),o={targetKind:i.kind,...a,...Re(i.settle,e.settleRefsGeneration),...r??{}},s=z({data:i.backendResult,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:{...o,...Le(i)}}),c=z({data:t.publicData,fallbackX:i.point?.x,fallbackY:i.point?.y,referenceFrame:n,extra:o}),l=ze(`warning`in i?i.warning:void 0,e.staleRefsWarning);return l&&(s.warning=l,c.warning=l),{result:s,responseData:c,...Ie(i)}}function Ie(e){let t=R(e)?.node??(`node`in e?e.node:void 0),n=`preActionNodes`in e?e.preActionNodes:void 0;return t&&n?{recordedTarget:{node:t,preActionNodes:n}}:{}}function Le(e){let t=R(e);return t?{selectorChain:t.selectorChain,refLabel:t.refLabel}:{}}function R(e){return`recordingTarget`in e?e.recordingTarget:void 0}function Re(e,t){return!e?.diff||t===void 0?{}:{settle:{...e,refsGeneration:t}}}function ze(e,t){return t?e?`${e} ${t}`:t:e}function z(e){let{data:t,fallbackX:n,fallbackY:r,referenceFrame:i,extra:a}=e,o=Ve(a,n,r)??(typeof t?.message==`string`?t.message:void 0);return Be({...t??{},...n===void 0||r===void 0?{}:{x:n,y:r},...i??{},...a??{},...g(o)})}function Be(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function Ve(e,t,n){let r=B(e,`text`);if(r!==void 0)return`Filled ${Array.from(r).length} chars`;let i=He(t,n),a=Ue(e);if(a)return Ge(a,e??{},i);if(i)return We(e,i)}function B(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function He(e,t){return e===void 0||t===void 0?``:` (${e}, ${t})`}function Ue(e){let t=B(e,`ref`);return t===void 0?B(e,`selector`):`@${t}`}function We(e,t){return e?.gesture===`longpress`?`Long pressed${t}`:`Tapped${t}`}function Ge(e,t,n){let r=typeof t.button==`string`?t.button:void 0;return t.gesture===`longpress`?`Long pressed ${e}${n}`:r&&r!==`primary`?`Clicked ${r} ${e}${n}`:`Tapped ${e}${n}`}function V(e,t){return!b(e.device)||e.surface!==`desktop`&&e.surface!==`menubar`||e.surface===`menubar`&&(t===`click`||t===`press`)?null:D(`UNSUPPORTED_OPERATION`,`${t} is not supported on macOS ${e.surface} sessions yet. Open an app session to act, or use the ${e.surface} surface to inspect.`)}function H(e){let n=e.sessionStore.get(e.sessionName);if(!n)throw new t(`SESSION_NOT_FOUND`,ie);return te({backend:Ke({...e,session:n}),...Se(`interaction commands`,{plural:!0}),sessions:oe({sessionName:e.sessionName,getSession:()=>n,recordOptions:{includeSnapshot:!0,omitRefFrameSnapshot:e.req.internal?.findResolvedTarget===!0},setRecord:t=>{t.snapshot&&(ce(n,t.snapshot),e.sessionStore.set(e.sessionName,n))}})})}function Ke(e){let{req:t,session:n}=e,r=qe(n);return{platform:x(n.device),captureSnapshot:async(r,i)=>({snapshot:await e.captureSnapshotForSession(n,t.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:i?.interactiveOnly===!0,includeRects:i?.includeRects===!0})}),resolveGestureViewport:async()=>e.pairedGestureViewport??await re(n.device,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)),tap:async(r,i)=>(O(n),U(await E(n.device,`press`,[String(i.x),String(i.y)],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))),tapTarget:r?.clickRef?async(e,t)=>(O(n),await r.clickRef?.(t.ref),{ref:M(t.ref)}):void 0,fill:async(r,i,a)=>(O(n),U(await E(n.device,`fill`,[String(i.x),String(i.y),a],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))),fillTarget:r?.fillRef?async(e,t,i,a)=>(O(n),await r.fillRef?.(t.ref,i,a),{ref:M(t.ref),text:i,delayMs:a?.delayMs??0}):void 0,longPress:async(r,i,a)=>(O(n),U(await E(n.device,`longpress`,[String(i.x),String(i.y),...a?.durationMs===void 0?[]:[String(a.durationMs)]],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))),performGesture:async(r,i)=>(O(n),U(await ae(n.device,i,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath)))),typeText:async(r,i)=>(O(n),U(await E(n.device,`type`,[i],t.flags?.out,e.contextFromFlags(t.flags,n.appBundleId,n.trace?.outPath))))}}function qe(e){if(e.device.platform!==`web`)return;let t=fe();return t.clickRef||t.fillRef?t:void 0}function U(e){return e&&typeof e==`object`?e:void 0}function W(e){let t=e.ref.startsWith(`@`)?e.ref.slice(1):e.ref,n=se({session:e.session,refBody:t,mintedGeneration:e.mintedGeneration});if(n.admitted)return null;let r=me(e.session);return D(`COMMAND_FAILED`,Ye(n.reason,e.ref),{reason:n.reason,ref:e.ref,currentGeneration:ue(e.session),scope:r===`all`?`all`:Array.from(r),...e.mintedGeneration===void 0?{}:{mintedGeneration:e.mintedGeneration},hint:e.staleRefsWarning??Je})}const Je=`Capture a fresh interactive snapshot (snapshot -i) or use a stable selector, then retry.`;function Ye(e,t){switch(e){case`ref_frame_expired`:return`Ref ${t} belongs to an expired ref frame — a device action since the snapshot invalidated it`;case`ref_generation_mismatch`:return`Ref ${t} was minted from a superseded snapshot generation`;case`plain_ref_requires_complete_frame`:return`Ref ${t} needs a complete snapshot — the current frame only authorizes its emitted refs`;case`ref_not_issued`:return`Ref ${t} was not issued by the current ref frame`}}async function Xe(e){switch(e.req.command){case`press`:return await G(e,`press`);case`click`:return await G(e,`click`);case`longpress`:return await G(e,`longpress`);case`fill`:return await ct(e);default:return null}}async function G(e,t){let{req:n,sessionName:r,sessionStore:i}=e,a=i.get(r);if(!a)return C();let o=t===`click`?`click`:t,s=t===`longpress`?`longpress`:`press`,d=V(a,o);if(d)return d;let f=T(s,a.device);if(f)return f;let p=N(t,n.flags);if(p)return p;let m=u(n.flags),h=l(m);if(t!==`longpress`&&m!==`primary`){let e=c({commandLabel:o,platform:x(a.device),button:m,count:n.flags?.count,intervalMs:n.flags?.intervalMs,holdMs:n.flags?.holdMs,jitterPx:n.flags?.jitterPx,doubleTap:n.flags?.doubleTap});if(e)return D(e.code,e.message,e.details)}let g=t===`longpress`?be(n.positionals??[]):ve(n.positionals??[],o);if(!g.ok)return g.response;let _=g.target.kind===`ref`&&n.internal?.findResolvedTarget!==!0?A({session:a,ref:g.target.ref,mintedGeneration:g.refGeneration}):void 0,v;if(g.target.kind===`ref`){let r=e.refSnapshotFlagGuardResponse(t===`longpress`?`longpress`:`press`,n.flags);if(r)return r;let i=n.internal?.findResolvedTarget?null:W({session:a,ref:g.target.ref,mintedGeneration:g.refGeneration,staleRefsWarning:_});if(i)return i;v=await Z(e,a)}let y=n.internal?.replayTargetGuard,b=y?null:tt({session:a,commandLabel:o,target:g.target,flags:n.flags});if(b){let t=await rt(e,a,b);if(t)return t}let S=t===`longpress`?g.durationMs:void 0;return await X(e,{androidFreshnessBaseline:v,refContext:g.target.kind===`ref`&&n.internal?.findResolvedTarget!==!0?{ref:g.target.ref,mintedGeneration:g.refGeneration,staleRefsWarning:_}:void 0,run:async e=>await Ze({runtime:e,command:t,target:g.target,sessionName:r,requestId:n.meta?.requestId,clickButton:m,flags:n.flags,durationMs:S,expectedResolvedTarget:y}),afterRun:async e=>{a.lease?.leaseProvider||await ye(a,ge(g.target,e))},buildPayloads:async r=>{let i=et(r);return await Qe({params:e,session:a,result:r,staleRefsWarning:_,publicData:Y({session:a,command:t===`longpress`?void 0:t,flags:n.flags,data:r.backendResult}),extra:t===`longpress`?{...i===void 0?{}:{durationMs:i},gesture:`longpress`}:h})}})}async function Ze(e){let{runtime:t,command:n,target:r,sessionName:i,requestId:a,flags:o,expectedResolvedTarget:s}=e,c=j(o);if(n===`longpress`)return await t.interactions.longPress(r,{session:i,requestId:a,durationMs:e.durationMs,settle:c,expectedResolvedTarget:s});let l={session:i,requestId:a,button:e.clickButton,count:o?.count,intervalMs:o?.intervalMs,holdMs:o?.holdMs,jitterPx:o?.jitterPx,doubleTap:o?.doubleTap,verify:o?.verify,settle:c,expectedResolvedTarget:s};return n===`click`?await t.interactions.click(r,l):await t.interactions.press(r,l)}async function Qe(e){let{params:t,session:n,result:r,publicData:i,extra:a}=e,o=r.kind===`point`?await Oe({session:n,flags:t.req.flags,sessionStore:t.sessionStore,contextFromFlags:t.contextFromFlags,captureSnapshotForSession:t.captureSnapshotForSession}):F(n.snapshot?.nodes??[]);return L({source:{kind:`runtime`,result:r,publicData:i},referenceFrame:o,extra:a,staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:K(n,r)})}function K(e,t){if(t.settle?.diff)return pe(e,$e(t.settle)),e.snapshotGeneration}function $e(e){let t=[];for(let n of e.diff?.lines??[])n.ref&&t.push(n.ref);for(let n of e.refs??[])t.push(n.ref);for(let n of e.tail??[])t.push(n.ref);return t}function et(e){return`durationMs`in e?e.durationMs:void 0}function tt(e){let{session:t,commandLabel:n,target:r,flags:i}=e;return n!==`click`||r.kind!==`selector`||t.recordSession||nt(i)||a(n)&&i?.verify===!0||s(n)&&i?.settle===!0?null:q(t,r.selector,i)}function q(e,t,n){let r=he({session:e,selectorExpression:t});return r?{...r,...n?.maestro?.allowNonHittableCoordinateFallback?{allowNonHittableCoordinateFallback:!0}:{},...n?.maestro?.expectedTapPoint?{expectedPoint:n.maestro.expectedTapPoint}:{}}:null}function nt(e){return e?.count!==void 0||e?.intervalMs!==void 0||e?.holdMs!==void 0||e?.jitterPx!==void 0||e?.doubleTap!==void 0||e?.clickButton!==void 0&&e.clickButton!==`primary`}async function rt(e,t,n){return await J({params:e,session:t,selector:n,command:`press`,positionals:[],extra:{selector:n.raw},fallbackPhase:`ios_direct_selector_tap_fallback`})}async function J(t){let{params:n,session:i,selector:a,command:o,positionals:s,extra:c,fallbackPhase:l}=t,u=Date.now();O(i);try{let e=await E(i.device,o,s,n.req.flags?.out,{...n.contextFromFlags(n.req.flags,i.appBundleId,i.trace?.outPath),directElementSelector:a,surface:i.surface})??{},t=Date.now(),r=ot(e),l=Y({session:i,command:it(n.req.command,o),flags:n.req.flags,data:e}),d=at(a,e),{result:f,responseData:p}=L({source:{kind:`runner-payload`,targetKind:`selector`,data:e,publicData:l,point:r,maestroFallbackUsed:d.maestroNonHittableCoordinateFallbackUsed===!0},referenceFrame:st(e),extra:{...c,...d}});return P({session:i,sessionStore:n.sessionStore,command:n.req.command,positionals:n.req.positionals??[],retryPositionals:Q(r),flags:n.req.flags,result:f,responseData:p,actionStartedAt:u,actionFinishedAt:t})}catch(t){return Te(t,{delegateSemanticFailures:a.allowNonHittableCoordinateFallback!==!0})?(r({level:`debug`,phase:l,data:{selector:a.raw,error:t instanceof Error?t.message:String(t)}}),null):{ok:!1,error:e(t)}}}function Y(e){let t=S(e.session.device.platform)?Pe(e.data):e.data;return e.command?Ae({command:e.command,input:e.flags,data:t}):t}function it(e,t){return e===`click`||e===`press`||e===`fill`?e:t}function at(e,t){if(!e.allowNonHittableCoordinateFallback)return{};let n=t.maestroNonHittableCoordinateFallbackUsed===!0;return{maestroNonHittableCoordinateFallbackAllowed:!0,maestroNonHittableCoordinateFallbackUsed:n,...n?{maestroFallbackReason:`non-hittable-coordinate`}:{}}}function ot(e){let t=typeof e.x==`number`?e.x:void 0,n=typeof e.y==`number`?e.y:void 0;return t!==void 0&&n!==void 0?{x:t,y:n}:{x:0,y:0}}function st(e){return typeof e.referenceWidth==`number`&&typeof e.referenceHeight==`number`?{referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight}:void 0}async function ct(e){let{req:t,sessionName:n,sessionStore:r}=e,i=r.get(n);if(i){let e=V(i,`fill`);if(e)return e;let t=T(`fill`,i.device);if(t)return t}if(!i)return C();let a=N(`fill`,t.flags);if(a)return a;let o=Ce(t.positionals??[]);if(!o.ok)return o.response;let s=await lt(e,i,o.target,o.refGeneration);if(s.response)return s.response;let{staleRefsWarning:c}=s,l=t.internal?.replayTargetGuard;return(l?null:await ut(e,i,o.target,o.text))||await X(e,{refContext:o.target.kind===`ref`&&t.internal?.findResolvedTarget!==!0?{ref:o.target.ref,mintedGeneration:o.refGeneration,staleRefsWarning:c}:void 0,run:async e=>await e.interactions.fill(o.target,o.text,{session:n,requestId:t.meta?.requestId,delayMs:t.flags?.delayMs,verify:t.flags?.verify,settle:j(t.flags),expectedResolvedTarget:l}),buildPayloads:e=>dt({session:i,result:e,text:o.text,flags:t.flags,staleRefsWarning:c})})}async function lt(e,t,n,r){if(n.kind!==`ref`)return{};let i=e.req.internal?.findResolvedTarget===!0?void 0:A({session:t,ref:n.ref,mintedGeneration:r}),a=e.refSnapshotFlagGuardResponse(`fill`,e.req.flags);if(a)return{response:a,staleRefsWarning:i};let o=e.req.internal?.findResolvedTarget?null:W({session:t,ref:n.ref,mintedGeneration:r,staleRefsWarning:i});return o?{response:o,staleRefsWarning:i}:(await Z(e,t),{staleRefsWarning:i})}async function ut(e,t,n,r){let i=ft({session:t,target:n,flags:e.req.flags});return i?await pt(e,t,i,r):null}function dt(e){let{session:t,result:n}=e,r=n.kind===`point`?void 0:F(t.snapshot?.nodes??[]);return L({source:{kind:`runtime`,result:n,publicData:Y({session:t,command:`fill`,flags:e.flags,data:n.backendResult})},referenceFrame:r,extra:{text:e.text},staleRefsWarning:e.staleRefsWarning,settleRefsGeneration:K(t,n)})}function ft(e){let{session:t,target:n,flags:r}=e;return n.kind!==`selector`||t.recordSession||a(`fill`)&&r?.verify===!0||s(`fill`)&&r?.settle===!0?null:q(t,n.selector,r)}async function pt(e,t,n,r){return await J({params:e,session:t,selector:n,command:`fill`,positionals:[r],extra:{selector:n.raw,text:r},fallbackPhase:`ios_direct_selector_fill_fallback`})}async function X(e,t){let r=e.sessionStore.get(e.sessionName);if(!r)return C();let i=H(e),a=Date.now();try{let n=await mt(r,e.req.command,{refContext:t.refContext},async()=>{let e=await t.run(i);return await t.afterRun?.(e),e});if(n.aborted)return n.response;let{readiness:o,runtimeResult:s}=n,c=Date.now(),{result:l,responseData:u,recordedTarget:d}=await t.buildPayloads(s);if(o.status===`recovered`){let e=typeof u.warning==`string`?`${u.warning} ${o.warning}`:o.warning;l.warning=e,u.warning=e}return P({session:r,sessionStore:e.sessionStore,command:e.req.command,positionals:e.req.positionals??[],retryPositionals:gt(e.req.command,s),flags:e.req.flags,result:l,responseData:u,recordedTarget:d,actionStartedAt:a,actionFinishedAt:c,androidFreshnessBaseline:t.androidFreshnessBaseline})}catch(e){let t=n(e);if(Ee(t))throw t;return ht(e)}}async function mt(e,t,n,r){if(e.lease?.leaseProvider)return{aborted:!1,readiness:{status:`clear`},runtimeResult:await r()};let i=await k({session:e,command:t,phase:`before-command`});if(n.refContext&&i.status===`recovered`){let t=W({session:e,ref:n.refContext.ref,mintedGeneration:n.refContext.mintedGeneration,staleRefsWarning:n.refContext.staleRefsWarning});if(t)return{aborted:!0,response:t}}let a=await r();return await k({session:e,command:t,phase:`after-command`}),{aborted:!1,readiness:i,runtimeResult:a}}async function Z(e,t){if(!le(t))return;let n=t.snapshot?.comparisonSafe===!0?t.snapshot:void 0;try{await e.captureSnapshotForSession(t,e.req.flags,e.sessionStore,e.contextFromFlags,{interactiveOnly:!0,androidFreshnessMode:`ref-refresh`})}catch(t){r({level:`warn`,phase:`android_ref_snapshot_refresh_failed`,data:{command:e.req.command,error:t instanceof Error?t.message:String(t)}})}return n}function ht(t){return{ok:!1,error:e(t)}}function gt(e,t){if(!(t.kind===`ref`&&!t.node)&&(e===`click`||e===`press`))return t.point?Q(t.point):void 0}function Q(e){return[String(e.x),String(e.y)]}async function _t(e){return await bt(e,`gesture`,async t=>{let n=d(e.req.input),r=v(n);r.gesture.intent===`pan`&&e.req.internal?.gestureExecutionProfile&&(r.gesture.executionProfile=e.req.internal.gestureExecutionProfile),w(r.gesture,t.device);let i=await yt(e).interactions.gesture({session:e.sessionName,requestId:e.req.meta?.requestId,gesture:r.gesture});return{positionals:f(n),flags:Ot(n,e.req.flags),responseData:St(i,{executionProfile:xt(r.gesture)}),...n.kind===`pinch`?{recordingResultExtra:{scale:n.scale}}:{}}})}async function vt(e){return await bt(e,`swipe`,async t=>{let n=Ct(e.req.input);w(y(n).gesture,t.device);let r=n.count??1,i=n.pauseMs??0,a=n.pattern??`one-way`,o=await Et(yt(e),e,n,r,i,a);return{positionals:Tt(n),flags:e.req.flags,responseData:St(o,{from:n.from,to:n.to,x1:n.from.x,y1:n.from.y,x2:n.to.x,y2:n.to.y,effectiveDurationMs:o.durationMs,timingMode:`direct`,executionProfile:`endpoint-hold`,count:r,pauseMs:i,pattern:a})}})}function yt(e){return H({...e,pairedGestureViewport:e.req.internal?.gestureViewport})}async function bt(t,n,r){let i=t.sessionStore.get(t.sessionName);if(!i)return C();let a=Date.now();try{let e=ne(i.device),o=e?{status:`clear`}:await k({session:i,command:n,phase:`before-command`}),s=await r(i);e||await k({session:i,command:n,phase:`after-command`});let c={...s.responseData};return o.status===`recovered`&&(c.warning=`${typeof c.warning==`string`?`${c.warning} `:``}${o.warning}`),P({session:i,sessionStore:t.sessionStore,command:n,actionCommand:n,positionals:s.positionals,flags:s.flags,result:{...c,...s.recordingResultExtra??{}},responseData:c,actionStartedAt:a,actionFinishedAt:Date.now()})}catch(t){return{ok:!1,error:e(t)}}}function xt(e){if(e.intent===`fling`)return`endpoint-hold`;if(e.intent===`pan`)return e.executionProfile??`timed-pan`}function St(e,t={}){let n=typeof t.executionProfile==`string`?t.executionProfile:void 0;return{kind:e.kind,durationMs:e.durationMs,pointerCount:e.pointerCount,from:e.from,to:e.to,...e.backendResult??{},...t,...n?{timing:{executionProfile:n,gestureDurationMs:e.durationMs}}:{},message:e.message}}function Ct(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`swipe requires structured object input`);let n=e;if(n.durationMs!==void 0)throw new t(`INVALID_ARGS`,`swipe does not accept durationMs; use gesture pan for timed movement`);let r=n.pattern;if(r!==void 0&&r!==`one-way`&&r!==`ping-pong`)throw new t(`INVALID_ARGS`,`swipe pattern must be one-way or ping-pong`);let i={from:$(n.from,`swipe from`),to:$(n.to,`swipe to`),count:p(n,`count`,{min:1,max:200}),pauseMs:p(n,`pauseMs`,{min:0,max:m}),pattern:r};return wt(i),i}function wt(e){let n=e.count??1,r=e.pauseMs??0,i=n*100+Math.max(0,n-1)*r;if(!(i<=6e4))throw new t(`INVALID_ARGS`,`Swipe series must fit within ${h}ms.`,{count:n,pauseMs:r,gestureDurationMs:100,scheduledDurationMs:i,hint:`Reduce --count or --pause-ms.`})}function $(e,n){if(!e||typeof e!=`object`||Array.isArray(e))throw new t(`INVALID_ARGS`,`${n} must be a point`);let r=e;if(typeof r.x!=`number`||!Number.isFinite(r.x))throw new t(`INVALID_ARGS`,`${n} x must be finite`);if(typeof r.y!=`number`||!Number.isFinite(r.y))throw new t(`INVALID_ARGS`,`${n} y must be finite`);return{x:r.x,y:r.y}}function Tt(e){return[String(e.from.x),String(e.from.y),String(e.to.x),String(e.to.y)]}async function Et(e,t,n,r,i,a){let o;for(let s=0;s<r;s+=1){let c=y(Dt(n,a,s));o=await e.interactions.gesture({session:t.sessionName,requestId:t.req.meta?.requestId,gesture:c.gesture}),i>0&&s+1<r&&await ee(i)}if(!o)throw Error(`Swipe orchestration did not execute a gesture.`);return o}function Dt(e,t,n){return t===`ping-pong`&&n%2==1?{...e,from:e.to,to:e.from}:e}function Ot(e,t){return e.kind!==`pan`||e.pointerCount===void 0?t:{...t,pointerCount:e.pointerCount}}async function kt(e){let t=await Xe({...e,captureSnapshotForSession:I,refSnapshotFlagGuardResponse:De});if(t)return t;switch(e.req.command){case _.gesture:return await _t({...e,captureSnapshotForSession:I});case _.swipe:return await vt({...e,captureSnapshotForSession:I});case _.type:return await At({...e,captureSnapshotForSession:I});case`get`:return await xe(e);case`is`:return await we(e);default:return null}}async function At(e){let{sessionName:t,sessionStore:n}=e,r=n.get(t);return r?T(_.type,r.device)||await jt(r)||await Mt(e,r):C()}async function jt(e){return e.device.platform===`android`&&e.recording&&(await de({session:e})).status===`failed`?D(`COMMAND_FAILED`,`Android system dialog blocked the recording session`):null}async function Mt(t,n){let{req:r,sessionName:i,sessionStore:a}=t,o=(r.positionals??[]).join(` `),s=H(t),c=Date.now();try{let e=await k({session:n,command:r.command,phase:`before-command`}),t=await s.interactions.typeText(o,{session:i,requestId:r.meta?.requestId,delayMs:r.flags?.delayMs});await k({session:n,command:r.command,phase:`after-command`});let l=Date.now(),u={...t.backendResult??{},text:t.text,delayMs:t.delayMs,...g(t.message??`Typed ${Array.from(t.text).length} chars`)};return e.status===`recovered`&&(u.warning=e.warning),P({session:n,sessionStore:a,command:r.command,positionals:r.positionals??[],flags:r.flags,result:u,responseData:u,actionStartedAt:c,actionFinishedAt:l})}catch(t){return{ok:!1,error:e(t)}}}export{kt as handleInteractionCommands};
@@ -1,2 +1,2 @@
1
- import{_ as e}from"./sdk-contracts.js";import{F as t}from"./sdk-android-adb.js";import{_t as n,a as r,mt as i,ot as a,st as o}from"./tv-remote.js";import{c as s,d as c,s as l}from"./sdk-device.js";import{n as u}from"./snapshot-quality.js";import{i as d}from"./runner-client.js";import{o as f}from"./helper.js";import{c as p,i as m,n as h,o as g,r as _,s as v,u as y}from"./apps.js";import{n as b,t as x}from"./runner-sequence.js";function S(e,t,n){return{command:`remotePress`,remoteButton:e,...n===void 0?{}:{durationMs:n},...t===void 0?{}:{appBundleId:t}}}function C(e,t,n,r={includeDuration:!0}){let i=T(e.referenceWidth),a=T(e.referenceHeight);if(i===void 0||a===void 0)return E(e,{amount:n?.amount});let s=o({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:i,referenceHeight:a});return E(e,{amount:n?.amount,pixels:s.pixels,durationMs:r?.includeDuration?n?.durationMs:void 0,preferProvidedPixels:!0})}function w(e,t={includeDuration:!0}){return{...e?.amount===void 0?{}:{amount:e.amount},...e?.pixels===void 0?{}:{pixels:e.pixels},...t?.includeDuration&&e?.durationMs!==void 0?{durationMs:e.durationMs}:{}}}function T(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function E(e,t){let{x1:n,y1:r,x2:i,y2:a}=O(e),o=T(e.referenceWidth),s=T(e.referenceHeight),c=D(t,n!==void 0&&i!==void 0?Math.round(Math.abs(i-n)):void 0,r!==void 0&&a!==void 0?Math.round(Math.abs(a-r)):void 0);return{...n===void 0?{}:{x1:n},...r===void 0?{}:{y1:r},...i===void 0?{}:{x2:i},...a===void 0?{}:{y2:a},...o===void 0?{}:{referenceWidth:o},...s===void 0?{}:{referenceHeight:s},...t?.amount===void 0?{}:{amount:t.amount},...c===void 0?{}:{pixels:c},...t?.durationMs===void 0?{}:{durationMs:t.durationMs}}}function D(e,t,n){if(e?.preferProvidedPixels&&e.pixels!==void 0)return e.pixels;if(t!==void 0&&t>0)return t;if(n!==void 0&&n>0)return n}function O(e){let t=T(e.x),n=T(e.y),r=T(e.x2),i=T(e.y2);return{...t===void 0?{}:{x1:t},...n===void 0?{}:{y1:n},...r===void 0?{}:{x2:r},...i===void 0?{}:{y2:i}}}async function k(e,t,n,r,i,a){return C(await e(t,{command:`desktopScroll`,direction:i,...w(a,{includeDuration:!0}),appBundleId:n.appBundleId},r),i,a,{includeDuration:!0})}function A(e){return e===`system`?`backSystem`:`backInApp`}function j(e,t){let n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId,iosXctestrunFile:t.iosXctestrunFile,iosXctestDerivedDataPath:t.iosXctestDerivedDataPath,iosXctestEnvDir:t.iosXctestEnvDir,runnerLeaseContext:t.runnerLeaseContext};return{runnerOpts:n,overrides:{tap:async(r,i)=>await d(e,M(e,t,r,i),n),tapElementSelector:async r=>await d(e,{command:`tap`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},n),doubleTap:async(r,i)=>{let a=await d(e,x([{kind:`doubleTap`,x:r,y:i}],t.appBundleId),n);return b(a),a},swipe:async(r,i,a,o,s)=>await d(e,P(e,t,r,i,a,o,s,{defaultDurationMs:250,synthesized:N(e),dragSemantics:`swipe`}),n),pan:async(r,i,a,o,s)=>await d(e,P(e,t,r,i,a,o,s,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:N(e),dragSemantics:`pan`}),n),fling:async(r,i,a,o,s)=>await d(e,P(e,t,r,i,a,o,s,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:N(e),dragSemantics:`fling`}),n),longPress:async(r,i,a)=>await d(e,{command:`longPress`,x:r,y:i,durationMs:a,appBundleId:t.appBundleId},n),focus:async(r,i)=>await d(e,M(e,t,r,i),n),type:async(r,i)=>{await d(e,{command:`type`,text:r,delayMs:i,textEntryMode:r===`
2
- `?void 0:`append`,appBundleId:t.appBundleId},n)},fillElementSelector:async(r,i,a)=>await d(e,{command:`type`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,text:i,delayMs:a,textEntryMode:`replace`,appBundleId:t.appBundleId},n),fill:async(r,i,a,o)=>await d(e,{command:`type`,x:r,y:i,text:a,delayMs:o,textEntryMode:`replace`,appBundleId:t.appBundleId},n),scroll:async(r,i)=>await I(d,e,t,n,r,i),pinch:async(r,i,a)=>{await d(e,{command:`pinch`,scale:r,x:i,y:a,appBundleId:t.appBundleId},n)},rotateGesture:async(r,i,a,o)=>{await d(e,{command:`rotateGesture`,degrees:r,x:i,y:a,velocity:o,appBundleId:t.appBundleId},n)},transformGesture:async r=>await d(e,{command:`transformGesture`,x:r.x,y:r.y,dx:r.dx,dy:r.dy,scale:r.scale,degrees:r.degrees,durationMs:r.durationMs,appBundleId:t.appBundleId},n)}}}function M(e,t,n,r){return{command:`tap`,x:n,y:r,...N(e)?{synthesized:!0}:{},appBundleId:t.appBundleId}}function N(e){return l(e)&&!c(e)}function P(e,t,n,r,i,a,o,s){let u=l(e)&&!c(e)?F(o,s.defaultDurationMs):o??s.legacyDefaultDurationMs;return{command:`drag`,x:n,y:r,x2:i,y2:a,...u===void 0?{}:{durationMs:u},...s.synthesized===!0?{synthesized:!0,dragSemantics:s.dragSemantics}:{},appBundleId:t.appBundleId}}function F(e,t){return e===void 0?t:Math.min(1e4,Math.max(16,Math.round(e)))}async function I(e,t,r,o,l,u){return n(u?.durationMs,{invalidMessage:`scroll durationMs must be a non-negative integer at most ${i}`}),c(t)?E(await e(t,S(l,r.appBundleId,u?.durationMs),o),{amount:u?.amount,durationMs:u?.durationMs}):(a(u??{}),s(t)?await k(e,t,r,o,l,u):C(await e(t,{command:`scroll`,direction:l,...w(u),appBundleId:r.appBundleId},o),l,u))}function L(n,i){if(n.appleOs===`watchos`)throw new e(`UNSUPPORTED_PLATFORM`,`watchOS is not supported: XCUITest cannot drive watchOS UI, so this device has no runner backend.`);let{overrides:a,runnerOpts:o}=j(n,i);return{open:(e,t)=>v(n,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,terminateRunningApp:t?.terminateRunningApp,url:t?.url}),openDevice:()=>p(n),close:e=>g(n,e),screenshot:(e,t)=>R(n,e,t,o),snapshot:async r=>{let i=B(await t(`snapshot_capture`,async()=>await d(n,{command:`snapshot`,appBundleId:r?.appBundleId,interactiveOnly:r?.interactiveOnly,depth:r?.depth,scope:r?.scope,raw:r?.raw},o),{backend:`xctest`})),a=i.nodes??[];if(a.length===0&&n.kind===`simulator`)throw new e(`COMMAND_FAILED`,`XCTest snapshot returned 0 nodes on iOS simulator.`);return{nodes:a,truncated:i.truncated??!1,backend:`xctest`,...i.quality?{quality:i.quality}:{},...!i.quality&&i.message?{warnings:[i.message]}:{}}},back:async e=>{if(c(n)){await d(n,S(`menu`,i.appBundleId),o);return}await d(n,{command:A(e),appBundleId:i.appBundleId},o)},home:async()=>{if(c(n)){await d(n,S(`home`,i.appBundleId),o);return}await d(n,{command:`home`,appBundleId:i.appBundleId},o)},rotate:async e=>{await d(n,{command:`rotate`,orientation:e,appBundleId:i.appBundleId},o)},appSwitcher:async()=>{await d(n,{command:`appSwitcher`,appBundleId:i.appBundleId},o)},tvRemote:async(e,t)=>{await d(n,S(r(e),i.appBundleId,t),o)},readClipboard:()=>_(n),writeClipboard:e=>m(n,e),setSetting:(e,t,r,i)=>h(n,e,t,r,i),...a}}async function R(e,t,n={},r){if(z(e,n.surface)){await f(t,{surface:n.surface,fullscreen:n.fullscreen});return}await y(e,t,{appBundleId:n.appBundleId,pixelDensity:n.pixelDensity,fullscreen:n.fullscreen,runnerOptions:r,normalizeStatusBar:n.normalizeStatusBar,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck})}function z(e,t){return s(e)&&t!==void 0&&t!==`app`}function B(e){return{nodes:Array.isArray(e.nodes)?e.nodes:void 0,truncated:typeof e.truncated==`boolean`?e.truncated:void 0,quality:u(e.snapshotQuality),message:typeof e.message==`string`&&e.message.trim().length>0?e.message:void 0}}export{L as createAppleInteractor};
1
+ import{_ as e}from"./sdk-contracts.js";import{F as t}from"./sdk-android-adb.js";import{a as n,gt as r,mt as i,wt as a,xt as o}from"./tv-remote.js";import{c as s,d as c,s as l}from"./sdk-device.js";import{n as u}from"./snapshot-quality.js";import{a as d}from"./runtime.js";import{t as f}from"./apple-multitouch-support.js";import{o as p}from"./helper.js";import{a as m}from"./runner-client.js";import{a as h,c as g,i as _,l as v,n as y,o as b,r as x,s as S}from"./apps.js";import{n as C,t as w}from"./runner-sequence.js";function T(e,t,n){return{command:`remotePress`,remoteButton:e,...n===void 0?{}:{durationMs:n},...t===void 0?{}:{appBundleId:t}}}function E(e,t,n,i={includeDuration:!0}){let a=O(e.referenceWidth),o=O(e.referenceHeight);if(a===void 0||o===void 0)return k(e,{amount:n?.amount});let s=r({direction:t,amount:n?.amount,pixels:n?.pixels,referenceWidth:a,referenceHeight:o});return k(e,{amount:n?.amount,pixels:s.pixels,durationMs:i?.includeDuration?n?.durationMs:void 0,preferProvidedPixels:!0})}function D(e,t={includeDuration:!0}){return{...e?.amount===void 0?{}:{amount:e.amount},...e?.pixels===void 0?{}:{pixels:e.pixels},...t?.includeDuration&&e?.durationMs!==void 0?{durationMs:e.durationMs}:{}}}function O(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function k(e,t){let{x1:n,y1:r,x2:i,y2:a}=j(e),o=O(e.referenceWidth),s=O(e.referenceHeight),c=A(t,n!==void 0&&i!==void 0?Math.round(Math.abs(i-n)):void 0,r!==void 0&&a!==void 0?Math.round(Math.abs(a-r)):void 0);return{...n===void 0?{}:{x1:n},...r===void 0?{}:{y1:r},...i===void 0?{}:{x2:i},...a===void 0?{}:{y2:a},...o===void 0?{}:{referenceWidth:o},...s===void 0?{}:{referenceHeight:s},...t?.amount===void 0?{}:{amount:t.amount},...c===void 0?{}:{pixels:c},...t?.durationMs===void 0?{}:{durationMs:t.durationMs}}}function A(e,t,n){if(e?.preferProvidedPixels&&e.pixels!==void 0)return e.pixels;if(t!==void 0&&t>0)return t;if(n!==void 0&&n>0)return n}function j(e){let t=O(e.x),n=O(e.y),r=O(e.x2),i=O(e.y2);return{...t===void 0?{}:{x1:t},...n===void 0?{}:{y1:n},...r===void 0?{}:{x2:r},...i===void 0?{}:{y2:i}}}async function M(e,t,n,r,i,a){return E(await e(t,{command:`desktopScroll`,direction:i,...D(a,{includeDuration:!0}),appBundleId:n.appBundleId},r),i,a,{includeDuration:!0})}function N(e){return e===`system`?`backSystem`:`backInApp`}function P(e,t){let n={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId,iosXctestrunFile:t.iosXctestrunFile,iosXctestDerivedDataPath:t.iosXctestDerivedDataPath,iosXctestEnvDir:t.iosXctestEnvDir,runnerLeaseContext:t.runnerLeaseContext};return{runnerOpts:n,overrides:{tap:async(r,i)=>await m(e,z(e,t,r,i),n),tapElementSelector:async r=>await m(e,{command:`tap`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,...r.expectedPoint?{x:r.expectedPoint.x,y:r.expectedPoint.y}:{},appBundleId:t.appBundleId},n),doubleTap:async(r,i)=>{let a=await m(e,w([{kind:`doubleTap`,x:r,y:i}],t.appBundleId),n);return C(a),a},longPress:async(r,i,a)=>await m(e,{command:`longPress`,x:r,y:i,durationMs:a,appBundleId:t.appBundleId},n),focus:async(r,i)=>await m(e,z(e,t,r,i),n),type:async(r,i)=>{await m(e,{command:`type`,text:r,delayMs:i,textEntryMode:r===`
2
+ `?void 0:`append`,appBundleId:t.appBundleId},n)},fillElementSelector:async(r,i,a)=>await m(e,{command:`type`,selectorKey:r.key,selectorValue:r.value,allowNonHittableCoordinateFallback:r.allowNonHittableCoordinateFallback,text:i,delayMs:a,textEntryMode:`replace`,appBundleId:t.appBundleId},n),fill:async(r,i,a,o)=>await m(e,{command:`type`,x:r,y:i,text:a,delayMs:o,textEntryMode:`replace`,appBundleId:t.appBundleId},n),scroll:async(r,i)=>await V(m,e,t,n,r,i),performGesture:async r=>await L(e,t,n,r),gestureViewport:async()=>F(await m(e,{command:`gestureViewport`,appBundleId:t.appBundleId},n))}}}function F(t){let n=I(t.x),r=I(t.y),i=I(t.x2),a=I(t.y2);if(n===void 0||r===void 0||i===void 0||a===void 0||i<=0||a<=0)throw new e(`COMMAND_FAILED`,`Apple runner returned an invalid gesture viewport`);return{x:n,y:r,width:i,height:a}}function I(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}async function L(e,t,n,r){if(r.topology===`two`&&f(e,r.intent),r.topology===`single`&&s(e)){let{start:i,end:a}=d(r);return await m(e,{command:`drag`,x:i.x,y:i.y,x2:a.x,y2:a.y,durationMs:r.durationMs,appBundleId:t.appBundleId},n)}if(r.topology===`single`&&c(e)){let{start:i,end:a}=d(r);return await m(e,{command:`swipe`,direction:R(i,a),appBundleId:t.appBundleId},n)}return await m(e,{command:`gesture`,gesturePlan:r,appBundleId:t.appBundleId},n)}function R(e,t){let n=t.x-e.x,r=t.y-e.y;return Math.abs(n)>=Math.abs(r)?n>=0?`right`:`left`:r>=0?`down`:`up`}function z(e,t,n,r){return{command:`tap`,x:n,y:r,...B(e)?{synthesized:!0}:{},appBundleId:t.appBundleId}}function B(e){return l(e)&&!c(e)}async function V(e,t,n,r,l,u){return a(u?.durationMs,{invalidMessage:`scroll durationMs must be a non-negative integer at most ${o}`}),c(t)?k(await e(t,T(l,n.appBundleId,u?.durationMs),r),{amount:u?.amount,durationMs:u?.durationMs}):(i(u??{}),s(t)?await M(e,t,n,r,l,u):E(await e(t,{command:`scroll`,direction:l,...D(u),appBundleId:n.appBundleId},r),l,u))}function H(r,i){if(r.appleOs===`watchos`)throw new e(`UNSUPPORTED_PLATFORM`,`watchOS is not supported: XCUITest cannot drive watchOS UI, so this device has no runner backend.`);let{overrides:a,runnerOpts:o}=P(r,i);return{open:(e,t)=>b(r,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,terminateRunningApp:t?.terminateRunningApp,url:t?.url}),openDevice:()=>S(r),close:e=>h(r,e),screenshot:(e,t)=>U(r,e,t,o),snapshot:async n=>{let i=G(await t(`snapshot_capture`,async()=>await m(r,{command:`snapshot`,appBundleId:n?.appBundleId,interactiveOnly:n?.interactiveOnly,depth:n?.depth,scope:n?.scope,raw:n?.raw},o),{backend:`xctest`})),a=i.nodes??[];if(a.length===0&&r.kind===`simulator`)throw new e(`COMMAND_FAILED`,`XCTest snapshot returned 0 nodes on iOS simulator.`);return{nodes:a,truncated:i.truncated??!1,backend:`xctest`,...i.quality?{quality:i.quality}:{},...!i.quality&&i.message?{warnings:[i.message]}:{}}},back:async e=>{if(c(r)){await m(r,T(`menu`,i.appBundleId),o);return}await m(r,{command:N(e),appBundleId:i.appBundleId},o)},home:async()=>{if(c(r)){await m(r,T(`home`,i.appBundleId),o);return}await m(r,{command:`home`,appBundleId:i.appBundleId},o)},setOrientation:async e=>{await m(r,{command:`rotate`,orientation:e,appBundleId:i.appBundleId},o)},appSwitcher:async()=>{await m(r,{command:`appSwitcher`,appBundleId:i.appBundleId},o)},tvRemote:async(e,t)=>{await m(r,T(n(e),i.appBundleId,t),o)},readClipboard:()=>x(r),writeClipboard:e=>_(r,e),setSetting:(e,t,n,i)=>y(r,e,t,n,i),...a}}async function U(e,t,n={},r){if(W(e,n.surface)){await p(t,{surface:n.surface,fullscreen:n.fullscreen});return}if(n.captureBackend===`runner`){await g(e,t,n.appBundleId,n.fullscreen,r);return}await v(e,t,{appBundleId:n.appBundleId,pixelDensity:n.pixelDensity,fullscreen:n.fullscreen,runnerOptions:r,normalizeStatusBar:n.normalizeStatusBar,skipIosSimulatorBootCheck:n.skipIosSimulatorBootCheck})}function W(e,t){return s(e)&&t!==void 0&&t!==`app`}function G(e){return{nodes:Array.isArray(e.nodes)?e.nodes:void 0,truncated:typeof e.truncated==`boolean`?e.truncated:void 0,quality:u(e.snapshotQuality),message:typeof e.message==`string`&&e.message.trim().length>0?e.message:void 0}}export{H as createAppleInteractor};
@@ -1,2 +1,2 @@
1
- const e=process.argv.slice(2);t(e)||(e[0]===`mcp`&&!e.includes(`--help`)&&!e.includes(`-h`)?import(`../server.js`).then(({runAgentDeviceMcpServer:e})=>e()).catch(m):p(e));function t(e){return n(e)||r(e)||i(e)}function n(e){return e.length!==1||!f(e[0])?!1:(process.stdout.write(`0.19.3
1
+ const e=process.argv.slice(2);t(e)||(e[0]===`mcp`&&!e.includes(`--help`)&&!e.includes(`-h`)?import(`../server.js`).then(({runAgentDeviceMcpServer:e})=>e()).catch(m):p(e));function t(e){return n(e)||r(e)||i(e)}function n(e){return e.length!==1||!f(e[0])?!1:(process.stdout.write(`0.20.0
2
2
  `),!0)}function r(e){return e.length===0?(import(`../cli-help.js`).then(({buildUsageText:e})=>{process.stdout.write(`${e()}\n`),process.exit(1)}).catch(m),!0):!1}function i(e){let t=a(e);return t===void 0?!1:(import(`../cli-help.js`).then(({buildCommandUsageText:n,buildUsageText:r})=>{if(t===null){process.stdout.write(`${r()}\n`);return}let i=n(l(t));if(i){process.stdout.write(i);return}p(e)}).catch(m),!0)}function a(e){switch(e.length){case 1:return o(e[0]);case 2:return s(e[0],e[1]);default:return}}function o(e){return e===`help`||d(e)?null:void 0}function s(e,t){return u(e)?t:c(e,t)}function c(e,t){return d(t)?e:void 0}function l(e){return e===`long-press`?`longpress`:e===`metrics`?`perf`:e}function u(e){return e===`help`}function d(e){return e===`--help`||e===`-h`}function f(e){return e===`--version`||e===`-V`}function p(e){import(`../cli.js`).then(({runCli:t})=>t(e)).catch(m)}function m(e){process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exit(1)}export{};