agent-device 0.17.4 → 0.17.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +2 -2
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.4.apk → agent-device-android-multitouch-helper-0.17.6.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.6.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.4.manifest.json → agent-device-android-multitouch-helper-0.17.6.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.4.apk → agent-device-android-snapshot-helper-0.17.6.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.6.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.4.manifest.json → agent-device-android-snapshot-helper-0.17.6.manifest.json} +6 -6
  8. package/dist/src/2133.js +1 -0
  9. package/dist/src/2748.js +1 -0
  10. package/dist/src/{4012.js → 2892.js} +1 -1
  11. package/dist/src/2948.js +1 -0
  12. package/dist/src/2954.js +2 -0
  13. package/dist/src/{7651.js → 3006.js} +1 -1
  14. package/dist/src/314.js +1 -0
  15. package/dist/src/{8806.js → 3340.js} +5 -5
  16. package/dist/src/4291.js +2 -0
  17. package/dist/src/{7599.js → 432.js} +1 -1
  18. package/dist/src/4418.js +1 -0
  19. package/dist/src/{2403.js → 4428.js} +1 -1
  20. package/dist/src/4723.js +1 -0
  21. package/dist/src/5299.js +1 -0
  22. package/dist/src/{113.js → 5448.js} +1 -1
  23. package/dist/src/5484.js +1 -0
  24. package/dist/src/5628.js +1 -0
  25. package/dist/src/587.js +1 -0
  26. package/dist/src/6311.js +27 -0
  27. package/dist/src/6918.js +1 -0
  28. package/dist/src/7244.js +1 -0
  29. package/dist/src/7394.js +6 -0
  30. package/dist/src/8184.js +1 -0
  31. package/dist/src/8225.js +1 -0
  32. package/dist/src/{1974.js → 8275.js} +1 -1
  33. package/dist/src/8875.js +1 -0
  34. package/dist/src/{1352.js → 9581.js} +1 -1
  35. package/dist/src/9624.js +1 -0
  36. package/dist/src/9722.js +38 -0
  37. package/dist/src/9836.js +1 -0
  38. package/dist/src/9873.js +1 -0
  39. package/dist/src/9919.js +6 -0
  40. package/dist/src/android-adb.d.ts +3 -3
  41. package/dist/src/android-adb.js +1 -1
  42. package/dist/src/android-snapshot-helper.js +1 -1
  43. package/dist/src/android.js +1 -1
  44. package/dist/src/apple.js +1 -1
  45. package/dist/src/apps.js +6 -6
  46. package/dist/src/artifacts.js +1 -1
  47. package/dist/src/batch.d.ts +4 -4
  48. package/dist/src/batch.js +1 -1
  49. package/dist/src/{args.js → cli-help.js} +18 -18
  50. package/dist/src/cli-output.js +4 -30
  51. package/dist/src/cli.js +17 -17
  52. package/dist/src/command-surface.js +1 -1
  53. package/dist/src/contracts.d.ts +6 -6
  54. package/dist/src/contracts.js +1 -1
  55. package/dist/src/devices.js +1 -1
  56. package/dist/src/find.js +1 -1
  57. package/dist/src/finders.d.ts +1 -1
  58. package/dist/src/finders.js +1 -1
  59. package/dist/src/generic.js +8 -14
  60. package/dist/src/index.d.ts +28 -25
  61. package/dist/src/index.js +1 -1
  62. package/dist/src/input-actions.js +1 -1
  63. package/dist/src/input-actions~1.js +1 -1
  64. package/dist/src/install-source.js +1 -1
  65. package/dist/src/interaction.js +1 -1
  66. package/dist/src/internal/bin.js +5 -5
  67. package/dist/src/internal/companion-tunnel.js +1 -1
  68. package/dist/src/internal/daemon.js +1 -1
  69. package/dist/src/internal/png-worker.js +1 -1
  70. package/dist/src/internal/update-check-entry.js +1 -1
  71. package/dist/src/io.js +1 -1
  72. package/dist/src/lease.js +1 -1
  73. package/dist/src/linux.js +1 -1
  74. package/dist/src/metro.js +1 -1
  75. package/dist/src/notifications.js +1 -1
  76. package/dist/src/react-native.js +1 -1
  77. package/dist/src/record-trace-recording.js +2 -2
  78. package/dist/src/record-trace.js +1 -1
  79. package/dist/src/recording-provider.js +1 -1
  80. package/dist/src/remote-config.d.ts +5 -5
  81. package/dist/src/remote-config.js +1 -1
  82. package/dist/src/rslib-runtime.js +1 -1
  83. package/dist/src/selector-runtime.js +1 -1
  84. package/dist/src/selectors.d.ts +1 -1
  85. package/dist/src/selectors.js +1 -1
  86. package/dist/src/server.js +1 -1
  87. package/dist/src/session.js +7 -7
  88. package/dist/src/snapshot.js +2 -2
  89. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +4 -0
  90. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +8 -0
  91. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +118 -10
  92. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +5 -0
  93. package/package.json +14 -13
  94. package/server.json +3 -3
  95. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.4.apk.sha256 +0 -1
  96. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.4.apk.sha256 +0 -1
  97. package/dist/src/1010.js +0 -1
  98. package/dist/src/123.js +0 -1
  99. package/dist/src/1231.js +0 -1
  100. package/dist/src/208.js +0 -1
  101. package/dist/src/221.js +0 -6
  102. package/dist/src/2415.js +0 -38
  103. package/dist/src/3675.js +0 -1
  104. package/dist/src/5611.js +0 -1
  105. package/dist/src/5827.js +0 -1
  106. package/dist/src/6088.js +0 -1
  107. package/dist/src/6133.js +0 -1
  108. package/dist/src/6629.js +0 -1
  109. package/dist/src/7556.js +0 -1
  110. package/dist/src/7719.js +0 -1
  111. package/dist/src/7847.js +0 -1
  112. package/dist/src/8133.js +0 -1
  113. package/dist/src/8656.js +0 -1
  114. package/dist/src/9010.js +0 -1
  115. package/dist/src/9471.js +0 -1
  116. package/dist/src/9542.js +0 -6
  117. package/dist/src/9616.js +0 -2
  118. package/dist/src/9639.js +0 -2
  119. package/dist/src/9671.js +0 -1
  120. package/dist/src/9818.js +0 -1
  121. package/dist/src/989.js +0 -1
  122. /package/dist/src/{2301.js → 4069.js} +0 -0
  123. /package/dist/src/{4829.js → 5560.js} +0 -0
  124. /package/dist/src/{4778.js → 6024.js} +0 -0
  125. /package/dist/src/{9152.js → 733.js} +0 -0
  126. /package/dist/src/{3267.js → 9612.js} +0 -0
@@ -1 +1 @@
1
- import{AppError as t}from"./9152.js";import{resolveAppsFilter as e}from"./3675.js";import{parseAndroidForegroundApp as i,parseAndroidLaunchablePackages as a,parseAndroidUserInstalledPackages as r,inferAndroidAppName as o,parseAndroidLaunchComponent as n,isAmStartError as d}from"./8806.js";let l="android.intent.category.LAUNCHER",s="android.intent.category.LEANBACK_LAUNCHER";async function c(t,i={}){let a=await A(t,i.target??"auto");return("user-installed"===e(i.filter)?(await p(t)).filter(t=>a.has(t)):Array.from(a)).map(t=>({package:t,name:o(t)})).sort((t,e)=>t.package.localeCompare(e.package))}async function u(t){let e=await f(t,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(e)return e;let i=await f(t,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return i||{}}async function A(t,e){return new Set((await Promise.all((function(t){switch(t){case"mobile":return[l];case"tv":return[s];default:return[l,s]}})(e).map(async e=>{var i;let r=await t(["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",e],{allowFailure:!0});return 0===r.exitCode?0===(i=r.stdout).trim().length?[]:a(i):[]}))).flat())}async function p(e){let i=await e(["shell","pm","list","packages","-3"],{allowFailure:!0});if(0!==i.exitCode)throw new t("COMMAND_FAILED","Failed to list Android user-installed apps",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return r(i.stdout)}async function f(t,e){for(let a of e){let e=i((await t(a,{allowFailure:!0})).stdout??"");if(e)return e}return null}let _="android.intent.category.LAUNCHER",m="android.intent.category.DEFAULT";async function w(t,e){await t(["shell","am","force-stop",e])}async function h(t,e,i=[_]){for(let a of i){let i=await t(["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",a,e],{allowFailure:!0});if(0!==i.exitCode)continue;let r=n(i.stdout);if(r)return r}return null}async function C(e,i,a={}){let r=a.category??_;if(a.activity){var o,n;return void await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",(o=i,(n=a.activity).includes("/")?n:`${o}/${n.startsWith(".")?n:`.${n}`}`)])}let l=await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-p",i],{allowFailure:!0});if(0===l.exitCode&&!d(l.stdout,l.stderr))return;let s=await h(e,i,[r]);if(!s)throw new t("COMMAND_FAILED",`Failed to resolve Android launch component for ${i}`,{stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode});await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",s])}export{captureAndroidLogcatWithAdb,streamAndroidLogcatWithAdb}from"./8806.js";export{createAndroidPortReverseManager,createLocalAndroidAdbProvider}from"./9639.js";export{dismissAndroidKeyboardWithAdb,getAndroidKeyboardStatusWithAdb,readAndroidClipboardWithAdb,writeAndroidClipboardWithAdb}from"./8133.js";export{w as forceStopAndroidAppWithAdb,u as getAndroidAppStateWithAdb,c as listAndroidAppsWithAdb,C as openAndroidAppWithAdb,h as resolveAndroidLaunchComponentWithAdb};
1
+ import{AppError as t}from"./733.js";import{resolveAppsFilter as e}from"./2748.js";import{parseAndroidForegroundApp as i,parseAndroidLaunchablePackages as a,parseAndroidUserInstalledPackages as r,inferAndroidAppName as o,parseAndroidLaunchComponent as n,isAmStartError as d}from"./3340.js";let l="android.intent.category.LAUNCHER",s="android.intent.category.LEANBACK_LAUNCHER";async function c(t,i={}){let a=await A(t,i.target??"auto");return("user-installed"===e(i.filter)?(await p(t)).filter(t=>a.has(t)):Array.from(a)).map(t=>({package:t,name:o(t)})).sort((t,e)=>t.package.localeCompare(e.package))}async function u(t){let e=await f(t,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(e)return e;let i=await f(t,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return i||{}}async function A(t,e){return new Set((await Promise.all((function(t){switch(t){case"mobile":return[l];case"tv":return[s];default:return[l,s]}})(e).map(async e=>{var i;let r=await t(["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",e],{allowFailure:!0});return 0===r.exitCode?0===(i=r.stdout).trim().length?[]:a(i):[]}))).flat())}async function p(e){let i=await e(["shell","pm","list","packages","-3"],{allowFailure:!0});if(0!==i.exitCode)throw new t("COMMAND_FAILED","Failed to list Android user-installed apps",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return r(i.stdout)}async function f(t,e){for(let a of e){let e=i((await t(a,{allowFailure:!0})).stdout??"");if(e)return e}return null}let _="android.intent.category.LAUNCHER",m="android.intent.category.DEFAULT";async function w(t,e){await t(["shell","am","force-stop",e])}async function h(t,e,i=[_]){for(let a of i){let i=await t(["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",a,e],{allowFailure:!0});if(0!==i.exitCode)continue;let r=n(i.stdout);if(r)return r}return null}async function C(e,i,a={}){let r=a.category??_;if(a.activity){var o,n;return void await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",(o=i,(n=a.activity).includes("/")?n:`${o}/${n.startsWith(".")?n:`.${n}`}`)])}let l=await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-p",i],{allowFailure:!0});if(0===l.exitCode&&!d(l.stdout,l.stderr))return;let s=await h(e,i,[r]);if(!s)throw new t("COMMAND_FAILED",`Failed to resolve Android launch component for ${i}`,{stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode});await e(["shell","am","start","-W","-a","android.intent.action.MAIN","-c",m,"-c",r,"-n",s])}export{captureAndroidLogcatWithAdb,streamAndroidLogcatWithAdb}from"./3340.js";export{createAndroidPortReverseManager,createLocalAndroidAdbProvider}from"./2954.js";export{dismissAndroidKeyboardWithAdb,getAndroidKeyboardStatusWithAdb,readAndroidClipboardWithAdb,writeAndroidClipboardWithAdb}from"./9624.js";export{w as forceStopAndroidAppWithAdb,u as getAndroidAppStateWithAdb,c as listAndroidAppsWithAdb,C as openAndroidAppWithAdb,h as resolveAndroidLaunchComponentWithAdb};
@@ -1 +1 @@
1
- var _=500;export{ANDROID_SNAPSHOT_HELPER_NAME,ANDROID_SNAPSHOT_HELPER_OUTPUT_FORMAT,ANDROID_SNAPSHOT_HELPER_PACKAGE,ANDROID_SNAPSHOT_HELPER_PROTOCOL,ANDROID_SNAPSHOT_HELPER_RUNNER,captureAndroidSnapshotWithHelper,ensureAndroidSnapshotHelper,parseAndroidSnapshotHelperManifest,parseAndroidSnapshotHelperOutput,parseAndroidSnapshotHelperXml,prepareAndroidSnapshotHelperArtifactFromManifestUrl,verifyAndroidSnapshotHelperArtifact}from"./221.js";export{_ as ANDROID_SNAPSHOT_HELPER_WAIT_FOR_IDLE_TIMEOUT_MS};
1
+ var _=500;export{ANDROID_SNAPSHOT_HELPER_NAME,ANDROID_SNAPSHOT_HELPER_OUTPUT_FORMAT,ANDROID_SNAPSHOT_HELPER_PACKAGE,ANDROID_SNAPSHOT_HELPER_PROTOCOL,ANDROID_SNAPSHOT_HELPER_RUNNER,captureAndroidSnapshotWithHelper,ensureAndroidSnapshotHelper,parseAndroidSnapshotHelperManifest,parseAndroidSnapshotHelperOutput,parseAndroidSnapshotHelperXml,prepareAndroidSnapshotHelperArtifactFromManifestUrl,verifyAndroidSnapshotHelperArtifact}from"./7394.js";export{_ as ANDROID_SNAPSHOT_HELPER_WAIT_FOR_IDLE_TIMEOUT_MS};
@@ -1,4 +1,4 @@
1
- import e from"node:crypto";import t from"node:fs/promises";import r from"node:path";import{promises as i}from"node:fs";import{normalizeError as a,AppError as n}from"./9152.js";import{withDiagnosticTimer as o,emitDiagnostic as s}from"./7599.js";import{readVersion as d,findProjectRoot as l}from"./9671.js";import{resolveAndroidTouchInjector as u,resolveAndroidAdbProvider as c,resolveAndroidAdbExecutor as p,installAndroidAdbPackage as m}from"./9639.js";import{appSwitcherAndroid as h,homeAndroid as f,scrollAndroid as w,longPressAndroid as _,typeAndroid as A,getAndroidScreenSize as g,pressAndroid as y,focusAndroid as N,swipeAndroid as I,rotateAndroid as v,fillAndroid as M,backAndroid as C}from"./input-actions.js";import{requireLocationCoordinates as S,snapshotCaptureAnnotationsFrom as R}from"./6133.js";import{parseAppearanceAction as D,summarizeCommandAttemptFailures as E,parseSettingState as x,parsePermissionTarget as k,parsePermissionAction as b}from"./6629.js";import{openAndroidDevice as O,runAndroidAdb as L,openAndroidApp as F,resolveAndroidApp as P,closeAndroidApp as T}from"./8806.js";import{writeAndroidClipboardText as U,readAndroidClipboardText as $}from"./8133.js";import{snapshotAndroid as G}from"./2415.js";import{sleep as K}from"./4829.js";let V="android-multitouch-helper-v1",H="ANDROID_MULTITOUCH_HELPER_NO_FINAL_RESULT",q="ANDROID_MULTITOUCH_HELPER_REPORTED_FAILURE";async function B(e,t){let r=await Q(e,{kind:"swipe",...t});if(r)return r;try{return await Y(e,{kind:"swipe",...t})}catch(r){return s({level:"warn",phase:"android_swipe_helper_fallback",data:{error:a(r).message}}),await I(e,t.x1,t.y1,t.x2,t.y2,t.durationMs),{backend:"adb-input-swipe-fallback"}}}async function j(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture pinch requires scale > 0");let r=await W(e,t.x,t.y);return await X(e,{kind:"pinch",x:r.x,y:r.y,scale:t.scale,durationMs:t.durationMs})}async function z(e,t){if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture rotate requires finite degrees");if(void 0!==t.velocity&&(!Number.isFinite(t.velocity)||0===t.velocity))throw new n("INVALID_ARGS","gesture rotate velocity must be a non-zero number");let r=await W(e,t.x,t.y),i=t.degrees;return await X(e,{kind:"rotate",x:r.x,y:r.y,degrees:i,durationMs:t.durationMs})}async function J(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture transform requires scale > 0");if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture transform requires finite degrees");if(![t.x,t.y,t.dx,t.dy].every(Number.isFinite))throw new n("INVALID_ARGS","gesture transform requires finite x y dx dy");return await X(e,{kind:"transform",x:t.x,y:t.y,dx:t.dx,dy:t.dy,scale:t.scale,degrees:t.degrees,durationMs:t.durationMs})}async function W(e,t,r){if(void 0!==t&&void 0!==r)return{x:t,y:r};let i=await g(e);return{x:Math.round(i.width/2),y:Math.round(i.height/2)}}async function X(e,t){let r=await Q(e,t);return r||await Y(e,t)}async function Q(e,t){let r=u(e);if(r)return{backend:"provider-native-touch",...await r(t)??{}}}async function Y(e,t){let r=p(e),i=await et(),a=c(e),n=await o("android_multitouch_helper_install",async()=>{var t;return await er({adb:r,adbProvider:a,artifact:i,deviceKey:(t=e,`${t.platform}:${t.id}`)})},{packageName:i.manifest.packageName,versionCode:i.manifest.versionCode});s({phase:"android_multitouch_helper_install_decision",data:n});let d=await o("android_multitouch_helper_gesture",async()=>await Z({adb:r,request:function(e){var t;let r=Math.round(void 0!==(t=e).durationMs?t.durationMs:"swipe"===t.kind||"pinch"===t.kind?300:Math.min(Math.max(300,16*Math.ceil(Math.abs(t.degrees)/3)),2400));switch(e.kind){case"swipe":return{kind:"swipe",x1:Math.round(e.x1),y1:Math.round(e.y1),x2:Math.round(e.x2),y2:Math.round(e.y2),durationMs:r};case"pinch":return{kind:"pinch",x:Math.round(e.x),y:Math.round(e.y),scale:e.scale,radius:160,durationMs:r};case"rotate":return{kind:"rotate",x:Math.round(e.x),y:Math.round(e.y),degrees:e.degrees,radius:160,durationMs:r};case"transform":return{kind:"transform",x:Math.round(e.x),y:Math.round(e.y),dx:Math.round(e.dx),dy:Math.round(e.dy),scale:e.scale,degrees:e.degrees,durationMs:r}}}(t),packageName:i.manifest.packageName,instrumentationRunner:i.manifest.instrumentationRunner}),{packageName:i.manifest.packageName,version:i.manifest.version});return{backend:"android-multitouch-helper",helperVersion:i.manifest.version,installReason:n.reason,...d}}async function Z(e){let t,r=Buffer.from(JSON.stringify({protocol:V,...e.request})).toString("base64"),i=await e.adb(["shell","am","instrument","-w","-e","payloadBase64",r,e.instrumentationRunner],{allowFailure:!0,timeoutMs:45e3});try{t=function(e){let t=(function(e){let t=[],r=null;for(let i of e.split(/\r?\n/))i.startsWith("INSTRUMENTATION_RESULT: ")?(r??={},function(e,t){let r=e.indexOf("=");r>=0&&(t[e.slice(0,r)]=e.slice(r+1))}(i.slice(24),r)):i.startsWith("INSTRUMENTATION_CODE: ")&&r&&(t.push(r),r=null);return r&&t.push(r),t})(e).find(e=>e.agentDeviceProtocol===V);if(!t)throw new n(H,"Android multi-touch helper did not return a final result");if("true"!==t.ok){var r;throw new n(q,(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android multi-touch helper returned an error",{errorType:t.errorType,helper:t})}return{kind:t.kind,helperApiVersion:t.helperApiVersion,injectedEvents:ee(t.injectedEvents),elapsedMs:ee(t.elapsedMs)}}(`${i.stdout}
1
+ import e from"node:crypto";import t from"node:fs/promises";import r from"node:path";import{promises as i}from"node:fs";import{normalizeError as a,AppError as n}from"./733.js";import{withDiagnosticTimer as o,emitDiagnostic as s}from"./432.js";import{readVersion as d,findProjectRoot as l}from"./7244.js";import{resolveAndroidTouchInjector as u,resolveAndroidAdbProvider as c,resolveAndroidAdbExecutor as p,installAndroidAdbPackage as m}from"./2954.js";import{appSwitcherAndroid as h,homeAndroid as f,scrollAndroid as w,longPressAndroid as _,typeAndroid as A,getAndroidScreenSize as g,pressAndroid as y,focusAndroid as N,swipeAndroid as I,rotateAndroid as v,fillAndroid as M,backAndroid as C}from"./input-actions.js";import{requireLocationCoordinates as S,snapshotCaptureAnnotationsFrom as R}from"./9873.js";import{parseAppearanceAction as D,summarizeCommandAttemptFailures as E,parseSettingState as x,parsePermissionTarget as k,parsePermissionAction as b}from"./8225.js";import{openAndroidDevice as O,runAndroidAdb as L,openAndroidApp as F,resolveAndroidApp as P,closeAndroidApp as T}from"./3340.js";import{writeAndroidClipboardText as U,readAndroidClipboardText as $}from"./9624.js";import{snapshotAndroid as G}from"./9722.js";import{sleep as K}from"./5560.js";let V="android-multitouch-helper-v1",H="ANDROID_MULTITOUCH_HELPER_NO_FINAL_RESULT",q="ANDROID_MULTITOUCH_HELPER_REPORTED_FAILURE";async function B(e,t){let r=await Q(e,{kind:"swipe",...t});if(r)return r;try{return await Y(e,{kind:"swipe",...t})}catch(r){return s({level:"warn",phase:"android_swipe_helper_fallback",data:{error:a(r).message}}),await I(e,t.x1,t.y1,t.x2,t.y2,t.durationMs),{backend:"adb-input-swipe-fallback"}}}async function j(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture pinch requires scale > 0");let r=await W(e,t.x,t.y);return await X(e,{kind:"pinch",x:r.x,y:r.y,scale:t.scale,durationMs:t.durationMs})}async function z(e,t){if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture rotate requires finite degrees");if(void 0!==t.velocity&&(!Number.isFinite(t.velocity)||0===t.velocity))throw new n("INVALID_ARGS","gesture rotate velocity must be a non-zero number");let r=await W(e,t.x,t.y),i=t.degrees;return await X(e,{kind:"rotate",x:r.x,y:r.y,degrees:i,durationMs:t.durationMs})}async function J(e,t){if(!Number.isFinite(t.scale)||t.scale<=0)throw new n("INVALID_ARGS","gesture transform requires scale > 0");if(!Number.isFinite(t.degrees))throw new n("INVALID_ARGS","gesture transform requires finite degrees");if(![t.x,t.y,t.dx,t.dy].every(Number.isFinite))throw new n("INVALID_ARGS","gesture transform requires finite x y dx dy");return await X(e,{kind:"transform",x:t.x,y:t.y,dx:t.dx,dy:t.dy,scale:t.scale,degrees:t.degrees,durationMs:t.durationMs})}async function W(e,t,r){if(void 0!==t&&void 0!==r)return{x:t,y:r};let i=await g(e);return{x:Math.round(i.width/2),y:Math.round(i.height/2)}}async function X(e,t){let r=await Q(e,t);return r||await Y(e,t)}async function Q(e,t){let r=u(e);if(r)return{backend:"provider-native-touch",...await r(t)??{}}}async function Y(e,t){let r=p(e),i=await et(),a=c(e),n=await o("android_multitouch_helper_install",async()=>{var t;return await er({adb:r,adbProvider:a,artifact:i,deviceKey:(t=e,`${t.platform}:${t.id}`)})},{packageName:i.manifest.packageName,versionCode:i.manifest.versionCode});s({phase:"android_multitouch_helper_install_decision",data:n});let d=await o("android_multitouch_helper_gesture",async()=>await Z({adb:r,request:function(e){var t;let r=Math.round(void 0!==(t=e).durationMs?t.durationMs:"swipe"===t.kind||"pinch"===t.kind?300:Math.min(Math.max(300,16*Math.ceil(Math.abs(t.degrees)/3)),2400));switch(e.kind){case"swipe":return{kind:"swipe",x1:Math.round(e.x1),y1:Math.round(e.y1),x2:Math.round(e.x2),y2:Math.round(e.y2),durationMs:r};case"pinch":return{kind:"pinch",x:Math.round(e.x),y:Math.round(e.y),scale:e.scale,radius:160,durationMs:r};case"rotate":return{kind:"rotate",x:Math.round(e.x),y:Math.round(e.y),degrees:e.degrees,radius:160,durationMs:r};case"transform":return{kind:"transform",x:Math.round(e.x),y:Math.round(e.y),dx:Math.round(e.dx),dy:Math.round(e.dy),scale:e.scale,degrees:e.degrees,durationMs:r}}}(t),packageName:i.manifest.packageName,instrumentationRunner:i.manifest.instrumentationRunner}),{packageName:i.manifest.packageName,version:i.manifest.version});return{backend:"android-multitouch-helper",helperVersion:i.manifest.version,installReason:n.reason,...d}}async function Z(e){let t,r=Buffer.from(JSON.stringify({protocol:V,...e.request})).toString("base64"),i=await e.adb(["shell","am","instrument","-w","-e","payloadBase64",r,e.instrumentationRunner],{allowFailure:!0,timeoutMs:45e3});try{t=function(e){let t=(function(e){let t=[],r=null;for(let i of e.split(/\r?\n/))i.startsWith("INSTRUMENTATION_RESULT: ")?(r??={},function(e,t){let r=e.indexOf("=");r>=0&&(t[e.slice(0,r)]=e.slice(r+1))}(i.slice(24),r)):i.startsWith("INSTRUMENTATION_CODE: ")&&r&&(t.push(r),r=null);return r&&t.push(r),t})(e).find(e=>e.agentDeviceProtocol===V);if(!t)throw new n(H,"Android multi-touch helper did not return a final result");if("true"!==t.ok){var r;throw new n(q,(r=t).message&&"null"!==r.message?r.message:r.errorType||"Android multi-touch helper returned an error",{errorType:t.errorType,helper:t})}return{kind:t.kind,helperApiVersion:t.helperApiVersion,injectedEvents:ee(t.injectedEvents),elapsedMs:ee(t.elapsedMs)}}(`${i.stdout}
2
2
  ${i.stderr}`)}catch(e){if(e instanceof n){if(e.code===q)throw new n("COMMAND_FAILED",e.message,e.details,e);if(e.code!==H)throw e}throw new n("COMMAND_FAILED",0===i.exitCode?"Android multi-touch helper output could not be parsed":"Android multi-touch helper failed before returning parseable output",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode},e)}if(0!==i.exitCode)throw new n("COMMAND_FAILED","Android multi-touch helper failed",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,helper:t});return t}function ee(e){if(void 0===e)return;let t=Number(e);return Number.isFinite(t)?t:void 0}async function et(){let e=d(),i=r.join(l(),"android-multitouch-helper","dist"),o=r.join(i,`agent-device-android-multitouch-helper-${e}.manifest.json`);try{let e=function(e){if(!e||"object"!=typeof e||Array.isArray(e))throw new n("INVALID_ARGS","Android multi-touch helper manifest must be an object.");return{name:ed(e.name,"name","android-multitouch-helper"),version:es(e.version,"version"),assetName:es(e.assetName,"assetName"),sha256:function(e){let t=es(e,"sha256").trim().toLowerCase();if(64!==t.length||!/^[0-9a-f]+$/.test(t))throw new n("INVALID_ARGS","Android multi-touch helper manifest sha256 must be a 64-character hex string.");return t}(e.sha256),packageName:ed(e.packageName,"packageName","com.callstack.agentdevice.multitouchhelper"),versionCode:function(e,t){if(!Number.isInteger(e))throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be an integer.`);return e}(e.versionCode,"versionCode"),instrumentationRunner:ed(e.instrumentationRunner,"instrumentationRunner","com.callstack.agentdevice.multitouchhelper/.MultiTouchInstrumentation"),statusProtocol:ed(e.statusProtocol,"statusProtocol",V)}}(JSON.parse(await t.readFile(o,"utf8"))),a=r.join(i,e.assetName);return await t.access(a),{apkPath:a,manifest:e}}catch(e){throw new n("UNSUPPORTED_OPERATION","Android touch gestures require the bundled Android touch helper artifact, but it was not found or could not be read",{manifestPath:o,error:a(e).message},e)}}async function er(e){let{adb:t,artifact:r}=e,i=r.manifest.packageName,a=r.manifest.versionCode,o=`${e.deviceKey}\0${i}\0${a}`;if(ei.has(o))return{packageName:i,versionCode:a,installed:!1,reason:"current"};let s=await ea(t,i);if(void 0!==s&&s>=a)return ei.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!1,reason:"current"};await en(r);let d=await m(r.apkPath,{provider:e.adbProvider,replace:!0,allowTestPackages:!0,allowFailure:!0,timeoutMs:3e4});if(0!==d.exitCode)throw new n("COMMAND_FAILED","Failed to install Android multi-touch helper",{packageName:i,versionCode:a,stdout:d.stdout,stderr:d.stderr,exitCode:d.exitCode});return ei.add(o),{packageName:i,versionCode:a,installedVersionCode:s,installed:!0,reason:void 0===s?"missing":"outdated"}}let ei=new Set;async function ea(e,t){let r=await e(["shell","cmd","package","list","packages","--show-versioncode",t],{allowFailure:!0,timeoutMs:5e3});if(0!==r.exitCode)return;let i=RegExp(`package:${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(?:\\s|$).*versionCode:(\\d+)`).exec(`${r.stdout}
3
3
  ${r.stderr}`);return i?Number(i[1]):void 0}async function en(e){let t=await eo(e.apkPath);if(t!==e.manifest.sha256)throw new n("COMMAND_FAILED","Android multi-touch helper APK checksum mismatch",{apkPath:e.apkPath,expectedSha256:e.manifest.sha256,actualSha256:t})}async function eo(r){let i=e.createHash("sha256");return i.update(await t.readFile(r)),i.digest("hex")}function es(e,t){if("string"!=typeof e||0===e.length)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} is required.`);return e}function ed(e,t,r){if(e!==r)throw new n("INVALID_ARGS",`Android multi-touch helper manifest ${t} must be "${r}".`);return r}let el=["window_animation_scale","transition_animation_scale","animator_duration_scale"];async function eu(e,t,r,i,a){switch(t.toLowerCase()){case"wifi":{let t=x(r);await L(e,["shell","svc","wifi",t?"enable":"disable"]);return}case"airplane":{let t=x(r);await L(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"]),await L(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]);return}case"location":{if("set"===r.toLowerCase()){if("emulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Android precise location coordinates are supported only on emulators.",{deviceId:e.id,hint:"Use an Android emulator for adb emu geo fix, or configure location through device/provider tooling."});let{latitude:t,longitude:r}=S(a);return await L(e,["emu","geo","fix",String(r),String(t)]),{latitude:t,longitude:r}}let t=x(r);await L(e,["shell","settings","put","secure","location_mode",t?"3":"0"]);return}case"animations":{let t=x(r)?"1":"0";for(let r of el)await L(e,["shell","settings","put","global",r,t]);return{scale:t,keys:[...el]}}case"appearance":{let t=await ep(e,r);await L(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]);return}case"clear-app-state":{if("clear"!==r.toLowerCase())throw new n("INVALID_ARGS","settings clear-app-state only supports clear.");if(!i)throw new n("INVALID_ARGS","settings clear-app-state requires an app id or an active app session.");let t=await P(e,i);if("intent"===t.type)throw new n("INVALID_ARGS","settings clear-app-state requires a package name, not an intent.");await L(e,["shell","am","force-stop",t.value],{allowFailure:!0});let a=await L(e,["shell","pm","clear",t.value],{allowFailure:!0});if(0!==a.exitCode||!/\bSuccess\b/i.test(a.stdout))throw new n("COMMAND_FAILED",`Failed to clear Android app data for ${t.value}`,{package:t.value,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{package:t.value,cleared:!0}}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new n("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await ec(e,t);return}case"permission":{if(!i)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t=b(r),o=function(e,t){let r=k(e);if(t?.trim())throw new n("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return{kind:"pm",value:"android.permission.CAMERA",type:"camera"};if("microphone"===r)return{kind:"pm",value:"android.permission.RECORD_AUDIO",type:"microphone"};if("photos"===r)return{kind:"pm",value:"android.permission.READ_MEDIA_IMAGES",type:"photos"};if("contacts"===r)return{kind:"pm",value:"android.permission.READ_CONTACTS",type:"contacts"};if("notifications"===r)return{kind:"notifications",appOps:"POST_NOTIFICATION",permission:"android.permission.POST_NOTIFICATIONS"};throw new n("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(a?.permissionTarget,a?.permissionMode);if("notifications"===o.kind)return void await eh(e,i,t,o);let s="grant"===t?"grant":"revoke";if("photos"===o.type)return void await em(e,i,s);await L(e,["shell","pm",s,i,o.value]);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function ec(e,t){var r;let i,a,o=(r=e,a=[["shell","cmd","fingerprint","touch",i="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",i]],"emulator"===r.kind&&a.push(["emu","finger","touch",i]),a),s=[];for(let t of o){let r=await L(e,t,{allowFailure:!0});if(0===r.exitCode)return;s.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let d=E(s);if(s.length>0&&s.every(e=>{var t,r;let i;return t=e.stdout,r=e.stderr,(i=`${t}
4
4
  ${r}`.toLowerCase()).includes("unknown command")||i.includes("can't find service: fingerprint")||i.includes("service fingerprint was not found")||i.includes("fingerprint cmd unavailable")||i.includes("emu command is not supported")||i.includes("emulator console is not running")||i.includes("fingerprint")&&i.includes("not found")}))throw new n("UNSUPPORTED_OPERATION","Android fingerprint simulation is not supported on this target/runtime.",{deviceId:e.id,action:t,hint:"Use an Android emulator with biometric support, or a device/runtime that exposes cmd fingerprint.",attempts:d});throw new n("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:d})}async function ep(e,t){let r=D(t);if("toggle"!==r)return r;let i=await L(e,["shell","cmd","uimode","night"],{allowFailure:!0});if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to read current Android appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});let a=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
package/dist/src/apple.js CHANGED
@@ -1 +1 @@
1
- import{readSnapshotQualityVerdict as e,assertScrollGestureInput as a,buildScrollGesturePlan as t}from"./6133.js";import{parseRunnerSequenceResult as n,buildRunnerSequenceCommand as d,runMacOsScreenshotAction as o,runIosRunnerCommand as r}from"./2415.js";import{writeIosClipboardText as i,openIosApp as l,openIosDevice as s,screenshotIos as p,closeIosApp as u,setIosSetting as c,readIosClipboardText as m}from"./apps.js";import{withDiagnosticTimer as y}from"./7599.js";import{AppError as f}from"./9152.js";function v(e,a,t,n){return{command:"tap",x:t,y:n,...I(e)?{synthesized:!0}:{},appBundleId:a.appBundleId}}function I(e){return"ios"===e.platform&&"tv"!==e.target}function h(e,a,t,n,d,o,r,i){var l,s;let p="ios"===e.platform&&"tv"!==e.target?(l=r,s=i.defaultDurationMs,void 0===l?s:Math.min(1e4,Math.max(16,Math.round(l)))):r??i.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:d,y2:o,...void 0!==p?{durationMs:p}:{},...!0===i.synthesized?{synthesized:!0}:{},appBundleId:a.appBundleId}}function w(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}async function B(e,n,d,o,r,i){if("tv"===n.target)return x(await e(n,w(r,d.appBundleId),o),i);a(i??{});let l=await e(n,{command:"scroll",direction:r,...i?.amount!==void 0?{amount:i.amount}:{},...i?.pixels!==void 0?{pixels:i.pixels}:{},appBundleId:d.appBundleId},o),s=g(l.referenceWidth),p=g(l.referenceHeight);if(void 0!==s&&void 0!==p){let e=t({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:s,referenceHeight:p});return x(l,{amount:i?.amount,pixels:e.pixels,preferProvidedPixels:!0})}return x(l,{amount:i?.amount})}function g(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function x(e,a){var t;let{x1:n,y1:d,x2:o,y2:r}={x1:g((t=e).x),y1:g(t.y),x2:g(t.x2),y2:g(t.y2)},i=g(e.referenceWidth),l=g(e.referenceHeight),s=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,p=void 0!==d&&void 0!==r?Math.round(Math.abs(r-d)):void 0,u=a?.preferProvidedPixels&&void 0!==a.pixels?a.pixels:s&&s>0?s:p&&p>0?p:void 0;return{...void 0!==n?{x1:n}:{},...void 0!==d?{y1:d}:{},...void 0!==o?{x2:o}:{},...void 0!==r?{y2:r}:{},...void 0!==i?{referenceWidth:i}:{},...void 0!==l?{referenceHeight:l}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==u?{pixels:u}:{}}}function M(a,t){let g,{overrides:x,runnerOpts:M}={runnerOpts:g={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId},overrides:{tap:async(e,n)=>await r(a,v(a,t,e,n),g),tapElementSelector:async e=>await r(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},g),doubleTap:async(e,o)=>{let i=await r(a,d([{kind:"doubleTap",x:e,y:o}],t.appBundleId),g);return n(i),i},swipe:async(e,n,d,o,i)=>await r(a,h(a,t,e,n,d,o,i,{defaultDurationMs:250,synthesized:I(a)}),g),pan:async(e,n,d,o,i)=>await r(a,h(a,t,e,n,d,o,i,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:I(a)}),g),fling:async(e,n,d,o,i)=>await r(a,h(a,t,e,n,d,o,i,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:I(a)}),g),longPress:async(e,n,d)=>await r(a,{command:"longPress",x:e,y:n,durationMs:d,appBundleId:t.appBundleId},g),focus:async(e,n)=>await r(a,v(a,t,e,n),g),type:async(e,n)=>{await r(a,{command:"type",text:e,delayMs:n,textEntryMode:"\n"===e?void 0:"append",appBundleId:t.appBundleId},g)},fillElementSelector:async(e,n,d)=>await r(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:n,delayMs:d,textEntryMode:"replace",appBundleId:t.appBundleId},g),fill:async(e,n,d,o)=>await r(a,{command:"type",x:e,y:n,text:d,delayMs:o,textEntryMode:"replace",appBundleId:t.appBundleId},g),scroll:async(e,n)=>await B(r,a,t,g,e,n),pinch:async(e,n,d)=>{await r(a,{command:"pinch",scale:e,x:n,y:d,appBundleId:t.appBundleId},g)},rotateGesture:async(e,n,d,o)=>{await r(a,{command:"rotateGesture",degrees:e,x:n,y:d,velocity:o,appBundleId:t.appBundleId},g)},transformGesture:async e=>await r(a,{command:"transformGesture",x:e.x,y:e.y,dx:e.dx,dy:e.dy,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs,appBundleId:t.appBundleId},g)}};return{open:(e,t)=>l(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,url:t?.url}),openDevice:()=>s(a),close:e=>u(a,e),screenshot:async(e,t)=>{"macos"===a.platform&&t?.surface&&"app"!==t.surface?await o(e,{surface:t.surface,fullscreen:t.fullscreen}):await p(a,e,t?.appBundleId,t?.fullscreen,M)},snapshot:async t=>{var n;let d={nodes:Array.isArray((n=await y("snapshot_capture",async()=>await r(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},M),{backend:"xctest"})).nodes)?n.nodes:void 0,truncated:"boolean"==typeof n.truncated?n.truncated:void 0,quality:e(n.snapshotQuality),message:"string"==typeof n.message&&n.message.trim().length>0?n.message:void 0},o=d.nodes??[];if(0===o.length&&"simulator"===a.kind)throw new f("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:o,truncated:d.truncated??!1,backend:"xctest",...d.quality?{quality:d.quality}:{},...!d.quality&&d.message?{warnings:[d.message]}:{}}},back:async e=>{"tv"===a.target?await r(a,w("menu",t.appBundleId),M):await r(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:t.appBundleId},M)},home:async()=>{"tv"===a.target?await r(a,w("home",t.appBundleId),M):await r(a,{command:"home",appBundleId:t.appBundleId},M)},rotate:async e=>{await r(a,{command:"rotate",orientation:e,appBundleId:t.appBundleId},M)},appSwitcher:async()=>{await r(a,{command:"appSwitcher",appBundleId:t.appBundleId},M)},readClipboard:()=>m(a),writeClipboard:e=>i(a,e),setSetting:(e,t,n,d)=>c(a,e,t,n,d),...x}}export{M as createAppleInteractor};
1
+ import{readSnapshotQualityVerdict as e,assertScrollGestureInput as a,buildScrollGesturePlan as t}from"./9873.js";import{parseRunnerSequenceResult as n,buildRunnerSequenceCommand as d,runMacOsScreenshotAction as o,runIosRunnerCommand as r}from"./9722.js";import{writeIosClipboardText as i,openIosApp as s,openIosDevice as l,screenshotIos as p,closeIosApp as u,setIosSetting as c,readIosClipboardText as m}from"./apps.js";import{withDiagnosticTimer as y}from"./432.js";import{AppError as v}from"./733.js";function f(e,a,t,n){return{command:"tap",x:t,y:n,...h(e)?{synthesized:!0}:{},appBundleId:a.appBundleId}}function h(e){return"ios"===e.platform&&"tv"!==e.target}function I(e,a,t,n,d,o,r,i){var s,l;let p="ios"===e.platform&&"tv"!==e.target?(s=r,l=i.defaultDurationMs,void 0===s?l:Math.min(1e4,Math.max(16,Math.round(s)))):r??i.legacyDefaultDurationMs;return{command:"drag",x:t,y:n,x2:d,y2:o,...void 0!==p?{durationMs:p}:{},...!0===i.synthesized?{synthesized:!0}:{},appBundleId:a.appBundleId}}function w(e,a,t){return{command:"remotePress",remoteButton:e,...void 0!==t?{durationMs:t}:{},...void 0!==a?{appBundleId:a}:{}}}async function B(e,n,d,o,r,i){if("tv"===n.target)return x(await e(n,w(r,d.appBundleId),o),i);a(i??{});let s=await e(n,{command:"scroll",direction:r,...i?.amount!==void 0?{amount:i.amount}:{},...i?.pixels!==void 0?{pixels:i.pixels}:{},appBundleId:d.appBundleId},o),l=g(s.referenceWidth),p=g(s.referenceHeight);if(void 0!==l&&void 0!==p){let e=t({direction:r,amount:i?.amount,pixels:i?.pixels,referenceWidth:l,referenceHeight:p});return x(s,{amount:i?.amount,pixels:e.pixels,preferProvidedPixels:!0})}return x(s,{amount:i?.amount})}function g(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function x(e,a){var t;let{x1:n,y1:d,x2:o,y2:r}={x1:g((t=e).x),y1:g(t.y),x2:g(t.x2),y2:g(t.y2)},i=g(e.referenceWidth),s=g(e.referenceHeight),l=void 0!==n&&void 0!==o?Math.round(Math.abs(o-n)):void 0,p=void 0!==d&&void 0!==r?Math.round(Math.abs(r-d)):void 0,u=a?.preferProvidedPixels&&void 0!==a.pixels?a.pixels:l&&l>0?l:p&&p>0?p:void 0;return{...void 0!==n?{x1:n}:{},...void 0!==d?{y1:d}:{},...void 0!==o?{x2:o}:{},...void 0!==r?{y2:r}:{},...void 0!==i?{referenceWidth:i}:{},...void 0!==s?{referenceHeight:s}:{},...a?.amount!==void 0?{amount:a.amount}:{},...void 0!==u?{pixels:u}:{}}}function M(a,t){let g,{overrides:x,runnerOpts:M}={runnerOpts:g={verbose:t.verbose,logPath:t.logPath,traceLogPath:t.traceLogPath,requestId:t.requestId,iosXctestrunFile:t.iosXctestrunFile,iosXctestDerivedDataPath:t.iosXctestDerivedDataPath,iosXctestEnvDir:t.iosXctestEnvDir},overrides:{tap:async(e,n)=>await r(a,f(a,t,e,n),g),tapElementSelector:async e=>await r(a,{command:"tap",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,appBundleId:t.appBundleId},g),doubleTap:async(e,o)=>{let i=await r(a,d([{kind:"doubleTap",x:e,y:o}],t.appBundleId),g);return n(i),i},swipe:async(e,n,d,o,i)=>await r(a,I(a,t,e,n,d,o,i,{defaultDurationMs:250,synthesized:h(a)}),g),pan:async(e,n,d,o,i)=>await r(a,I(a,t,e,n,d,o,i,{defaultDurationMs:500,legacyDefaultDurationMs:500,synthesized:h(a)}),g),fling:async(e,n,d,o,i)=>await r(a,I(a,t,e,n,d,o,i,{defaultDurationMs:16,legacyDefaultDurationMs:16,synthesized:h(a)}),g),longPress:async(e,n,d)=>await r(a,{command:"longPress",x:e,y:n,durationMs:d,appBundleId:t.appBundleId},g),focus:async(e,n)=>await r(a,f(a,t,e,n),g),type:async(e,n)=>{await r(a,{command:"type",text:e,delayMs:n,textEntryMode:"\n"===e?void 0:"append",appBundleId:t.appBundleId},g)},fillElementSelector:async(e,n,d)=>await r(a,{command:"type",selectorKey:e.key,selectorValue:e.value,allowNonHittableCoordinateFallback:e.allowNonHittableCoordinateFallback,text:n,delayMs:d,textEntryMode:"replace",appBundleId:t.appBundleId},g),fill:async(e,n,d,o)=>await r(a,{command:"type",x:e,y:n,text:d,delayMs:o,textEntryMode:"replace",appBundleId:t.appBundleId},g),scroll:async(e,n)=>await B(r,a,t,g,e,n),pinch:async(e,n,d)=>{await r(a,{command:"pinch",scale:e,x:n,y:d,appBundleId:t.appBundleId},g)},rotateGesture:async(e,n,d,o)=>{await r(a,{command:"rotateGesture",degrees:e,x:n,y:d,velocity:o,appBundleId:t.appBundleId},g)},transformGesture:async e=>await r(a,{command:"transformGesture",x:e.x,y:e.y,dx:e.dx,dy:e.dy,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs,appBundleId:t.appBundleId},g)}};return{open:(e,t)=>s(a,e,{appBundleId:t?.appBundleId,launchConsole:t?.launchConsole,launchArgs:t?.launchArgs,url:t?.url}),openDevice:()=>l(a),close:e=>u(a,e),screenshot:async(e,t)=>{"macos"===a.platform&&t?.surface&&"app"!==t.surface?await o(e,{surface:t.surface,fullscreen:t.fullscreen}):await p(a,e,t?.appBundleId,t?.fullscreen,M)},snapshot:async t=>{var n;let d={nodes:Array.isArray((n=await y("snapshot_capture",async()=>await r(a,{command:"snapshot",appBundleId:t?.appBundleId,interactiveOnly:t?.interactiveOnly,depth:t?.depth,scope:t?.scope,raw:t?.raw},M),{backend:"xctest"})).nodes)?n.nodes:void 0,truncated:"boolean"==typeof n.truncated?n.truncated:void 0,quality:e(n.snapshotQuality),message:"string"==typeof n.message&&n.message.trim().length>0?n.message:void 0},o=d.nodes??[];if(0===o.length&&"simulator"===a.kind)throw new v("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:o,truncated:d.truncated??!1,backend:"xctest",...d.quality?{quality:d.quality}:{},...!d.quality&&d.message?{warnings:[d.message]}:{}}},back:async e=>{"tv"===a.target?await r(a,w("menu",t.appBundleId),M):await r(a,{command:"system"===e?"backSystem":"backInApp",appBundleId:t.appBundleId},M)},home:async()=>{"tv"===a.target?await r(a,w("home",t.appBundleId),M):await r(a,{command:"home",appBundleId:t.appBundleId},M)},rotate:async e=>{await r(a,{command:"rotate",orientation:e,appBundleId:t.appBundleId},M)},appSwitcher:async()=>{await r(a,{command:"appSwitcher",appBundleId:t.appBundleId},M)},readClipboard:()=>m(a),writeClipboard:e=>i(a,e),setSetting:(e,t,n,d)=>c(a,e,t,n,d),...x}}export{M as createAppleInteractor};
package/dist/src/apps.js CHANGED
@@ -1,13 +1,13 @@
1
- let e;import{promises as t}from"node:fs";import i from"node:os";import a from"node:path";import{fileURLToPath as r}from"node:url";import{AppError as n}from"./9152.js";import{runXcrun as o,IOS_RUNNER_CONTAINER_BUNDLE_IDS as l,resolveIosDevicectlHint as s,LAUNCH_CONSOLE_DIRECT_APP_ONLY_MESSAGE as d,runIosRunnerCommand as u,resolveAppleToolProvider as c,runSimctlForDevice as p,IOS_DEVICECTL_DEFAULT_HINT as f,readInfoPlistString as w,requireSimulatorDevice as m,buildSimctlArgsForDevice as h,runMacOsPermissionAction as y,runIosDevicectl as A,filterAppleAppsByBundlePrefix as I,runAppleToolCommand as v,listIosDeviceApps as g,quitMacOsApp as _,ensureBootedSimulator as C,LAUNCH_CONSOLE_IOS_SIMULATOR_ONLY_MESSAGE as b,getSimulatorState as N}from"./2415.js";import{runCmd as S}from"./9818.js";import{materializeInstallablePath as L,isTrustedInstallSourceUrl as D}from"./989.js";import{parseAppearanceAction as M,summarizeCommandAttemptFailures as O,parseSettingState as P,parsePermissionTarget as F,parsePermissionAction as x}from"./6629.js";import{isWebUrl as R,createAppResolutionCache as $,isDeepLinkTarget as E,resolveIosSimulatorDeviceSetPath as k,resolveIosDeviceDeepLinkBundleId as T,retryWithPolicy as U,Deadline as B}from"./8806.js";import{emitDiagnostic as G}from"./7599.js";import{getUnsupportedMacOsSettingMessage as V,requireLocationCoordinates as j}from"./6133.js";function W(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let i=String(t.stderr??"").toLowerCase();return i.includes("fbsopenapplicationserviceerrordomain")&&i.includes("the request to open")}async function H(e,t){let i=await o(h(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==i.exitCode)return{installed:!1};let a=i.stdout.trim();if(!a)return{installed:!1};let r=await v("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==r.exitCode||!r.stdout.trim())return{installed:!0};let n=r.stdout.trim(),l=`${a}/${n}`,s=await v("otool",["-l",l],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let d=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:d.includes("iossimulator")||d.includes("platform 7")}}async function K(e,t){let i;if("url"===e.kind&&!D(e.url))throw new n("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 L({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||D(e.url),signal:t?.signal});try{let e=i=await q(a.installablePath,t),r=await z(e.installPath);return{archivePath:a.archivePath??(a.installablePath.toLowerCase().endsWith(".ipa")?a.installablePath:void 0),installablePath:e.installPath,bundleId:r.bundleId,appName:r.appName,cleanup:async()=>{await e.cleanup(),await a.cleanup()}}}catch(e){try{await i?.cleanup()}finally{await a.cleanup()}throw e}}async function z(e){let t=a.join(e,"Info.plist"),[i,r,n]=await Promise.all([w(t,"CFBundleIdentifier"),w(t,"CFBundleDisplayName"),w(t,"CFBundleName")]);return{bundleId:i,appName:r??n}}async function q(e,r){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let o=await t.mkdtemp(a.join(i.tmpdir(),"agent-device-ios-ipa-")),l=async()=>{await t.rm(o,{recursive:!0,force:!0})};try{await S("unzip",["-q",e,"-d",o]);let i=a.join(o,"Payload"),s=(await t.readdir(i,{withFileTypes:!0}).catch(()=>{throw new n("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:a.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")})),d=s[0];if(void 0!==d&&1===s.length)return{installPath:d.installPath,cleanup:l};if(0===s.length)throw new n("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await J(s);let u=r?.appIdentifierHint?.trim();if(u){let e=function(e,t){let i=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===i);if(1===a.length)return a[0];if(a.length>1)throw new n("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===i);if(1===t.length)return t[0]}}(s,u);if(e)return{installPath:e.installPath,cleanup:l};throw new n("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${u}". Available bundles: ${s.map(Z).join(", ")}`)}throw new n("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(Z).join(", ")}`)}catch(e){throw await l(),e}}async function J(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await z(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function Z(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}let Q={settings:"com.apple.systempreferences"},X=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,Y={platform:"macos",deviceId:"host",variant:"all"},ee=$();async function et(e){let t=e.trim(),i=Q[t.toLowerCase()];if(i)return i;if(X.test(t))return t;let a=ee.get(Y,t);if(a)return a;let r=(await es("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase()),o=r[0];if(void 0!==o&&1===r.length)return ee.set(Y,t,o.bundleId);if(r.length>1)throw new n("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:r});throw new n("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function ei(e,t,i){let a=i?.url?.trim();if(a){if(!E(a))throw new n("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=i?.appBundleId??await et(t);await ed().openBundle(e,a);return}let r=t.trim();if(E(r))return void await ed().openTarget(r);let o=i?.appBundleId??await et(r);await ed().openBundle(o)}async function ea(e,t){let i=await et(t),a=await _(i);if(a.running&&!a.terminated&&!a.forceTerminated)throw new n("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:i,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function er(){return await ed().readClipboard()}async function en(e){await ed().writeClipboard(e)}async function eo(){return await ed().readDarkMode()}async function el(e){let t=M(e),i="toggle"===t?!await eo():"dark"===t;await ed().setDarkMode(i)}async function es(e){return await ed().listApps(e)}function ed(){let e=c().macosHost;if(!e)throw new n("UNSUPPORTED_OPERATION","macOS host provider is not available");return e}function eu(e){if(!(e instanceof n))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},i=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:i}}let ec=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],ep={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},ef={1:"searching",2:"failed",3:"active"},ew={0:"notSupported",1:"searching",2:"failed",3:"active"};async function em(e){let t=null,i=!1;try{t=await ey(e),i=!0}catch(t){ev(e,"snapshot_failed",t)}try{await eA(e),await eI(e,ec)}catch(t){ev(e,"prepare_failed",t)}return async()=>{await eh(e,i?t:null)}}async function eh(e,t){var i,a;let r;await eA(e),t&&await eI(e,(r=[],(i=t).dataNetwork&&r.push("--dataNetwork",i.dataNetwork),i.wifiMode&&r.push("--wifiMode",i.wifiMode),void 0!==i.wifiBars&&("wifi"===i.dataNetwork||i.wifiMode)&&r.push("--wifiBars",i.wifiBars),i.cellularMode&&r.push("--cellularMode",i.cellularMode),void 0!==i.cellularBars&&(i.cellularMode||(a=i.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==i.operatorName)&&r.push("--cellularBars",i.cellularBars),void 0!==i.operatorName&&r.push("--operatorName",i.operatorName),r))}async function ey(e){var t;let i=await (t=["status_bar",e.id,"list"],p(e,t,{allowFailure:!0}));if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:i.exitCode,stdout:i.stdout,stderr:i.stderr});return function(e){let t={};for(let i of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(i);if(e){let i=Number(e[1]),a=ep[i];if(!a)throw new n("COMMAND_FAILED",`Unsupported simulator data network type: ${i}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(i);if(a){let e=ef[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let r=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(i);if(r){let e=Number(r[1]),i=ew[e];if(!i)throw new n("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=i,t.cellularBars=r[2];continue}let o=/^Operator Name:\s*(.*)$/.exec(i);if(o){t.operatorName=o[1]??"";continue}}return 0===Object.keys(t).length?null:t}(i.stdout)}async function eA(e){await p(e,["status_bar",e.id,"clear"],void 0)}async function eI(e,t){0!==t.length&&await p(e,["status_bar",e.id,"override",...t],void 0)}function ev(e,t,i){G({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...eu(i)}})}let eg={ensureBooted:C,prepareStatusBarForScreenshot:em,captureWithRetry:eb,captureWithRunner:eN,shouldFallbackToRunner:eP};async function e_(e,t,i,a,r){if("macos"===e.platform)return void await eN(e,t,i,a,r);if("simulator"===e.kind)return void await eC(e,t,i,a,void 0,r);try{await A(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},i="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=`${e.message}
1
+ let e;import{promises as t}from"node:fs";import i from"node:os";import a from"node:path";import{fileURLToPath as r}from"node:url";import{AppError as n}from"./733.js";import{runXcrun as o,IOS_RUNNER_CONTAINER_BUNDLE_IDS as l,resolveIosDevicectlHint as s,LAUNCH_CONSOLE_DIRECT_APP_ONLY_MESSAGE as d,runIosRunnerCommand as u,resolveAppleToolProvider as c,runSimctlForDevice as p,IOS_DEVICECTL_DEFAULT_HINT as f,readInfoPlistString as w,requireSimulatorDevice as m,buildSimctlArgsForDevice as h,runMacOsPermissionAction as y,runIosDevicectl as A,filterAppleAppsByBundlePrefix as I,runAppleToolCommand as v,listIosDeviceApps as g,quitMacOsApp as _,ensureBootedSimulator as C,LAUNCH_CONSOLE_IOS_SIMULATOR_ONLY_MESSAGE as b,getSimulatorState as N}from"./9722.js";import{runCmd as S}from"./8875.js";import{materializeInstallablePath as L,isTrustedInstallSourceUrl as D}from"./5484.js";import{parseAppearanceAction as M,summarizeCommandAttemptFailures as O,parseSettingState as P,parsePermissionTarget as F,parsePermissionAction as x}from"./8225.js";import{isWebUrl as R,createAppResolutionCache as $,isDeepLinkTarget as E,resolveIosSimulatorDeviceSetPath as k,resolveIosDeviceDeepLinkBundleId as T,retryWithPolicy as U,Deadline as B}from"./3340.js";import{emitDiagnostic as G}from"./432.js";import{getUnsupportedMacOsSettingMessage as V,requireLocationCoordinates as j}from"./9873.js";function W(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let i=String(t.stderr??"").toLowerCase();return i.includes("fbsopenapplicationserviceerrordomain")&&i.includes("the request to open")}async function H(e,t){let i=await o(h(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==i.exitCode)return{installed:!1};let a=i.stdout.trim();if(!a)return{installed:!1};let r=await v("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==r.exitCode||!r.stdout.trim())return{installed:!0};let n=r.stdout.trim(),l=`${a}/${n}`,s=await v("otool",["-l",l],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let d=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:d.includes("iossimulator")||d.includes("platform 7")}}async function K(e,t){let i;if("url"===e.kind&&!D(e.url))throw new n("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 L({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",allowArchiveExtraction:"url"!==e.kind||D(e.url),signal:t?.signal});try{let e=i=await q(a.installablePath,t),r=await z(e.installPath);return{archivePath:a.archivePath??(a.installablePath.toLowerCase().endsWith(".ipa")?a.installablePath:void 0),installablePath:e.installPath,bundleId:r.bundleId,appName:r.appName,cleanup:async()=>{await e.cleanup(),await a.cleanup()}}}catch(e){try{await i?.cleanup()}finally{await a.cleanup()}throw e}}async function z(e){let t=a.join(e,"Info.plist"),[i,r,n]=await Promise.all([w(t,"CFBundleIdentifier"),w(t,"CFBundleDisplayName"),w(t,"CFBundleName")]);return{bundleId:i,appName:r??n}}async function q(e,r){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let o=await t.mkdtemp(a.join(i.tmpdir(),"agent-device-ios-ipa-")),l=async()=>{await t.rm(o,{recursive:!0,force:!0})};try{await S("unzip",["-q",e,"-d",o]);let i=a.join(o,"Payload"),s=(await t.readdir(i,{withFileTypes:!0}).catch(()=>{throw new n("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:a.join(i,e.name),bundleName:e.name.replace(/\.app$/i,"")})),d=s[0];if(void 0!==d&&1===s.length)return{installPath:d.installPath,cleanup:l};if(0===s.length)throw new n("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await J(s);let u=r?.appIdentifierHint?.trim();if(u){let e=function(e,t){let i=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===i);if(1===a.length)return a[0];if(a.length>1)throw new n("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${t}" by name. Use a bundle id hint instead.`);if(t.includes(".")){let t=e.filter(e=>e.bundleId?.toLowerCase()===i);if(1===t.length)return t[0]}}(s,u);if(e)return{installPath:e.installPath,cleanup:l};throw new n("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${u}". Available bundles: ${s.map(Z).join(", ")}`)}throw new n("INVALID_ARGS",`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(Z).join(", ")}`)}catch(e){throw await l(),e}}async function J(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await z(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function Z(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}let Q={settings:"com.apple.systempreferences"},X=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,Y={platform:"macos",deviceId:"host",variant:"all"},ee=$();async function et(e){let t=e.trim(),i=Q[t.toLowerCase()];if(i)return i;if(X.test(t))return t;let a=ee.get(Y,t);if(a)return a;let r=(await es("all")).filter(e=>e.name.toLowerCase()===t.toLowerCase()),o=r[0];if(void 0!==o&&1===r.length)return ee.set(Y,t,o.bundleId);if(r.length>1)throw new n("INVALID_ARGS",`Multiple apps matched "${e}"`,{matches:r});throw new n("APP_NOT_INSTALLED",`No app found matching "${e}"`)}async function ei(e,t,i){let a=i?.url?.trim();if(a){if(!E(a))throw new n("INVALID_ARGS","open <app> <url> requires a valid URL target");let e=i?.appBundleId??await et(t);await ed().openBundle(e,a);return}let r=t.trim();if(E(r))return void await ed().openTarget(r);let o=i?.appBundleId??await et(r);await ed().openBundle(o)}async function ea(e,t){let i=await et(t),a=await _(i);if(a.running&&!a.terminated&&!a.forceTerminated)throw new n("COMMAND_FAILED",`Failed to close macOS app ${t}`,{bundleId:i,running:a.running,terminated:a.terminated,forceTerminated:a.forceTerminated})}async function er(){return await ed().readClipboard()}async function en(e){await ed().writeClipboard(e)}async function eo(){return await ed().readDarkMode()}async function el(e){let t=M(e),i="toggle"===t?!await eo():"dark"===t;await ed().setDarkMode(i)}async function es(e){return await ed().listApps(e)}function ed(){let e=c().macosHost;if(!e)throw new n("UNSUPPORTED_OPERATION","macOS host provider is not available");return e}function eu(e){if(!(e instanceof n))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},i=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:"number"==typeof t.timeoutMs?t.timeoutMs:void 0,exitCode:"number"==typeof t.exitCode?t.exitCode:void 0,stderr:"string"==typeof t.stderr&&t.stderr.trim()?t.stderr:void 0,stdout:"string"==typeof t.stdout&&t.stdout.trim()?t.stdout:void 0,commandArgs:i}}let ec=["--time","9:41","--dataNetwork","wifi","--wifiMode","active","--wifiBars","3","--batteryState","charged","--batteryLevel","100"],ep={0:"hide",1:"wifi",6:"3g",7:"4g",8:"lte",9:"lte-a",10:"lte+",11:"5g",12:"5g+",13:"5g-uwb",14:"5g-uc"},ef={1:"searching",2:"failed",3:"active"},ew={0:"notSupported",1:"searching",2:"failed",3:"active"};async function em(e){let t=null,i=!1;try{t=await ey(e),i=!0}catch(t){ev(e,"snapshot_failed",t)}try{await eA(e),await eI(e,ec)}catch(t){ev(e,"prepare_failed",t)}return async()=>{await eh(e,i?t:null)}}async function eh(e,t){var i,a;let r;await eA(e),t&&await eI(e,(r=[],(i=t).dataNetwork&&r.push("--dataNetwork",i.dataNetwork),i.wifiMode&&r.push("--wifiMode",i.wifiMode),void 0!==i.wifiBars&&("wifi"===i.dataNetwork||i.wifiMode)&&r.push("--wifiBars",i.wifiBars),i.cellularMode&&r.push("--cellularMode",i.cellularMode),void 0!==i.cellularBars&&(i.cellularMode||(a=i.dataNetwork)&&"hide"!==a&&"wifi"!==a||void 0!==i.operatorName)&&r.push("--cellularBars",i.cellularBars),void 0!==i.operatorName&&r.push("--operatorName",i.operatorName),r))}async function ey(e){var t;let i=await (t=["status_bar",e.id,"list"],p(e,t,{allowFailure:!0}));if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to read simulator status bar overrides",{exitCode:i.exitCode,stdout:i.stdout,stderr:i.stderr});return function(e){let t={};for(let i of e.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&"Current Status Bar Overrides:"!==e&&!/^=+$/.test(e))){let e=/^DataNetworkType:\s+(\d+)$/.exec(i);if(e){let i=Number(e[1]),a=ep[i];if(!a)throw new n("COMMAND_FAILED",`Unsupported simulator data network type: ${i}`);t.dataNetwork=a;continue}let a=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(i);if(a){let e=ef[Number(a[1])];e&&(t.wifiMode=e),t.wifiBars=a[2];continue}let r=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(i);if(r){let e=Number(r[1]),i=ew[e];if(!i)throw new n("COMMAND_FAILED",`Unsupported simulator cellular mode: ${e}`);t.cellularMode=i,t.cellularBars=r[2];continue}let o=/^Operator Name:\s*(.*)$/.exec(i);if(o){t.operatorName=o[1]??"";continue}}return 0===Object.keys(t).length?null:t}(i.stdout)}async function eA(e){await p(e,["status_bar",e.id,"clear"],void 0)}async function eI(e,t){0!==t.length&&await p(e,["status_bar",e.id,"override",...t],void 0)}function ev(e,t,i){G({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...eu(i)}})}let eg={ensureBooted:C,prepareStatusBarForScreenshot:em,captureWithRetry:eb,captureWithRunner:eN,shouldFallbackToRunner:eP};async function e_(e,t,i,a,r){if("macos"===e.platform)return void await eN(e,t,i,a,r);if("simulator"===e.kind)return void await eC(e,t,i,a,void 0,r);try{await A(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},i="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=`${e.message}
2
2
  ${i}
3
3
  ${a}`.toLowerCase();return r.includes("unknown option '--device'")||r.includes("unknown subcommand")&&r.includes("screenshot")||r.includes("unrecognized subcommand")&&r.includes("screenshot")}(t))throw t;eM(e,"devicectl_screenshot",t)}await eN(e,t,i,a,r)}async function eC(e,t,i,a,r=eg,o){if("simulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");let l="object"==typeof a&&null!==a?a:r;await l.ensureBooted(e);let s=async()=>{};try{s=await l.prepareStatusBarForScreenshot(e)}catch(t){eO(e,"prepare_failed",t)}try{try{await l.captureWithRetry(e,t);return}catch(t){if(!l.shouldFallbackToRunner(t))throw t;eM(e,"simctl_screenshot",t)}await l.captureWithRunner(e,t,i,"boolean"==typeof a?a:void 0,o)}finally{await s().catch(t=>eO(e,"restore_failed",t))}}async function eb(e,t){let i=B.fromTimeoutMs(2e4);await U(async({deadline:i})=>{var a;await (a=["io",e.id,"screenshot",t],p(e,a,{timeoutMs:Math.max(1e3,i?.remainingMs()??2e4)}))},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>eP(e)},{deadline:i,phase:"ios_simulator_screenshot"})}async function eN(e,i,a,r,o){let l=(await u(e,{command:"screenshot",appBundleId:a,fullscreen:r},o)).message;if(!l)throw new n("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"macos"===e.platform?await t.copyFile(l,i):"simulator"===e.kind?await eL(e,l,i):await eS(e,l,i)}async function eS(e,t,i){let a=B.fromTimeoutMs(2e4),r={exitCode:1,stdout:"",stderr:""};for(let n of l)if(0===(r=await o(["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",i,"--domain-type","appDataContainer","--domain-identifier",n],{allowFailure:!0,timeoutMs:eD(a,2e4,"runner screenshot copy")})).exitCode)return;let s=r.stderr.trim()||r.stdout.trim()||`devicectl exited with code ${r.exitCode}`;throw new n("COMMAND_FAILED",`Failed to capture iOS screenshot: ${s}`)}async function eL(e,i,r){let o=B.fromTimeoutMs(2e4),s="Unable to locate runner container for simulator screenshot";for(let n of l){var d;let l=await (d=["get_app_container",e.id,n,"data"],p(e,d,{allowFailure:!0,timeoutMs:eD(o,2e4,"runner screenshot container lookup")}));if(0!==l.exitCode){let e=l.stderr.trim();e&&(s=e);continue}let u=l.stdout.trim();if(!u){s="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let i=a.resolve(e),r=t.trim();if(!r)return[];let n=[],o=new Set,l=e=>{let t=a.normalize(e);o.has(t)||(o.add(t),n.push(t))},s=r.replace(/^\/+/,""),d=s.replace(/\\/g,"/");if(s&&l(a.join(i,s)),a.isAbsolute(r)&&l(a.normalize(r)),d.startsWith("tmp/"))l(a.join(i,d));else{let e=d.lastIndexOf("/tmp/");if(e>=0){let t=d.slice(e+1);l(a.join(i,t))}}let u=a.basename(r);return u&&l(a.join(i,"tmp",u)),n}(u,i))try{await t.copyFile(e,r);return}catch(e){s=e instanceof Error?e.message:String(e)}}throw new n("COMMAND_FAILED",`Failed to capture iOS screenshot: ${s}`)}function eD(e,t,i){let a=e.remainingMs();if(a>0)return a;throw new n("COMMAND_FAILED",`iOS ${i} timed out after ${t}ms`,{timeoutMs:t,step:i})}function eM(e,t,i){let a=eu(i);G({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function eO(e,t,i){G({level:"warn",phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...eu(i)}})}function eP(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},i="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",r=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",o=`${e.message}
4
4
  ${i}
5
5
  ${a}
6
- ${r}`.toLowerCase();return o.includes("timeout waiting for screen surfaces")||o.includes("nsposixerrordomain")&&o.includes("code=60")&&o.includes("screenshot")||o.includes("timed out")&&o.includes("screenshot")}let eF={settings:"com.apple.Preferences"},ex=$(),eR=null;function e$(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function eE(e,t,i){return o(h(e,t),i)}function ek(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function eT(e,t){if("macos"===e.platform)return await et(t);let i=t.trim();if(i.includes("."))return i;let a=eF[i.toLowerCase()];if(a)return a;let r=e$(e),o=ex.get(r,i);if(o)return o;let l=("simulator"===e.kind?await e0(e):await g(e,"all")).filter(e=>e.name.toLowerCase()===i.toLowerCase()),s=l[0];if(void 0!==s&&1===l.length)return ex.set(r,i,s.bundleId);if(l.length>1)throw new n("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:l});throw new n("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function eU(e,t){var i;let r;if("ios"!==e.platform||"simulator"!==e.kind)return;let n=(i=t,r=/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(i.trim()),r?.[1]?.toLowerCase());if(!n)return;let o=await e1(e),l=[];for(let e of o)!e.bundleId.startsWith("com.callstack.agentdevice.runner")&&e.path&&(await e2(a.join(e.path,"Info.plist"))).has(n)&&l.push(e);let s=l.filter(e=>"User"===e.applicationType);return 1===s.length?s[0]?.bundleId:s.length>1?void 0:1===l.length?l[0]?.bundleId:void 0}async function eB(e,t,i){let a=i?.launchConsole?.trim(),r=i?.launchArgs;if(a&&("ios"!==e.platform||"simulator"!==e.kind))throw new n("UNSUPPORTED_OPERATION",b);if("macos"===e.platform){if(r&&r.length>0)throw new n("UNSUPPORTED_OPERATION","--launch-args is not supported on macOS; launch arguments are currently iOS-only.");await ei(e,t,i);return}let o=i?.url?.trim();if(o){if(a)throw new n("INVALID_ARGS",d);if(!E(o))throw new n("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){if(r||R(o)){let a=i?.appBundleId??await eT(e,t);await e7(e,a,{...r?{launchArgs:r}:{}})}await eG(e,o,void 0);return}let l=T(i?.appBundleId??await eT(e,t),o);if(!l)throw new n("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await ti(e,l,{payloadUrl:o,launchArgs:r});return}let l=t.trim();if(E(l)){if(a)throw new n("INVALID_ARGS",d);if("simulator"===e.kind)return void await eG(e,l,r);let t=T(i?.appBundleId,l);if(!t)throw new n("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");return void await ti(e,t,{payloadUrl:l,launchArgs:r})}let s=i?.appBundleId??await eT(e,t);"simulator"===e.kind?await e7(e,s,{...a?{launchConsole:a}:{},...r?{launchArgs:r}:{}}):await ti(e,s,{launchArgs:r})}async function eG(e,t,i){if(i&&i.length>0)throw new n("INVALID_ARGS","--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.");await C(e),await eE(e,["openurl",e.id,t])}async function eV(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await N(e)&&await C(e)}async function ej(e,t){if("macos"===e.platform)return void await ea(e,t);let i=await eT(e,t);if("simulator"===e.kind){await C(e);let t=h(e,["terminate",e.id,i]),a=await o(t,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new n("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await A(["device","process","terminate","--device",e.id,i],{action:"terminate iOS app",deviceId:e.id})}async function eW(e,i){if("ios"!==e.platform||"simulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Clearing app state is currently supported only on iOS simulators.");let r=await eT(e,i);await C(e),await ej(e,r);let o=await eE(e,["get_app_container",e.id,r,"data"],{allowFailure:!0});if(0!==o.exitCode)throw new n("COMMAND_FAILED",`simctl get_app_container failed for ${r}`,{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});let l=o.stdout.trim();if(!l)throw new n("COMMAND_FAILED",`simctl get_app_container returned an empty data container path for ${r}`);let s=await t.readdir(l);return await Promise.all(s.map(e=>t.rm(a.join(l,e),{recursive:!0,force:!0}))),{bundleId:r,containerPath:l}}async function eH(e,t){return await ex.invalidateWhile(e$(e),async()=>{let i=await eT(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,i],a=await o(t,{allowFailure:!0,timeoutMs:2e4});if(0!==a.exitCode){let r=String(a.stdout??""),o=String(a.stderr??"");if(!ek(`${r}
6
+ ${r}`.toLowerCase();return o.includes("timeout waiting for screen surfaces")||o.includes("nsposixerrordomain")&&o.includes("code=60")&&o.includes("screenshot")||o.includes("timed out")&&o.includes("screenshot")}let eF={settings:"com.apple.Preferences"},ex=$(),eR=null;function e$(e){return{platform:"ios",deviceId:e.id,variant:e.kind}}function eE(e,t,i){return o(h(e,t),i)}function ek(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function eT(e,t){if("macos"===e.platform)return await et(t);let i=t.trim();if(i.includes("."))return i;let a=eF[i.toLowerCase()];if(a)return a;let r=e$(e),o=ex.get(r,i);if(o)return o;let l=("simulator"===e.kind?await e0(e):await g(e,"all")).filter(e=>e.name.toLowerCase()===i.toLowerCase()),s=l[0];if(void 0!==s&&1===l.length)return ex.set(r,i,s.bundleId);if(l.length>1)throw new n("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:l});throw new n("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function eU(e,t){var i;let r;if("ios"!==e.platform||"simulator"!==e.kind)return;let n=(i=t,r=/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(i.trim()),r?.[1]?.toLowerCase());if(!n)return;let o=await e1(e),l=[];for(let e of o)!e.bundleId.startsWith("com.callstack.agentdevice.runner")&&e.path&&(await e2(a.join(e.path,"Info.plist"))).has(n)&&l.push(e);let s=l.filter(e=>"User"===e.applicationType);return 1===s.length?s[0]?.bundleId:s.length>1?void 0:1===l.length?l[0]?.bundleId:void 0}async function eB(e,t,i){let a=i?.launchConsole?.trim(),r=i?.launchArgs;if(a&&("ios"!==e.platform||"simulator"!==e.kind))throw new n("UNSUPPORTED_OPERATION",b);if("macos"===e.platform){if(r&&r.length>0)throw new n("UNSUPPORTED_OPERATION","--launch-args is not supported on macOS; launch arguments are currently iOS-only.");await ei(e,t,i);return}let o=i?.url?.trim();if(o){if(a)throw new n("INVALID_ARGS",d);if(!E(o))throw new n("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){if(r||R(o)){let a=i?.appBundleId??await eT(e,t);await e6(e,a,{...r?{launchArgs:r}:{}})}await eG(e,o,void 0);return}let l=T(i?.appBundleId??await eT(e,t),o);if(!l)throw new n("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await ti(e,l,{payloadUrl:o,launchArgs:r});return}let l=t.trim();if(E(l)){if(a)throw new n("INVALID_ARGS",d);if("simulator"===e.kind)return void await eG(e,l,r);let t=T(i?.appBundleId,l);if(!t)throw new n("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");return void await ti(e,t,{payloadUrl:l,launchArgs:r})}let s=i?.appBundleId??await eT(e,t);"simulator"===e.kind?await e6(e,s,{...a?{launchConsole:a}:{},...r?{launchArgs:r}:{}}):await ti(e,s,{launchArgs:r})}async function eG(e,t,i){if(i&&i.length>0)throw new n("INVALID_ARGS","--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.");await C(e),await eE(e,["openurl",e.id,t])}async function eV(e){"macos"===e.platform||"simulator"!==e.kind||"Booted"!==await N(e)&&await C(e)}async function ej(e,t){if("macos"===e.platform)return void await ea(e,t);let i=await eT(e,t);if("simulator"===e.kind){await C(e);let t=h(e,["terminate",e.id,i]),a=await o(t,{allowFailure:!0,timeoutMs:15e3});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new n("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await A(["device","process","terminate","--device",e.id,i],{action:"terminate iOS app",deviceId:e.id})}async function eW(e,i){if("ios"!==e.platform||"simulator"!==e.kind)throw new n("UNSUPPORTED_OPERATION","Clearing app state is currently supported only on iOS simulators.");let r=await eT(e,i);await C(e),await ej(e,r);let o=await eE(e,["get_app_container",e.id,r,"data"],{allowFailure:!0});if(0!==o.exitCode)throw new n("COMMAND_FAILED",`simctl get_app_container failed for ${r}`,{stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode});let l=o.stdout.trim();if(!l)throw new n("COMMAND_FAILED",`simctl get_app_container returned an empty data container path for ${r}`);let s=await t.readdir(l);return await Promise.all(s.map(e=>t.rm(a.join(l,e),{recursive:!0,force:!0}))),{bundleId:r,containerPath:l}}async function eH(e,t){return await ex.invalidateWhile(e$(e),async()=>{let i=await eT(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,i],a=await o(t,{allowFailure:!0,timeoutMs:2e4});if(0!==a.exitCode){let r=String(a.stdout??""),o=String(a.stderr??"");if(!ek(`${r}
7
7
  ${o}`.toLowerCase()))throw new n("COMMAND_FAILED",`Failed to uninstall iOS app ${i}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:r,stderr:o,deviceId:e.id,hint:s(r,o)??f})}return{bundleId:i}}await C(e);let a=await eE(e,["uninstall",e.id,i],{allowFailure:!0});if(0!==a.exitCode&&!ek(`${a.stdout}
8
8
  ${a.stderr}`.toLowerCase()))throw new n("COMMAND_FAILED",`simctl uninstall failed for ${i}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:i}})}async function eK(e,t,i){let a=await K({kind:"path",path:t},i);try{return await eq(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function ez(e,t,i){return await ex.invalidateWhile(e$(e),async()=>{let{bundleId:a}=await eH(e,t);return await eK(e,i,{appIdentifierHint:t}),{bundleId:a}})}async function eq(e,t){await ex.invalidateWhile(e$(e),async()=>{"simulator"!==e.kind?await A(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await C(e),await eE(e,["install",e.id,t]))})}async function eJ(e){if("macos"===e.platform)return await er();m(e,"clipboard"),await C(e);let t=await eE(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new n("COMMAND_FAILED","Failed to read iOS simulator clipboard",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return t.stdout.replace(/\r\n/g,"\n").replace(/\n$/,"")}async function eZ(e,t){if("macos"===e.platform)return void await en(t);m(e,"clipboard"),await C(e);let i=await eE(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==i.exitCode)throw new n("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})}async function eQ(e,r,n){m(e,"push"),await C(e);let o=await t.mkdtemp(a.join(i.tmpdir(),"agent-device-ios-push-")),l=a.join(o,"payload.apns");try{await t.writeFile(l,`${JSON.stringify(n)}
9
- `,"utf8"),await eE(e,["push",e.id,r,l])}finally{await t.rm(o,{recursive:!0,force:!0})}}async function eX(e,t,i,a,r){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await el(i);if("permission"===e){let e=x(i);if("deny"===e)throw new n("INVALID_ARGS",V("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new n("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(r?.permissionTarget);return await y(e,t)}throw new n("INVALID_ARGS",V(t))}m(e,"settings"),await C(e);let o=t.toLowerCase();switch(o){case"clear-app-state":{if("clear"!==i.toLowerCase())throw new n("INVALID_ARGS","settings clear-app-state only supports clear.");if(!a)throw new n("INVALID_ARGS","settings clear-app-state requires an app id or an active app session.");let t=await eW(e,a);return{bundleId:t.bundleId,containerPath:t.containerPath,cleared:!0}}case"wifi":{let t=P(i);await eE(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(P(i)?await eE(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await eE(e,["status_bar",e.id,"clear"]));case"location":{if("set"===i.toLowerCase()){let{latitude:t,longitude:i}=j(r);return await eE(e,["location",e.id,"set",`${t},${i}`]),{latitude:t,longitude:i}}let t=P(i);if(!a)throw new n("INVALID_ARGS","location setting requires an active app in session");await eE(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=e4[o],a=function(e,t){let i=e.trim().toLowerCase();if("match"===i)return"match";if("nonmatch"===i)return"nonmatch";if("enroll"===i)return"enroll";if("unenroll"===i)return"unenroll";throw new n("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(i,o);await e8(e,a,{settingName:o,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await e3(e,i);await eE(e,["ui",e.id,"appearance",t]);return}case"permission":{var l;if(!a)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(l=x(i))?"revoke":l,o=function(e,t){let i=F(e);if("photos"!==i&&t?.trim())throw new n("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===i)return"camera";if("microphone"===i)return"microphone";if("contacts"===i)return"contacts";if("contacts-limited"===i)return"contacts-limited";if("notifications"===i)return"notifications";if("calendar"===i)return"calendar";if("location"===i)return"location";if("location-always"===i)return"location-always";if("media-library"===i)return"media-library";if("motion"===i)return"motion";if("reminders"===i)return"reminders";if("siri"===i)return"siri";if("photos"===i){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new n("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new n("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(r?.permissionTarget,r?.permissionMode);await e5(e,t,o,a);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function eY(e,t){return"macos"===e.platform?await es(t):"simulator"===e.kind?I(await e0(e),t):await g(e,t)}async function e0(e){return(await e1(e)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function e1(e){let t=(await eE(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let i=null;if(t.startsWith("{"))try{i=JSON.parse(t)}catch{i=null}if(!i&&t.startsWith("{"))try{let e=await v("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(i=JSON.parse(e.stdout))}catch{i=null}return i?Object.entries(i).map(([e,t])=>{let i=function(e){if(e.Path)return e.Path;if(e.Bundle)try{return r(e.Bundle)}catch{return}}(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...i?{path:i}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}async function e2(e){let t=await v("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode)return new Set;try{let e=JSON.parse(t.stdout),i=new Set;for(let t of e.CFBundleURLTypes??[])if(Array.isArray(t.CFBundleURLSchemes))for(let e of t.CFBundleURLSchemes)"string"==typeof e&&e.trim()&&i.add(e.trim().toLowerCase());return i}catch{return new Set}}async function e3(e,t){let i=M(t);if("toggle"!==i)return i;let a=await eE(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new n("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let i=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
10
- ${t}`);if(!i)return null;let a=i[1]?.toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!r)throw new n("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===r?"light":"dark"}let e4={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function e5(e,t,i,a){let r=await e6(e);if(!r.has(i))throw new n("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${i}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(r).sort().join(", ")}`});let o=["privacy",e.id,t,i,a],l="notifications"===i;if(!("reset"===t&&l))try{await eE(e,o);return}catch(t){if(!(l&&e9(t)))throw t;throw new n("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:a,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await eE(e,o);return}catch(e){if(!e9(e))throw e}try{await eE(e,["privacy",e.id,"reset","all",a])}catch(t){throw new n("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:a,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function e9(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function e6(t){let i=k(t.simulatorSetPath),a=`${process.env.PATH??""}::${i??""}`;if(eR&&e===a)return eR;let r=await eE(t,["privacy","help"],{allowFailure:!0}),o=function(e){let t=new Set,i=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){i=!0;continue}if(!i)continue;if(e.startsWith("bundle identifier"))break;let r=/^([a-z-]+)\s+-\s+/.exec(e),n=r?.[1];void 0!==n&&t.add(n)}return t}(`${r.stdout}
11
- ${r.stderr}`);if(0===o.size)throw new n("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return eR=o,e=a,o}async function e8(e,t,i){let a=function(e,t,i){let a=i.length>0?i:["face"];switch(t){case"match":return a.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return a.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,i.modalityAliases),r=[];for(let t of a){let i=h(e,t),a=await o(i,{allowFailure:!0});if(0===a.exitCode)return;r.push({args:i,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let l=O(r);if(r.length>0&&r.every(e=>{var t,i;let a;return t=e.stdout,i=e.stderr,(a=`${t}
12
- ${i}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new n("UNSUPPORTED_OPERATION",`${i.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:i.settingName,attempts:l});throw new n("COMMAND_FAILED",`Failed to simulate ${i.settingName}.`,{deviceId:e.id,action:t,setting:i.settingName,attempts:l})}async function e7(e,t,i){await C(e);let a=0,r=B.fromTimeoutMs(6e4);try{await U(async({deadline:a})=>{var r,l,s,d;let u;if(a?.isExpired())throw new n("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:6e4});let c=(l=e.id,s=t,d=i,u=["launch"],d?.launchConsole&&u.push("--console-pty"),u.push(l,s),d?.launchArgs&&d.launchArgs.length>0&&u.push(...d.launchArgs),r=u,h(e,r)),p=i?.launchConsole?await te(c,i.launchConsole):await o(c,{allowFailure:!0});if(0!==p.exitCode)throw new n("COMMAND_FAILED",`xcrun exited with code ${p.exitCode}`,{cmd:"xcrun",args:c,stdout:p.stdout,stderr:p.stderr,exitCode:p.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!W(e)&&(a+=1)<3},{deadline:r})}catch(i){if(W(i)){var l;let a=(l=await H(e,t)).installed?!1===l.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";i.details={...i.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw i}}async function te(e,i){await t.mkdir(a.dirname(i),{recursive:!0});try{let t=await o(e,{allowFailure:!0,timeoutMs:25e3});return await tt(i,t.stdout,t.stderr),t}catch(t){let e=(t instanceof n?t:void 0)?.details;if(e?.timeoutMs===25e3){let t="string"==typeof e.stdout?e.stdout:"",a="string"==typeof e.stderr?e.stderr:"";return await tt(i,t,a),G({level:"warn",phase:"ios_simulator_launch_console_capture_timeout",data:{timeoutMs:25e3,logPath:i,stdoutBytes:Buffer.byteLength(t),stderrBytes:Buffer.byteLength(a)}}),{stdout:t,stderr:a,exitCode:0}}throw t}}async function tt(e,i,a){var r,n;await t.writeFile(e,(r=i,n=a,!r||!n||r.endsWith("\n")||r.endsWith("\r")?`${r}${n}`:`${r}
9
+ `,"utf8"),await eE(e,["push",e.id,r,l])}finally{await t.rm(o,{recursive:!0,force:!0})}}async function eX(e,t,i,a,r){if("macos"===e.platform){let e=t.toLowerCase();if("appearance"===e)return void await el(i);if("permission"===e){let e=x(i);if("deny"===e)throw new n("INVALID_ARGS",V("permission"));let t=function(e){let t=e?.trim().toLowerCase();if("accessibility"===t||"screen-recording"===t||"input-monitoring"===t)return t;throw new n("INVALID_ARGS","Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.")}(r?.permissionTarget);return await y(e,t)}throw new n("INVALID_ARGS",V(t))}m(e,"settings"),await C(e);let o=t.toLowerCase();switch(o){case"clear-app-state":{if("clear"!==i.toLowerCase())throw new n("INVALID_ARGS","settings clear-app-state only supports clear.");if(!a)throw new n("INVALID_ARGS","settings clear-app-state requires an app id or an active app session.");let t=await eW(e,a);return{bundleId:t.bundleId,containerPath:t.containerPath,cleared:!0}}case"wifi":{let t=P(i);await eE(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(P(i)?await eE(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await eE(e,["status_bar",e.id,"clear"]));case"location":{if("set"===i.toLowerCase()){let{latitude:t,longitude:i}=j(r);return await eE(e,["location",e.id,"set",`${t},${i}`]),{latitude:t,longitude:i}}let t=P(i);if(!a)throw new n("INVALID_ARGS","location setting requires an active app in session");await eE(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=e4[o],a=function(e,t){let i=e.trim().toLowerCase();if("match"===i)return"match";if("nonmatch"===i)return"nonmatch";if("enroll"===i)return"enroll";if("unenroll"===i)return"unenroll";throw new n("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(i,o);await e7(e,a,{settingName:o,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await e3(e,i);await eE(e,["ui",e.id,"appearance",t]);return}case"permission":{var l;if(!a)throw new n("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(l=x(i))?"revoke":l,o=function(e,t){let i=F(e);if("photos"!==i&&t?.trim())throw new n("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===i)return"camera";if("microphone"===i)return"microphone";if("contacts"===i)return"contacts";if("contacts-limited"===i)return"contacts-limited";if("notifications"===i)return"notifications";if("calendar"===i)return"calendar";if("location"===i)return"location";if("location-always"===i)return"location-always";if("media-library"===i)return"media-library";if("motion"===i)return"motion";if("reminders"===i)return"reminders";if("siri"===i)return"siri";if("photos"===i){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new n("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new n("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(r?.permissionTarget,r?.permissionMode);await e5(e,t,o,a);return}default:throw new n("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function eY(e,t){return"macos"===e.platform?await es(t):"simulator"===e.kind?I(await e0(e),t):await g(e,t)}async function e0(e){return(await e1(e)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function e1(e){let t=(await eE(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let i=null;if(t.startsWith("{"))try{i=JSON.parse(t)}catch{i=null}if(!i&&t.startsWith("{"))try{let e=await v("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(i=JSON.parse(e.stdout))}catch{i=null}return i?Object.entries(i).map(([e,t])=>{let i=function(e){if(e.Path)return e.Path;if(e.Bundle)try{return r(e.Bundle)}catch{return}}(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...i?{path:i}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}async function e2(e){let t=await v("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==t.exitCode)return new Set;try{let e=JSON.parse(t.stdout),i=new Set;for(let t of e.CFBundleURLTypes??[])if(Array.isArray(t.CFBundleURLSchemes))for(let e of t.CFBundleURLSchemes)"string"==typeof e&&e.trim()&&i.add(e.trim().toLowerCase());return i}catch{return new Set}}async function e3(e,t){let i=M(t);if("toggle"!==i)return i;let a=await eE(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new n("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let r=function(e,t){let i=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
10
+ ${t}`);if(!i)return null;let a=i[1]?.toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!r)throw new n("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===r?"light":"dark"}let e4={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function e5(e,t,i,a){let r=await e9(e);if(!r.has(i))throw new n("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${i}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(r).sort().join(", ")}`});let o=["privacy",e.id,t,i,a],l="notifications"===i;if(!("reset"===t&&l))try{await eE(e,o);return}catch(t){if(!(l&&e8(t)))throw t;throw new n("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:a,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await eE(e,o);return}catch(e){if(!e8(e))throw e}try{await eE(e,["privacy",e.id,"reset","all",a])}catch(t){throw new n("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:a,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function e8(e){if(!(e instanceof n)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return(t.includes("failed to grant access")||t.includes("failed to revoke access")||t.includes("failed to reset access"))&&t.includes("operation not permitted")}async function e9(t){let i=k(t.simulatorSetPath),a=`${process.env.PATH??""}::${i??""}`;if(eR&&e===a)return eR;let r=await eE(t,["privacy","help"],{allowFailure:!0}),o=function(e){let t=new Set,i=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){i=!0;continue}if(!i)continue;if(e.startsWith("bundle identifier"))break;let r=/^([a-z-]+)\s+-\s+/.exec(e),n=r?.[1];void 0!==n&&t.add(n)}return t}(`${r.stdout}
11
+ ${r.stderr}`);if(0===o.size)throw new n("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return eR=o,e=a,o}async function e7(e,t,i){let a=function(e,t,i){let a=i.length>0?i:["face"];switch(t){case"match":return a.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return a.flatMap(t=>[["biometric",e,"nonmatch",t],["biometric",e,"nomatch",t],["biometric","nonmatch",e,t],["biometric","nomatch",e,t]]);case"enroll":return[["biometric",e,"enroll","yes"],["biometric",e,"enroll","1"],["biometric","enroll",e,"yes"],["biometric","enroll",e,"1"]];case"unenroll":return[["biometric",e,"enroll","no"],["biometric",e,"enroll","0"],["biometric","enroll",e,"no"],["biometric","enroll",e,"0"]]}}(e.id,t,i.modalityAliases),r=[];for(let t of a){let i=h(e,t),a=await o(i,{allowFailure:!0});if(0===a.exitCode)return;r.push({args:i,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let l=O(r);if(r.length>0&&r.every(e=>{var t,i;let a;return t=e.stdout,i=e.stderr,(a=`${t}
12
+ ${i}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new n("UNSUPPORTED_OPERATION",`${i.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:i.settingName,attempts:l});throw new n("COMMAND_FAILED",`Failed to simulate ${i.settingName}.`,{deviceId:e.id,action:t,setting:i.settingName,attempts:l})}async function e6(e,t,i){await C(e);let a=0,r=B.fromTimeoutMs(6e4);try{await U(async({deadline:a})=>{var r,l,s,d;let u;if(a?.isExpired())throw new n("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:6e4});let c=(l=e.id,s=t,d=i,u=["launch"],d?.launchConsole&&u.push("--console-pty"),u.push(l,s),d?.launchArgs&&d.launchArgs.length>0&&u.push(...d.launchArgs),r=u,h(e,r)),p=i?.launchConsole?await te(c,i.launchConsole):await o(c,{allowFailure:!0});if(0!==p.exitCode)throw new n("COMMAND_FAILED",`xcrun exited with code ${p.exitCode}`,{cmd:"xcrun",args:c,stdout:p.stdout,stderr:p.stderr,exitCode:p.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!W(e)&&(a+=1)<3},{deadline:r})}catch(i){if(W(i)){var l;let a=(l=await H(e,t)).installed?!1===l.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";i.details={...i.details,hint:function(e){switch(e){case"ARCH_MISMATCH":return"The app binary was not built for the simulator platform. Rebuild with a simulator destination or use a physical device.";case"APP_NOT_INSTALLED":return"The app bundle is not installed on this simulator. Run install before open.";case"PERSISTENT_LAUNCH_FAIL":return"The simulator repeatedly refused to launch the app. Inspect crash logs in Console.app or ~/Library/Logs/DiagnosticReports/ and consider reinstalling the app.";default:return"The simulator failed to launch the app. Retry with --debug and inspect diagnostics log for details."}}(a)}}throw i}}async function te(e,i){await t.mkdir(a.dirname(i),{recursive:!0});try{let t=await o(e,{allowFailure:!0,timeoutMs:25e3});return await tt(i,t.stdout,t.stderr),t}catch(t){let e=(t instanceof n?t:void 0)?.details;if(e?.timeoutMs===25e3){let t="string"==typeof e.stdout?e.stdout:"",a="string"==typeof e.stderr?e.stderr:"";return await tt(i,t,a),G({level:"warn",phase:"ios_simulator_launch_console_capture_timeout",data:{timeoutMs:25e3,logPath:i,stdoutBytes:Buffer.byteLength(t),stderrBytes:Buffer.byteLength(a)}}),{stdout:t,stderr:a,exitCode:0}}throw t}}async function tt(e,i,a){var r,n;await t.writeFile(e,(r=i,n=a,!r||!n||r.endsWith("\n")||r.endsWith("\r")?`${r}${n}`:`${r}
13
13
  ${n}`),"utf8")}async function ti(e,t,i){let a=["device","process","launch","--device",e.id,t];i?.payloadUrl&&a.push("--payload-url",i.payloadUrl),i?.launchArgs&&i.launchArgs.length>0&&a.push("--",...i.launchArgs),await A(a,{action:"launch iOS app",deviceId:e.id})}export{ej as closeIosApp,eK as installIosApp,eq as installIosInstallablePath,eY as listIosApps,eB as openIosApp,eV as openIosDevice,K as prepareIosInstallArtifact,eQ as pushIosNotification,eJ as readIosClipboardText,ez as reinstallIosApp,eT as resolveIosApp,eU as resolveIosSimulatorDeepLinkBundleId,e_ as screenshotIos,eX as setIosSetting,eZ as writeIosClipboardText};
@@ -1 +1 @@
1
- export{resolveAndroidArchivePackageName}from"./7651.js";
1
+ export{resolveAndroidArchivePackageName}from"./3006.js";
@@ -22,7 +22,7 @@ export declare type BatchStepResult = {
22
22
 
23
23
  export declare function buildBatchStepFlags(parentFlags: BatchFlags | Record<string, unknown> | undefined, stepFlags: DaemonBatchStep['flags'] | Record<string, unknown> | undefined): BatchFlags;
24
24
 
25
- declare const DAEMON_LOCK_POLICIES: readonly ["reject", "strip"];
25
+ declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
26
26
 
27
27
  declare type DaemonArtifact = {
28
28
  field: string;
@@ -116,9 +116,9 @@ declare type DaemonResponseData = Record<string, unknown> & {
116
116
 
117
117
  export declare const DEFAULT_BATCH_MAX_STEPS = 100;
118
118
 
119
- export declare const INHERITED_PARENT_FLAG_KEYS: readonly ["platform", "target", "device", "udid", "serial", "verbose", "out"];
119
+ export declare const INHERITED_PARENT_FLAG_KEYS: readonly ['platform', 'target', 'device', 'udid', 'serial', 'verbose', 'out'];
120
120
 
121
- declare const LEASE_BACKENDS: readonly ["ios-simulator", "ios-instance", "android-instance"];
121
+ declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
122
122
 
123
123
  declare type LeaseBackend = (typeof LEASE_BACKENDS)[number];
124
124
 
@@ -135,7 +135,7 @@ declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
135
135
 
136
136
  export declare function runBatch(req: BatchRequest, sessionName: string, invoke: BatchInvoke): Promise<DaemonResponse>;
137
137
 
138
- declare const SESSION_ISOLATION_MODES: readonly ["none", "tenant"];
138
+ declare const SESSION_ISOLATION_MODES: readonly ['none', 'tenant'];
139
139
 
140
140
  declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
141
141
 
package/dist/src/batch.js CHANGED
@@ -1 +1 @@
1
- var _=100;export{BATCH_BLOCKED_COMMANDS,INHERITED_PARENT_FLAG_KEYS}from"./6088.js";export{buildBatchStepFlags,runBatch,validateAndNormalizeBatchSteps}from"./1231.js";export{_ as DEFAULT_BATCH_MAX_STEPS};
1
+ var _=100;export{BATCH_BLOCKED_COMMANDS,INHERITED_PARENT_FLAG_KEYS}from"./2133.js";export{buildBatchStepFlags,runBatch,validateAndNormalizeBatchSteps}from"./6918.js";export{_ as DEFAULT_BATCH_MAX_STEPS};
@@ -1,4 +1,4 @@
1
- import{listCliCommandNames as e}from"./6088.js";import{getCliCommandSchema as t,getCommandSchema as o,applyCommandDefaults as a}from"./1352.js";import{parseSourceValue as s,buildPrimaryEnvVarName as n}from"./1010.js";import{AppError as r}from"./9152.js";import{GLOBAL_FLAG_KEYS as i,getFlagDefinition as l,getFlagDefinitions as c}from"./6133.js";function d(e,t){for(let[o,a]of Object.entries(t))void 0!==a&&(e[o]=a);return e}let p=[{label:"help workflow",description:"Normal bootstrap, exploration, and validation loop"},{label:"help debugging",description:"Logs, network, perf memory, and traces"},{label:"help react-native",description:"React Native app automation hazards, overlays, Metro, and routing"},{label:"help react-devtools",description:"React Native performance, profiling, component tree, and renders"},{label:"help physical-device",description:"Connected phone/tablet setup and iOS signing prerequisites"},{label:"help remote",description:"Remote/cloud config, tenants, leases, and local service tunnels"},{label:"help macos",description:"Desktop, frontmost-app, and menu bar surfaces"},{label:"help dogfood",description:"Exploratory QA report workflow"}],u=["Default loop: devices/apps -> open -> snapshot -i -> press/fill/get/is/wait/find -> verify -> close.",'Use selectors or refs as positional targets: id="submit", label="Allow", or @e12 from snapshot -i.',"Plain snapshot reads state; snapshot -i refreshes current interactive refs only.","Default snapshot text is an agent-facing, token-efficient view for planning and targeting actions.","Read-only visible/state question: use snapshot/get/is/find; use snapshot -i only when refs are needed.","Anti-pattern: snapshot -i followed by snapshot -i | grep ...; prior refs stay valid until app state changes, and --force-full is the explicit full re-read.","Truncated text/input preview: expand first with snapshot -s @e12, not get text.","React Native apps: read help react-native for Metro, DevTools routing, and RN-specific blockers; use react-native dismiss-overlay for LogBox/RedBox overlays.","Android RN/Expo Metro: direct Android localhost URL opens with a port auto-configure host reachability.",'Expo Go/dev clients: use the provided URL when given; on iOS prefer open "Expo Go" <url>; Android URL opens infer the foreground package for logs/perf when possible.',"Install flows: install/install-from-source first, then open the installed id with --relaunch.",'Text: fill \'id="field-email"\' "qa@example.com" replaces; type appends after press.','Clearing text: do not use fill <target> ""; use a visible clear/reset control or report that clearing is unsupported.',"Android IME capture: if fill says input was captured by the keyboard/IME, inspect keyboard state and switch/disable handwriting before retrying; do not loop fill/type.","Implicit default sessions are scoped to the current worktree; use --session only when intentionally sharing a named session.","Run mutating commands serially within one session; parallelize only read-only commands or separate sessions/devices.","Clipboard limits: iOS Allow Paste cannot be automated through XCUITest; prefill with clipboard write. Android non-ASCII should use fill/type, not raw adb input.","After mutation: refs are stale. If the next target is known, use its selector directly; otherwise refresh with snapshot -i, scoped with -s when a stable container is known.","Raw coordinates are fallback-only: use snapshot -i --json rects when iOS refs no-op or child refs are missing.",'Batch JSON steps use "command" and structured "input"; legacy "positionals"/"flags" steps still run in CLI but are deprecated until the next major version.',"Navigation: app-owned back uses back; system back uses back --system.","Verification commands must name the expected text/selector; bare screenshots/snapshots are not enough.","Debug evidence: Session state contains request diagnostics and runner.log; use logs clear --restart/mark/path, trace, and network dump --include headers for app evidence.","Use agent-device commands in final plans; raw platform tools, pseudo commands, and helper prose are wrong.","Full operating guide: agent-device help workflow. Exploratory QA: agent-device help dogfood."],f=["Default config files: ~/.agent-device/config.json, ./agent-device.json","Use --config <path> or AGENT_DEVICE_CONFIG to load one explicit config file."],h=[{label:"AGENT_DEVICE_SESSION",description:"Explicit session name"},{label:"AGENT_DEVICE_PLATFORM",description:"Default platform binding"},{label:"AGENT_DEVICE_SESSION_LOCK",description:"Bound-session conflict mode"},{label:"AGENT_DEVICE_DAEMON_BASE_URL",description:"Connect to remote daemon"},{label:"AGENT_DEVICE_DAEMON_AUTH_TOKEN",description:"Remote daemon service/API token"},{label:"AGENT_DEVICE_CLOUD_BASE_URL",description:"Bridge/control-plane API origin for cloud auth and /api-keys"}],m=["agent-device open Settings --platform ios","agent-device open TextEdit --platform macos","agent-device snapshot -i","agent-device react-devtools get tree --depth 3",'agent-device fill @e3 "test@example.com"',"agent-device replay ./session.ad","agent-device test ./suite --platform android"],g={workflow:{summary:"Normal agent-device bootstrap, exploration, and validation loop",body:`agent-device help workflow
1
+ import{listCliCommandNames as e}from"./2133.js";import{getCliCommandSchema as t,getCommandSchema as a}from"./9581.js";import{getFlagDefinitions as o,GLOBAL_FLAG_KEYS as s}from"./9873.js";let n=[{label:"help workflow",description:"Normal bootstrap, exploration, and validation loop"},{label:"help debugging",description:"Logs, network, perf memory, and traces"},{label:"help react-native",description:"React Native app automation hazards, overlays, Metro, and routing"},{label:"help react-devtools",description:"React Native performance, profiling, component tree, and renders"},{label:"help physical-device",description:"Connected phone/tablet setup and iOS signing prerequisites"},{label:"help remote",description:"Remote/cloud config, tenants, leases, and local service tunnels"},{label:"help macos",description:"Desktop, frontmost-app, and menu bar surfaces"},{label:"help dogfood",description:"Exploratory QA report workflow"}],r=["Default loop: devices/apps -> open -> snapshot -i -> press/fill/get/is/wait/find -> verify -> close.",'Use selectors or refs as positional targets: id="submit", label="Allow", or @e12 from snapshot -i.',"Plain snapshot reads state; snapshot -i refreshes current interactive refs only.","Default snapshot text is an agent-facing, token-efficient view for planning and targeting actions.","Read-only visible/state question: use snapshot/get/is/find; use snapshot -i only when refs are needed.","Anti-pattern: snapshot -i followed by snapshot -i | grep ...; prior refs stay valid until app state changes, and --force-full is the explicit full re-read.","Truncated text/input preview: expand first with snapshot -s @e12, not get text.","React Native apps: read help react-native for Metro, DevTools routing, and RN-specific blockers; use react-native dismiss-overlay for LogBox/RedBox overlays.","Android RN/Expo Metro: direct Android localhost URL opens with a port auto-configure host reachability.",'Expo Go/dev clients: use the provided URL when given; on iOS prefer open "Expo Go" <url>; Android URL opens infer the foreground package for logs/perf when possible.',"Install flows: install/install-from-source first, then open the installed id with --relaunch.",'Text: fill \'id="field-email"\' "qa@example.com" replaces; type appends after press.','Clearing text: do not use fill <target> ""; use a visible clear/reset control or report that clearing is unsupported.',"Android IME capture: if fill says input was captured by the keyboard/IME, inspect keyboard state and switch/disable handwriting before retrying; do not loop fill/type.","Implicit default sessions are scoped to the current worktree; use --session only when intentionally sharing a named session.","Run mutating commands serially within one session; parallelize only read-only commands or separate sessions/devices.","Clipboard limits: iOS Allow Paste cannot be automated through XCUITest; prefill with clipboard write. Android non-ASCII should use fill/type, not raw adb input.","After mutation: refs are stale. If the next target is known, use its selector directly; otherwise refresh with snapshot -i, scoped with -s when a stable container is known.","Raw coordinates are fallback-only: use snapshot -i --json rects when iOS refs no-op or child refs are missing.",'Batch JSON steps use "command" and structured "input"; legacy "positionals"/"flags" steps still run in CLI but are deprecated until the next major version.',"Navigation: app-owned back uses back; system back uses back --system.","Verification commands must name the expected text/selector; bare screenshots/snapshots are not enough.","Debug evidence: Session state contains request diagnostics and runner.log; use logs clear --restart/mark/path, trace, and network dump --include headers for app evidence.","Use agent-device commands in final plans; raw platform tools, pseudo commands, and helper prose are wrong.","Full operating guide: agent-device help workflow. Exploratory QA: agent-device help dogfood."],i=["Default config files: ~/.agent-device/config.json, ./agent-device.json","Use --config <path> or AGENT_DEVICE_CONFIG to load one explicit config file."],l=[{label:"AGENT_DEVICE_SESSION",description:"Explicit session name"},{label:"AGENT_DEVICE_PLATFORM",description:"Default platform binding"},{label:"AGENT_DEVICE_SESSION_LOCK",description:"Bound-session conflict mode"},{label:"AGENT_DEVICE_DAEMON_BASE_URL",description:"Connect to remote daemon"},{label:"AGENT_DEVICE_DAEMON_AUTH_TOKEN",description:"Remote daemon service/API token"},{label:"AGENT_DEVICE_CLOUD_BASE_URL",description:"Bridge/control-plane API origin for cloud auth and /api-keys"}],d=["agent-device open Settings --platform ios","agent-device open TextEdit --platform macos","agent-device snapshot -i","agent-device react-devtools get tree --depth 3",'agent-device fill @e3 "test@example.com"',"agent-device replay ./session.ad","agent-device test ./suite --platform android"],c={workflow:{summary:"Normal agent-device bootstrap, exploration, and validation loop",body:`agent-device help workflow
2
2
 
3
3
  Version-matched operating guide for normal agent-device work.
4
4
 
@@ -488,37 +488,37 @@ Rules:
488
488
  Prefer refs for exploration and selectors for deterministic replay.
489
489
  Use logs, network, screenshot --overlay-refs, trace, perf metrics, perf frames, or react-devtools only when they add evidence to a specific issue.
490
490
  Never delete screenshots, videos, traces, or report artifacts during a session.
491
- Escalate to help debugging or help react-devtools when runtime symptoms require those tools.`}};function v(e){let t=e.endsWith("?"),o=t?e.slice(0,-1):e;return t?`[${o}]`:`<${o}>`}function b(e){return c().filter(t=>e.has(t.key)&&void 0!==t.usageLabel&&void 0!==t.usageDescription)}function w(e,t){return y(e,t.map(e=>({label:e.usageLabel??"",description:e.usageDescription??""})))}function y(e,t){if(0===t.length)return`${e}
492
- (none)`;let o=Math.max(...t.map(e=>e.label.length))+2,a=[e];for(let e of t)a.push(` ${e.label.padEnd(o)}${e.description}`);return a.join("\n")}function k(e,t){return 0===t.length?`${e}
493
- (none)`:[e,...t.map(e=>` ${e}`)].join("\n")}let x=new Set(["config","remoteConfig","help","version","batchSteps","githubActionsArtifact"]),A=new Set(["appsFilter","iosSimulatorDeviceSet","sessionLocked","sessionLockConflicts"]),I=function(){let o=new Map;for(let e of c()){let t=o.get(e.key);t?t.push(e):o.set(e.key,[e])}let a=new Map;for(let e of i)a.set(e,new Set(["*"]));for(let o of e())for(let e of t(o).allowedFlags??[]){let t=a.get(e);t&&t.has("*")||(t?t.add(o):a.set(e,new Set([o])))}return[...o.entries()].map(([e,t])=>({key:e,flagDefinitions:t,config:{enabled:!x.has(e),key:e},env:{names:A.has(e)?[]:[n(e)]},supportsCommand(t){let o=a.get(e);return!!o&&(!!o.has("*")||!!t&&o.has(t))}})).sort((e,t)=>e.key.localeCompare(t.key))}(),R=new Map(I.map(e=>[e.key,e]));function S(e){return R.get(e)}function U(e){return I.filter(t=>t.config.enabled&&t.supportsCommand(e))}function N(e,t){return S(e)?.supportsCommand(t)??!1}function D(e,t,o,a){return s(function(e){let t=e.flagDefinitions.find(e=>void 0===e.setValue);if(t)return t;let o=function(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}(e);if("enum"===o.type){let t=o.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>void 0!==e);return{...o,setValue:void 0,enumValues:t}}return o}(e),t,o,a)}function E(e){let t={json:!1,help:!1,version:!1},a=null,s=[],n=[],i=!0;for(let u=0;u<e.length;u+=1){var c,d,p;let f=e[u];if(i&&"--"===f){i=!1;continue}if(!i){a?s.push(f):a=P(f);continue}let h=f.startsWith("--"),m=f.startsWith("-")&&f.length>1;if(!h&&!m){a?s.push(f):a=P(f);continue}let[g,v]=h?O(f):[f,void 0];if(c=a,"-c"===g&&("snapshot"===c||"diff"===c))continue;let b=l(g);if(d=a,p=b,"react-devtools"===d&&(!p||!N(p.key,d))){s.push(f);continue}if(!b){if(function(e,t,a){var s;if(s=a,!/^-\d+(\.\d+)?$/.test(s)||!e)return!1;let n=o(e);if(!n||n.allowsExtraPositionals)return!0;let r=n.positionalArgs??[];return 0!==r.length&&(t.length<r.length||r.some(e=>e.includes("?")))}(a,s,f)){a?s.push(f):a=f;continue}throw new r("INVALID_ARGS",`Unknown flag: ${g}`)}let w=function(e,t,o,a){if(void 0!==e.setValue){if(void 0!==o)throw new r("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:e.setValue,consumeNext:!1}}if("boolean"===e.type){if(void 0!==o)throw new r("INVALID_ARGS",`Flag ${t} does not take a value.`);return{value:!0,consumeNext:!1}}if("booleanOrString"===e.type){if(void 0!==o){if(0===o.trim().length)throw new r("INVALID_ARGS",`Flag ${t} requires a non-empty value when provided.`);return{value:o,consumeNext:!1}}return void 0===a||L(a)||!function(e){let t=e.trim();return!(!t||/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t))&&!!(t.startsWith("./")||t.startsWith("../")||t.startsWith("~/")||t.startsWith("/")||t.includes("/")||t.includes("\\"))}(a)?{value:!0,consumeNext:!1}:{value:a,consumeNext:!0}}let s=o??a;if(void 0===s||void 0===o&&L(s))throw new r("INVALID_ARGS",`Flag ${t} requires a value.`);if("string"===e.type)return{value:s,consumeNext:void 0===o};if("enum"===e.type){if(!e.enumValues?.includes(s))throw new r("INVALID_ARGS",`Invalid ${_(t)}: ${s}`);return{value:s,consumeNext:void 0===o}}let n=Number(s);if(!Number.isFinite(n)||"number"==typeof e.min&&n<e.min||"number"==typeof e.max&&n>e.max)throw new r("INVALID_ARGS",`Invalid ${_(t)}: ${s}`);return{value:Math.floor(n),consumeNext:void 0===o}}(b,g,v,e[u+1]);w.consumeNext&&(u+=1);let y=t[b.key];if(b.multiple){let e=Array.isArray(y)?[...y,w.value]:void 0===y?[w.value]:[y,w.value];t[b.key]=e}else t[b.key]=w.value;n.push({key:b.key,token:g})}return{command:a,positionals:s,flags:t,warnings:[],providedFlags:n}}function C(e,t){let o=t?.strictFlags??!0,s=[...e.warnings],n=d({json:!1,help:!1,version:!1},t?.defaultFlags??{});d(n,e.flags);let i=e.providedFlags.filter(t=>!N(t.key,e.command));if(i.length>0){var l,c;let t=i.map(e=>e.token),a=(l=e.command,c=t,l?1===c.length?`Flag ${c[0]} is not supported for command ${l}.`:`Flags ${c.join(", ")} are not supported for command ${l}.`:1===c.length?`Flag ${c[0]} requires a command that supports it.`:`Flags ${c.join(", ")} require a command that supports them.`);if(o)throw new r("INVALID_ARGS",a);for(let e of(s.push(a),i))delete n[e.key]}for(let t of Object.keys(n))void 0!==n[t]&&(N(t,e.command)||delete n[t]);if(function(e){if("back"===e.command&&!(new Set(e.providedFlags.filter(e=>"backMode"===e.key).map(e=>e.token)).size<=1))throw new r("INVALID_ARGS","back accepts only one explicit mode flag: use either --in-app or --system.")}(e),a(e.command,n),"batch"===e.command&&1!=+!!n.steps+ +!!n.stepsFile)throw new r("INVALID_ARGS","batch requires exactly one step source: --steps or --steps-file.");return function(e){if(e.flags.help)return e;if("snapshot"===e.command&&e.flags.snapshotDiff){let{snapshotDiff:t,...o}=e.flags;return{command:"diff",positionals:["snapshot",...e.positionals],flags:o,warnings:e.warnings}}return e}({command:e.command,positionals:e.positionals,flags:n,warnings:s})}function O(e){let t=e.indexOf("=");return -1===t?[e,void 0]:[e.slice(0,t),e.slice(t+1)]}function _(e){return e.replace(/^-+/,"")}function L(e){if(!e.startsWith("-")||"-"===e)return!1;let[t]=e.startsWith("--")?O(e):[e,void 0];return void 0!==l(t)}function T(){let o,a,s,n,r,l,c,d;return o=`agent-device <command> [args] [--json]
491
+ Escalate to help debugging or help react-devtools when runtime symptoms require those tools.`}};function p(e){let t=e.endsWith("?"),a=t?e.slice(0,-1):e;return t?`[${a}]`:`<${a}>`}function u(){let a,o,c,p,u,v,b,w;return a=`agent-device <command> [args] [--json]
494
492
 
495
493
  CLI to control iOS and Android devices for AI agents.
496
- `,a=y("Commands:",e().map(e=>{let o=t(e);return{name:e,schema:o,usage:function(e,t){if(t.listUsageOverride)return t.listUsageOverride;let o=(t.positionalArgs??[]).map(o=>{var a,s,n;let r,i,l,c;return a=e,s=t,i=(r=(n=o).endsWith("?"))?n.slice(0,-1):n,c=(l=/^[a-z-]+(?:\|[a-z-]+)+$/i.test(i))||void 0!==s.usageOverride&&s.usageOverride.startsWith(`${a} ${i}`),r?l?`[${i}]`:c?i:`[${i}]`:c?i:`<${i}>`});return[e,...o].join(" ")}(e,o)}}).map(e=>({label:e.usage,description:e.schema.summary??e.schema.helpDescription}))),s=w("Flags:",b(i)),n=k("Agent Quickstart:",u),r=y("Agent Workflows:",p),l=k("Configuration:",f),c=y("Environment:",h),d=k("Examples:",m),`${o}
497
- ${a}
494
+ `,o=m("Commands:",e().map(e=>{let a=t(e);return{name:e,schema:a,usage:function(e,t){if(t.listUsageOverride)return t.listUsageOverride;let a=(t.positionalArgs??[]).map(a=>{var o,s,n;let r,i,l,d;return o=e,s=t,i=(r=(n=a).endsWith("?"))?n.slice(0,-1):n,d=(l=/^[a-z-]+(?:\|[a-z-]+)+$/i.test(i))||void 0!==s.usageOverride&&s.usageOverride.startsWith(`${o} ${i}`),r?l?`[${i}]`:d?i:`[${i}]`:d?i:`<${i}>`});return[e,...a].join(" ")}(e,a)}}).map(e=>({label:e.usage,description:e.schema.summary??e.schema.helpDescription}))),c=f("Flags:",h(s)),p=g("Agent Quickstart:",r),u=m("Agent Workflows:",n),v=g("Configuration:",i),b=m("Environment:",l),w=g("Examples:",d),`${a}
495
+ ${o}
498
496
 
499
- ${s}
497
+ ${c}
500
498
 
501
- ${n}
499
+ ${p}
502
500
 
503
- ${r}
501
+ ${u}
504
502
 
505
- ${l}
503
+ ${v}
506
504
 
507
- ${c}
505
+ ${b}
508
506
 
509
- ${d}
510
- `}function M(e){return function(e){var t,a;let s,n=(s=g[e])?`${s.body}
507
+ ${w}
508
+ `}function h(e){return o().filter(t=>e.has(t.key)&&void 0!==t.usageLabel&&void 0!==t.usageDescription)}function f(e,t){return m(e,t.map(e=>({label:e.usageLabel??"",description:e.usageDescription??""})))}function m(e,t){if(0===t.length)return`${e}
509
+ (none)`;let a=Math.max(...t.map(e=>e.label.length))+2,o=[e];for(let e of t)o.push(` ${e.label.padEnd(a)}${e.description}`);return o.join("\n")}function g(e,t){return 0===t.length?`${e}
510
+ (none)`:[e,...t.map(e=>` ${e}`)].join("\n")}function v(e){var t,n;let r,i=(r=c[e])?`${r.body}
511
511
 
512
512
  Related:
513
513
  agent-device help command list and global flags
514
514
  agent-device help <command> command-specific flags
515
515
  agent-device help workflow normal app automation loop
516
- `:null;if(n)return n;let r=o(e);if(!r)return null;let l=(t=e,(a=r).usageOverride?a.usageOverride:[t,...(a.positionalArgs??[]).map(v),...(a.allowedFlags??[]).flatMap(e=>{var t;return(t=e,c().filter(e=>e.key===t)).map(e=>e.usageLabel??e.names[0])}).map(e=>`[${e}]`)].join(" ")),d=b(new Set(r.allowedFlags??[])),p=b(i),u=[];return d.length>0&&u.push(w("Command flags:",d)),u.push(w("Global flags:",p)),`agent-device ${l}
516
+ `:null;if(i)return i;let l=a(e);if(!l)return null;let d=(t=e,(n=l).usageOverride?n.usageOverride:[t,...(n.positionalArgs??[]).map(p),...(n.allowedFlags??[]).flatMap(e=>{var t;return(t=e,o().filter(e=>e.key===t)).map(e=>e.usageLabel??e.names[0])}).map(e=>`[${e}]`)].join(" ")),u=h(new Set(l.allowedFlags??[])),m=h(s),g=[];return u.length>0&&g.push(f("Command flags:",u)),g.push(f("Global flags:",m)),`agent-device ${d}
517
517
 
518
- ${r.helpDescription}
518
+ ${l.helpDescription}
519
519
 
520
520
  Usage:
521
- agent-device ${l}
521
+ agent-device ${d}
522
522
 
523
- ${u.join("\n\n")}
524
- `}(P(e))}function P(e){return"long-press"===e?"longpress":"metrics"===e?"perf":e}export{T as usage,C as finalizeParsedArgs,U as getConfigurableOptionSpecs,S as getOptionSpec,d as mergeDefinedFlags,D as parseOptionValueFromSource,E as parseRawArgs,M as usageForCommand};
523
+ ${g.join("\n\n")}
524
+ `}export{v as buildCommandUsageText,u as buildUsageText};