agent-device 0.7.20 → 0.7.22

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 (128) hide show
  1. package/README.md +42 -0
  2. package/dist/src/224.js +2 -0
  3. package/dist/src/274.js +1 -0
  4. package/dist/src/331.js +3 -0
  5. package/dist/src/bin.d.ts +1 -0
  6. package/dist/src/bin.js +63 -59
  7. package/dist/src/cli-client-commands.d.ts +8 -0
  8. package/dist/src/cli.d.ts +6 -0
  9. package/dist/src/client-normalizers.d.ts +21 -0
  10. package/dist/src/client-types.d.ts +265 -0
  11. package/dist/src/client.d.ts +5 -0
  12. package/dist/src/core/app-events.d.ts +8 -0
  13. package/dist/src/core/batch.d.ts +17 -0
  14. package/dist/src/core/capabilities.d.ts +3 -0
  15. package/dist/src/core/dispatch-payload.d.ts +1 -0
  16. package/dist/src/core/dispatch-resolve.d.ts +28 -0
  17. package/dist/src/core/dispatch-series.d.ts +7 -0
  18. package/dist/src/core/dispatch.d.ts +34 -0
  19. package/dist/src/core/open-target.d.ts +4 -0
  20. package/dist/src/core/settings-contract.d.ts +8 -0
  21. package/dist/src/daemon/action-utils.d.ts +3 -0
  22. package/dist/src/daemon/app-log-android.d.ts +4 -0
  23. package/dist/src/daemon/app-log-ios.d.ts +6 -0
  24. package/dist/src/daemon/app-log-process.d.ts +15 -0
  25. package/dist/src/daemon/app-log-stream.d.ts +19 -0
  26. package/dist/src/daemon/app-log.d.ts +28 -0
  27. package/dist/src/daemon/artifact-archive.d.ts +12 -0
  28. package/dist/src/daemon/artifact-download.d.ts +12 -0
  29. package/dist/src/daemon/artifact-materialization.d.ts +17 -0
  30. package/dist/src/daemon/artifact-registry.d.ts +12 -0
  31. package/dist/src/daemon/config.d.ts +16 -0
  32. package/dist/src/daemon/context.d.ts +22 -0
  33. package/dist/src/daemon/device-ready.d.ts +6 -0
  34. package/dist/src/daemon/handlers/find.d.ts +40 -0
  35. package/dist/src/daemon/handlers/install-source.d.ts +10 -0
  36. package/dist/src/daemon/handlers/interaction.d.ts +14 -0
  37. package/dist/src/daemon/handlers/lease.d.ts +8 -0
  38. package/dist/src/daemon/handlers/parse-utils.d.ts +3 -0
  39. package/dist/src/daemon/handlers/record-trace.d.ts +15 -0
  40. package/dist/src/daemon/handlers/session-replay-heal.d.ts +8 -0
  41. package/dist/src/daemon/handlers/session-replay-script.d.ts +3 -0
  42. package/dist/src/daemon/handlers/session.d.ts +67 -0
  43. package/dist/src/daemon/handlers/snapshot.d.ts +32 -0
  44. package/dist/src/daemon/http-server.d.ts +26 -0
  45. package/dist/src/daemon/is-predicates.d.ts +14 -0
  46. package/dist/src/daemon/lease-context.d.ts +9 -0
  47. package/dist/src/daemon/lease-registry.d.ts +63 -0
  48. package/dist/src/daemon/materialized-path-registry.d.ts +15 -0
  49. package/dist/src/daemon/network-log.d.ts +32 -0
  50. package/dist/src/daemon/request-cancel.d.ts +9 -0
  51. package/dist/src/daemon/request-router.d.ts +17 -0
  52. package/dist/src/daemon/runtime-hints.d.ts +19 -0
  53. package/dist/src/daemon/script-utils.d.ts +15 -0
  54. package/dist/src/daemon/scroll-planner.d.ts +12 -0
  55. package/dist/src/daemon/selectors.d.ts +65 -0
  56. package/dist/src/daemon/server-lifecycle.d.ts +23 -0
  57. package/dist/src/daemon/session-routing.d.ts +3 -0
  58. package/dist/src/daemon/session-selector.d.ts +3 -0
  59. package/dist/src/daemon/session-store.d.ts +32 -0
  60. package/dist/src/daemon/snapshot-diff.d.ts +20 -0
  61. package/dist/src/daemon/snapshot-processing.d.ts +8 -0
  62. package/dist/src/daemon/transport.d.ts +6 -0
  63. package/dist/src/daemon/types.d.ts +115 -0
  64. package/dist/src/daemon/upload-registry.d.ts +7 -0
  65. package/dist/src/daemon/upload.d.ts +5 -0
  66. package/dist/src/daemon-client.d.ts +38 -0
  67. package/dist/src/daemon.d.ts +1 -0
  68. package/dist/src/daemon.js +36 -36
  69. package/dist/src/index.d.ts +4 -0
  70. package/dist/src/index.js +1 -0
  71. package/dist/src/platforms/android/adb.d.ts +5 -0
  72. package/dist/src/platforms/android/app-lifecycle.d.ts +30 -0
  73. package/dist/src/platforms/android/device-input-state.d.ts +19 -0
  74. package/dist/src/platforms/android/devices.d.ts +22 -0
  75. package/dist/src/platforms/android/index.d.ts +7 -0
  76. package/dist/src/platforms/android/input-actions.d.ts +12 -0
  77. package/dist/src/platforms/android/install-artifact.d.ts +11 -0
  78. package/dist/src/platforms/android/manifest.d.ts +1 -0
  79. package/dist/src/platforms/android/notifications.d.ts +11 -0
  80. package/dist/src/platforms/android/open-target.d.ts +4 -0
  81. package/dist/src/platforms/android/settings.d.ts +3 -0
  82. package/dist/src/platforms/android/snapshot.d.ts +8 -0
  83. package/dist/src/platforms/android/ui-hierarchy.d.ts +21 -0
  84. package/dist/src/platforms/appearance.d.ts +2 -0
  85. package/dist/src/platforms/boot-diagnostics.d.ts +14 -0
  86. package/dist/src/platforms/install-source.d.ts +26 -0
  87. package/dist/src/platforms/ios/apps.d.ts +34 -0
  88. package/dist/src/platforms/ios/config.d.ts +9 -0
  89. package/dist/src/platforms/ios/devicectl.d.ts +13 -0
  90. package/dist/src/platforms/ios/devices.d.ts +39 -0
  91. package/dist/src/platforms/ios/ensure-simulator.d.ts +18 -0
  92. package/dist/src/platforms/ios/index.d.ts +3 -0
  93. package/dist/src/platforms/ios/install-artifact.d.ts +18 -0
  94. package/dist/src/platforms/ios/launch-diagnostics.d.ts +11 -0
  95. package/dist/src/platforms/ios/plist.d.ts +1 -0
  96. package/dist/src/platforms/ios/runner-client.d.ts +36 -0
  97. package/dist/src/platforms/ios/runner-errors.d.ts +20 -0
  98. package/dist/src/platforms/ios/runner-session.d.ts +25 -0
  99. package/dist/src/platforms/ios/runner-transport.d.ts +10 -0
  100. package/dist/src/platforms/ios/runner-xctestrun.d.ts +18 -0
  101. package/dist/src/platforms/ios/screenshot.d.ts +13 -0
  102. package/dist/src/platforms/ios/simctl.d.ts +7 -0
  103. package/dist/src/platforms/ios/simulator.d.ts +11 -0
  104. package/dist/src/platforms/permission-utils.d.ts +9 -0
  105. package/dist/src/upload-client.d.ts +7 -0
  106. package/dist/src/utils/args.d.ts +15 -0
  107. package/dist/src/utils/command-schema.d.ts +93 -0
  108. package/dist/src/utils/device-isolation.d.ts +3 -0
  109. package/dist/src/utils/device.d.ts +27 -0
  110. package/dist/src/utils/diagnostics.d.ts +30 -0
  111. package/dist/src/utils/errors.d.ts +26 -0
  112. package/dist/src/utils/exec.d.ts +32 -0
  113. package/dist/src/utils/finders.d.ts +12 -0
  114. package/dist/src/utils/interactive.d.ts +1 -0
  115. package/dist/src/utils/interactors.d.ts +31 -0
  116. package/dist/src/utils/json-input.d.ts +1 -0
  117. package/dist/src/utils/keyed-lock.d.ts +1 -0
  118. package/dist/src/utils/output.d.ts +25 -0
  119. package/dist/src/utils/payload-input.d.ts +12 -0
  120. package/dist/src/utils/process-identity.d.ts +11 -0
  121. package/dist/src/utils/retry.d.ts +54 -0
  122. package/dist/src/utils/snapshot-lines.d.ts +12 -0
  123. package/dist/src/utils/snapshot.d.ts +42 -0
  124. package/dist/src/utils/timeouts.d.ts +3 -0
  125. package/dist/src/utils/version.d.ts +2 -0
  126. package/package.json +9 -1
  127. package/skills/agent-device/references/session-management.md +1 -1
  128. package/dist/src/678.js +0 -3
@@ -1,41 +1,41 @@
1
- let e;import{isCancel as t,select as r}from"@clack/prompts";import{formatSnapshotLine as i,node_path as n,readProcessCommand as a,normalizeTenantId as o,isAgentDeviceDaemonProcess as s,runCmdDetached as l,runCmdBackground as d,node_crypto as u,validateAndNormalizeBatchSteps as c,runCmd as p,SETTINGS_INVALID_ARGS_MESSAGE as f,displayLabel as m,spawn as h,asAppError as w,pathToFileURL as g,AppError as I,external_node_url_URL as v,whichCmd as A,buildSnapshotDisplayLines as y,fileURLToPath as b,runCmdStreaming as N,formatRole as S,normalizeError as _,resolveSessionIsolationMode as D,readVersion as E,findProjectRoot as k,getDiagnosticsMeta as O,withDiagnosticTimer as L,emitDiagnostic as M,promises as x,DEFAULT_BATCH_MAX_STEPS as C,isProcessAlive as R,readProcessStartTime as T,withDiagnosticsScope as P,node_fs as $,flushDiagnosticsToSessionFile as F,node_os as V,node_net as U,resolveDaemonServerMode as G,resolveDaemonPaths as B,node_http as j}from"./678.js";let q=H(process.env.AGENT_DEVICE_RETRY_LOGS);function H(e){return["1","true","yes","on"].includes((e??"").toLowerCase())}let W=2e4,J=12e4,z=1e4;class K{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new K(t,e)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return 0>=this.remainingMs(e)}}async function X(e,t={},r={}){let i,n={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=n.maxAttempts;t+=1){if(r.signal?.aborted)throw new I("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(r.deadline?.isExpired()&&t>1)break;try{let i=await e({attempt:t,maxAttempts:n.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),Z({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),i}catch(d){i=d;let e=r.classifyReason?.(d),a={phase:r.phase,event:"attempt_failed",attempt:t,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};if(r.onEvent?.(a),Z(a),t>=n.maxAttempts||n.shouldRetry&&!n.shouldRetry(d,t))break;let o=function(e,t,r,i){let n=Math.min(t,e*2**(i-1));return Math.max(0,n+n*r*(2*Math.random()-1))}(n.baseDelayMs,n.maxDelayMs,n.jitter,t),s=r.deadline?Math.min(o,r.deadline.remainingMs()):o;if(s<=0)break;let l={phase:r.phase,event:"retry_scheduled",attempt:t,maxAttempts:n.maxAttempts,delayMs:s,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};r.onEvent?.(l),Z(l),await function(e,t){return new Promise(r=>{let i;if(t?.aborted)return void r();let n=!1,a=()=>{n||(n=!0,t&&i&&t.removeEventListener("abort",i),r())},o=setTimeout(a,e);i=()=>{clearTimeout(o),a()},t&&t.addEventListener("abort",i,{once:!0})})}(s,r.signal)}}let a={phase:r.phase,event:"exhausted",attempt:n.maxAttempts,maxAttempts:n.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(i)};if(r.onEvent?.(a),Z(a),i)throw i;throw new I("COMMAND_FAILED","retry failed")}async function Y(e,t={}){return X(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function Z(e){M({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),q&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
2
- `)}let Q=new Set,ee=new Map,et="request_canceled",er="request canceled";function ei(e,t){if("string"==typeof e&&e.length>0)return e;let r=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",i=Math.random().toString(36).slice(2,10);return`req:${r}:${process.pid}:${Date.now()}:${i}`}function en(e){if(!e)return;let t=new AbortController;ee.set(e,t),Q.has(e)&&t.abort()}function ea(e){e&&(Q.add(e),ee.get(e)?.abort())}function eo(e){e&&(Q.delete(e),ee.delete(e))}function es(e){return!!e&&Q.has(e)}function el(){return new I("COMMAND_FAILED",er,{reason:et})}function ed(e){return e instanceof I&&"COMMAND_FAILED"===e.code&&(e.details?.reason===et||e.message===er)}function eu(e){let t=e.error?w(e.error):null,r=e.context?.platform,i=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===r?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let n=t?.details??{},a="string"==typeof n.message?n.message:void 0,o="string"==typeof n.stdout?n.stdout:void 0,s="string"==typeof n.stderr?n.stderr:void 0,l=n.boot&&"object"==typeof n.boot?n.boot:null,d=n.bootstatus&&"object"==typeof n.bootstatus?n.bootstatus:null,u=[e.message,t?.message,e.stdout,e.stderr,a,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof d?.stdout?d.stdout:void 0,"string"==typeof d?.stderr?d.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===r&&(u.includes("runner did not accept connection")||"connect"===i&&(u.includes("timed out")||u.includes("timeout")||u.includes("econnrefused")||u.includes("connection refused")||u.includes("fetch failed")||u.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===r&&"boot"===i&&(u.includes("timed out")||u.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===r&&"boot"===i&&(u.includes("timed out")||u.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":u.includes("resource temporarily unavailable")||u.includes("killed: 9")||u.includes("cannot allocate memory")||u.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===r&&(u.includes("device not found")||u.includes("no devices")||u.includes("device offline")||u.includes("offline")||u.includes("unauthorized")||u.includes("not authorized")||u.includes("unable to locate device")||u.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||u.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function ec(e){switch(e){case"IOS_BOOT_TIMEOUT":return"Retry simulator boot and inspect simctl bootstatus logs; in CI consider increasing AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS.";case"IOS_RUNNER_CONNECT_TIMEOUT":return"Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.";case"ANDROID_BOOT_TIMEOUT":return"Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.";case"ADB_TRANSPORT_UNAVAILABLE":return"Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.";case"CI_RESOURCE_STARVATION_SUSPECTED":return"CI machine may be resource constrained; reduce parallel jobs or use a larger runner.";case"IOS_TOOL_MISSING":return"Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.";case"BOOT_COMMAND_FAILED":return"Inspect command stderr/stdout for the failing boot phase and retry after environment validation.";default:return"Retry once and inspect verbose logs for the failing phase."}}function ep(e){return!(e instanceof I)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function ef(e){let{port:t,endpoints:r,logPath:i,lastError:n}=e,a="Runner did not accept connection";return new I("COMMAND_FAILED",a,{port:t,endpoints:r,logPath:i,lastError:n?String(n):void 0,reason:eu({error:n,message:a,context:{platform:"ios",phase:"connect"}}),hint:ec("IOS_RUNNER_CONNECT_TIMEOUT")})}async function em(e){var t,r;let i,{session:n,port:a,logPath:o}=e,s=await n.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=eu({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new I("COMMAND_FAILED",l,{port:a,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,r=s.stderr,(i=`${l}
1
+ let e;import{isCancel as t,select as r}from"@clack/prompts";import a from"node:fs/promises";import{node_path as i,readProcessCommand as n,normalizeTenantId as o,isAgentDeviceDaemonProcess as s,runCmdDetached as l,runCmdBackground as d,node_crypto as u,runCmd as c,spawn as p,asAppError as f,pathToFileURL as m,AppError as h,external_node_url_URL as w,whichCmd as g,fileURLToPath as I,runCmdStreaming as v,normalizeError as A,resolveSessionIsolationMode as y,readVersion as b,findProjectRoot as N,getDiagnosticsMeta as _,withDiagnosticTimer as S,emitDiagnostic as D,promises as E,isProcessAlive as k,readProcessStartTime as L,withDiagnosticsScope as O,node_fs as M,flushDiagnosticsToSessionFile as x,node_os as C,node_net as R,resolveDaemonServerMode as T,resolveDaemonPaths as P,node_http as $}from"./331.js";import{buildSnapshotDisplayLines as F,DEFAULT_BATCH_MAX_STEPS as U,formatRole as V,validateAndNormalizeBatchSteps as G,SETTINGS_INVALID_ARGS_MESSAGE as j,displayLabel as B,TextDecoder as q,formatSnapshotLine as H}from"./274.js";let W=z(process.env.AGENT_DEVICE_RETRY_LOGS);function z(e){return["1","true","yes","on"].includes((e??"").toLowerCase())}let J=2e4,K=12e4,X=1e4;class Z{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(e,t=Date.now()){return new Z(t,e)}remainingMs(e=Date.now()){return Math.max(0,this.expiresAtMs-e)}elapsedMs(e=Date.now()){return Math.max(0,e-this.startedAtMs)}isExpired(e=Date.now()){return 0>=this.remainingMs(e)}}async function Y(e,t={},r={}){let a,i={maxAttempts:t.maxAttempts??3,baseDelayMs:t.baseDelayMs??200,maxDelayMs:t.maxDelayMs??2e3,jitter:t.jitter??.2,shouldRetry:t.shouldRetry};for(let t=1;t<=i.maxAttempts;t+=1){if(r.signal?.aborted)throw new h("COMMAND_FAILED","request canceled",{reason:"request_canceled"});if(r.deadline?.isExpired()&&t>1)break;try{let a=await e({attempt:t,maxAttempts:i.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),ee({phase:r.phase,event:"succeeded",attempt:t,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),a}catch(d){a=d;let e=r.classifyReason?.(d),n={phase:r.phase,event:"attempt_failed",attempt:t,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};if(r.onEvent?.(n),ee(n),t>=i.maxAttempts||i.shouldRetry&&!i.shouldRetry(d,t))break;let o=function(e,t,r,a){let i=Math.min(t,e*2**(a-1));return Math.max(0,i+i*r*(2*Math.random()-1))}(i.baseDelayMs,i.maxDelayMs,i.jitter,t),s=r.deadline?Math.min(o,r.deadline.remainingMs()):o;if(s<=0)break;let l={phase:r.phase,event:"retry_scheduled",attempt:t,maxAttempts:i.maxAttempts,delayMs:s,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:e};r.onEvent?.(l),ee(l),await function(e,t){return new Promise(r=>{let a;if(t?.aborted)return void r();let i=!1,n=()=>{i||(i=!0,t&&a&&t.removeEventListener("abort",a),r())},o=setTimeout(n,e);a=()=>{clearTimeout(o),n()},t&&t.addEventListener("abort",a,{once:!0})})}(s,r.signal)}}let n={phase:r.phase,event:"exhausted",attempt:i.maxAttempts,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(a)};if(r.onEvent?.(n),ee(n),a)throw a;throw new h("COMMAND_FAILED","retry failed")}async function Q(e,t={}){return Y(()=>e(),{maxAttempts:t.attempts,baseDelayMs:t.baseDelayMs,maxDelayMs:t.maxDelayMs,jitter:t.jitter,shouldRetry:t.shouldRetry})}function ee(e){D({level:"attempt_failed"===e.event||"exhausted"===e.event?"warn":"debug",phase:"retry",data:{...e}}),W&&process.stderr.write(`[agent-device][retry] ${JSON.stringify(e)}
2
+ `)}let et=new Set,er=new Map,ea="request_canceled",ei="request canceled";function en(e,t){if("string"==typeof e&&e.length>0)return e;let r=("string"==typeof t?t:"number"==typeof t&&Number.isFinite(t)?String(t):"generated").trim().replace(/[^a-zA-Z0-9_-]/g,"_").slice(0,32)||"generated",a=Math.random().toString(36).slice(2,10);return`req:${r}:${process.pid}:${Date.now()}:${a}`}function eo(e){if(!e)return;let t=new AbortController;er.set(e,t),et.has(e)&&t.abort()}function es(e){e&&(et.add(e),er.get(e)?.abort())}function el(e){e&&(et.delete(e),er.delete(e))}function ed(e){return!!e&&et.has(e)}function eu(e){if(e)return er.get(e)?.signal}function ec(){return new h("COMMAND_FAILED",ei,{reason:ea})}function ep(e){return e instanceof h&&"COMMAND_FAILED"===e.code&&(e.details?.reason===ea||e.message===ei)}function ef(e){let t=e.error?f(e.error):null,r=e.context?.platform,a=e.context?.phase;if(t?.code==="TOOL_MISSING")return"android"===r?"ADB_TRANSPORT_UNAVAILABLE":"IOS_TOOL_MISSING";let i=t?.details??{},n="string"==typeof i.message?i.message:void 0,o="string"==typeof i.stdout?i.stdout:void 0,s="string"==typeof i.stderr?i.stderr:void 0,l=i.boot&&"object"==typeof i.boot?i.boot:null,d=i.bootstatus&&"object"==typeof i.bootstatus?i.bootstatus:null,u=[e.message,t?.message,e.stdout,e.stderr,n,o,s,"string"==typeof l?.stdout?l.stdout:void 0,"string"==typeof l?.stderr?l.stderr:void 0,"string"==typeof d?.stdout?d.stdout:void 0,"string"==typeof d?.stderr?d.stderr:void 0].filter(Boolean).join("\n").toLowerCase();return"ios"===r&&(u.includes("runner did not accept connection")||"connect"===a&&(u.includes("timed out")||u.includes("timeout")||u.includes("econnrefused")||u.includes("connection refused")||u.includes("fetch failed")||u.includes("socket hang up")))?"IOS_RUNNER_CONNECT_TIMEOUT":"ios"===r&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"IOS_BOOT_TIMEOUT":"android"===r&&"boot"===a&&(u.includes("timed out")||u.includes("timeout"))?"ANDROID_BOOT_TIMEOUT":u.includes("resource temporarily unavailable")||u.includes("killed: 9")||u.includes("cannot allocate memory")||u.includes("system is low on memory")?"CI_RESOURCE_STARVATION_SUSPECTED":"android"===r&&(u.includes("device not found")||u.includes("no devices")||u.includes("device offline")||u.includes("offline")||u.includes("unauthorized")||u.includes("not authorized")||u.includes("unable to locate device")||u.includes("invalid device"))?"ADB_TRANSPORT_UNAVAILABLE":t?.code==="COMMAND_FAILED"||u.length>0?"BOOT_COMMAND_FAILED":"UNKNOWN"}function em(e){switch(e){case"IOS_BOOT_TIMEOUT":return"Retry simulator boot and inspect simctl bootstatus logs; in CI consider increasing AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS.";case"IOS_RUNNER_CONNECT_TIMEOUT":return"Retry runner startup, inspect xcodebuild logs, and verify simulator responsiveness before command execution.";case"ANDROID_BOOT_TIMEOUT":return"Retry emulator startup and verify sys.boot_completed reaches 1; consider increasing startup budget in CI.";case"ADB_TRANSPORT_UNAVAILABLE":return"Check adb server/device transport (adb devices -l), restart adb, and ensure the target device is online and authorized.";case"CI_RESOURCE_STARVATION_SUSPECTED":return"CI machine may be resource constrained; reduce parallel jobs or use a larger runner.";case"IOS_TOOL_MISSING":return"Xcode command-line tools are missing or not in PATH; run xcode-select --install and verify xcrun works.";case"BOOT_COMMAND_FAILED":return"Inspect command stderr/stdout for the failing boot phase and retry after environment validation.";default:return"Retry once and inspect verbose logs for the failing phase."}}function eh(e){return!(e instanceof h)||"COMMAND_FAILED"!==e.code||!String(e.message??"").toLowerCase().includes("xcodebuild exited early")}function ew(e){let{port:t,endpoints:r,logPath:a,lastError:i}=e,n="Runner did not accept connection";return new h("COMMAND_FAILED",n,{port:t,endpoints:r,logPath:a,lastError:i?String(i):void 0,reason:ef({error:i,message:n,context:{platform:"ios",phase:"connect"}}),hint:em("IOS_RUNNER_CONNECT_TIMEOUT")})}async function eg(e){var t,r;let a,{session:i,port:n,logPath:o}=e,s=await i.testPromise,l="Runner did not accept connection (xcodebuild exited early)",d=ef({message:l,stdout:s.stdout,stderr:s.stderr,context:{platform:"ios",phase:"connect"}});return new h("COMMAND_FAILED",l,{port:n,logPath:o,xcodebuild:{exitCode:s.exitCode,stdout:s.stdout,stderr:s.stderr},reason:d,hint:(t=s.stdout,r=s.stderr,(a=`${l}
3
3
  ${t}
4
- ${r}`.toLowerCase()).includes("device is busy")&&i.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":ec("IOS_RUNNER_CONNECT_TIMEOUT"))})}function eh(e){if(es(e))throw el()}function ew(e,t,r){if(!e)return t;let i=Number(e);return Number.isFinite(i)?Math.max(r,Math.floor(i)):t}let eg=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],eI=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function ev(e){return e?.trim()||void 0}function eA(e,t){for(let r of e){let e=ev(t[r]);if(e)return e}}function ey(e,t=process.env){return ev(e)??eA(eg,t)}function eb(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function eN(e,t=process.env){let r=ev(e)??eA(eI,t);if(r)return eb(r)}function eS(e,t={}){let r=ey(t.simulatorSetPath);return r?["simctl","--set",r,...e]:["simctl",...e]}function e_(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:eS(t,{simulatorSetPath:e.simulatorSetPath})}let eD=ew(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),eE=ew(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),ek=ew(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),eO=ew(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),eL=ew(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),eM=ew(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),ex=ew(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),eC=ew(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function eR(e,t,r,i,n=eD,a,o){let s=K.fromTimeoutMs(n),l=await eT(e,t,s.remainingMs()),d=null,u=Math.max(1,Math.ceil(n/ek));try{return await X(async({deadline:s})=>{if(s?.isExpired())throw new I("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:n});if(a&&null!==a.child.exitCode&&void 0!==a.child.exitCode)throw await em({session:a,port:t,logPath:i});for(let i of("device"===e.kind&&(l=await eT(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??n;if(e<=0)throw new I("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:n});return await eP(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},Math.min(eM,e),o)}catch(e){if(o?.aborted||ed(e))throw el();d=e}throw new I("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:d?String(d):void 0})},{maxAttempts:u,baseDelayMs:eO,maxDelayMs:eL,jitter:.2,shouldRetry:ep},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||ed(e))throw el();d||(d=e)}if(o?.aborted)throw el();if("simulator"===e.kind){let n=s.remainingMs();if(n<=0)throw ef({port:t,endpoints:l,logPath:i,lastError:d});let a=await eF(e,t,r,n);return new Response(a.body,{status:a.status})}throw ef({port:t,endpoints:l,logPath:i,lastError:d})}async function eT(e,t,r){let i=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return i;let n=await e$(e.id,r);return n&&i.unshift(`http://[${n}]:${t}/command`),i}async function eP(e,t,r,i){let n,a=new AbortController,o=setTimeout(()=>a.abort(),r);i&&(i.aborted?(clearTimeout(o),a.abort()):(n=()=>a.abort(),i.addEventListener("abort",n,{once:!0})));try{return await fetch(e,{...t,signal:a.signal})}finally{clearTimeout(o),n&&i&&i.removeEventListener("abort",n)}}async function e$(e,t){if("number"==typeof t&&t<=0)return null;let r="number"==typeof t?Math.max(1,Math.min(ex,t)):ex,i=n.join(V.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(r/1e3)),n=await p("xcrun",["devicectl","device","info","details","--device",e,"--json-output",i,"--timeout",String(t)],{allowFailure:!0,timeoutMs:r});if(0!==n.exitCode||!$.existsSync(i))return null;let a=JSON.parse($.readFileSync(i,"utf8"));if(a.info?.outcome&&"success"!==a.info.outcome)return null;let o=(a.result?.connectionProperties?.tunnelIPAddress??a.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return o&&o.length>0?o:null}catch{return null}finally{eG(i)}}async function eF(e,t,r,i){let n=JSON.stringify(r),a=e_(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",n,`http://127.0.0.1:${t}/command`]),o=await p("xcrun",a,{allowFailure:!0,timeoutMs:i}),s=o.stdout;if(0!==o.exitCode){let e=eu({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new I("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:ec(e)})}return{status:200,body:s}}async function eV(){return await new Promise((e,t)=>{let r=U.createServer();r.listen(0,"127.0.0.1",()=>{let i=r.address();r.close(),"object"==typeof i&&i?.port?e(i.port):t(new I("COMMAND_FAILED","Failed to allocate port"))}),r.on("error",t)})}function eU(e,t,r,i){t&&$.appendFileSync(t,e),r&&$.appendFileSync(r,e),i&&process.stderr.write(e)}function eG(e){try{$.existsSync(e)&&$.unlinkSync(e)}catch{}}async function eB(e,t,r){let i=(e.get(t)??Promise.resolve()).catch(()=>{}).then(r);return e.set(t,i),i.finally(()=>{e.get(t)===i&&e.delete(t)})}function ej(e){return"apple"===e?"ios":e}async function eq(e,i,n={}){let a=e,o=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(i.platform&&(a=a.filter(e=>e.platform===i.platform)),i.target&&(a=a.filter(e=>(e.target??"mobile")===i.target)),i.udid){let e=a.find(e=>e.id===i.udid&&"ios"===e.platform);if(!e)throw new I("DEVICE_NOT_FOUND",`No iOS device with UDID ${i.udid}`);return e}if(i.serial){let e=a.find(e=>e.id===i.serial&&"android"===e.platform);if(!e)throw new I("DEVICE_NOT_FOUND",`No Android device with serial ${i.serial}`);return e}if(i.deviceName){let e=o(i.deviceName),t=a.find(t=>o(t.name)===e);if(!t)throw new I("DEVICE_NOT_FOUND",`No device named ${i.deviceName}`);return t}if(1===a.length)return a[0];if(0===a.length){let e=n.simulatorSetPath;if(e&&(!i.platform||"ios"===i.platform))throw new I("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
5
- xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:i});throw new I("DEVICE_NOT_FOUND","No devices found",{selector:i})}let s=a.filter(e=>"device"!==e.kind);s.length>0&&(a=s);let l=a.filter(e=>e.booted);if(1===l.length)return l[0];if(!process.env.CI&&process.stdin.isTTY&&process.stdout.isTTY){let e=await r({message:"Multiple devices available. Choose a device to continue:",options:(l.length>0?l:a).map(e=>({label:`${e.name} (${e.platform}${e.kind?`, ${e.kind}`:""}${e.booted?", booted":""})`,value:e.id}))});if(t(e))throw new I("INVALID_ARGS","Device selection cancelled");if(e){let t=a.find(t=>t.id===e);if(t)return t}}return l[0]??a[0]}let eH=n.join(V.homedir(),".agent-device","ios-runner"),eW=new Map,eJ=new Set;function ez(e){return e?.trim()??""}function eK(e=process.env){return ez(e.AGENT_DEVICE_IOS_BUNDLE_ID)||ez(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function eX(e=process.env){let t=ez(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${eK(e)}.uitests`}let eY=function(e=process.env){let t=eK(e),r=eX(e);return Array.from(new Set([ez(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${r}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);async function eZ(e,t){var r;let i,a=(r=e.kind,(i=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?n.resolve(i):"simulator"===r?n.join(eH,"derived"):n.join(eH,"derived",r));return await eB(eW,a,async()=>{if(H(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)){!function(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return H(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new I("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}(a);try{$.rmSync(a,{recursive:!0,force:!0})}catch{}}let r=eQ(a);if(r)return r;let i=function(){let e=n.dirname(b(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=n.join(t,"package.json");if($.existsSync(e))return t;t=n.dirname(t)}return e}(),o=n.join(i,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!$.existsSync(o))throw new I("COMMAND_FAILED","iOS runner project not found",{projectPath:o});let s=function(e=process.env){let t=eK(e),r=eX(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${r}`]}(process.env),l=function(e=process.env,t=!1){if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",i=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",n=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",a=["CODE_SIGN_STYLE=Automatic"];return r&&a.push(`DEVELOPMENT_TEAM=${r}`),i&&a.push(`CODE_SIGN_IDENTITY=${i}`),n&&a.push(`PROVISIONING_PROFILE_SPECIFIER=${n}`),a}(process.env,"device"===e.kind),d="device"===e.kind?["-allowProvisioningUpdates"]:[];try{var u;let r;await N("xcodebuild",["build-for-testing","-project",o,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",e2(e),"1","-destination",(u=e,r=e1(u),"simulator"===u.kind?`platform=${r} Simulator,id=${u.id}`:`generic/platform=${r}`),"-derivedDataPath",a,"COMPILER_INDEX_STORE_ENABLE=NO",...s,...d,...l],{detached:!0,onSpawn:e=>{eJ.add(e),e.on("close",()=>{eJ.delete(e)})},onStdoutChunk:e=>{eU(e,t.logPath,t.traceLogPath,t.verbose)},onStderrChunk:e=>{eU(e,t.logPath,t.traceLogPath,t.verbose)}})}catch(a){let e,r,i=a instanceof I?a:new I("COMMAND_FAILED",String(a)),n=(e=i.details?JSON.stringify(i.details):"",(r=`${i.message}
6
- ${e}`.toLowerCase()).includes("failed registering bundle identifier")||r.includes("app identifier")&&r.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":r.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":r.includes("no profiles for")||r.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":r.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new I("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:i.message,details:i.details,logPath:t.logPath,hint:n})}let c=eQ(a);if(!c)throw new I("COMMAND_FAILED","Failed to locate .xctestrun after build");return c})}function eQ(e){if(!$.existsSync(e))return null;let t=[],r=[e];for(;r.length>0;){let e=r.pop();for(let i of $.readdirSync(e,{withFileTypes:!0})){let a=n.join(e,i.name);if(i.isDirectory()){r.push(a);continue}if(i.isFile()&&i.name.endsWith(".xctestrun"))try{let e=$.statSync(a);t.push({path:a,mtimeMs:e.mtimeMs})}catch{}}}return 0===t.length?null:(t.sort((e,t)=>t.mtimeMs-e.mtimeMs),t[0]?.path??null)}async function e0(e,t,r){let i,a=n.dirname(e),o=r.replace(/[^a-zA-Z0-9._-]/g,"_"),s=n.join(a,`AgentDeviceRunner.env.${o}.json`),l=n.join(a,`AgentDeviceRunner.env.${o}.xctestrun`),d=await p("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==d.exitCode||!d.stdout.trim())throw new I("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:d.stderr});try{i=JSON.parse(d.stdout)}catch(t){throw new I("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let u=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},c=i.TestConfigurations;if(Array.isArray(c))for(let e of c){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&u(e)}for(let[e,t]of Object.entries(i))t&&"object"==typeof t&&t.TestBundlePath&&(u(t),i[e]=t);$.writeFileSync(s,JSON.stringify(i,null,2));let f=await p("plutil",["-convert","xml1","-o",l,s],{allowFailure:!0});if(0!==f.exitCode)throw new I("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:l,stderr:f.stderr});return{xctestrunPath:l,jsonPath:s}}function e1(e){if("ios"!==e.platform)throw new I("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"tv"===e.target?"tvOS":"iOS"}function e2(e){return"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}let e3=new Map,e4=new Map;async function e8(e,t){return await eB(e4,e.id,async()=>{var r,i;let n,a=e3.get(e.id);if(a){if((r=a.child.pid)&&R(r))return a;await e6(e.id,a)}await ("simulator"!==(i=e).kind?Promise.resolve():tr(i));let o=await eZ(e,t),s=await eV(),{xctestrunPath:l,jsonPath:u}=await e0(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),{child:c,wait:p}=d("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",e2(e),"1","-destination-timeout",String(eC),"-xctestrun",l,"-destination",(n=e1(e),"simulator"===e.kind?`platform=${n} Simulator,id=${e.id}`:`platform=${n},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0});c.stdout?.on("data",e=>{eU(e,t.logPath,t.traceLogPath,t.verbose)}),c.stderr?.on("data",e=>{eU(e,t.logPath,t.traceLogPath,t.verbose)});let f={device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:u,testPromise:p,child:c,ready:!1};return e3.set(e.id,f),f})}async function e5(e){await eB(e4,e.deviceId,async()=>{await e6(e.deviceId,e)})}async function e6(e,t){let r=t??e3.get(e);if(r){try{await eR(r.device,r.port,{command:"shutdown"},void 0,15e3)}catch{await tt(r.child.pid,"SIGTERM")}try{await Promise.race([r.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}await tt(r.child.pid,"SIGKILL"),eG(r.xctestrunPath),eG(r.jsonPath),e3.get(e)===r&&e3.delete(e)}}async function e9(e){await eB(e4,e,async()=>{await e6(e)})}async function e7(){let e=Array.from(e3.values()),t=Array.from(eJ);await Promise.allSettled(e.map(async e=>{await tt(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await tt(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await tt(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await tt(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await tt(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await tt(e.pid,"SIGKILL"),eJ.delete(e)}))}async function te(){await e7();let e=Array.from(e3.keys());await Promise.allSettled(e.map(async e=>{await e9(e)}));let t=Array.from(eJ);await Promise.allSettled(t.map(async e=>{try{await tt(e.pid,"SIGTERM"),await tt(e.pid,"SIGKILL")}finally{eJ.delete(e)}}))}async function tt(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}try{process.kill(e,t)}catch{}let r="SIGINT"===t?"INT":"SIGTERM"===t?"TERM":"KILL";try{await p("pkill",[`-${r}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function tr(e){await p("xcrun",e_(e,["bootstatus",e.id,"-b"]),{timeoutMs:eD})}async function ti(e,t,r,i,n,a){let o=await eR(e,t.port,r,i,n,t,a);return await tn(o,t,i)}async function tn(e,t,r){let i=await e.text(),n={};try{n=JSON.parse(i)}catch{throw new I("COMMAND_FAILED","Invalid runner response",{text:i})}if(!n.ok)throw new I("COMMAND_FAILED",n.error?.message??"Runner error",{runner:n,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:r});return t.ready=!0,n.data??{}}async function ta(e,t,r={}){var i;if("ios"!==e.platform)throw new I("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new I("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(eh(r.requestId),"snapshot"===(i=t.command)||"screenshot"===i||"findText"===i||"alert"===i)?Y(()=>(eh(r.requestId),to(e,t,r)),{shouldRetry:e=>{eh(r.requestId);if(!(e instanceof I)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}}):to(e,t,r)}async function to(e,t,r={}){let i;eh(r.requestId);let n=function(e){if(e)return ee.get(e)?.signal}(r.requestId);try{let a=(i=await e8(e,r)).ready?eE:eD;return await ti(e,i,t,r.logPath,a,n)}catch(o){let a=o instanceof I?o:new I("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===a.code&&"string"==typeof a.message&&a.message.includes("Runner did not accept connection")&&ep(a)&&i?.ready){eh(r.requestId),i?await e5(i):await e9(e.id),i=await e8(e,r);let a=await eR(i.device,i.port,t,r.logPath,eD,void 0,n);return await tn(a,i,r.logPath)}throw o}}function ts(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function tl(e){let t=new Set,r=[];for(let i of e)t.has(i)||(t.add(i),r.push(i));return r}let td=/^-?\d+(\.\d+)?$/,tu=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tc=new Map([["--count","count"],["--pause-ms","pauseMs"]]);function tp(e){return"click"===e||"press"===e}function tf(e){let t=e.trim();return t.startsWith("@")||td.test(t)?t:JSON.stringify(t)}function tm(e,t){let r=t.flags??{};if(tp(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");return}"swipe"===t.command&&("number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern))}function th(e,t){let r=[],i={},n=tp(e)?tu:"swipe"===e?tc:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(tp(e)&&"--double-tap"===o){i.doubleTap=!0;continue}let s=n?.get(o);if(s&&a+1<t.length){let e=function(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}(t[a+1]);null!==e&&(i[s]=e),a+=1;continue}if("swipe"===e&&"--pattern"===o&&a+1<t.length){let e=t[a+1];("one-way"===e||"ping-pong"===e)&&(i.pattern=e),a+=1;continue}r.push(o)}return{positionals:r,flags:i}}class tw{sessions=new Map;runtimeHints=new Map;sessionsDir;constructor(e){this.sessionsDir=e}get(e){return this.sessions.get(e)}has(e){return this.sessions.has(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){t.flags?.noRecord||(t.flags?.saveScript&&(e.recordSession=!0,"string"==typeof t.flags.saveScript&&(e.saveScriptPath=tw.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,flags:function(e){if(!e)return{};let{platform:t,device:r,udid:i,serial:n,out:a,verbose:o,snapshotInteractiveOnly:s,snapshotCompact:l,snapshotDepth:d,snapshotScope:u,snapshotRaw:c,relaunch:p,saveScript:f,noRecord:m,count:h,intervalMs:w,holdMs:g,jitterPx:I,doubleTap:v,pauseMs:A,pattern:y}=e;return{platform:t,device:r,udid:i,serial:n,out:a,verbose:o,snapshotInteractiveOnly:s,snapshotCompact:l,snapshotDepth:d,snapshotScope:u,snapshotRaw:c,relaunch:p,saveScript:f,noRecord:m,count:h,intervalMs:w,holdMs:g,jitterPx:I,doubleTap:v,pauseMs:A,pattern:y}}(t.flags),result:t.result}),M({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=n.dirname(t);$.existsSync(r)||$.mkdirSync(r,{recursive:!0});let i=function(e,t){let r=[],i=e.device.name.replace(/"/g,'\\"'),n=e.device.kind?` kind=${e.device.kind}`:"";for(let a of(r.push(`context platform=${e.device.platform} device="${i}"${n} theme=unknown`),t))a.flags?.noRecord||r.push(function(e){let t=[e.command];if(tp(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tf(r));let i=e.result?.refLabel;return"string"==typeof i&&i.trim().length>0&&t.push(tf(i)),tm(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tf(r)),tm(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tf(r));let i=e.result?.refLabel,n=e.positionals.slice(1).join(" ");return"string"==typeof i&&i.trim().length>0&&t.push(tf(i)),n&&t.push(tf(n)),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],i=e.positionals?.[1];if(r&&i){if(t.push(tf(r)),t.push(tf(i)),i.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tf(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tf(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command){for(let r of e.positionals??[])t.push(tf(r));return e.flags?.relaunch&&t.push("--relaunch"),t.join(" ")}for(let r of e.positionals??[])t.push(tf(r));return tm(t,e),t.join(" ")}(a));return`${r.join("\n")}
7
- `}(e,this.buildOptimizedActions(e));$.writeFileSync(t,i)}catch{}}defaultTracePath(e){let t=tw.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return n.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return n.join(this.sessionsDir,tw.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return n.join(this.sessionsDir,tw.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return e.startsWith("~/")?n.join(V.homedir(),e.slice(2)):t&&!n.isAbsolute(e)?n.resolve(t,e):n.resolve(e)}resolveScriptPath(e){if(e.saveScriptPath)return tw.expandHome(e.saveScriptPath);$.existsSync(this.sessionsDir)||$.mkdirSync(this.sessionsDir,{recursive:!0});let t=tw.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return n.join(this.sessionsDir,`${t}-${r}.ad`)}buildOptimizedActions(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let i=Array.isArray(r.result?.selectorChain)&&r.result?.selectorChain.every(e=>"string"==typeof e)?r.result.selectorChain:[];if(i.length>0&&(tp(r.command)||"fill"===r.command||"get"===r.command)){let e=i.join(" || ");if(tp(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let i=ts(r);if(i.length>0){t.push({...r,positionals:[e,i]});continue}}if("get"===r.command){let i=r.positionals?.[0];if("text"===i||"attrs"===i){t.push({...r,positionals:[i,e]});continue}}}if(tp(r.command)||"fill"===r.command||"get"===r.command){let i=r.result?.refLabel;"string"==typeof i&&i.trim().length>0&&t.push({ts:r.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:i.trim()},result:{scope:i.trim()}})}t.push(r)}return t}}function tg(e,t){if(!e)return;let r=n.dirname(e);$.existsSync(r)||$.mkdirSync(r,{recursive:!0});let i={pid:t,startTime:T(t)??void 0,command:a(t)??void 0};$.writeFileSync(e,`${JSON.stringify(i)}
8
- `)}function tI(e){if(e&&$.existsSync(e))try{$.unlinkSync(e)}catch{}}async function tv(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}async function tA(e){await new Promise(t=>setTimeout(t,e))}function ty(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],i="",n=i=>{(!(r.length>0)||r.some(e=>i.includes(e)))&&e.write(function(e,t){if(0===t.length)return e;let r=e;for(let e of t)r=r.replace(e,"[REDACTED]");return r}(i,t.redactionPatterns))};return{onChunk:e=>{let t=`${i}${e}`.split("\n");for(let e of(i=t.pop()??"",t))n(`${e}
9
- `)},flush:()=>{i&&(n(i),i="")}}}function tb(e,t,r){let i=e.stdout,n=e.stderr;return i&&n?(i.setEncoding("utf8"),n.setEncoding("utf8"),i.on("data",r.writer.onChunk),n.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(i=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),i({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}async function tN(e,t){let r=(await p("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tS(e,t,r,i,n){let a,o,s="active",l=!1,d=(async()=>{try{for(;!l;){let d=await tN(e,t);if(!d){await tA(1e3);continue}let u=h("adb",["-s",e,"logcat","-v","time","--pid",d],{stdio:["ignore","pipe","pipe"]});a=u;let c=ty(r,{redactionPatterns:i});o=tb(u,r,{endStreamOnClose:!1,writer:c}),"number"==typeof u.pid&&tg(n,u.pid);let p=await o;if(tI(n),a=void 0,o=void 0,l)break;0!==p.exitCode&&(s="failed"),await tA(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),tI(n)}})();return{backend:"android",getState:()=>s,startedAt:Date.now(),wait:d,stop:async()=>{l=!0,a&&!a.killed&&a.kill("SIGINT"),o&&await tv(o),a&&!a.killed&&a.kill("SIGKILL"),await tv(d),tI(n)}}}async function t_(e,t,r,i){let n="active",a=h("log",["stream","--style","compact","--predicate",`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}" OR eventMessage CONTAINS[c] "${e}"`],{stdio:["ignore","pipe","pipe"]}),o=ty(t,{redactionPatterns:r});"number"==typeof a.pid&&tg(i,a.pid);let s=tb(a,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(n="failed"),tI(i),e));return{backend:"ios-simulator",getState:()=>n,startedAt:Date.now(),wait:s,stop:async()=>{a.killed||a.kill("SIGINT"),await tv(s),a.killed||a.kill("SIGKILL"),await tv(s),tI(i)}}}async function tD(e,t,r,i){let n="active",a=h("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=ty(t,{redactionPatterns:r});"number"==typeof a.pid&&tg(i,a.pid);let s=tb(a,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(n="failed"),tI(i),e));return{backend:"ios-device",getState:()=>n,startedAt:Date.now(),wait:s,stop:async()=>{a.killed||a.kill("SIGINT"),await tv(s),a.killed||a.kill("SIGKILL"),await tv(s),tI(i)}}}function tE(e,t){let r=process.env[e];if(!r)return t;let i=Number.parseInt(r,10);return Number.isInteger(i)&&i>0?i:t}function tk(e){let t=n.dirname(e);$.existsSync(t)||$.mkdirSync(t,{recursive:!0}),function(e,t){if($.existsSync(e)&&!($.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,i=`${e}.${r}`;$.existsSync(t)&&($.existsSync(i)&&$.unlinkSync(i),$.renameSync(t,i))}}(e,{maxBytes:tE("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:tE("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function tO(e,t,r,i){tk(r);let n=$.createWriteStream(r,{flags:"a"}),a=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await tD(e.id,n,a,i):await t_(t,n,a,i);if("android"===e.platform){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new I("INVALID_ARGS",`Invalid Android package name for logs: ${t}`);return await tS(e.id,t,n,a,i)}throw n.end(),new I("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function tL(e){await e.stop(),await tv(e.wait)}async function tM(e,t){let r={},i=[];if(t||i.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await p("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await p("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await p("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await p("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}return{checks:r,notes:i}}function tx(e){let t=n.dirname(e),r=n.basename(e);$.existsSync(t)||$.mkdirSync(t,{recursive:!0}),$.existsSync(e)?$.truncateSync(e,0):$.writeFileSync(e,"","utf8");let i=0;for(let e of $.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let a=e.slice(r.length+1);if(/^\d+$/.test(a))try{$.unlinkSync(n.join(t,e)),i+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:i}}let tC=new Map;function tR(e){let t=tC.get(e);if(t&&(clearTimeout(t.timer),tC.delete(e),t.deleteAfterDownload))try{$.rmSync(t.artifactPath,{force:!0})}catch{}}let tT=new Map;function tP(e){let t=tT.get(e);t&&(clearTimeout(t.timer),tT.delete(e),$.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function t$(e){let t=e.headers["x-artifact-type"],r=e.headers["x-artifact-filename"];if(!t||!r)throw new I("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==t&&"app-bundle"!==t)throw new I("INVALID_ARGS",`Invalid x-artifact-type: ${t}. Must be "file" or "app-bundle".`);!function(e){let t=e.headers["content-length"];if("string"!=typeof t)return;let r=Number(t);if(Number.isFinite(r)&&r>0x80000000)throw new I("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e);let i=function(e){let t=n.basename(e);if(!t||"."===t||".."===t)throw new I("INVALID_ARGS",`Invalid artifact filename: ${e}`);return t}(r),a=$.mkdtempSync(n.join(V.tmpdir(),"agent-device-upload-"));try{if("file"===t){let t=n.join(a,i);return await tF(e,t),{artifactPath:t,tempDir:a}}let r=n.join(a,"artifact.tar");await tF(e,r),await tV(r,i),await p("tar",["xf",r,"-C",a]),$.rmSync(r,{force:!0});let o=n.join(a,i);if(!$.existsSync(o))throw new I("INVALID_ARGS",`Expected extracted bundle "${i}" not found in archive`);return{artifactPath:o,tempDir:a}}catch(e){throw $.rmSync(a,{recursive:!0,force:!0}),e}}function tF(e,t){return new Promise((r,i)=>{let n=$.createWriteStream(t),a=!1,o=0,s=e=>{a||(a=!0,i(e))};e.on("data",t=>{if((o+=t.length)>0x80000000){let t=new I("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");e.destroy(t),n.destroy(t)}}),e.pipe(n),n.on("finish",()=>{a||(a=!0,r())}),n.on("error",s),e.on("error",s)})}async function tV(e,t){let r=(await p("tar",["-tf",e])).stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new I("INVALID_ARGS","Uploaded app bundle archive is empty");if(!r.some(e=>e===t||e.startsWith(`${t}/`)))throw new I("INVALID_ARGS",`Uploaded archive must contain a top-level "${t}" bundle`);for(let e of r)!function(e,t){if(e.includes("\0"))throw new I("INVALID_ARGS",`Invalid archive entry: ${e}`);if(n.posix.isAbsolute(e))throw new I("INVALID_ARGS",`Archive entry must be relative: ${e}`);let r=n.posix.normalize(e).replace(/^\.\/+/,"");if(!r||"."===r||r.startsWith("../"))throw new I("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);if(r!==t&&!r.startsWith(`${t}/`))throw new I("INVALID_ARGS",`Archive entry must stay inside top-level "${t}" bundle: ${e}`)}(e,t);for(let t of(await p("tar",["-tvf",e])).stdout.split(/\r?\n/).filter(Boolean)){let e=t[0];if("l"===e||"h"===e)throw new I("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links")}}let tU=new Set(["agent_device.command","agent-device.command"]),tG={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},tB=new Set([...tU,...Object.keys(tG)]);function tj(e,t,r,i){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:i}}}function tq(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function tH(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function tW(e,t){let r="string"==typeof t.authorization?t.authorization:"",i=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,n="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??n??i??""}function tJ(e,t){let r=e[t];return"string"==typeof r?r:void 0}async function tz(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=_(new I("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:tj(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=_(new I(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:tj(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=o(r.tenantId);if(!e){let e=_(new I("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:tj(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function tK(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",i=n.isAbsolute(t)?t:n.resolve(t);try{e=await import(g(i).href)}catch(e){throw new I("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:i,error:e instanceof Error?e.message:String(e)})}let a=e[r];if("function"!=typeof a)throw new I("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:i,exportName:r});return a}async function tX(e){let t=await tK(),{handleRequest:r,token:i}=e;return j.createServer((e,n)=>{if("GET"===e.method&&"/health"===e.url){n.statusCode=200,n.setHeader("content-type","application/json"),n.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void tY(e,n,t,i);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void tZ(e,n,t,i);if("POST"!==e.method||"/rpc"!==e.url){n.statusCode=404,n.end("Not found");return}let a="";e.setEncoding("utf8"),e.on("data",t=>{(a+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{n.headersSent||tq(n,tj(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let i,o;try{i=JSON.parse(a)}catch{tq(n,tj(null,-32700,"Parse error"),400);return}if("2.0"!==i.jsonrpc||"string"!=typeof i.method)return void tq(n,tj(i.id??null,-32600,"Invalid Request"),400);if(!tB.has(i.method))return void tq(n,tj(i.id??null,-32601,`Method not found: ${i.method}`),404);if(!i.params||"object"!=typeof i.params)return void tq(n,tj(i.id??null,-32602,"Invalid params"),400);try{var s;let a=i.params,l=function(e,t,r){if(tU.has(e))return{token:tW(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,meta:t.meta};let i=tG[e];if(i){let e;return{token:tW(t,r),session:tJ(t,"session")??"default",command:i,positionals:[],meta:{tenantId:tJ(t,"tenantId")??tJ(t,"tenant"),runId:tJ(t,"runId"),leaseId:tJ(t,"leaseId"),leaseTtlMs:(e=t.ttlMs,Number.isInteger(e)?Number(e):void 0),leaseBackend:tJ(t,"backend")}}}throw new I("INVALID_ARGS",`Method not found: ${e}`)}(i.method,a,e.headers);if(s=i.method,tU.has(s)&&("string"!=typeof l.command||0===l.command.length))return void tq(n,tj(i.id??null,-32602,"Invalid params: command is required"),400);o=ei(l.meta?.requestId,i.id),l.meta={...l.meta,requestId:o},en(o);let d=()=>{n.writableFinished||ea(o)};e.on("aborted",d),n.on("close",d);let u=await tz(t,{headers:e.headers,rpcRequest:i,daemonRequest:l});if(!u.ok)return void tq(n,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void tq(n,{jsonrpc:"2.0",id:i.id??null,result:c});tq(n,tj(i.id??null,-32e3,c.error.message,c.error),tH(c.error.code))}catch(t){let e=_(t);tq(n,tj(i.id??null,-32e3,e.message,e),tH(e.code))}finally{eo(o)}})})}async function tY(e,t,r,i){try{var n;let a,o,s=tW({},e.headers),l=tQ(s,i);if(l){t.statusCode=tH(l.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.message,code:l.code}));return}let d=await tz(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:s,session:"default",command:"upload",positionals:[]}});if(!d.ok){t.statusCode=d.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.response.error?.data?.message??d.response.error?.message??"Unauthorized"}));return}let c=await t$(e),p=(n={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:d.tenantId},a=u.randomUUID(),o=setTimeout(()=>{tP(a)},3e5),tT.set(a,{artifactPath:n.artifactPath,tempDir:n.tempDir,tenantId:n.tenantId,timer:o}),a);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:p}))}catch(r){let e=_(r);t.statusCode=tH(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function tZ(e,t,r,i){let n=e.url?.slice("/upload/".length)??"";if(!n){t.statusCode=400,t.end("Missing artifact id");return}try{let a=tW({},e.headers),o=tQ(a,i);if(o){t.statusCode=tH(o.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:o.message,code:o.code}));return}let s=await tz(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:a,session:"default",command:"download_artifact",positionals:[n]}});if(!s.ok){t.statusCode=s.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.response.error?.data?.message??s.response.error?.message??"Unauthorized"}));return}let l=function(e,t){let r=tC.get(e);if(!r)throw new I("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new I("UNAUTHORIZED","Artifact belongs to a different tenant");if(!$.existsSync(r.artifactPath))throw tR(e),new I("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(n,s.tenantId),d=$.createReadStream(l.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),l.fileName&&t.setHeader("content-disposition",`attachment; filename="${l.fileName.replace(/"/g,"")}"`),d.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=_(e);t.statusCode=tH(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&tR(n)}),d.pipe(t)}catch(r){let e=_(r);t.statusCode=tH(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function tQ(e,t){return t&&e!==t?_(new I("UNAUTHORIZED","Invalid token")):null}function t0(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function t1(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function t2(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";throw new I("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class t3{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=t2(e.backend),r=o(e.tenantId);if(!r)throw new I("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let i=t0(e.runId);if(!i)throw new I("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let n=this.resolveLeaseTtlMs(e.ttlMs),a=this.bindingKey(r,i,t),s=this.runBindings.get(a);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,n);this.runBindings.delete(a)}this.enforceCapacity(t);let l=this.now(),d={leaseId:u.randomBytes(16).toString("hex"),tenantId:r,runId:i,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+n};return this.leases.set(d.leaseId,d),this.runBindings.set(a,d.leaseId),{...d}}heartbeatLease(e){let t=t1(e.leaseId);if(!t)throw new I("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new I("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let i=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,i)}releaseLease(e){let t=t1(e.leaseId);if(!t)throw new I("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=t2(e.backend),r=o(e.tenantId);if(!r)throw new I("INVALID_ARGS","tenant isolation requires tenant id.");let i=t0(e.runId);if(!i)throw new I("INVALID_ARGS","tenant isolation requires run id.");let n=t1(e.leaseId);if(!n)throw new I("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let a=this.leases.get(n);if(!a)throw new I("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(a.backend!==t||a.tenantId!==r||a.runId!==i)throw new I("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new I("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new I("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),i={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(i.leaseId,i),this.runBindings.set(this.bindingKey(i.tenantId,i.runId,i.backend),i.leaseId),{...i}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let i=o(t),n=t0(r);if(t&&!i)throw new I("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!n)throw new I("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(i&&e.tenantId!==i||n&&e.runId!==n)throw new I("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}function t4(e,t){return["-s",e.id,...t]}async function t8(){if(!await A("adb"))throw new I("TOOL_MISSING","adb not found in PATH")}function t5(e,t){let r=`${e}
10
- ${t}`.toLowerCase();return r.includes("no shell command implementation")||r.includes("unknown command")}async function t6(e){await new Promise(t=>setTimeout(t,e))}function t9(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let r=/^([A-Za-z][A-Za-z0-9+.-]*):(.+)$/.exec(t);if(!r)return!1;let i=r[1]?.toLowerCase(),n=r[2]??"";return"http"!==i&&"https"!==i&&"ws"!==i&&"wss"!==i&&"ftp"!==i&&"ftps"!==i||n.startsWith("//")}function t7(e,t){let r,i=e?.trim();return i?i:"http"===(r=t.trim().split(":")[0]?.toLowerCase())||"https"===r?"com.apple.mobilesafari":void 0}let re=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];function rt(e){return`${e.stdout}
11
- ${e.stderr}`}function rr(e,t){return["-s",e,...t]}function ri(e){return e.startsWith("emulator-")}function rn(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function ra(e,t=z){return p("adb",rr(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function ro(e,t){let r=t.replace(/_/g," ").trim();if(!ri(e))return r||e;let i=await rs(e);return i?i.replace(/_/g," "):r||e}async function rs(e){for(let t of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let r=await p("adb",rr(e,["shell","getprop",t]),{allowFailure:!0,timeoutMs:1e4}),i=r.stdout.trim();if(0===r.exitCode&&i.length>0)return i}let t=await p("adb",rr(e,["emu","avd","name"]),{allowFailure:!0,timeoutMs:1e4}),r=t.stdout.trim();if(0===t.exitCode&&r.length>0)return r}async function rl(e,t){let r=rt(await p("adb",rr(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:z})).toLowerCase();return!!r.includes("true")||!r.includes("false")&&null}async function rd(e){return(await Promise.all(re.map(async t=>await rl(e,t)))).some(e=>!0===e)}async function ru(e){var t;let r;return"tv"===((r=rt(await p("adb",rr(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:z})).toLowerCase()).includes("tv")||r.includes("leanback")?"tv":null)||await rd(e)?"tv":(t=rt(await p("adb",rr(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:z})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function rc(e={}){if(!await A("adb"))throw new I("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??eN(void 0),r=(await rp()).filter(e=>!t||t.has(e.serial));return await Promise.all(r.map(async({serial:e,rawModel:t})=>{let[r,i,n]=await Promise.all([ro(e,t),rw(e),ru(e)]);return{platform:"android",id:e,name:r,kind:ri(e)?"emulator":"device",target:n,booted:i}}))}async function rp(){return(await p("adb",["devices","-l"],{timeoutMs:z})).stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith("List of devices")).map(e=>e.split(/\s+/)).filter(e=>"device"===e[1]).map(e=>({serial:e[0],rawModel:(e.find(e=>e.startsWith("model:"))??"").replace("model:","")}))}async function rf(){let e=await p("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:z});if(0!==e.exitCode)throw new I("COMMAND_FAILED","Failed to list Android emulator AVDs",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,hint:"Verify Android emulator tooling is installed and available in PATH."});return e.stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}async function rm(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await rh(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await new Promise(e=>setTimeout(e,1e3))}throw new I("COMMAND_FAILED","Android emulator did not appear in time",{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:"Check emulator logs and verify the AVD can start from command line."})}async function rh(e,t){let r=rn(e);for(let e of(await rp()).filter(e=>(!t||e.serial===t)&&ri(e.serial)))if(rn(e.rawModel)===r||rn(await ro(e.serial,e.rawModel))===r)return e.serial}async function rw(e){try{let t=await ra(e);return"1"===t.stdout.trim()}catch{return!1}}async function rg(e){var t,r;let i,n=e.avdName.trim();if(!n)throw new I("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let a=e.timeoutMs??12e4;if(!await A("adb"))throw new I("TOOL_MISSING","adb not found in PATH");if(!await A("emulator"))throw new I("TOOL_MISSING","emulator not found in PATH");let o=await rf(),s=function(e,t){let r=e.find(e=>e===t);if(r)return r;let i=rn(t);return e.find(e=>rn(e)===i)}(o,n);if(!s)throw new I("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:n,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let d=Date.now(),u=(t=await rc(),r=e.serial,i=rn(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!r||e.id===r)&&rn(e.name)===i));if(!u){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),l("emulator",t)}let c=u??await rm({avdName:s,serial:e.serial,timeoutMs:a}),p=Math.max(1e3,a-(Date.now()-d));await rI(c.id,p);let f=(await rc()).find(e=>e.id===c.id);return f?{...f,name:s,booted:!0}:{...c,name:s,booted:!0}}async function rI(e,t=6e4){let r,i=K.fromTimeoutMs(t),n=Math.max(1,Math.ceil(t/1e3)),a=!1;try{await X(async({deadline:n})=>{if(n?.isExpired())throw a=!0,new I("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:i.elapsedMs(),message:"timeout"});let o=Math.max(1e3,n?.remainingMs()??t),s=await ra(e,Math.min(o,z));if(r=s,"1"!==s.stdout.trim())throw new I("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:n,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=eu({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:i,phase:"boot",classifyReason:e=>eu({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let n=w(c),o=r?.stdout,s=r?.stderr,l=r?.exitCode,d=eu({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===n.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:i.elapsedMs(),reason:d,hint:ec(d),stdout:o,stderr:s,exitCode:l};if(a||"ANDROID_BOOT_TIMEOUT"===d)throw new I("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===n.code)throw new I("TOOL_MISSING",n.message,{...u,...n.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new I("COMMAND_FAILED",n.message,{...u,...n.details??{}});throw new I(n.code,n.message,{...u,...n.details??{}},n.cause)}}let rv={settings:{type:"intent",value:"android.settings.SETTINGS"}},rA="android.intent.category.LAUNCHER",ry="android.intent.category.LEANBACK_LAUNCHER",rb="android.intent.category.DEFAULT";async function rN(e,t){let r=t.trim();if(r.includes(".")&&!r.includes("/"))return{type:"package",value:r};let i=rv[r.toLowerCase()];if(i)return i;let n=(await p("adb",t4(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase()));if(1===n.length)return{type:"package",value:n[0]};if(n.length>1)throw new I("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:n});throw new I("APP_NOT_INSTALLED",`No package found matching "${t}"`)}async function rS(e,t="all"){let r=await r_(e);return("user-installed"===t?(await rE(e)).filter(e=>r.has(e)):Array.from(r)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:function(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),r=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),i=r[r.length-1]??e;for(let e=r.length-1;e>=0;e-=1){let n=r[e];if(!t.has(n)){i=n;break}}return i.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}(e)}))}async function r_(e){let t=new Set;for(let r of rD(e,{includeFallbackWhenUnknown:!0})){let i=await p("adb",t4(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",r]),{allowFailure:!0});if(0===i.exitCode&&0!==i.stdout.trim().length)for(let e of i.stdout.split("\n")){let r=e.trim();if(!r)continue;let i=r.split(/\s+/)[0],n=i.includes("/")?i.split("/")[0]:i;n&&t.add(n)}}return t}function rD(e,t={}){return"tv"===e.target?[ry]:"mobile"===e.target?[rA]:t.includeFallbackWhenUnknown?[rA,ry]:[rA]}async function rE(e){return(await p("adb",t4(e,["shell","pm","list","packages","-3"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean)}async function rk(e){let t=await rO(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let r=await rO(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return r||{}}async function rO(e,t){for(let r of t){let t=function(e){for(let t of[/mCurrentFocus=Window\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mFocusedApp=AppWindowToken\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/,/ResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/]){let r=t.exec(e);if(r)return{package:r[1],activity:r[2]}}return null}((await p("adb",t4(e,r),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function rL(e,t,r){var i,n;let a;e.booted||await rI(e.id);let o=t.trim();if(t9(o)){if(r)throw new I("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await p("adb",t4(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await rN(e,t),l=rD(e)[0]??rA;if("intent"===s.type){if(r)throw new I("INVALID_ARGS","Activity override requires a package name, not an intent");await p("adb",t4(e,["shell","am","start","-W","-a",s.value]));return}if(r){let t=r.includes("/")?r:`${s.value}/${r.startsWith(".")?r:`.${r}`}`;await p("adb",t4(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rb,"-c",l,"-n",t]));return}let d=await p("adb",t4(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rb,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(i=d.stdout,n=d.stderr,a=`${i}
12
- ${n}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(a)))return;let u=await rM(e,s.value);if(!u)throw new I("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:d.stdout,stderr:d.stderr});await p("adb",t4(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rb,"-c",l,"-n",u]))}async function rM(e,t){for(let r of Array.from(new Set(rD(e,{includeFallbackWhenUnknown:!0})))){let i=await p("adb",t4(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",r,t]),{allowFailure:!0});if(0!==i.exitCode)continue;let n=function(e){let t=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e-=1){let r=t[e];if(r.includes("/"))return r.split(/\s+/)[0]}return null}(i.stdout);if(n)return n}return null}async function rx(e){e.booted||await rI(e.id)}async function rC(e,t){if("settings"===t.trim().toLowerCase())return void await p("adb",t4(e,["shell","am","force-stop","com.android.settings"]));let r=await rN(e,t);if("intent"===r.type)throw new I("INVALID_ARGS","Close requires a package name, not an intent");await p("adb",t4(e,["shell","am","force-stop",r.value]))}async function rR(e,t){let r=await rN(e,t);if("intent"===r.type)throw new I("INVALID_ARGS","App uninstall requires a package name, not an intent");let i=await p("adb",t4(e,["uninstall",r.value]),{allowFailure:!0});if(0!==i.exitCode){let e=`${i.stdout}
13
- ${i.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new I("COMMAND_FAILED",`adb uninstall failed for ${r.value}`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})}return{package:r.value}}let rT=null;async function rP(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(rT?.key===e)return rT.invocation;if(await A("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return rT={key:e,invocation:t},t}let t=process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim();if(!t)throw new I("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");try{await x.access(t)}catch{throw new I("TOOL_MISSING",`AGENT_DEVICE_BUNDLETOOL_JAR points to a missing file: ${t}`)}let r={cmd:"java",prefixArgs:["-jar",t]};return rT={key:e,invocation:r},r}async function r$(e){let t=await rP();await p(t.cmd,[...t.prefixArgs,...e])}async function rF(e,t){let r,i=await x.mkdtemp(n.join(V.tmpdir(),"agent-device-aab-")),a=n.join(i,"bundle.apks"),o=(r=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&r.length>0?r:"universal";try{await r$(["build-apks","--bundle",t,"--output",a,"--mode",o]),await r$(["install-apks","--apks",a,"--device-id",e.id])}finally{await x.rm(i,{recursive:!0,force:!0})}}async function rV(e,t){".aab"===n.extname(t).toLowerCase()?await rF(e,t):await p("adb",t4(e,["install","-r",t]))}async function rU(e,t){e.booted||await rI(e.id),await rV(e,t)}async function rG(e,t,r){e.booted||await rI(e.id);let{package:i}=await rR(e,t);return await rV(e,r),{package:i}}function rB(e){let t=rj(e),r=e=>{let r=rq(t,e);if(null!==r)return"true"===r};return{text:rq(t,"text"),desc:rq(t,"content-desc"),resourceId:rq(t,"resource-id"),className:rq(t,"class"),bounds:rq(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused")}}function rj(e){let t=new Map,r=e.indexOf(" "),i=e.lastIndexOf(">");if(r<0||i<=r)return t;let n=/([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/y,a=r;for(;a<i;){for(;a<i;){let t=e[a];if(" "!==t&&"\n"!==t&&"\r"!==t&&" "!==t)break;a+=1}if(a>=i)break;let r=e[a];if("/"===r||">"===r)break;n.lastIndex=a;let o=n.exec(e);if(!o)break;t.set(o[1],o[3]),a=n.lastIndex}return t}function rq(e,t){return e.get(t)??null}function rH(e){if(!e)return;let t=/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),i=Number(t[2]);return{x:r,y:i,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-i)}}function rW(e){return e?e.toLowerCase():""}function rJ(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}async function rz(e,t={}){return function(e,t,r){let i=function(e){let t={type:null,label:null,value:null,identifier:null,depth:-1,children:[]},r=[t],i=/<node\b[^>]*>|<\/node>/g,n=i.exec(e);for(;n;){let t=n[0];if(t.startsWith("</node")){r.length>1&&r.pop(),n=i.exec(e);continue}let a=rB(t),o=rH(a.bounds),s=r[r.length-1],l={type:a.className,label:a.text||a.desc,value:a.text,identifier:a.resourceId,rect:o,enabled:a.enabled,hittable:a.clickable??a.focusable,depth:s.depth+1,parentIndex:void 0,children:[]};s.children.push(l),t.endsWith("/>")||r.push(l),n=i.exec(e)}return t}(e),n=[],a=!1,o=r.depth??1/0,s=r.scope?function(e,t){let r=t.toLowerCase(),i=[...e.children];for(;i.length>0;){let e=i.shift(),t=e.label?.toLowerCase()??"",n=e.value?.toLowerCase()??"",a=e.identifier?.toLowerCase()??"";if(t.includes(r)||n.includes(r)||a.includes(r))return e;i.push(...e.children)}return null}(i,r.scope):null,l=s?[s]:i.children,d=new Map,u=e=>{let t=d.get(e);if(void 0!==t)return t;for(let t of e.children)if(t.hittable||u(t))return d.set(e,!0),!0;return d.set(e,!1),!1},c=(e,t,i,s=!1,l=!1)=>{var d,p,f,m,h,w;let g,I,v,A,y,b,N,S;if(n.length>=800){a=!0;return}if(t>o)return;let _=!!r.raw||(d=e,p=r,f=s,m=u(e),h=l,I=rW(d.type),v=!!(d.label&&d.label.trim().length>0),A=!!(d.identifier&&d.identifier.trim().length>0),y=v&&!rJ(d.label??""),b=A&&!rJ(d.identifier??""),N=(g=(w=I).split(".").pop()??w).includes("layout")||"viewgroup"===g||"view"===g,S="imageview"===I||"imagebutton"===I,p.interactiveOnly?!!d.hittable||!!(y||b)&&!S&&(!N||!!h)&&(f||m||h):p.compact?y||b||!!d.hittable:!N&&!S||!!d.hittable||!!y||!!b&&!!m||m),D=i;_&&(D=n.length,n.push({index:D,type:e.type??void 0,label:e.label??void 0,value:e.value??void 0,identifier:e.identifier??void 0,rect:e.rect,enabled:e.enabled,hittable:e.hittable,depth:t,parentIndex:i}));let E=s||!!e.hittable,k=l||function(e){if(!e)return!1;let t=rW(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(e.type);for(let r of e.children)if(c(r,t+1,D,E,k),a)return};for(let e of l)if(c(e,0,void 0,!1,!1),a)break;return a?{nodes:n,truncated:a}:{nodes:n}}(await rY(e),0,t)}let rK=Buffer.from([137,80,78,71,13,10,26,10]);async function rX(e,t){let r=await p("adb",t4(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!r.stdoutBuffer)throw new I("COMMAND_FAILED","Failed to capture screenshot");let i=r.stdoutBuffer.indexOf(rK);if(i<0)throw new I("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let n=function(e,t){let r=t+rK.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),i=r+4,n=e.toString("ascii",i,i+4),a=r+12+t;if(a>e.length)break;if("IEND"===n)return a;r=a}return null}(r.stdoutBuffer,i);if(!n)throw new I("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await x.writeFile(t,r.stdoutBuffer.subarray(i,n))}async function rY(e){return Y(()=>rZ(e),{shouldRetry:r0})}async function rZ(e){var t,r,i;let n,a,o=await p("adb",t4(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0});if(0===o.exitCode){let e=rQ(o.stdout,o.stderr);if(e)return e}let s="/sdcard/window_dump.xml",l=await p("adb",t4(e,["shell","uiautomator","dump",s])),d=(t=s,r=l.stdout,i=l.stderr,n=`${r}
14
- ${i}`,a=/dumped to:\s*(\S+)/i.exec(n),a?.[1]??t),u=await p("adb",t4(e,["shell","cat",d])),c=rQ(u.stdout,u.stderr);if(!c)throw new I("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:u.stdout,stderr:u.stderr});return c}function rQ(e,t){let r=`${e}
15
- ${t}`,i=r.indexOf("<?xml"),n=i>=0?i:r.indexOf("<hierarchy");if(n<0)return null;let a=r.lastIndexOf("</hierarchy>");if(a<0||a<n)return null;let o=r.slice(n,a+12).trim();return o.length>0?o:null}function r0(e){if(!(e instanceof I)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.details?.stderr??""}`.toLowerCase();return!!(t.includes("device offline")||t.includes("device not found")||t.includes("transport error")||t.includes("connection reset")||t.includes("broken pipe")||t.includes("timed out")||t.includes("no such file or directory"))}async function r1(e,t,r){await p("adb",t4(e,["shell","input","tap",String(t),String(r)]))}async function r2(e,t,r,i,n,a=250){await p("adb",t4(e,["shell","input","swipe",String(t),String(r),String(i),String(n),String(a)]))}async function r3(e){await p("adb",t4(e,["shell","input","keyevent","4"]))}async function r4(e){await p("adb",t4(e,["shell","input","keyevent","3"]))}async function r8(e){await p("adb",t4(e,["shell","input","keyevent","187"]))}async function r5(e,t,r,i=800){await p("adb",t4(e,["shell","input","swipe",String(t),String(r),String(t),String(r),String(i)]))}async function r6(e,t){let r=ia(t);if(!r||"ok"!==await io(e,t))try{let r=t.replace(/ /g,"%s");await p("adb",t4(e,["shell","input","text",r]))}catch(e){if(r&&function(e){if(!(e instanceof I)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return!!(t.includes("exception occurred while executing 'text'")||t.includes("nullpointerexception")&&t.includes("inputshellcommand.sendtext"))}(e))throw new I("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function r9(e,t,r){await r1(e,t,r)}async function r7(e,t,r,i){let n=Array.from(i).length,a=ia(i),o=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];a||(o.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),o.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96}));let s=null;for(let a of o){var l,d;await r9(e,t,r);let o=(l=n+a.clearPadding,d=a.minClear,Math.max(d,Math.min(a.maxClear,l)));if(await is(e,o),"input_text"===a.strategy)await r6(e,i);else if("clipboard_paste"===a.strategy){if("ok"!==await io(e,i))continue}else await ii(e,i,1,15);if((s=await il(e,t,r))===i)return}throw new I("COMMAND_FAILED","Android fill verification failed",{expected:i,actual:s??null})}async function ie(e,t,r=.6){let{width:i,height:n}=await ir(e),a=Math.floor(i*r),o=Math.floor(n*r),s=Math.floor(i/2),l=Math.floor(n/2),d=s,u=l,c=s,f=l;switch(t){case"up":u=l-Math.floor(o/2),f=l+Math.floor(o/2);break;case"down":u=l+Math.floor(o/2),f=l-Math.floor(o/2);break;case"left":d=s-Math.floor(a/2),c=s+Math.floor(a/2);break;case"right":d=s+Math.floor(a/2),c=s-Math.floor(a/2);break;default:throw new I("INVALID_ARGS",`Unknown direction: ${t}`)}await p("adb",t4(e,["shell","input","swipe",String(d),String(u),String(c),String(f),"300"]))}async function it(e,t){for(let r=0;r<8;r+=1){let r="";try{r=await rY(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new I("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(function(e,t){let r=t.toLowerCase(),i=/<node[^>]+>/g,n=i.exec(e);for(;n;){let t=rj(n[0]),a=(rq(t,"text")??"").toLowerCase(),o=(rq(t,"content-desc")??"").toLowerCase();if(a.includes(r)||o.includes(r)){let e=rH(rq(t,"bounds"));if(e)return{x:Math.floor(e.x+e.width/2),y:Math.floor(e.y+e.height/2)};return{x:0,y:0}}n=i.exec(e)}return null}(r,t))return;await ie(e,"down",.5)}throw new I("COMMAND_FAILED",`Could not find element containing "${t}" after scrolling`)}async function ir(e){let t=(await p("adb",t4(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new I("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function ii(e,t,r,i){let n=Math.max(1,Math.floor(r)),a=Array.from(t);for(let t=0;t<a.length;t+=n){let r=a.slice(t,t+n).join("");await r6(e,r),i>0&&t+n<a.length&&await t6(i)}}function ia(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&(e<32||e>126))return!0}return!1}async function io(e,t){let r=await p("adb",t4(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==r.exitCode?"failed":t5(r.stdout,r.stderr)?"unsupported":0===(await p("adb",t4(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await p("adb",t4(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function is(e,t){let r=Math.max(0,t);await p("adb",t4(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<r;t+=24){let i=Math.min(24,r-t);await p("adb",t4(e,["shell","input","keyevent",...Array(i).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function il(e,t,r){let i,n=await rY(e),a=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(i=a.exec(n));){let e=rB(i[0]),n=rH(e.bounds);if(!n)continue;let a=e.className??"",d=(e.text??"").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,n.width*n.height),p=t>=n.x&&t<=n.x+n.width&&r>=n.y&&r<=n.y+n.height;if(u&&id(a)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&id(a)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function id(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function iu(e){let t=await p("adb",t4(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new I("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let r of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=r[1],i=r[2]?.toLowerCase();e&&("true"===i||"false"===i)&&t.set(e,"true"===i)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),r=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(r=(1&e)!=0)}}let i=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),n=i.length>0?i[i.length-1]?.[1]:void 0,a=n?`0x${n.toLowerCase()}`:void 0;return{visible:r,inputType:a,type:a?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let r=15&t;if(2===r)return"number";if(3===r)return"phone";if(4===r)return"datetime";if(1!==r)return"unknown";let i=4080&t;return 32===i||208===i?"email":128===i||224===i||144===i?"password":"text"}(a):void 0}}(t.stdout)}async function ic(e){let t=await iu(e),r=t,i=0;for(;r.visible&&i<2;)await r3(e),i+=1,await t6(120),r=await iu(e);return{attempts:i,wasVisible:t.visible,dismissed:t.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type}}async function ip(e){let t,r;return(r=(t=(await ih(e,["shell","cmd","clipboard","get","text"],"read")).replace(/\r\n/g,"\n").replace(/\n$/,"")).match(/^clipboard text:\s*(.*)$/i))?r[1]??"":"null"===t.trim().toLowerCase()?"":t}async function im(e,t){await ih(e,["shell","cmd","clipboard","set","text",t],"write")}async function ih(e,t,r){let i=await p("adb",t4(e,t),{allowFailure:!0});if(t5(i.stdout,i.stderr))throw new I("UNSUPPORTED_OPERATION",`Android shell clipboard ${r} is not supported on this device.`);if(0!==i.exitCode)throw new I("COMMAND_FAILED",`Failed to ${r} Android clipboard text`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return i.stdout}let iw=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function ig(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new I("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function iI(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new I("INVALID_ARGS",`permission setting requires a target: ${iw.join("|")}`)}function iv(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new I("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}async function iA(e,t,r,i,n){switch(t.toLowerCase()){case"wifi":{let t=ib(r);await p("adb",t4(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=ib(r);await p("adb",t4(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await p("adb",t4(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=ib(r);await p("adb",t4(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"appearance":{let t=await iN(e,r);await p("adb",t4(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]));return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new I("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await iy(e,t);return}case"permission":{if(!i)throw new I("INVALID_ARGS","permission setting requires an active app in session");let t=ig(r),a=function(e,t){let r=iI(e);if(t?.trim())throw new I("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 I("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(n?.permissionTarget,n?.permissionMode);if("notifications"===a.kind)return void await i_(e,i,t,a);let o="grant"===t?"grant":"revoke";if("photos"===a.type)return void await iS(e,i,o);await p("adb",t4(e,["shell","pm",o,i,a.value]));return}default:throw new I("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function iy(e,t){var r;let i,n,a=(r=e,n=[["shell","cmd","fingerprint","touch",i="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",i]],"emulator"===r.kind&&n.push(["emu","finger","touch",i]),n),o=[];for(let t of a){let r=await p("adb",t4(e,t),{allowFailure:!0});if(0===r.exitCode)return;o.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,r;let i;return t=e.stdout,r=e.stderr,(i=`${t}
16
- ${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 I("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:s});throw new I("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function ib(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new I("INVALID_ARGS",`Invalid setting state: ${e}`)}async function iN(e,t){let r=iv(t);if("toggle"!==r)return r;let i=await p("adb",t4(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==i.exitCode)throw new I("COMMAND_FAILED","Failed to read current Android appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});let n=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
17
- ${t}`);if(!r)return null;let i=r[1].toLowerCase();return"yes"===i?"dark":"no"===i?"light":"auto"===i?"auto":null}(i.stdout,i.stderr);if(!n)throw new I("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:i.stdout,stderr:i.stderr});return"auto"===n?"dark":"dark"===n?"light":"dark"}async function iS(e,t,r){let i=await iD(e),n=[];for(let a of null!==i&&i>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let i=await p("adb",t4(e,["shell","pm",r,t,a]),{allowFailure:!0});if(0===i.exitCode)return;n.push({permission:a,stderr:i.stderr,exitCode:i.exitCode})}throw new I("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:i,attempts:n})}async function i_(e,t,r,i){"grant"===r?await p("adb",t4(e,["shell","pm","grant",t,i.permission]),{allowFailure:!0}):(await p("adb",t4(e,["shell","pm","revoke",t,i.permission]),{allowFailure:!0}),"reset"===r&&(await p("adb",t4(e,["shell","pm","clear-permission-flags",t,i.permission,"user-set"]),{allowFailure:!0}),await p("adb",t4(e,["shell","pm","clear-permission-flags",t,i.permission,"user-fixed"]),{allowFailure:!0}))),await p("adb",t4(e,["shell","appops","set",t,i.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"]))}async function iD(e){let t=await p("adb",t4(e,["shell","getprop","ro.build.version.sdk"]),{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}async function iE(e,t,r){let i="string"==typeof r.action&&r.action.trim()?r.action.trim():`${t}.TEST_PUSH`,n=["shell","am","broadcast","-a",i,"-p",t],a="string"==typeof r.receiver?r.receiver.trim():"";a&&n.push("-n",a);let o=r.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new I("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,r){if("string"==typeof r)return e.push("--es",t,r);if("boolean"==typeof r)return e.push("--ez",t,r?"true":"false");if("number"==typeof r&&Number.isFinite(r))return Number.isInteger(r)?e.push("--ei",t,String(r)):e.push("--ef",t,String(r));throw new I("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(n,e,t),s+=1);return await p("adb",t4(e,n)),{action:i,extrasCount:s}}let ik=ew(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,J,5e3),iO=ew(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,W,1e3),iL=ew(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),iM=ew(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),ix=ew(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),iC=ew(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3);async function iR(e,t){let r=["devicectl",...e],i=await p("xcrun",r,{allowFailure:!0,timeoutMs:iM});if(0===i.exitCode)return;let n=String(i.stdout??""),a=String(i.stderr??"");throw new I("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:r,exitCode:i.exitCode,stdout:n,stderr:a,deviceId:t.deviceId,hint:i$(n,a)??iP})}async function iT(e,t){let r=n.join(V.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),i=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",r],a=await p("xcrun",i,{allowFailure:!0,timeoutMs:iM});try{var o,s;if(0!==a.exitCode){let t=String(a.stdout??""),r=String(a.stderr??"");throw new I("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:i,exitCode:a.exitCode,stdout:t,stderr:r,deviceId:e.id,hint:i$(t,r)??iP})}let n=await x.readFile(r,"utf8");return o=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let i="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t;r.push({bundleId:t,name:i})}return r}(JSON.parse(n)),s=t,"user-installed"===s?o.filter(e=>!e.bundleId.startsWith("com.apple.")):o}catch(t){if(t instanceof I)throw t;throw new I("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await x.unlink(r).catch(()=>{})}}let iP="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function i$(e,t){let r=`${e}
18
- ${t}`.toLowerCase();return r.includes("device is busy")&&r.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":r.includes("coredeviceservice")&&r.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function iF(e){if(!(e instanceof I)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let r=String(t.stderr??"").toLowerCase();return r.includes("fbsopenapplicationserviceerrordomain")&&r.includes("the request to open")}async function iV(e,t){let r=await p("xcrun",e_(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==r.exitCode)return{installed:!1};let i=r.stdout.trim();if(!i)return{installed:!1};let n=await p("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${i}/Info.plist`],{allowFailure:!0});if(0!==n.exitCode||!n.stdout.trim())return{installed:!0};let a=n.stdout.trim(),o=`${i}/${a}`,s=await p("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function iU(e,t){if("simulator"!==e.kind)throw new I("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function iG(){await p("open",["-a","Simulator"],{allowFailure:!0})}async function iB(e){let t,r;if("simulator"!==e.kind||"Booted"===await iq(e))return;let i=K.fromTimeoutMs(ik);try{await X(async({deadline:i})=>{if(i?.isExpired())throw new I("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:ik});let n=Math.max(1e3,i?.remainingMs()??ik),a=await p("xcrun",e_(e,["boot",e.id]),{allowFailure:!0,timeoutMs:n});t={stdout:String(a.stdout??""),stderr:String(a.stderr??""),exitCode:a.exitCode};let o=`${t.stdout}
19
- ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new I("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await p("xcrun",e_(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:n});if(r={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==r.exitCode)throw new I("COMMAND_FAILED","simctl bootstatus failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let d=await iq(e);if("Booted"!==d)throw new I("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let i=eu({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==i&&"CI_RESOURCE_STARVATION_SUSPECTED"!==i}},{deadline:i,phase:"boot",classifyReason:e=>eu({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(a){let n=eu({error:a,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new I("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:ik,elapsedMs:i.elapsedMs(),reason:n,hint:ec(n),boot:t,bootstatus:r})}}async function ij(e){let t=e_(e,["shutdown",e.id]),r=await p("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===r.exitCode,exitCode:r.exitCode,stdout:String(r.stdout??""),stderr:String(r.stderr??"")}}async function iq(e){let t="string"==typeof e?e:e.id,r="string"==typeof e?eS(["list","devices","-j"]):e_(e,["list","devices","-j"]),i=await p("xcrun",r,{allowFailure:!0,timeoutMs:iO});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let r of Object.values(e.devices??{})){let e=r.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}function iH(e,t,r){return p("xcrun",e_(e,t),r)}let iW={ensureBooted:iB,captureWithRetry:iK,captureWithRunner:iX,shouldFallbackToRunner:i1};async function iJ(e,t,r){if("simulator"===e.kind)return void await iz(e,t,r);try{await iR(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof I)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",i="string"==typeof t.stderr?t.stderr:"",n=`${e.message}
4
+ ${r}`.toLowerCase()).includes("device is busy")&&a.includes("connecting")?"Target iOS device is still connecting. Keep it unlocked, wait for device trust/connection to settle, then retry.":em("IOS_RUNNER_CONNECT_TIMEOUT"))})}function eI(e){if(ed(e))throw ec()}function ev(e,t,r){if(!e)return t;let a=Number(e);return Number.isFinite(a)?Math.max(r,Math.floor(a)):t}let eA=["AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET","IOS_SIMULATOR_DEVICE_SET"],ey=["AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST","ANDROID_DEVICE_ALLOWLIST"];function eb(e){return e?.trim()||void 0}function eN(e,t){for(let r of e){let e=eb(t[r]);if(e)return e}}function e_(e,t=process.env){return eb(e)??eN(eA,t)}function eS(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function eD(e,t=process.env){let r=eb(e)??eN(ey,t);if(r)return eS(r)}function eE(e,t={}){let r=e_(t.simulatorSetPath);return r?["simctl","--set",r,...e]:["simctl",...e]}function ek(e,t){return"ios"!==e.platform||"simulator"!==e.kind?["simctl",...t]:eE(t,{simulatorSetPath:e.simulatorSetPath})}let eL=ev(process.env.AGENT_DEVICE_RUNNER_STARTUP_TIMEOUT_MS,45e3,5e3),eO=ev(process.env.AGENT_DEVICE_RUNNER_COMMAND_TIMEOUT_MS,45e3,1e3),eM=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_ATTEMPT_INTERVAL_MS,250,50),ex=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_BASE_DELAY_MS,300,10),eC=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_RETRY_MAX_DELAY_MS,2e3,10),eR=ev(process.env.AGENT_DEVICE_RUNNER_CONNECT_REQUEST_TIMEOUT_MS,2e4,250),eT=ev(process.env.AGENT_DEVICE_IOS_DEVICE_INFO_TIMEOUT_MS,1e4,500),eP=ev(process.env.AGENT_DEVICE_RUNNER_DESTINATION_TIMEOUT_SECONDS,20,5);async function e$(e,t,r,a,i=eL,n,o){let s=Z.fromTimeoutMs(i),l=await eF(e,t,s.remainingMs()),d=null,u=Math.max(1,Math.ceil(i/eM));try{return await Y(async({deadline:s})=>{if(s?.isExpired())throw new h("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:i});if(n&&null!==n.child.exitCode&&void 0!==n.child.exitCode)throw await eg({session:n,port:t,logPath:a});for(let a of("device"===e.kind&&(l=await eF(e,t,s?.remainingMs())),l))try{let e=s?.remainingMs()??i;if(e<=0)throw new h("COMMAND_FAILED","Runner connection deadline exceeded",{port:t,timeoutMs:i});return await eU(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},Math.min(eR,e),o)}catch(e){if(o?.aborted||ep(e))throw ec();d=e}throw new h("COMMAND_FAILED","Runner endpoint probe failed",{port:t,endpoints:l,lastError:d?String(d):void 0})},{maxAttempts:u,baseDelayMs:ex,maxDelayMs:eC,jitter:.2,shouldRetry:eh},{deadline:s,phase:"ios_runner_connect",signal:o})}catch(e){if(o?.aborted||ep(e))throw ec();d||(d=e)}if(o?.aborted)throw ec();if("simulator"===e.kind){let i=s.remainingMs();if(i<=0)throw ew({port:t,endpoints:l,logPath:a,lastError:d});let n=await eG(e,t,r,i);return new Response(n.body,{status:n.status})}throw ew({port:t,endpoints:l,logPath:a,lastError:d})}async function eF(e,t,r){let a=[`http://127.0.0.1:${t}/command`];if("device"!==e.kind)return a;let i=await eV(e.id,r);return i&&a.unshift(`http://[${i}]:${t}/command`),a}async function eU(e,t,r,a){let i,n=new AbortController,o=setTimeout(()=>n.abort(),r);a&&(a.aborted?(clearTimeout(o),n.abort()):(i=()=>n.abort(),a.addEventListener("abort",i,{once:!0})));try{return await fetch(e,{...t,signal:n.signal})}finally{clearTimeout(o),i&&a&&a.removeEventListener("abort",i)}}async function eV(e,t){if("number"==typeof t&&t<=0)return null;let r="number"==typeof t?Math.max(1,Math.min(eT,t)):eT,a=i.join(C.tmpdir(),`agent-device-devicectl-info-${process.pid}-${Date.now()}.json`);try{let t=Math.max(1,Math.ceil(r/1e3)),i=await c("xcrun",["devicectl","device","info","details","--device",e,"--json-output",a,"--timeout",String(t)],{allowFailure:!0,timeoutMs:r});if(0!==i.exitCode||!M.existsSync(a))return null;let n=JSON.parse(M.readFileSync(a,"utf8"));if(n.info?.outcome&&"success"!==n.info.outcome)return null;let o=(n.result?.connectionProperties?.tunnelIPAddress??n.result?.device?.connectionProperties?.tunnelIPAddress)?.trim();return o&&o.length>0?o:null}catch{return null}finally{eq(a)}}async function eG(e,t,r,a){let i=JSON.stringify(r),n=ek(e,["spawn",e.id,"/usr/bin/curl","-s","-X","POST","-H","Content-Type: application/json","--data",i,`http://127.0.0.1:${t}/command`]),o=await c("xcrun",n,{allowFailure:!0,timeoutMs:a}),s=o.stdout;if(0!==o.exitCode){let e=ef({message:"Runner did not accept connection (simctl spawn)",stdout:o.stdout,stderr:o.stderr,context:{platform:"ios",phase:"connect"}});throw new h("COMMAND_FAILED","Runner did not accept connection (simctl spawn)",{port:t,stdout:o.stdout,stderr:o.stderr,exitCode:o.exitCode,reason:e,hint:em(e)})}return{status:200,body:s}}async function ej(){return await new Promise((e,t)=>{let r=R.createServer();r.listen(0,"127.0.0.1",()=>{let a=r.address();r.close(),"object"==typeof a&&a?.port?e(a.port):t(new h("COMMAND_FAILED","Failed to allocate port"))}),r.on("error",t)})}function eB(e,t,r,a){t&&M.appendFileSync(t,e),r&&M.appendFileSync(r,e),a&&process.stderr.write(e)}function eq(e){try{M.existsSync(e)&&M.unlinkSync(e)}catch{}}async function eH(e,t,r){let a=(e.get(t)??Promise.resolve()).catch(()=>{}).then(r);return e.set(t,a),a.finally(()=>{e.get(t)===a&&e.delete(t)})}function eW(e){return"apple"===e?"ios":e}async function ez(e,a,i={}){let n=e,o=e=>e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim();if(a.platform&&(n=n.filter(e=>e.platform===a.platform)),a.target&&(n=n.filter(e=>(e.target??"mobile")===a.target)),a.udid){let e=n.find(e=>e.id===a.udid&&"ios"===e.platform);if(!e)throw new h("DEVICE_NOT_FOUND",`No iOS device with UDID ${a.udid}`);return e}if(a.serial){let e=n.find(e=>e.id===a.serial&&"android"===e.platform);if(!e)throw new h("DEVICE_NOT_FOUND",`No Android device with serial ${a.serial}`);return e}if(a.deviceName){let e=o(a.deviceName),t=n.find(t=>o(t.name)===e);if(!t)throw new h("DEVICE_NOT_FOUND",`No device named ${a.deviceName}`);return t}if(1===n.length)return n[0];if(0===n.length){let e=i.simulatorSetPath;if(e&&(!a.platform||"ios"===a.platform))throw new h("DEVICE_NOT_FOUND","No devices found in the scoped simulator set",{simulatorSetPath:e,hint:`The simulator set at "${e}" appears to be empty. Create a simulator first:
5
+ xcrun simctl --set "${e}" create "iPhone 16" com.apple.CoreSimulator.SimDeviceType.iPhone-16 com.apple.CoreSimulator.SimRuntime.iOS-18-0`,selector:a});throw new h("DEVICE_NOT_FOUND","No devices found",{selector:a})}let s=n.filter(e=>"device"!==e.kind);s.length>0&&(n=s);let l=n.filter(e=>e.booted);if(1===l.length)return l[0];if(!process.env.CI&&process.stdin.isTTY&&process.stdout.isTTY){let e=await r({message:"Multiple devices available. Choose a device to continue:",options:(l.length>0?l:n).map(e=>({label:`${e.name} (${e.platform}${e.kind?`, ${e.kind}`:""}${e.booted?", booted":""})`,value:e.id}))});if(t(e))throw new h("INVALID_ARGS","Device selection cancelled");if(e){let t=n.find(t=>t.id===e);if(t)return t}}return l[0]??n[0]}let eJ=i.join(C.homedir(),".agent-device","ios-runner"),eK=new Map,eX=new Set;function eZ(e){return e?.trim()??""}function eY(e=process.env){return eZ(e.AGENT_DEVICE_IOS_BUNDLE_ID)||eZ(e.AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID)||"com.callstack.agentdevice.runner"}function eQ(e=process.env){let t=eZ(e.AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID);return t||`${eY(e)}.uitests`}let e0=function(e=process.env){let t=eY(e),r=eQ(e);return Array.from(new Set([eZ(e.AGENT_DEVICE_IOS_RUNNER_CONTAINER_BUNDLE_ID),`${r}.xctrunner`,t].filter(e=>e.length>0)))}(process.env);async function e1(e,t){var r;let a,n=(r=e.kind,(a=process.env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim())?i.resolve(a):"simulator"===r?i.join(eJ,"derived"):i.join(eJ,"derived",r));return await eH(eK,n,async()=>{if(z(process.env.AGENT_DEVICE_IOS_CLEAN_DERIVED)){!function(e,t=process.env){if(t.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH?.trim()&&!function(e=process.env){return z(e.AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN)}(t))throw new h("COMMAND_FAILED","Refusing to clean AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH automatically",{derivedPath:e,hint:"Unset AGENT_DEVICE_IOS_CLEAN_DERIVED, or set AGENT_DEVICE_IOS_ALLOW_OVERRIDE_DERIVED_CLEAN=1 if you trust this path."})}(n);try{M.rmSync(n,{recursive:!0,force:!0})}catch{}}let r=e2(n);if(r)return r;let a=function(){let e=i.dirname(I(import.meta.url)),t=e;for(let e=0;e<6;e+=1){let e=i.join(t,"package.json");if(M.existsSync(e))return t;t=i.dirname(t)}return e}(),o=i.join(a,"ios-runner","AgentDeviceRunner","AgentDeviceRunner.xcodeproj");if(!M.existsSync(o))throw new h("COMMAND_FAILED","iOS runner project not found",{projectPath:o});let s=function(e=process.env){let t=eY(e),r=eQ(e);return[`AGENT_DEVICE_IOS_RUNNER_APP_BUNDLE_ID=${t}`,`AGENT_DEVICE_IOS_RUNNER_TEST_BUNDLE_ID=${r}`]}(process.env),l=function(e=process.env,t=!1){if(!t)return[];let r=e.AGENT_DEVICE_IOS_TEAM_ID?.trim()||"",a=e.AGENT_DEVICE_IOS_SIGNING_IDENTITY?.trim()||"",i=e.AGENT_DEVICE_IOS_PROVISIONING_PROFILE?.trim()||"",n=["CODE_SIGN_STYLE=Automatic"];return r&&n.push(`DEVELOPMENT_TEAM=${r}`),a&&n.push(`CODE_SIGN_IDENTITY=${a}`),i&&n.push(`PROVISIONING_PROFILE_SPECIFIER=${i}`),n}(process.env,"device"===e.kind),d="device"===e.kind?["-allowProvisioningUpdates"]:[];try{var u;let r;await v("xcodebuild",["build-for-testing","-project",o,"-scheme","AgentDeviceRunner","-parallel-testing-enabled","NO",e8(e),"1","-destination",(u=e,r=e4(u),"simulator"===u.kind?`platform=${r} Simulator,id=${u.id}`:`generic/platform=${r}`),"-derivedDataPath",n,"COMPILER_INDEX_STORE_ENABLE=NO",...s,...d,...l],{detached:!0,onSpawn:e=>{eX.add(e),e.on("close",()=>{eX.delete(e)})},onStdoutChunk:e=>{eB(e,t.logPath,t.traceLogPath,t.verbose)},onStderrChunk:e=>{eB(e,t.logPath,t.traceLogPath,t.verbose)}})}catch(n){let e,r,a=n instanceof h?n:new h("COMMAND_FAILED",String(n)),i=(e=a.details?JSON.stringify(a.details):"",(r=`${a.message}
6
+ ${e}`.toLowerCase()).includes("failed registering bundle identifier")||r.includes("app identifier")&&r.includes("not available")?"Set AGENT_DEVICE_IOS_BUNDLE_ID to a unique reverse-DNS value (for example, com.yourname.agentdevice.runner), then retry.":r.includes("requires a development team")?"Configure signing in Xcode or set AGENT_DEVICE_IOS_TEAM_ID for physical-device runs.":r.includes("no profiles for")||r.includes("provisioning profile")?"Install/select a valid iOS provisioning profile, or set AGENT_DEVICE_IOS_PROVISIONING_PROFILE.":r.includes("code signing")?"Enable Automatic Signing in Xcode or provide AGENT_DEVICE_IOS_TEAM_ID and optional AGENT_DEVICE_IOS_SIGNING_IDENTITY.":void 0);throw new h("COMMAND_FAILED","xcodebuild build-for-testing failed",{error:a.message,details:a.details,logPath:t.logPath,hint:i})}let c=e2(n);if(!c)throw new h("COMMAND_FAILED","Failed to locate .xctestrun after build");return c})}function e2(e){if(!M.existsSync(e))return null;let t=[],r=[e];for(;r.length>0;){let e=r.pop();for(let a of M.readdirSync(e,{withFileTypes:!0})){let n=i.join(e,a.name);if(a.isDirectory()){r.push(n);continue}if(a.isFile()&&a.name.endsWith(".xctestrun"))try{let e=M.statSync(n);t.push({path:n,mtimeMs:e.mtimeMs})}catch{}}}return 0===t.length?null:(t.sort((e,t)=>t.mtimeMs-e.mtimeMs),t[0]?.path??null)}async function e3(e,t,r){let a,n=i.dirname(e),o=r.replace(/[^a-zA-Z0-9._-]/g,"_"),s=i.join(n,`AgentDeviceRunner.env.${o}.json`),l=i.join(n,`AgentDeviceRunner.env.${o}.xctestrun`),d=await c("plutil",["-convert","json","-o","-",e],{allowFailure:!0});if(0!==d.exitCode||!d.stdout.trim())throw new h("COMMAND_FAILED","Failed to read xctestrun plist",{xctestrunPath:e,stderr:d.stderr});try{a=JSON.parse(d.stdout)}catch(t){throw new h("COMMAND_FAILED","Failed to parse xctestrun JSON",{xctestrunPath:e,error:String(t)})}let u=e=>{e.EnvironmentVariables={...e.EnvironmentVariables??{},...t},e.UITestEnvironmentVariables={...e.UITestEnvironmentVariables??{},...t},e.UITargetAppEnvironmentVariables={...e.UITargetAppEnvironmentVariables??{},...t},e.TestingEnvironmentVariables={...e.TestingEnvironmentVariables??{},...t}},p=a.TestConfigurations;if(Array.isArray(p))for(let e of p){if(!e||"object"!=typeof e)continue;let t=e.TestTargets;if(Array.isArray(t))for(let e of t)e&&"object"==typeof e&&u(e)}for(let[e,t]of Object.entries(a))t&&"object"==typeof t&&t.TestBundlePath&&(u(t),a[e]=t);M.writeFileSync(s,JSON.stringify(a,null,2));let f=await c("plutil",["-convert","xml1","-o",l,s],{allowFailure:!0});if(0!==f.exitCode)throw new h("COMMAND_FAILED","Failed to write xctestrun plist",{tmpXctestrunPath:l,stderr:f.stderr});return{xctestrunPath:l,jsonPath:s}}function e4(e){if("ios"!==e.platform)throw new h("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);return"tv"===e.target?"tvOS":"iOS"}function e8(e){return"device"===e.kind?"-maximum-concurrent-test-device-destinations":"-maximum-concurrent-test-simulator-destinations"}let e6=new Map,e5=new Map;async function e9(e,t){return await eH(e5,e.id,async()=>{var r,a;let i,n=e6.get(e.id);if(n){if((r=n.child.pid)&&k(r))return n;await te(e.id,n)}await ("simulator"!==(a=e).kind?Promise.resolve():tn(a));let o=await e1(e,t),s=await ej(),{xctestrunPath:l,jsonPath:u}=await e3(o,{AGENT_DEVICE_RUNNER_PORT:String(s)},`session-${e.id}-${s}`),{child:c,wait:p}=d("xcodebuild",["test-without-building","-only-testing","AgentDeviceRunnerUITests/RunnerTests/testCommand","-parallel-testing-enabled","NO","-test-timeouts-enabled","NO","-collect-test-diagnostics","never",e8(e),"1","-destination-timeout",String(eP),"-xctestrun",l,"-destination",(i=e4(e),"simulator"===e.kind?`platform=${i} Simulator,id=${e.id}`:`platform=${i},id=${e.id}`)],{allowFailure:!0,env:{...process.env,AGENT_DEVICE_RUNNER_PORT:String(s)},detached:!0});c.stdout?.on("data",e=>{eB(e,t.logPath,t.traceLogPath,t.verbose)}),c.stderr?.on("data",e=>{eB(e,t.logPath,t.traceLogPath,t.verbose)});let f={device:e,deviceId:e.id,port:s,xctestrunPath:l,jsonPath:u,testPromise:p,child:c,ready:!1};return e6.set(e.id,f),f})}async function e7(e){await eH(e5,e.deviceId,async()=>{await te(e.deviceId,e)})}async function te(e,t){let r=t??e6.get(e);if(r){try{await e$(r.device,r.port,{command:"shutdown"},void 0,15e3)}catch{await ti(r.child.pid,"SIGTERM")}try{await Promise.race([r.testPromise,new Promise(e=>setTimeout(e,1e4))])}catch{}await ti(r.child.pid,"SIGKILL"),eq(r.xctestrunPath),eq(r.jsonPath),e6.get(e)===r&&e6.delete(e)}}async function tt(e){await eH(e5,e,async()=>{await te(e)})}async function tr(){let e=Array.from(e6.values()),t=Array.from(eX);await Promise.allSettled(e.map(async e=>{await ti(e.child.pid,"SIGINT")})),await Promise.allSettled(t.map(async e=>{await ti(e.pid,"SIGINT")})),await Promise.allSettled(e.map(async e=>{await ti(e.child.pid,"SIGTERM")})),await Promise.allSettled(t.map(async e=>{await ti(e.pid,"SIGTERM")})),await Promise.allSettled(e.map(async e=>{await ti(e.child.pid,"SIGKILL")})),await Promise.allSettled(t.map(async e=>{await ti(e.pid,"SIGKILL"),eX.delete(e)}))}async function ta(){await tr();let e=Array.from(e6.keys());await Promise.allSettled(e.map(async e=>{await tt(e)}));let t=Array.from(eX);await Promise.allSettled(t.map(async e=>{try{await ti(e.pid,"SIGTERM"),await ti(e.pid,"SIGKILL")}finally{eX.delete(e)}}))}async function ti(e,t){if(!e||e<=0)return;try{process.kill(-e,t)}catch{}try{process.kill(e,t)}catch{}let r="SIGINT"===t?"INT":"SIGTERM"===t?"TERM":"KILL";try{await c("pkill",[`-${r}`,"-P",String(e)],{allowFailure:!0})}catch{}}async function tn(e){await c("xcrun",ek(e,["bootstatus",e.id,"-b"]),{timeoutMs:eL})}async function to(e,t,r,a,i,n){let o=await e$(e,t.port,r,a,i,t,n);return await ts(o,t,a)}async function ts(e,t,r){let a=await e.text(),i={};try{i=JSON.parse(a)}catch{throw new h("COMMAND_FAILED","Invalid runner response",{text:a})}if(!i.ok)throw new h("COMMAND_FAILED",i.error?.message??"Runner error",{runner:i,xcodebuild:{exitCode:1,stdout:"",stderr:""},logPath:r});return t.ready=!0,i.data??{}}async function tl(e,t,r={}){var a;if("ios"!==e.platform)throw new h("UNSUPPORTED_PLATFORM",`Unsupported platform for iOS runner: ${e.platform}`);if("simulator"!==e.kind&&"device"!==e.kind)throw new h("UNSUPPORTED_OPERATION",`Unsupported iOS device kind for runner: ${e.kind}`);return(eI(r.requestId),"snapshot"===(a=t.command)||"screenshot"===a||"findText"===a||"alert"===a)?Q(()=>(eI(r.requestId),td(e,t,r)),{shouldRetry:e=>{eI(r.requestId);if(!(e instanceof h)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.message??""}`.toLowerCase();return!(t.includes("xcodebuild exited early")||t.includes("device is busy")&&t.includes("connecting"))&&!!(t.includes("runner did not accept connection")||t.includes("fetch failed")||t.includes("econnrefused")||t.includes("socket hang up"))}}):td(e,t,r)}async function td(e,t,r={}){let a;eI(r.requestId);let i=eu(r.requestId);try{let n=(a=await e9(e,r)).ready?eO:eL;return await to(e,a,t,r.logPath,n,i)}catch(o){let n=o instanceof h?o:new h("COMMAND_FAILED",String(o));if("COMMAND_FAILED"===n.code&&"string"==typeof n.message&&n.message.includes("Runner did not accept connection")&&eh(n)&&a?.ready){eI(r.requestId),a?await e7(a):await tt(e.id),a=await e9(e,r);let n=await e$(a.device,a.port,t,r.logPath,eL,void 0,i);return await ts(n,a,r.logPath)}throw o}}function tu(e){let t=e.result?.text;if("string"==typeof t&&t.trim().length>0)return t;let r=e.positionals??[];return 0===r.length?"":r[0].startsWith("@")?r.length>=3?r.slice(2).join(" ").trim():r.slice(1).join(" ").trim():!(r.length>=3)||Number.isNaN(Number(r[0]))||Number.isNaN(Number(r[1]))?r.slice(1).join(" ").trim():r.slice(2).join(" ").trim()}function tc(e){let t=new Set,r=[];for(let a of e)t.has(a)||(t.add(a),r.push(a));return r}let tp=/^-?\d+(\.\d+)?$/,tf=new Map([["--count","count"],["--interval-ms","intervalMs"],["--hold-ms","holdMs"],["--jitter-px","jitterPx"]]),tm=new Map([["--count","count"],["--pause-ms","pauseMs"]]);function th(e){return"click"===e||"press"===e}function tw(e){let t=e.trim();return t.startsWith("@")||tp.test(t)?t:JSON.stringify(t)}function tg(e){let t=e.trim();return/\s/.test(t)?JSON.stringify(t):t}function tI(e,t){let r=t.flags??{};if(th(t.command)){"number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.intervalMs&&e.push("--interval-ms",String(r.intervalMs)),"number"==typeof r.holdMs&&e.push("--hold-ms",String(r.holdMs)),"number"==typeof r.jitterPx&&e.push("--jitter-px",String(r.jitterPx)),!0===r.doubleTap&&e.push("--double-tap");return}"swipe"===t.command&&("number"==typeof r.count&&e.push("--count",String(r.count)),"number"==typeof r.pauseMs&&e.push("--pause-ms",String(r.pauseMs)),("one-way"===r.pattern||"ping-pong"===r.pattern)&&e.push("--pattern",r.pattern))}function tv(e,t){t&&(("ios"===t.platform||"android"===t.platform)&&e.push("--platform",t.platform),"string"==typeof t.metroHost&&t.metroHost.length>0&&e.push("--metro-host",tg(t.metroHost)),"number"==typeof t.metroPort&&e.push("--metro-port",String(t.metroPort)),"string"==typeof t.bundleUrl&&t.bundleUrl.length>0&&e.push("--bundle-url",tg(t.bundleUrl)),"string"==typeof t.launchUrl&&t.launchUrl.length>0&&e.push("--launch-url",tg(t.launchUrl)))}function tA(e,t){let r=[],a={},i=th(e)?tf:"swipe"===e?tm:void 0;for(let n=0;n<t.length;n+=1){let o=t[n];if(th(e)&&"--double-tap"===o){a.doubleTap=!0;continue}let s=i?.get(o);if(s&&n+1<t.length){let e=ty(t[n+1]);null!==e&&(a[s]=e),n+=1;continue}if("swipe"===e&&"--pattern"===o&&n+1<t.length){let e=t[n+1];("one-way"===e||"ping-pong"===e)&&(a.pattern=e),n+=1;continue}r.push(o)}return{positionals:r,flags:a}}function ty(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}class tb{sessions=new Map;runtimeHints=new Map;sessionsDir;constructor(e){this.sessionsDir=e}get(e){return this.sessions.get(e)}has(e){return this.sessions.has(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){t.flags?.noRecord||(t.flags?.saveScript&&(e.recordSession=!0,"string"==typeof t.flags.saveScript&&(e.saveScriptPath=tb.expandHome(t.flags.saveScript))),e.actions.push({ts:Date.now(),command:t.command,positionals:t.positionals,flags:function(e){if(!e)return{};let{platform:t,device:r,udid:a,serial:i,out:n,verbose:o,metroHost:s,metroPort:l,bundleUrl:d,launchUrl:u,snapshotInteractiveOnly:c,snapshotCompact:p,snapshotDepth:f,snapshotScope:m,snapshotRaw:h,relaunch:w,saveScript:g,noRecord:I,count:v,intervalMs:A,holdMs:y,jitterPx:b,doubleTap:N,pauseMs:_,pattern:S}=e;return{platform:t,device:r,udid:a,serial:i,out:n,verbose:o,metroHost:s,metroPort:l,bundleUrl:d,launchUrl:u,snapshotInteractiveOnly:c,snapshotCompact:p,snapshotDepth:f,snapshotScope:m,snapshotRaw:h,relaunch:w,saveScript:g,noRecord:I,count:v,intervalMs:A,holdMs:y,jitterPx:b,doubleTap:N,pauseMs:_,pattern:S}}(t.flags),result:t.result}),D({level:"debug",phase:"record_action",data:{command:t.command,session:e.name}}))}writeSessionLog(e){try{if(!e.recordSession)return;let t=this.resolveScriptPath(e),r=i.dirname(t);M.existsSync(r)||M.mkdirSync(r,{recursive:!0});let a=function(e,t){let r=[],a=e.device.name.replace(/"/g,'\\"'),i=e.device.kind?` kind=${e.device.kind}`:"";for(let n of(r.push(`context platform=${e.device.platform} device="${a}"${i} theme=unknown`),t))n.flags?.noRecord||r.push(function(e){let t=[e.command];if(th(e.command)){let r=e.positionals?.[0];if(r){if(r.startsWith("@")){t.push(tw(r));let a=e.result?.refLabel;return"string"==typeof a&&a.trim().length>0&&t.push(tw(a)),tI(t,e),t.join(" ")}if(1===e.positionals.length)return t.push(tw(r)),tI(t,e),t.join(" ")}}if("fill"===e.command){let r=e.positionals?.[0];if(r&&r.startsWith("@")){t.push(tw(r));let a=e.result?.refLabel,i=e.positionals.slice(1).join(" ");return"string"==typeof a&&a.trim().length>0&&t.push(tw(a)),i&&t.push(tw(i)),t.join(" ")}}if("get"===e.command){let r=e.positionals?.[0],a=e.positionals?.[1];if(r&&a){if(t.push(tw(r)),t.push(tw(a)),a.startsWith("@")){let r=e.result?.refLabel;"string"==typeof r&&r.trim().length>0&&t.push(tw(r))}return t.join(" ")}}if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tw(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command){for(let r of e.positionals??[])t.push(tw(r));return e.flags?.relaunch&&t.push("--relaunch"),t.join(" ")}if("runtime"===e.command){let r=e.positionals?.[0];return r&&t.push(tg(r)),tv(t,e.flags),t.join(" ")}for(let r of e.positionals??[])t.push(tw(r));return tI(t,e),t.join(" ")}(n));return`${r.join("\n")}
7
+ `}(e,this.buildOptimizedActions(e));M.writeFileSync(t,a)}catch{}}defaultTracePath(e){let t=tb.safeSessionName(e.name),r=new Date().toISOString().replace(/[:.]/g,"-");return i.join(this.sessionsDir,`${t}-${r}.trace.log`)}resolveAppLogPath(e){return i.join(this.sessionsDir,tb.safeSessionName(e),"app.log")}resolveAppLogPidPath(e){return i.join(this.sessionsDir,tb.safeSessionName(e),"app-log.pid")}static safeSessionName(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_")}static expandHome(e,t){return e.startsWith("~/")?i.join(C.homedir(),e.slice(2)):t&&!i.isAbsolute(e)?i.resolve(t,e):i.resolve(e)}resolveScriptPath(e){if(e.saveScriptPath)return tb.expandHome(e.saveScriptPath);M.existsSync(this.sessionsDir)||M.mkdirSync(this.sessionsDir,{recursive:!0});let t=tb.safeSessionName(e.name),r=new Date(e.createdAt).toISOString().replace(/[:.]/g,"-");return i.join(this.sessionsDir,`${t}-${r}.ad`)}buildOptimizedActions(e){let t=[];for(let r of e.actions){if("snapshot"===r.command)continue;let a=Array.isArray(r.result?.selectorChain)&&r.result?.selectorChain.every(e=>"string"==typeof e)?r.result.selectorChain:[];if(a.length>0&&(th(r.command)||"fill"===r.command||"get"===r.command)){let e=a.join(" || ");if(th(r.command)){t.push({...r,positionals:[e]});continue}if("fill"===r.command){let a=tu(r);if(a.length>0){t.push({...r,positionals:[e,a]});continue}}if("get"===r.command){let a=r.positionals?.[0];if("text"===a||"attrs"===a){t.push({...r,positionals:[a,e]});continue}}}if(th(r.command)||"fill"===r.command||"get"===r.command){let a=r.result?.refLabel;"string"==typeof a&&a.trim().length>0&&t.push({ts:r.ts,command:"snapshot",positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotCompact:!0,snapshotScope:a.trim()},result:{scope:a.trim()}})}t.push(r)}return t}}function tN(e,t){if(!e)return;let r=i.dirname(e);M.existsSync(r)||M.mkdirSync(r,{recursive:!0});let a={pid:t,startTime:L(t)??void 0,command:n(t)??void 0};M.writeFileSync(e,`${JSON.stringify(a)}
8
+ `)}function t_(e){if(e&&M.existsSync(e))try{M.unlinkSync(e)}catch{}}async function tS(e,t=2e3){await Promise.race([e.then(()=>void 0).catch(()=>void 0),new Promise(e=>setTimeout(e,t))])}async function tD(e){await new Promise(t=>setTimeout(t,e))}function tE(e,t){let r=t.includeTokens?.filter(e=>e.length>0)??[],a="",i=a=>{(!(r.length>0)||r.some(e=>a.includes(e)))&&e.write(function(e,t){if(0===t.length)return e;let r=e;for(let e of t)r=r.replace(e,"[REDACTED]");return r}(a,t.redactionPatterns))};return{onChunk:e=>{let t=`${a}${e}`.split("\n");for(let e of(a=t.pop()??"",t))i(`${e}
9
+ `)},flush:()=>{a&&(i(a),a="")}}}function tk(e,t,r){let a=e.stdout,i=e.stderr;return a&&i?(a.setEncoding("utf8"),i.setEncoding("utf8"),a.on("data",r.writer.onChunk),i.on("data",r.writer.onChunk),t.on("error",()=>{e.killed||e.kill("SIGKILL")}),e.on("error",()=>t.destroy()),new Promise(a=>{e.on("close",e=>{r.writer.flush(),r.endStreamOnClose&&t.end(),a({stdout:"",stderr:"",exitCode:e??1})})})):Promise.resolve({stdout:"",stderr:"missing stdio pipes",exitCode:1})}async function tL(e,t){let r=(await c("adb",["-s",e,"shell","pidof",t],{allowFailure:!0})).stdout.trim().split(/\s+/)[0];return r&&/^\d+$/.test(r)?r:null}async function tO(e,t,r,a,i){let n,o,s="active",l=!1,d=(async()=>{try{for(;!l;){let d=await tL(e,t);if(!d){await tD(1e3);continue}let u=p("adb",["-s",e,"logcat","-v","time","--pid",d],{stdio:["ignore","pipe","pipe"]});n=u;let c=tE(r,{redactionPatterns:a});o=tk(u,r,{endStreamOnClose:!1,writer:c}),"number"==typeof u.pid&&tN(i,u.pid);let f=await o;if(t_(i),n=void 0,o=void 0,l)break;0!==f.exitCode&&(s="failed"),await tD(500)}return{stdout:"",stderr:"",exitCode:0}}finally{r.end(),t_(i)}})();return{backend:"android",getState:()=>s,startedAt:Date.now(),wait:d,stop:async()=>{l=!0,n&&!n.killed&&n.kill("SIGINT"),o&&await tS(o),n&&!n.killed&&n.kill("SIGKILL"),await tS(d),t_(i)}}}async function tM(e,t,r,a){let i="active",n=p("log",["stream","--style","compact","--predicate",`subsystem == "${e}" OR processImagePath ENDSWITH[c] "/${e}" OR senderImagePath ENDSWITH[c] "/${e}" OR eventMessage CONTAINS[c] "${e}"`],{stdio:["ignore","pipe","pipe"]}),o=tE(t,{redactionPatterns:r});"number"==typeof n.pid&&tN(a,n.pid);let s=tk(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),t_(a),e));return{backend:"ios-simulator",getState:()=>i,startedAt:Date.now(),wait:s,stop:async()=>{n.killed||n.kill("SIGINT"),await tS(s),n.killed||n.kill("SIGKILL"),await tS(s),t_(a)}}}async function tx(e,t,r,a){let i="active",n=p("xcrun",["devicectl","device","log","stream","--device",e],{stdio:["ignore","pipe","pipe"]}),o=tE(t,{redactionPatterns:r});"number"==typeof n.pid&&tN(a,n.pid);let s=tk(n,t,{endStreamOnClose:!0,writer:o}).then(e=>(0!==e.exitCode&&(i="failed"),t_(a),e));return{backend:"ios-device",getState:()=>i,startedAt:Date.now(),wait:s,stop:async()=>{n.killed||n.kill("SIGINT"),await tS(s),n.killed||n.kill("SIGKILL"),await tS(s),t_(a)}}}function tC(e,t){let r=process.env[e];if(!r)return t;let a=Number.parseInt(r,10);return Number.isInteger(a)&&a>0?a:t}function tR(e){let t=i.dirname(e);M.existsSync(t)||M.mkdirSync(t,{recursive:!0}),function(e,t){if(M.existsSync(e)&&!(M.statSync(e).size<t.maxBytes))for(let r=t.maxRotatedFiles;r>=1;r-=1){let t=1===r?e:`${e}.${r-1}`,a=`${e}.${r}`;M.existsSync(t)&&(M.existsSync(a)&&M.unlinkSync(a),M.renameSync(t,a))}}(e,{maxBytes:tC("AGENT_DEVICE_APP_LOG_MAX_BYTES",5242880),maxRotatedFiles:tC("AGENT_DEVICE_APP_LOG_MAX_FILES",1)})}async function tT(e,t,r,a){tR(r);let i=M.createWriteStream(r,{flags:"a"}),n=function(){let e=process.env.AGENT_DEVICE_APP_LOG_REDACT_PATTERNS;if(!e)return[];let t=e.split(",").map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of t)try{r.push(RegExp(e,"gi"))}catch{}return r}();if("ios"===e.platform)return"device"===e.kind?await tx(e.id,i,n,a):await tM(t,i,n,a);if("android"===e.platform){if(!/^[a-zA-Z0-9._:-]+$/.test(t))throw new h("INVALID_ARGS",`Invalid Android package name for logs: ${t}`);return await tO(e.id,t,i,n,a)}throw i.end(),new h("UNSUPPORTED_PLATFORM",`unsupported platform: ${e.platform}`)}async function tP(e){await e.stop(),await tS(e.wait)}async function t$(e,t){let r={},a=[];if(t||a.push("No app bundle is tracked in this session. Run open <app> first for app-scoped logs."),"android"===e.platform){try{let e=await c("adb",["version"],{allowFailure:!0});r.adbAvailable=0===e.exitCode}catch{r.adbAvailable=!1}if(t)try{r.androidPidVisible=(await c("adb",["-s",e.id,"shell","pidof",t],{allowFailure:!0})).stdout.trim().length>0}catch{r.androidPidVisible=!1}}if("ios"===e.platform&&"simulator"===e.kind)try{let e=await c("xcrun",["simctl","help"],{allowFailure:!0});r.simctlAvailable=0===e.exitCode}catch{r.simctlAvailable=!1}if("ios"===e.platform&&"device"===e.kind)try{let e=await c("xcrun",["devicectl","--version"],{allowFailure:!0});r.devicectlAvailable=0===e.exitCode}catch{r.devicectlAvailable=!1}return{checks:r,notes:a}}function tF(e){let t=i.dirname(e),r=i.basename(e);M.existsSync(t)||M.mkdirSync(t,{recursive:!0}),M.existsSync(e)?M.truncateSync(e,0):M.writeFileSync(e,"","utf8");let a=0;for(let e of M.readdirSync(t)){if(!e.startsWith(`${r}.`))continue;let n=e.slice(r.length+1);if(/^\d+$/.test(n))try{M.unlinkSync(i.join(t,e)),a+=1}catch{}}return{path:e,cleared:!0,removedRotatedFiles:a}}let tU=new Map;function tV(e){let t=tU.get(e);if(t&&(clearTimeout(t.timer),tU.delete(e),t.deleteAfterDownload))try{M.rmSync(t.artifactPath,{force:!0})}catch{}}let tG=new Map;function tj(e){let t=tG.get(e);t&&(clearTimeout(t.timer),tG.delete(e),M.rmSync(t.tempDir,{recursive:!0,force:!0}))}async function tB(e){let t=await tq(e);await c("tar",["xf",e.archivePath,"-C",e.tempDir]);let r=i.join(e.tempDir,t);if(!M.existsSync(r))throw new h("INVALID_ARGS",`Expected extracted bundle "${t}" not found in archive`);return r}async function tq(e){let t=await c("tar",["-tf",e.archivePath],{allowFailure:!0});if(0!==t.exitCode)throw new h("INVALID_ARGS","Artifact is not a valid tar archive",{archivePath:e.archivePath,stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let r=t.stdout.split(/\r?\n/).map(e=>e.trim()).filter(Boolean);if(0===r.length)throw new h("INVALID_ARGS","Uploaded app bundle archive is empty");let a=r.map(e=>(function(e){if(e.includes("\0"))throw new h("INVALID_ARGS",`Invalid archive entry: ${e}`);if(i.posix.isAbsolute(e))throw new h("INVALID_ARGS",`Archive entry must be relative: ${e}`);let t=i.posix.normalize(e).replace(/^(\.\/)+/,"");if(!t||"."===t||t.startsWith("../"))throw new h("INVALID_ARGS",`Archive entry escapes bundle root: ${e}`);return t})(e)),n=e.expectedRootName??function(e,t){let r=new Set;for(let t of e){let[e]=t.split("/");e&&r.add(e)}let a=[...r];if("ios"===t){let e=a.filter(e=>e.toLowerCase().endsWith(".app"));if(1===e.length)return e[0];if(0===e.length)throw new h("INVALID_ARGS","iOS app bundle archives must contain a single top-level .app directory");throw new h("INVALID_ARGS",`iOS app bundle archives must contain exactly one top-level .app directory, found: ${e.join(", ")}`)}if(1===a.length)return a[0];throw new h("INVALID_ARGS",`Archive must contain a single top-level bundle, found: ${a.join(", ")}`)}(a,e.platform);if(!a.some(e=>e===n||e.startsWith(`${n}/`)))throw new h("INVALID_ARGS",`Uploaded archive must contain a top-level "${n}" bundle`);for(let e of a){var o=e,s=n;if(o!==s&&!o.startsWith(`${s}/`))throw new h("INVALID_ARGS",`Archive entry must stay inside top-level "${s}" bundle: ${o}`)}for(let t of(await c("tar",["-tvf",e.archivePath])).stdout.split(/\r?\n/).filter(Boolean)){let e=t[0];if("l"===e||"h"===e)throw new h("INVALID_ARGS","Uploaded app bundle archive cannot contain symlinks or hard links")}return n}let tH=ev(process.env.AGENT_DEVICE_ARTIFACT_IDLE_TIMEOUT_MS,6e4,1e3);function tW(e,t){return new Promise((r,a)=>{let i,n=M.createWriteStream(t),o=t=>{"destroy"in e&&"function"==typeof e.destroy&&e.destroy(t)},s=!1,l=0,d=e=>{if(!s){if(s=!0,i&&clearTimeout(i),e){n.destroy(),M.rmSync(t,{force:!0}),a(e);return}r()}},u=()=>{i&&clearTimeout(i),i=setTimeout(()=>{let e=new h("COMMAND_FAILED","Artifact transfer timed out due to inactivity",{timeoutMs:tH});o(e),n.destroy(e),d(e)},tH)};e.on("data",e=>{u();let t=Buffer.isBuffer(e)?e.length:Buffer.byteLength(e);if((l+=t)>0x80000000){let e=new h("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes");o(e),n.destroy(e),d(e)}}),e.on("error",d),e.on("aborted",()=>{d(new h("COMMAND_FAILED","Artifact transfer was interrupted"))}),n.on("error",d),n.on("finish",()=>d()),u(),e.pipe(n)})}async function tz(e){let t,r=e.headers["x-artifact-type"],a=e.headers["x-artifact-filename"];if(!r||!a)throw new h("INVALID_ARGS","Missing required headers: x-artifact-type and x-artifact-filename");if("file"!==r&&"app-bundle"!==r)throw new h("INVALID_ARGS",`Invalid x-artifact-type: ${r}. Must be "file" or "app-bundle".`);!function(e){if(void 0===e)return;let t=Number(e);if(Number.isFinite(t)&&t>0x80000000)throw new h("INVALID_ARGS","Upload exceeds maximum size of 2147483648 bytes")}(e.headers["content-length"]);let n=function(e){let t=e.trim(),r=i.basename(t);if(!r||"."===r||".."===r)throw new h("INVALID_ARGS",`Invalid artifact filename: ${e}`);return r}(a),o=(t=function(e){let t=e?.trim();if(!t)return"request";let r=t.replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"");return r.length>0?r.slice(0,48):"request"}("upload"),M.mkdtempSync(i.join(C.tmpdir(),`agent-device-artifact-${t}-`)));try{if("file"===r){let t=i.join(o,n);return await tW(e,t),{artifactPath:t,tempDir:o}}let t=i.join(o,"artifact.tar");await tW(e,t);let a=await tB({archivePath:t,tempDir:o,platform:"ios",expectedRootName:n});return M.rmSync(t,{force:!0}),{artifactPath:a,tempDir:o}}catch(e){throw M.rmSync(o,{recursive:!0,force:!0}),e}}let tJ=new Set(["agent_device.command","agent-device.command"]),tK=new Set(["agent_device.install_from_source","agent-device.install_from_source"]),tX=new Set(["agent_device.release_materialized_paths","agent-device.release_materialized_paths"]),tZ={"agent_device.lease.allocate":"lease_allocate","agent-device.lease.allocate":"lease_allocate","agent_device.lease.heartbeat":"lease_heartbeat","agent-device.lease.heartbeat":"lease_heartbeat","agent_device.lease.release":"lease_release","agent-device.lease.release":"lease_release"},tY=new Set([...tJ,...tK,...tX,...Object.keys(tZ)]);function tQ(e,t,r,a){return{jsonrpc:"2.0",id:e,error:{code:t,message:r,data:a}}}function t0(e,t,r=200){e.statusCode=r,e.setHeader("content-type","application/json"),e.end(JSON.stringify(t))}function t1(e){switch(e){case"INVALID_ARGS":return 400;case"UNAUTHORIZED":return 401;case"SESSION_NOT_FOUND":return 404;default:return 500}}function t2(e,t){let r="string"==typeof t.authorization?t.authorization:"",a=r.toLowerCase().startsWith("bearer ")?r.slice(7):void 0,i="string"==typeof t["x-agent-device-token"]?t["x-agent-device-token"]:void 0;return("string"==typeof e.token?e.token:void 0)??i??a??""}function t3(e,t){let r=e[t];return"string"==typeof r?r:void 0}function t4(e,t){let r=e[t];return Number.isInteger(r)?Number(r):void 0}async function t8(e,t){if(!e)return{ok:!0};let r=await e(t);if(void 0===r||!0===r)return{ok:!0};if(!1===r){let e=A(new h("UNAUTHORIZED","Request rejected by auth hook"));return{ok:!1,statusCode:401,response:tQ(t.rpcRequest.id??null,-32001,e.message,e)}}if(!1===r.ok){let e=A(new h(r.code??"UNAUTHORIZED",r.message??"Request rejected by auth hook",r.details));return{ok:!1,statusCode:401,response:tQ(t.rpcRequest.id??null,-32001,e.message,e)}}if("string"==typeof r.tenantId&&r.tenantId.length>0){let e=o(r.tenantId);if(!e){let e=A(new h("INVALID_ARGS","Auth hook returned invalid tenantId"));return{ok:!1,statusCode:500,response:tQ(t.rpcRequest.id??null,-32e3,e.message,e)}}return{ok:!0,tenantId:e}}return{ok:!0}}async function t6(){let e,t=process.env.AGENT_DEVICE_HTTP_AUTH_HOOK;if(!t)return null;let r=process.env.AGENT_DEVICE_HTTP_AUTH_EXPORT||"default",a=i.isAbsolute(t)?t:i.resolve(t);try{e=await import(m(a).href)}catch(e){throw new h("COMMAND_FAILED","Failed to load AGENT_DEVICE_HTTP_AUTH_HOOK module",{hookPath:a,error:e instanceof Error?e.message:String(e)})}let n=e[r];if("function"!=typeof n)throw new h("INVALID_ARGS",`Auth hook export ${r} is not a function`,{hookPath:a,exportName:r});return n}async function t5(e){let t=await t6(),{handleRequest:r,token:a}=e;return $.createServer((e,i)=>{if("GET"===e.method&&"/health"===e.url){i.statusCode=200,i.setHeader("content-type","application/json"),i.end(JSON.stringify({ok:!0}));return}if("POST"===e.method&&"/upload"===e.url)return void t9(e,i,t,a);if("GET"===e.method&&e.url?.startsWith("/upload/"))return void t7(e,i,t,a);if("POST"!==e.method||"/rpc"!==e.url){i.statusCode=404,i.end("Not found");return}let n="";e.setEncoding("utf8"),e.on("data",t=>{(n+=t).length>1048576&&e.destroy(Error("request too large"))}),e.on("error",()=>{i.headersSent||t0(i,tQ(null,-32700,"Parse error"),400)}),e.on("end",async()=>{let a,o;try{a=JSON.parse(n)}catch{t0(i,tQ(null,-32700,"Parse error"),400);return}if("2.0"!==a.jsonrpc||"string"!=typeof a.method)return void t0(i,tQ(a.id??null,-32600,"Invalid Request"),400);if(!tY.has(a.method))return void t0(i,tQ(a.id??null,-32601,`Method not found: ${a.method}`),404);if(!a.params||"object"!=typeof a.params)return void t0(i,tQ(a.id??null,-32602,"Invalid params"),400);try{var s;let n=a.params,l=function(e,t,r){if(tJ.has(e))return{token:t2(t,r),session:t.session??"default",command:t.command??"",positionals:Array.isArray(t.positionals)?t.positionals:[],flags:t.flags,runtime:t.runtime,meta:t.meta};if(tK.has(e)){let e,a=t3(t,"platform");if("ios"!==a&&"android"!==a)throw new h("INVALID_ARGS",'Invalid params: platform must be "ios" or "android"');return{token:t2(t,r),session:t3(t,"session")??"default",command:"install_source",positionals:[],flags:{platform:a},meta:{requestId:t3(t,"requestId"),installSource:function(e){let t=e.source;if(!t||"object"!=typeof t)throw new h("INVALID_ARGS","Invalid params: source is required");if("url"===t.kind){let e="string"==typeof t.url?t.url.trim():"";if(!e)throw new h("INVALID_ARGS","Invalid params: source.url is required for url sources");let r=t.headers,a={};if(void 0!==r){if(!r||"object"!=typeof r||Array.isArray(r))throw new h("INVALID_ARGS","Invalid params: source.headers must be a string map");for(let[e,t]of Object.entries(r)){if("string"!=typeof t)throw new h("INVALID_ARGS","Invalid params: source.headers values must be strings");a[e]=t}}return Object.keys(a).length>0?{kind:"url",url:e,headers:a}:{kind:"url",url:e}}if("path"===t.kind){let e="string"==typeof t.path?t.path.trim():"";if(!e)throw new h("INVALID_ARGS","Invalid params: source.path is required for path sources");return{kind:"path",path:e}}throw new h("INVALID_ARGS",'Invalid params: source.kind must be "url" or "path"')}(t),retainMaterializedPaths:(e=t.retainPaths,"boolean"==typeof e?e:void 0),materializedPathRetentionMs:t4(t,"retentionMs")}}}if(tX.has(e)){let e=t3(t,"materializationId")?.trim();if(!e)throw new h("INVALID_ARGS","Invalid params: materializationId is required");return{token:t2(t,r),session:t3(t,"session")??"default",command:"release_materialized_paths",positionals:[],meta:{requestId:t3(t,"requestId"),materializationId:e}}}let a=tZ[e];if(a)return{token:t2(t,r),session:t3(t,"session")??"default",command:a,positionals:[],meta:{tenantId:t3(t,"tenantId")??t3(t,"tenant"),runId:t3(t,"runId"),leaseId:t3(t,"leaseId"),leaseTtlMs:t4(t,"ttlMs"),leaseBackend:t3(t,"backend")}};throw new h("INVALID_ARGS",`Method not found: ${e}`)}(a.method,n,e.headers);if(s=a.method,tJ.has(s)&&("string"!=typeof l.command||0===l.command.length))return void t0(i,tQ(a.id??null,-32602,"Invalid params: command is required"),400);o=en(l.meta?.requestId,a.id),l.meta={...l.meta,requestId:o},eo(o);let d=()=>{i.writableFinished||es(o)};e.on("aborted",d),i.on("close",d);let u=await t8(t,{headers:e.headers,rpcRequest:a,daemonRequest:l});if(!u.ok)return void t0(i,u.response,u.statusCode);u.tenantId&&(l.meta={...l.meta,tenantId:u.tenantId,sessionIsolation:l.meta?.sessionIsolation??l.flags?.sessionIsolation??"tenant"});let c=await r(l);if(c.ok)return void t0(i,{jsonrpc:"2.0",id:a.id??null,result:c});t0(i,tQ(a.id??null,-32e3,c.error.message,c.error),t1(c.error.code))}catch(t){let e=A(t);t0(i,tQ(a.id??null,-32e3,e.message,e),t1(e.code))}finally{el(o)}})})}async function t9(e,t,r,a){try{var i;let n,o,s=t2({},e.headers),l=re(s,a);if(l){t.statusCode=t1(l.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:l.message,code:l.code}));return}let d=await t8(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:s,session:"default",command:"upload",positionals:[]}});if(!d.ok){t.statusCode=d.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:d.response.error?.data?.message??d.response.error?.message??"Unauthorized"}));return}let c=await tz(e),p=(i={artifactPath:c.artifactPath,tempDir:c.tempDir,tenantId:d.tenantId},n=u.randomUUID(),o=setTimeout(()=>{tj(n)},3e5),tG.set(n,{artifactPath:i.artifactPath,tempDir:i.tempDir,tenantId:i.tenantId,timer:o}),n);t.statusCode=200,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!0,uploadId:p}))}catch(r){let e=A(r);t.statusCode=t1(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}async function t7(e,t,r,a){let i=e.url?.slice("/upload/".length)??"";if(!i){t.statusCode=400,t.end("Missing artifact id");return}try{let n=t2({},e.headers),o=re(n,a);if(o){t.statusCode=t1(o.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:o.message,code:o.code}));return}let s=await t8(r,{headers:e.headers,rpcRequest:{jsonrpc:"2.0",id:null,method:"agent_device.command"},daemonRequest:{token:n,session:"default",command:"download_artifact",positionals:[i]}});if(!s.ok){t.statusCode=s.statusCode,t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:s.response.error?.data?.message??s.response.error?.message??"Unauthorized"}));return}let l=function(e,t){let r=tU.get(e);if(!r)throw new h("INVALID_ARGS",`Artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new h("UNAUTHORIZED","Artifact belongs to a different tenant");if(!M.existsSync(r.artifactPath))throw tV(e),new h("COMMAND_FAILED",`Artifact file is missing: ${r.artifactPath}`);return{artifactPath:r.artifactPath,fileName:r.fileName,deleteAfterDownload:r.deleteAfterDownload}}(i,s.tenantId),d=M.createReadStream(l.artifactPath);t.statusCode=200,t.setHeader("content-type","application/octet-stream"),l.fileName&&t.setHeader("content-disposition",`attachment; filename="${l.fileName.replace(/"/g,"")}"`),d.on("error",e=>{if(t.headersSent)t.destroy(e);else{let r=A(e);t.statusCode=t1(r.code),t.end(r.message)}}),t.on("close",()=>{t.writableFinished&&tV(i)}),d.pipe(t)}catch(r){let e=A(r);t.statusCode=t1(e.code),t.setHeader("content-type","application/json"),t.end(JSON.stringify({ok:!1,error:e.message,code:e.code}))}}function re(e,t){return t&&e!==t?A(new h("UNAUTHORIZED","Invalid token")):null}function rt(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}function rr(e){if(!e)return;let t=e.trim();if(t&&/^[a-f0-9]{16,128}$/i.test(t))return t.toLowerCase()}function ra(e){let t=(e??"").trim().toLowerCase();if(!t||"ios-simulator"===t)return"ios-simulator";throw new h("INVALID_ARGS",`Unsupported lease backend: ${e??""}`)}class ri{leases=new Map;runBindings=new Map;maxActiveSimulatorLeases;defaultLeaseTtlMs;minLeaseTtlMs;maxLeaseTtlMs;now;constructor(e={}){this.maxActiveSimulatorLeases=Number.isInteger(e.maxActiveSimulatorLeases)?Math.max(0,Number(e.maxActiveSimulatorLeases)):0,this.defaultLeaseTtlMs=Number.isInteger(e.defaultLeaseTtlMs)?Math.max(1,Number(e.defaultLeaseTtlMs)):6e4,this.minLeaseTtlMs=Number.isInteger(e.minLeaseTtlMs)?Math.max(1,Number(e.minLeaseTtlMs)):5e3,this.maxLeaseTtlMs=Number.isInteger(e.maxLeaseTtlMs)?Math.max(this.minLeaseTtlMs,Number(e.maxLeaseTtlMs)):6e5,this.now=e.now??(()=>Date.now())}allocateLease(e){let t=ra(e.backend),r=o(e.tenantId);if(!r)throw new h("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");let a=rt(e.runId);if(!a)throw new h("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");this.cleanupExpiredLeases();let i=this.resolveLeaseTtlMs(e.ttlMs),n=this.bindingKey(r,a,t),s=this.runBindings.get(n);if(s){let e=this.leases.get(s);if(e)return this.refreshLease(e,i);this.runBindings.delete(n)}this.enforceCapacity(t);let l=this.now(),d={leaseId:u.randomBytes(16).toString("hex"),tenantId:r,runId:a,backend:t,createdAt:l,heartbeatAt:l,expiresAt:l+i};return this.leases.set(d.leaseId,d),this.runBindings.set(n,d.leaseId),{...d}}heartbeatLease(e){let t=rr(e.leaseId);if(!t)throw new h("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);if(!r)throw new h("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});this.assertOptionalScopeMatch(r,e.tenantId,e.runId);let a=this.resolveLeaseTtlMs(e.ttlMs);return this.refreshLease(r,a)}releaseLease(e){let t=rr(e.leaseId);if(!t)throw new h("INVALID_ARGS","Invalid lease id.");this.cleanupExpiredLeases();let r=this.leases.get(t);return r?(this.assertOptionalScopeMatch(r,e.tenantId,e.runId),this.leases.delete(t),this.runBindings.delete(this.bindingKey(r.tenantId,r.runId,r.backend)),{released:!0}):{released:!1}}assertLeaseAdmission(e){let t=ra(e.backend),r=o(e.tenantId);if(!r)throw new h("INVALID_ARGS","tenant isolation requires tenant id.");let a=rt(e.runId);if(!a)throw new h("INVALID_ARGS","tenant isolation requires run id.");let i=rr(e.leaseId);if(!i)throw new h("INVALID_ARGS","tenant isolation requires lease id.");this.cleanupExpiredLeases();let n=this.leases.get(i);if(!n)throw new h("UNAUTHORIZED","Lease is not active",{reason:"LEASE_NOT_FOUND"});if(n.backend!==t||n.tenantId!==r||n.runId!==a)throw new h("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}listActiveLeases(){return this.cleanupExpiredLeases(),Array.from(this.leases.values()).map(e=>({...e}))}cleanupExpiredLeases(){let e=this.now();for(let t of this.leases.values())t.expiresAt>e||(this.leases.delete(t.leaseId),this.runBindings.delete(this.bindingKey(t.tenantId,t.runId,t.backend)))}enforceCapacity(e){if("ios-simulator"!==e||this.maxActiveSimulatorLeases<=0)return;let t=Array.from(this.leases.values()).filter(e=>"ios-simulator"===e.backend).length;if(!(t<this.maxActiveSimulatorLeases))throw new h("COMMAND_FAILED","No simulator lease capacity available",{reason:"LEASE_CAPACITY_EXCEEDED",activeLeases:t,maxActiveLeases:this.maxActiveSimulatorLeases,backend:e,hint:"Retry after releasing another simulator lease."})}resolveLeaseTtlMs(e){if(!Number.isInteger(e))return this.defaultLeaseTtlMs;let t=Number(e);if(t<this.minLeaseTtlMs||t>this.maxLeaseTtlMs)throw new h("INVALID_ARGS",`Lease ttlMs must be between ${this.minLeaseTtlMs} and ${this.maxLeaseTtlMs}.`);return t}refreshLease(e,t){let r=this.now(),a={...e,heartbeatAt:r,expiresAt:r+t};return this.leases.set(a.leaseId,a),this.runBindings.set(this.bindingKey(a.tenantId,a.runId,a.backend),a.leaseId),{...a}}bindingKey(e,t,r){return`${e}:${t}:${r}`}assertOptionalScopeMatch(e,t,r){let a=o(t),i=rt(r);if(t&&!a)throw new h("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(r&&!i)throw new h("INVALID_ARGS","Invalid run id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if(a&&e.tenantId!==a||i&&e.runId!==i)throw new h("UNAUTHORIZED","Lease does not match tenant/run scope",{reason:"LEASE_SCOPE_MISMATCH"})}}function rn(e,t){return["-s",e.id,...t]}async function ro(){if(!await g("adb"))throw new h("TOOL_MISSING","adb not found in PATH")}function rs(e,t){let r=`${e}
10
+ ${t}`.toLowerCase();return r.includes("no shell command implementation")||r.includes("unknown command")}async function rl(e){await new Promise(t=>setTimeout(t,e))}function rd(e){let t=e.trim();if(!t||/\s/.test(t))return!1;let r=/^([A-Za-z][A-Za-z0-9+.-]*):(.+)$/.exec(t);if(!r)return!1;let a=r[1]?.toLowerCase(),i=r[2]??"";return"http"!==a&&"https"!==a&&"ws"!==a&&"wss"!==a&&"ftp"!==a&&"ftps"!==a||i.startsWith("//")}function ru(e,t){let r,a=e?.trim();return a?a:"http"===(r=t.trim().split(":")[0]?.toLowerCase())||"https"===r?"com.apple.mobilesafari":void 0}let rc=["android.software.leanback","android.software.leanback_only","android.hardware.type.television"];function rp(e){return`${e.stdout}
11
+ ${e.stderr}`}function rf(e,t){return["-s",e,...t]}function rm(e){return e.startsWith("emulator-")}function rh(e){return e.toLowerCase().replace(/_/g," ").replace(/\s+/g," ").trim()}async function rw(e,t=X){return c("adb",rf(e,["shell","getprop","sys.boot_completed"]),{allowFailure:!0,timeoutMs:t})}async function rg(e,t){let r=t.replace(/_/g," ").trim();if(!rm(e))return r||e;let a=await rI(e);return a?a.replace(/_/g," "):r||e}async function rI(e){for(let t of["ro.boot.qemu.avd_name","persist.sys.avd_name"]){let r=await c("adb",rf(e,["shell","getprop",t]),{allowFailure:!0,timeoutMs:1e4}),a=r.stdout.trim();if(0===r.exitCode&&a.length>0)return a}let t=await c("adb",rf(e,["emu","avd","name"]),{allowFailure:!0,timeoutMs:1e4}),r=t.stdout.trim();if(0===t.exitCode&&r.length>0)return r}async function rv(e,t){let r=rp(await c("adb",rf(e,["shell","cmd","package","has-feature",t]),{allowFailure:!0,timeoutMs:X})).toLowerCase();return!!r.includes("true")||!r.includes("false")&&null}async function rA(e){return(await Promise.all(rc.map(async t=>await rv(e,t)))).some(e=>!0===e)}async function ry(e){var t;let r;return"tv"===((r=rp(await c("adb",rf(e,["shell","getprop","ro.build.characteristics"]),{allowFailure:!0,timeoutMs:X})).toLowerCase()).includes("tv")||r.includes("leanback")?"tv":null)||await rA(e)?"tv":(t=rp(await c("adb",rf(e,["shell","pm","list","features"]),{allowFailure:!0,timeoutMs:X})),/feature:android\.(software\.leanback(_only)?|hardware\.type\.television)\b/i.test(t))?"tv":"mobile"}async function rb(e={}){if(!await g("adb"))throw new h("TOOL_MISSING","adb not found in PATH");let t=e.serialAllowlist??eD(void 0),r=(await rN()).filter(e=>!t||t.has(e.serial));return await Promise.all(r.map(async({serial:e,rawModel:t})=>{let[r,a,i]=await Promise.all([rg(e,t),rE(e),ry(e)]);return{platform:"android",id:e,name:r,kind:rm(e)?"emulator":"device",target:i,booted:a}}))}async function rN(){return(await c("adb",["devices","-l"],{timeoutMs:X})).stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0&&!e.startsWith("List of devices")).map(e=>e.split(/\s+/)).filter(e=>"device"===e[1]).map(e=>({serial:e[0],rawModel:(e.find(e=>e.startsWith("model:"))??"").replace("model:","")}))}async function r_(){let e=await c("emulator",["-list-avds"],{allowFailure:!0,timeoutMs:X});if(0!==e.exitCode)throw new h("COMMAND_FAILED","Failed to list Android emulator AVDs",{stdout:e.stdout,stderr:e.stderr,exitCode:e.exitCode,hint:"Verify Android emulator tooling is installed and available in PATH."});return e.stdout.split("\n").map(e=>e.trim()).filter(e=>e.length>0)}async function rS(e){let t=Date.now();for(;Date.now()-t<e.timeoutMs;){try{let t=await rD(e.avdName,e.serial);if(t)return{platform:"android",id:t,name:e.avdName,kind:"emulator",target:"mobile",booted:!1}}catch{}await new Promise(e=>setTimeout(e,1e3))}throw new h("COMMAND_FAILED","Android emulator did not appear in time",{avdName:e.avdName,serial:e.serial,timeoutMs:e.timeoutMs,hint:"Check emulator logs and verify the AVD can start from command line."})}async function rD(e,t){let r=rh(e);for(let e of(await rN()).filter(e=>(!t||e.serial===t)&&rm(e.serial)))if(rh(e.rawModel)===r||rh(await rg(e.serial,e.rawModel))===r)return e.serial}async function rE(e){try{let t=await rw(e);return"1"===t.stdout.trim()}catch{return!1}}async function rk(e){var t,r;let a,i=e.avdName.trim();if(!i)throw new h("INVALID_ARGS","Android emulator boot requires a non-empty AVD name.");let n=e.timeoutMs??12e4;if(!await g("adb"))throw new h("TOOL_MISSING","adb not found in PATH");if(!await g("emulator"))throw new h("TOOL_MISSING","emulator not found in PATH");let o=await r_(),s=function(e,t){let r=e.find(e=>e===t);if(r)return r;let a=rh(t);return e.find(e=>rh(e)===a)}(o,i);if(!s)throw new h("DEVICE_NOT_FOUND",`No Android emulator AVD named ${e.avdName}`,{requestedAvdName:i,availableAvds:o,hint:"Run `emulator -list-avds` and pass an existing AVD name to --device."});let d=Date.now(),u=(t=await rb(),r=e.serial,a=rh(s),t.find(e=>"android"===e.platform&&"emulator"===e.kind&&(!r||e.id===r)&&rh(e.name)===a));if(!u){let t=["-avd",s];e.headless&&t.push("-no-window","-no-audio"),l("emulator",t)}let c=u??await rS({avdName:s,serial:e.serial,timeoutMs:n}),p=Math.max(1e3,n-(Date.now()-d));await rL(c.id,p);let f=(await rb()).find(e=>e.id===c.id);return f?{...f,name:s,booted:!0}:{...c,name:s,booted:!0}}async function rL(e,t=6e4){let r,a=Z.fromTimeoutMs(t),i=Math.max(1,Math.ceil(t/1e3)),n=!1;try{await Y(async({deadline:i})=>{if(i?.isExpired())throw n=!0,new h("COMMAND_FAILED","Android boot deadline exceeded",{serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),message:"timeout"});let o=Math.max(1e3,i?.remainingMs()??t),s=await rw(e,Math.min(o,X));if(r=s,"1"!==s.stdout.trim())throw new h("COMMAND_FAILED","Android device is still booting",{serial:e,stdout:s.stdout,stderr:s.stderr,exitCode:s.exitCode})},{maxAttempts:i,baseDelayMs:1e3,maxDelayMs:1e3,jitter:0,shouldRetry:e=>{let t=ef({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}});return"ADB_TRANSPORT_UNAVAILABLE"!==t&&"ANDROID_BOOT_TIMEOUT"!==t}},{deadline:a,phase:"boot",classifyReason:e=>ef({error:e,stdout:r?.stdout,stderr:r?.stderr,context:{platform:"android",phase:"boot"}})})}catch(c){let i=f(c),o=r?.stdout,s=r?.stderr,l=r?.exitCode,d=ef({error:c,stdout:o,stderr:s,context:{platform:"android",phase:"boot"}});"BOOT_COMMAND_FAILED"===d&&"Android device is still booting"===i.message&&(d="ANDROID_BOOT_TIMEOUT");let u={serial:e,timeoutMs:t,elapsedMs:a.elapsedMs(),reason:d,hint:em(d),stdout:o,stderr:s,exitCode:l};if(n||"ANDROID_BOOT_TIMEOUT"===d)throw new h("COMMAND_FAILED","Android device did not finish booting in time",u);if("TOOL_MISSING"===i.code)throw new h("TOOL_MISSING",i.message,{...u,...i.details??{}});if("ADB_TRANSPORT_UNAVAILABLE"===d)throw new h("COMMAND_FAILED",i.message,{...u,...i.details??{}});throw new h(i.code,i.message,{...u,...i.details??{}},i.cause)}}let rO=/\.(?:apk|aab)$/i,rM=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function rx(e){var t,r;let a=e.trim();return 0===a.length?"other":rO.test(a)?a.includes("/")||a.includes("\\")||a.startsWith(".")||a.startsWith("~")||(t=a,!rM.test(t))?"binary":"package":(r=a,rM.test(r))?"package":"other"}function rC(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}let rR=[".zip",".tar",".tar.gz",".tgz"],rT=ev(process.env.AGENT_DEVICE_SOURCE_DOWNLOAD_TIMEOUT_MS,12e4,1e3);async function rP(e){let t=[];try{let r=await r$(e.source,{signal:e.signal,downloadTimeoutMs:e.downloadTimeoutMs});t.push(r.cleanup);let a=await rU(r.localPath,{archivePath:void 0,isInstallablePath:e.isInstallablePath,installableLabel:e.installableLabel,registerCleanup:e=>{t.push(e)}});return{archivePath:a.archivePath,installablePath:a.installablePath,cleanup:async()=>{await rB(t)}}}catch(e){throw await rB(t),e}}async function r$(e,t){if("path"===e.kind){var r;return{localPath:(r=e.path).startsWith("~")?"~"===r?C.homedir():r.startsWith("~/")?i.join(C.homedir(),r.slice(2)):r:r,cleanup:async()=>{}}}let a=await E.mkdtemp(i.join(C.tmpdir(),"agent-device-source-"));try{return{localPath:await rF(a,e.url,e.headers,t),cleanup:async()=>{await E.rm(a,{recursive:!0,force:!0})}}}catch(e){throw await E.rm(a,{recursive:!0,force:!0}),e}}async function rF(e,t,r,a){let n;try{n=new URL(t)}catch{throw new h("INVALID_ARGS",`Invalid source URL: ${t}`)}let o=a?.signal;if(o?.aborted)throw new h("COMMAND_FAILED","request canceled",{reason:"request_canceled"});let s=new AbortController,l=()=>{s.abort(o?.reason)};o?.addEventListener("abort",l,{once:!0});let d=a?.downloadTimeoutMs??rT,u=setTimeout(()=>{s.abort(Error("download timeout"))},d);try{let t=await fetch(n,{headers:r,redirect:"follow",signal:s.signal});if(!t.ok)throw new h("COMMAND_FAILED",`Failed to download app source: ${t.status} ${t.statusText}`,{status:t.status,statusText:t.statusText,url:n.toString()});let a=function(e,t){let r=e.headers.get("content-disposition"),a=r?.match(/filename\*?=(?:UTF-8'')?"?([^";]+)"?/i),n=a?.[1]?.trim();if(n)return i.basename(n);let o=i.basename(t.pathname);return o||"downloaded-artifact.bin"}(t,n),o=i.join(e,a),l=t.body;if(!l)throw new h("COMMAND_FAILED","Download response body was empty",{url:n.toString()});let d=await E.open(o,"w");try{for await(let e of l)await d.write(e)}finally{await d.close()}return o}catch(e){if(o?.aborted)throw new h("COMMAND_FAILED","request canceled",{reason:"request_canceled"},e);if(s.signal.aborted)throw new h("COMMAND_FAILED",`App source download timed out after ${d}ms`,{timeoutMs:d,url:n.toString()},e);throw e}finally{o?.removeEventListener("abort",l),clearTimeout(u)}}async function rU(e,t){let r=await E.stat(e).catch(()=>null);if(!r)throw new h("INVALID_ARGS",`App source not found: ${e}`);if(t.isInstallablePath(e,r))return{archivePath:t.archivePath,installablePath:e};if(r.isFile()&&rj(e)){let r=await rG(e);return t.registerCleanup(r.cleanup),await rU(r.outputPath,{...t,archivePath:t.archivePath??e})}if(r.isDirectory()){let r=await rV(e,t.isInstallablePath);if(1===r.length)return{archivePath:t.archivePath,installablePath:r[0]};if(r.length>1)throw new h("INVALID_ARGS",`Found multiple ${t.installableLabel} candidates under ${e}`,{matches:r});let a=await rV(e,(e,t)=>t.isFile()&&rj(e));if(1===a.length){let e=await rG(a[0]);return t.registerCleanup(e.cleanup),await rU(e.outputPath,{...t,archivePath:t.archivePath??a[0]})}if(a.length>1)throw new h("INVALID_ARGS",`Found multiple nested archives under ${e}; expected one ${t.installableLabel} source`,{matches:a})}throw new h("INVALID_ARGS",`Expected ${t.installableLabel} source, but got ${e}`)}async function rV(e,t){let r=[],a=[{path:e,depth:0}];for(;a.length>0;){let e=a.shift();if(!e)continue;let n=await E.readdir(e.path,{withFileTypes:!0});for(let o of(n.sort((e,t)=>e.name.localeCompare(t.name)),n)){let n=i.join(e.path,o.name);if(t(n,o)){r.push(n);continue}o.isDirectory()&&e.depth<5&&a.push({path:n,depth:e.depth+1})}}return r}async function rG(e){let t=await E.mkdtemp(i.join(C.tmpdir(),"agent-device-archive-"));try{return e.toLowerCase().endsWith(".zip")?await c("ditto",["-x","-k",e,t]):e.toLowerCase().endsWith(".tar.gz")||e.toLowerCase().endsWith(".tgz")?await c("tar",["-xzf",e,"-C",t]):await c("tar",["-xf",e,"-C",t]),{outputPath:t,cleanup:async()=>{await E.rm(t,{recursive:!0,force:!0})}}}catch(e){throw await E.rm(t,{recursive:!0,force:!0}),e}}function rj(e){let t=e.toLowerCase();return rR.some(e=>t.endsWith(e))}async function rB(e){for(let t=e.length-1;t>=0;t-=1)await e[t]()}let rq=new q("utf-16le");async function rH(e){for(let r of["AndroidManifest.xml","base/manifest/AndroidManifest.xml"]){var t;let a=await rW(e,r);if(!a)continue;let i=(t=a).subarray(0,Math.min(t.length,128)).toString("utf8").trimStart().startsWith("<")?function(e){let t=e.match(/<manifest\b[^>]*\bpackage\s*=\s*["']([^"']+)["']/i);return t?.[1]}(t.toString("utf8")):function(e){let t;if(!(e.length<8)&&3===e.readUInt16LE(0))for(let r=e.readUInt16LE(2);r+8<=e.length;){let a=e.readUInt16LE(r),i=e.readUInt16LE(r+2),n=e.readUInt32LE(r+4);if(n<=0||r+n>e.length)break;if(1===a)t=function(e){if(e.length<28)return[];let t=e.readUInt32LE(8),r=e.readUInt32LE(16),a=e.readUInt32LE(20),i=(256&r)!=0,n=[];for(let r=0;r<t;r+=1){let t=28+4*r;if(t+4>e.length)break;let o=a+e.readUInt32LE(t);n.push(i?function(e,t){let[,r]=rz(e,t),[a,i]=rz(e,t+r),n=t+r+i;return e.subarray(n,n+a).toString("utf8")}(e,o):function(e,t){let[r,a]=function(e,t){let r=e.readUInt16LE(t);return(32768&r)==0?[r,2]:[(32767&r)<<16|e.readUInt16LE(t+2),4]}(e,t),i=t+a;return rq.decode(e.subarray(i,i+2*r))}(e,o))}return n}(e.subarray(r,r+n));else if(258===a&&t){let a=function(e,t,r,a){if(r<36||t+r>e.length||"manifest"!==a[e.readUInt32LE(t+20)])return;let i=e.readUInt16LE(t+24),n=e.readUInt16LE(t+26),o=e.readUInt16LE(t+28),s=t+i;for(let t=0;t<o;t+=1){let r=s+t*n;if(r+20>e.length)break;if("package"!==a[e.readUInt32LE(r+4)])continue;let i=e.readUInt32LE(r+8);if(0xffffffff!==i)return a[i];let o=e.readUInt8(r+15),l=e.readUInt32LE(r+16);if(3===o)return a[l];break}}(e,r,i,t);if(a)return a}r+=n}}(t);if(i)return i}}async function rW(e,t){try{let r=await c("unzip",["-p",e,t],{allowFailure:!0,binaryStdout:!0});if(0!==r.exitCode||!r.stdoutBuffer||0===r.stdoutBuffer.length)return;return r.stdoutBuffer}catch{return}}function rz(e,t){let r=e.readUInt8(t);return(128&r)==0?[r,1]:[(127&r)<<8|e.readUInt8(t+1),2]}async function rJ(e,t){let r=await rP({source:e,isInstallablePath:(e,t)=>{var r;let a;return t.isFile()&&(r=e,".apk"===(a=i.extname(r).toLowerCase())||".aab"===a)},installableLabel:"Android installable (.apk or .aab)",signal:t?.signal}),a=t?.resolveIdentity===!1?{}:await rK(r.installablePath);return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:a.packageName,cleanup:r.cleanup}}async function rK(e){let t=i.extname(e).toLowerCase();return".apk"!==t&&".aab"!==t?{}:{packageName:await rH(e)}}let rX={settings:{type:"intent",value:"android.settings.SETTINGS"}},rZ="android.intent.category.LAUNCHER",rY="android.intent.category.LEANBACK_LAUNCHER",rQ="android.intent.category.DEFAULT";async function r0(e,t){let r=t.trim();if("package"===rx(r))return{type:"package",value:r};let a=rX[r.toLowerCase()];if(a)return a;let i=(await c("adb",rn(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase()));if(1===i.length)return{type:"package",value:i[0]};if(i.length>1)throw new h("INVALID_ARGS",`Multiple packages matched "${t}"`,{matches:i});throw new h("APP_NOT_INSTALLED",`No package found matching "${t}"`)}async function r1(e,t="all"){let r=await r2(e);return("user-installed"===t?(await r4(e)).filter(e=>r.has(e)):Array.from(r)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:r8(e)}))}async function r2(e){let t=new Set;for(let r of r3(e,{includeFallbackWhenUnknown:!0})){let a=await c("adb",rn(e,["shell","cmd","package","query-activities","--brief","-a","android.intent.action.MAIN","-c",r]),{allowFailure:!0});if(0===a.exitCode&&0!==a.stdout.trim().length)for(let e of a.stdout.split("\n")){let r=e.trim();if(!r)continue;let a=r.split(/\s+/)[0],i=a.includes("/")?a.split("/")[0]:a;i&&t.add(i)}}return t}function r3(e,t={}){return"tv"===e.target?[rY]:"mobile"===e.target?[rZ]:t.includeFallbackWhenUnknown?[rZ,rY]:[rZ]}async function r4(e){return(await c("adb",rn(e,["shell","pm","list","packages","-3"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean)}function r8(e){let t=new Set(["com","android","google","app","apps","service","services","mobile","client"]),r=e.split(".").flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),a=r[r.length-1]??e;for(let e=r.length-1;e>=0;e-=1){let i=r[e];if(!t.has(i)){a=i;break}}return a.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function r6(e){let t=await r5(e,[["shell","dumpsys","window","windows"],["shell","dumpsys","window"]]);if(t)return t;let r=await r5(e,[["shell","dumpsys","activity","activities"],["shell","dumpsys","activity"]]);return r||{}}async function r5(e,t){for(let r of t){let t=function(e){for(let t of[/mCurrentFocus=Window\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mFocusedApp=AppWindowToken\{[^}]*\s([\w.]+)\/([\w.$]+)/,/mResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/,/ResumedActivity:.*?\s([\w.]+)\/([\w.$]+)/]){let r=t.exec(e);if(r)return{package:r[1],activity:r[2]}}return null}((await c("adb",rn(e,r),{allowFailure:!0})).stdout??"");if(t)return t}return null}async function r9(e,t,r){var a,i;let n;e.booted||await rL(e.id);let o=t.trim();if(rd(o)){if(r)throw new h("INVALID_ARGS","Activity override is not supported when opening a deep link URL");await c("adb",rn(e,["shell","am","start","-W","-a","android.intent.action.VIEW","-d",o]));return}let s=await r0(e,t),l=r3(e)[0]??rZ;if("intent"===s.type){if(r)throw new h("INVALID_ARGS","Activity override requires a package name, not an intent");await c("adb",rn(e,["shell","am","start","-W","-a",s.value]));return}if(r){let t=r.includes("/")?r:`${s.value}/${r.startsWith(".")?r:`.${r}`}`;await c("adb",rn(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rQ,"-c",l,"-n",t]));return}let d=await c("adb",rn(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rQ,"-c",l,"-p",s.value]),{allowFailure:!0});if(0===d.exitCode&&(a=d.stdout,i=d.stderr,n=`${a}
12
+ ${i}`,!/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(n)))return;let u=await r7(e,s.value);if(!u)throw new h("COMMAND_FAILED",`Failed to launch ${s.value}`,{stdout:d.stdout,stderr:d.stderr});await c("adb",rn(e,["shell","am","start","-W","-a","android.intent.action.MAIN","-c",rQ,"-c",l,"-n",u]))}async function r7(e,t){for(let r of Array.from(new Set(r3(e,{includeFallbackWhenUnknown:!0})))){let a=await c("adb",rn(e,["shell","cmd","package","resolve-activity","--brief","-a","android.intent.action.MAIN","-c",r,t]),{allowFailure:!0});if(0!==a.exitCode)continue;let i=function(e){let t=e.split("\n").map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;e-=1){let r=t[e];if(r.includes("/"))return r.split(/\s+/)[0]}return null}(a.stdout);if(i)return i}return null}async function ae(e){e.booted||await rL(e.id)}async function at(e,t){if("settings"===t.trim().toLowerCase())return void await c("adb",rn(e,["shell","am","force-stop","com.android.settings"]));let r=await r0(e,t);if("intent"===r.type)throw new h("INVALID_ARGS","Close requires a package name, not an intent");await c("adb",rn(e,["shell","am","force-stop",r.value]))}async function ar(e,t){let r=await r0(e,t);if("intent"===r.type)throw new h("INVALID_ARGS","App uninstall requires a package name, not an intent");let a=await c("adb",rn(e,["uninstall",r.value]),{allowFailure:!0});if(0!==a.exitCode){let e=`${a.stdout}
13
+ ${a.stderr}`.toLowerCase();if(!e.includes("unknown package")&&!e.includes("not installed"))throw new h("COMMAND_FAILED",`adb uninstall failed for ${r.value}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return{package:r.value}}let aa=null;async function ai(){let e=`${process.env.PATH??""}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??""}`;if(aa?.key===e)return aa.invocation;if(await g("bundletool")){let t={cmd:"bundletool",prefixArgs:[]};return aa={key:e,invocation:t},t}let t=process.env.AGENT_DEVICE_BUNDLETOOL_JAR?.trim();if(!t)throw new h("TOOL_MISSING","bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.");try{await E.access(t)}catch{throw new h("TOOL_MISSING",`AGENT_DEVICE_BUNDLETOOL_JAR points to a missing file: ${t}`)}let r={cmd:"java",prefixArgs:["-jar",t]};return aa={key:e,invocation:r},r}async function an(e){let t=await ai();await c(t.cmd,[...t.prefixArgs,...e])}async function ao(e,t){let r,a=await E.mkdtemp(i.join(C.tmpdir(),"agent-device-aab-")),n=i.join(a,"bundle.apks"),o=(r=process.env.AGENT_DEVICE_ANDROID_BUNDLETOOL_MODE?.trim())&&r.length>0?r:"universal";try{await an(["build-apks","--bundle",t,"--output",n,"--mode",o]),await an(["install-apks","--apks",n,"--device-id",e.id])}finally{await E.rm(a,{recursive:!0,force:!0})}}async function as(e,t){".aab"===i.extname(t).toLowerCase()?await ao(e,t):await c("adb",rn(e,["install","-r",t]))}async function al(e){return new Set((await c("adb",rn(e,["shell","pm","list","packages"]))).stdout.split("\n").map(e=>e.replace("package:","").trim()).filter(Boolean))}async function ad(e,t){let r=Array.from(await al(e)).filter(e=>!t.has(e));if(1===r.length)return r[0]}async function au(e,t){e.booted||await rL(e.id),await as(e,t)}async function ac(e,t){e.booted||await rL(e.id);let r=await rJ({kind:"path",path:t});try{let t=r.packageName?void 0:await al(e);await au(e,r.installablePath);let a=r.packageName??(t?await ad(e,t):void 0),i=a?r8(a):void 0;return{archivePath:r.archivePath,installablePath:r.installablePath,packageName:a,appName:i,launchTarget:a}}finally{await r.cleanup()}}async function ap(e,t,r){e.booted||await rL(e.id);let{package:a}=await ar(e,t),i=await rJ({kind:"path",path:r},{resolveIdentity:!1});try{return await au(e,i.installablePath),{package:a}}finally{await i.cleanup()}}function af(e){let t=am(e),r=e=>{let r=ah(t,e);if(null!==r)return"true"===r};return{text:ah(t,"text"),desc:ah(t,"content-desc"),resourceId:ah(t,"resource-id"),className:ah(t,"class"),bounds:ah(t,"bounds"),clickable:r("clickable"),enabled:r("enabled"),focusable:r("focusable"),focused:r("focused")}}function am(e){let t=new Map,r=e.indexOf(" "),a=e.lastIndexOf(">");if(r<0||a<=r)return t;let i=/([^\s=/>]+)\s*=\s*(["'])([\s\S]*?)\2/y,n=r;for(;n<a;){for(;n<a;){let t=e[n];if(" "!==t&&"\n"!==t&&"\r"!==t&&" "!==t)break;n+=1}if(n>=a)break;let r=e[n];if("/"===r||">"===r)break;i.lastIndex=n;let o=i.exec(e);if(!o)break;t.set(o[1],o[3]),n=i.lastIndex}return t}function ah(e,t){return e.get(t)??null}function aw(e){if(!e)return;let t=/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/.exec(e);if(!t)return;let r=Number(t[1]),a=Number(t[2]);return{x:r,y:a,width:Math.max(0,Number(t[3])-r),height:Math.max(0,Number(t[4])-a)}}function ag(e){return e?e.toLowerCase():""}function aI(e){let t=e.trim();return!!t&&/^[\w.]+:id\/[\w.-]+$/i.test(t)}async function av(e,t={}){return function(e,t,r){let a=function(e){let t={type:null,label:null,value:null,identifier:null,depth:-1,children:[]},r=[t],a=/<node\b[^>]*>|<\/node>/g,i=a.exec(e);for(;i;){let t=i[0];if(t.startsWith("</node")){r.length>1&&r.pop(),i=a.exec(e);continue}let n=af(t),o=aw(n.bounds),s=r[r.length-1],l={type:n.className,label:n.text||n.desc,value:n.text,identifier:n.resourceId,rect:o,enabled:n.enabled,hittable:n.clickable??n.focusable,depth:s.depth+1,parentIndex:void 0,children:[]};s.children.push(l),t.endsWith("/>")||r.push(l),i=a.exec(e)}return t}(e),i=[],n=!1,o=r.depth??1/0,s=r.scope?function(e,t){let r=t.toLowerCase(),a=[...e.children];for(;a.length>0;){let e=a.shift(),t=e.label?.toLowerCase()??"",i=e.value?.toLowerCase()??"",n=e.identifier?.toLowerCase()??"";if(t.includes(r)||i.includes(r)||n.includes(r))return e;a.push(...e.children)}return null}(a,r.scope):null,l=s?[s]:a.children,d=new Map,u=e=>{let t=d.get(e);if(void 0!==t)return t;for(let t of e.children)if(t.hittable||u(t))return d.set(e,!0),!0;return d.set(e,!1),!1},c=(e,t,a,s=!1,l=!1)=>{var d,p,f,m,h,w;let g,I,v,A,y,b,N,_;if(i.length>=800){n=!0;return}if(t>o)return;let S=!!r.raw||(d=e,p=r,f=s,m=u(e),h=l,I=ag(d.type),v=!!(d.label&&d.label.trim().length>0),A=!!(d.identifier&&d.identifier.trim().length>0),y=v&&!aI(d.label??""),b=A&&!aI(d.identifier??""),N=(g=(w=I).split(".").pop()??w).includes("layout")||"viewgroup"===g||"view"===g,_="imageview"===I||"imagebutton"===I,p.interactiveOnly?!!d.hittable||!!(y||b)&&!_&&(!N||!!h)&&(f||m||h):p.compact?y||b||!!d.hittable:!N&&!_||!!d.hittable||!!y||!!b&&!!m||m),D=a;S&&(D=i.length,i.push({index:D,type:e.type??void 0,label:e.label??void 0,value:e.value??void 0,identifier:e.identifier??void 0,rect:e.rect,enabled:e.enabled,hittable:e.hittable,depth:t,parentIndex:a}));let E=s||!!e.hittable,k=l||function(e){if(!e)return!1;let t=ag(e);return t.includes("recyclerview")||t.includes("listview")||t.includes("gridview")}(e.type);for(let r of e.children)if(c(r,t+1,D,E,k),n)return};for(let e of l)if(c(e,0,void 0,!1,!1),n)break;return n?{nodes:i,truncated:n}:{nodes:i}}(await ab(e),0,t)}let aA=Buffer.from([137,80,78,71,13,10,26,10]);async function ay(e,t){let r=await c("adb",rn(e,["exec-out","screencap","-p"]),{binaryStdout:!0});if(!r.stdoutBuffer)throw new h("COMMAND_FAILED","Failed to capture screenshot");let a=r.stdoutBuffer.indexOf(aA);if(a<0)throw new h("COMMAND_FAILED","Screenshot data does not contain a valid PNG header");let i=function(e,t){let r=t+aA.length;for(;r+8<=e.length;){let t=e.readUInt32BE(r),a=r+4,i=e.toString("ascii",a,a+4),n=r+12+t;if(n>e.length)break;if("IEND"===i)return n;r=n}return null}(r.stdoutBuffer,a);if(!i)throw new h("COMMAND_FAILED","Screenshot data does not contain a complete PNG payload");await E.writeFile(t,r.stdoutBuffer.subarray(a,i))}async function ab(e){return Q(()=>aN(e),{shouldRetry:aS})}async function aN(e){var t,r,a;let i,n,o=await c("adb",rn(e,["exec-out","uiautomator","dump","/dev/tty"]),{allowFailure:!0});if(0===o.exitCode){let e=a_(o.stdout,o.stderr);if(e)return e}let s="/sdcard/window_dump.xml",l=await c("adb",rn(e,["shell","uiautomator","dump",s])),d=(t=s,r=l.stdout,a=l.stderr,i=`${r}
14
+ ${a}`,n=/dumped to:\s*(\S+)/i.exec(i),n?.[1]??t),u=await c("adb",rn(e,["shell","cat",d])),p=a_(u.stdout,u.stderr);if(!p)throw new h("COMMAND_FAILED","uiautomator dump did not return XML",{stdout:u.stdout,stderr:u.stderr});return p}function a_(e,t){let r=`${e}
15
+ ${t}`,a=r.indexOf("<?xml"),i=a>=0?a:r.indexOf("<hierarchy");if(i<0)return null;let n=r.lastIndexOf("</hierarchy>");if(n<0||n<i)return null;let o=r.slice(i,n+12).trim();return o.length>0?o:null}function aS(e){if(!(e instanceof h)||"COMMAND_FAILED"!==e.code)return!1;let t=`${e.details?.stderr??""}`.toLowerCase();return!!(t.includes("device offline")||t.includes("device not found")||t.includes("transport error")||t.includes("connection reset")||t.includes("broken pipe")||t.includes("timed out")||t.includes("no such file or directory"))}async function aD(e,t,r){await c("adb",rn(e,["shell","input","tap",String(t),String(r)]))}async function aE(e,t,r,a,i,n=250){await c("adb",rn(e,["shell","input","swipe",String(t),String(r),String(a),String(i),String(n)]))}async function ak(e){await c("adb",rn(e,["shell","input","keyevent","4"]))}async function aL(e){await c("adb",rn(e,["shell","input","keyevent","3"]))}async function aO(e){await c("adb",rn(e,["shell","input","keyevent","187"]))}async function aM(e,t,r,a=800){await c("adb",rn(e,["shell","input","swipe",String(t),String(r),String(t),String(r),String(a)]))}async function ax(e,t){let r=aU(t);if(!r||"ok"!==await aV(e,t))try{let r=t.replace(/ /g,"%s");await c("adb",rn(e,["shell","input","text",r]))}catch(e){if(r&&function(e){if(!(e instanceof h)||"COMMAND_FAILED"!==e.code)return!1;let t=String(e.details?.stderr??"").toLowerCase();return!!(t.includes("exception occurred while executing 'text'")||t.includes("nullpointerexception")&&t.includes("inputshellcommand.sendtext"))}(e))throw new h("COMMAND_FAILED","Non-ASCII text input is not supported on this Android shell. Install an ADB keyboard IME or use ASCII input.",{textPreview:t.slice(0,32)},e instanceof Error?e:void 0);throw e}}async function aC(e,t,r){await aD(e,t,r)}async function aR(e,t,r,a){let i=Array.from(a).length,n=aU(a),o=[{strategy:"input_text",clearPadding:12,minClear:8,maxClear:48}];n||(o.push({strategy:"clipboard_paste",clearPadding:12,minClear:8,maxClear:48}),o.push({strategy:"chunked_input",clearPadding:24,minClear:16,maxClear:96}));let s=null;for(let n of o){var l,d;await aC(e,t,r);let o=(l=i+n.clearPadding,d=n.minClear,Math.max(d,Math.min(n.maxClear,l)));if(await aG(e,o),"input_text"===n.strategy)await ax(e,a);else if("clipboard_paste"===n.strategy){if("ok"!==await aV(e,a))continue}else await aF(e,a,1,15);if((s=await aj(e,t,r))===a)return}throw new h("COMMAND_FAILED","Android fill verification failed",{expected:a,actual:s??null})}async function aT(e,t,r=.6){let{width:a,height:i}=await a$(e),n=Math.floor(a*r),o=Math.floor(i*r),s=Math.floor(a/2),l=Math.floor(i/2),d=s,u=l,p=s,f=l;switch(t){case"up":u=l-Math.floor(o/2),f=l+Math.floor(o/2);break;case"down":u=l+Math.floor(o/2),f=l-Math.floor(o/2);break;case"left":d=s-Math.floor(n/2),p=s+Math.floor(n/2);break;case"right":d=s+Math.floor(n/2),p=s-Math.floor(n/2);break;default:throw new h("INVALID_ARGS",`Unknown direction: ${t}`)}await c("adb",rn(e,["shell","input","swipe",String(d),String(u),String(p),String(f),"300"]))}async function aP(e,t){for(let r=0;r<8;r+=1){let r="";try{r=await ab(e)}catch(t){let e=t instanceof Error?t.message:String(t);throw new h("UNSUPPORTED_OPERATION",`uiautomator dump failed: ${e}`)}if(function(e,t){let r=t.toLowerCase(),a=/<node[^>]+>/g,i=a.exec(e);for(;i;){let t=am(i[0]),n=(ah(t,"text")??"").toLowerCase(),o=(ah(t,"content-desc")??"").toLowerCase();if(n.includes(r)||o.includes(r)){let e=aw(ah(t,"bounds"));if(e)return{x:Math.floor(e.x+e.width/2),y:Math.floor(e.y+e.height/2)};return{x:0,y:0}}i=a.exec(e)}return null}(r,t))return;await aT(e,"down",.5)}throw new h("COMMAND_FAILED",`Could not find element containing "${t}" after scrolling`)}async function a$(e){let t=(await c("adb",rn(e,["shell","wm","size"]))).stdout.match(/Physical size:\s*(\d+)x(\d+)/);if(!t)throw new h("COMMAND_FAILED","Unable to read screen size");return{width:Number(t[1]),height:Number(t[2])}}async function aF(e,t,r,a){let i=Math.max(1,Math.floor(r)),n=Array.from(t);for(let t=0;t<n.length;t+=i){let r=n.slice(t,t+i).join("");await ax(e,r),a>0&&t+i<n.length&&await rl(a)}}function aU(e){for(let t of e){let e=t.codePointAt(0);if(void 0!==e&&(e<32||e>126))return!0}return!1}async function aV(e,t){let r=await c("adb",rn(e,["shell","cmd","clipboard","set","text",t]),{allowFailure:!0});return 0!==r.exitCode?"failed":rs(r.stdout,r.stderr)?"unsupported":0===(await c("adb",rn(e,["shell","input","keyevent","KEYCODE_PASTE"]),{allowFailure:!0})).exitCode||0===(await c("adb",rn(e,["shell","input","keyevent","279"]),{allowFailure:!0})).exitCode?"ok":"failed"}async function aG(e,t){let r=Math.max(0,t);await c("adb",rn(e,["shell","input","keyevent","KEYCODE_MOVE_END"]),{allowFailure:!0});for(let t=0;t<r;t+=24){let a=Math.min(24,r-t);await c("adb",rn(e,["shell","input","keyevent",...Array(a).fill("KEYCODE_DEL")]),{allowFailure:!0})}}async function aj(e,t,r){let a,i=await ab(e),n=/<node\b[^>]*>/g,o=null,s=null,l=null;for(;null!==(a=n.exec(i));){let e=af(a[0]),i=aw(e.bounds);if(!i)continue;let n=e.className??"",d=(e.text??"").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&"),u=e.focused??!1;if(!d)continue;let c=Math.max(1,i.width*i.height),p=t>=i.x&&t<=i.x+i.width&&r>=i.y&&r<=i.y+i.height;if(u&&aB(n)){(!o||c<=o.area)&&(o={text:d,area:c});continue}if(p&&aB(n)){(!s||c<=s.area)&&(s={text:d,area:c});continue}p&&(!l||c<=l.area)&&(l={text:d,area:c})}return o?.text??s?.text??l?.text??null}function aB(e){let t=e.toLowerCase();return t.includes("edittext")||t.includes("textfield")}async function aq(e){let t=await c("adb",rn(e,["shell","dumpsys","input_method"]),{allowFailure:!0});if(0!==t.exitCode)throw new h("COMMAND_FAILED","Failed to query Android keyboard state",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});return function(e){let t=function(e){let t=new Map;for(let r of e.matchAll(/\b(mInputShown|mIsInputViewShown|isInputViewShown)=([a-zA-Z]+)\b/g)){let e=r[1],a=r[2]?.toLowerCase();e&&("true"===a||"false"===a)&&t.set(e,"true"===a)}if(0===t.size)return null;for(let e of t.values())if(e)return!0;return!1}(e),r=t??!1;if(null===t){let t=e.match(/\bmImeWindowVis=0x([0-9a-fA-F]+)\b/);if(t?.[1]){let e=Number.parseInt(t[1],16);Number.isNaN(e)||(r=(1&e)!=0)}}let a=Array.from(e.matchAll(/\binputType=0x([0-9a-fA-F]+)\b/gi)),i=a.length>0?a[a.length-1]?.[1]:void 0,n=i?`0x${i.toLowerCase()}`:void 0;return{visible:r,inputType:n,type:n?function(e){let t=Number.parseInt(e.replace(/^0x/i,""),16);if(Number.isNaN(t))return"unknown";let r=15&t;if(2===r)return"number";if(3===r)return"phone";if(4===r)return"datetime";if(1!==r)return"unknown";let a=4080&t;return 32===a||208===a?"email":128===a||224===a||144===a?"password":"text"}(n):void 0}}(t.stdout)}async function aH(e){let t=await aq(e),r=t,a=0;for(;r.visible&&a<2;)await ak(e),a+=1,await rl(120),r=await aq(e);return{attempts:a,wasVisible:t.visible,dismissed:t.visible&&!r.visible,visible:r.visible,inputType:r.inputType,type:r.type}}async function aW(e){let t,r;return(r=(t=(await aJ(e,["shell","cmd","clipboard","get","text"],"read")).replace(/\r\n/g,"\n").replace(/\n$/,"")).match(/^clipboard text:\s*(.*)$/i))?r[1]??"":"null"===t.trim().toLowerCase()?"":t}async function az(e,t){await aJ(e,["shell","cmd","clipboard","set","text",t],"write")}async function aJ(e,t,r){let a=await c("adb",rn(e,t),{allowFailure:!0});if(rs(a.stdout,a.stderr))throw new h("UNSUPPORTED_OPERATION",`Android shell clipboard ${r} is not supported on this device.`);if(0!==a.exitCode)throw new h("COMMAND_FAILED",`Failed to ${r} Android clipboard text`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return a.stdout}let aK=["camera","microphone","photos","contacts","contacts-limited","notifications","calendar","location","location-always","media-library","motion","reminders","siri"];function aX(e){let t=e.trim().toLowerCase();if("grant"===t)return"grant";if("deny"===t)return"deny";if("reset"===t)return"reset";throw new h("INVALID_ARGS",`Invalid permission action: ${e}. Use grant|deny|reset.`)}function aZ(e){let t=e?.trim().toLowerCase();if("camera"===t||"microphone"===t||"photos"===t||"contacts"===t||"contacts-limited"===t||"notifications"===t||"calendar"===t||"location"===t||"location-always"===t||"media-library"===t||"motion"===t||"reminders"===t||"siri"===t)return t;throw new h("INVALID_ARGS",`permission setting requires a target: ${aK.join("|")}`)}function aY(e){let t=e.trim().toLowerCase();if("light"===t)return"light";if("dark"===t)return"dark";if("toggle"===t)return"toggle";throw new h("INVALID_ARGS",`Invalid appearance state: ${e}. Use light|dark|toggle.`)}async function aQ(e,t,r,a,i){switch(t.toLowerCase()){case"wifi":{let t=a1(r);await c("adb",rn(e,["shell","svc","wifi",t?"enable":"disable"]));return}case"airplane":{let t=a1(r);await c("adb",rn(e,["shell","settings","put","global","airplane_mode_on",t?"1":"0"])),await c("adb",rn(e,["shell","am","broadcast","-a","android.intent.action.AIRPLANE_MODE","--ez","state",t?"true":"false"]));return}case"location":{let t=a1(r);await c("adb",rn(e,["shell","settings","put","secure","location_mode",t?"3":"0"]));return}case"appearance":{let t=await a2(e,r);await c("adb",rn(e,["shell","cmd","uimode","night","dark"===t?"yes":"no"]));return}case"fingerprint":{let t=function(e){let t=e.trim().toLowerCase();if("match"===t)return"match";if("nonmatch"===t)return"nonmatch";throw new h("INVALID_ARGS",`Invalid fingerprint state: ${e}. Use match|nonmatch.`)}(r);await a0(e,t);return}case"permission":{if(!a)throw new h("INVALID_ARGS","permission setting requires an active app in session");let t=aX(r),n=function(e,t){let r=aZ(e);if(t?.trim())throw new h("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 h("INVALID_ARGS",`Unsupported permission target on Android: ${e}. Use camera|microphone|photos|contacts|notifications.`)}(i?.permissionTarget,i?.permissionMode);if("notifications"===n.kind)return void await a4(e,a,t,n);let o="grant"===t?"grant":"revoke";if("photos"===n.type)return void await a3(e,a,o);await c("adb",rn(e,["shell","pm",o,a,n.value]));return}default:throw new h("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function a0(e,t){var r;let a,i,n=(r=e,i=[["shell","cmd","fingerprint","touch",a="match"===t?"1":"9999"],["shell","cmd","fingerprint","finger",a]],"emulator"===r.kind&&i.push(["emu","finger","touch",a]),i),o=[];for(let t of n){let r=await c("adb",rn(e,t),{allowFailure:!0});if(0===r.exitCode)return;o.push({args:t,stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}let s=o.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(o.length>0&&o.every(e=>{var t,r;let a;return t=e.stdout,r=e.stderr,(a=`${t}
16
+ ${r}`.toLowerCase()).includes("unknown command")||a.includes("can't find service: fingerprint")||a.includes("service fingerprint was not found")||a.includes("fingerprint cmd unavailable")||a.includes("emu command is not supported")||a.includes("emulator console is not running")||a.includes("fingerprint")&&a.includes("not found")}))throw new h("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:s});throw new h("COMMAND_FAILED","Failed to simulate Android fingerprint.",{deviceId:e.id,action:t,attempts:s})}function a1(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new h("INVALID_ARGS",`Invalid setting state: ${e}`)}async function a2(e,t){let r=aY(t);if("toggle"!==r)return r;let a=await c("adb",rn(e,["shell","cmd","uimode","night"]),{allowFailure:!0});if(0!==a.exitCode)throw new h("COMMAND_FAILED","Failed to read current Android appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let i=function(e,t){let r=/night mode:\s*(yes|no|auto)\b/i.exec(`${e}
17
+ ${t}`);if(!r)return null;let a=r[1].toLowerCase();return"yes"===a?"dark":"no"===a?"light":"auto"===a?"auto":null}(a.stdout,a.stderr);if(!i)throw new h("COMMAND_FAILED","Unable to determine current Android appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"auto"===i?"dark":"dark"===i?"light":"dark"}async function a3(e,t,r){let a=await a8(e),i=[];for(let n of null!==a&&a>=33?["android.permission.READ_MEDIA_IMAGES","android.permission.READ_EXTERNAL_STORAGE"]:["android.permission.READ_EXTERNAL_STORAGE","android.permission.READ_MEDIA_IMAGES"]){let a=await c("adb",rn(e,["shell","pm",r,t,n]),{allowFailure:!0});if(0===a.exitCode)return;i.push({permission:n,stderr:a.stderr,exitCode:a.exitCode})}throw new h("COMMAND_FAILED",`Failed to ${r} Android photos permission`,{appPackage:t,sdkInt:a,attempts:i})}async function a4(e,t,r,a){"grant"===r?await c("adb",rn(e,["shell","pm","grant",t,a.permission]),{allowFailure:!0}):(await c("adb",rn(e,["shell","pm","revoke",t,a.permission]),{allowFailure:!0}),"reset"===r&&(await c("adb",rn(e,["shell","pm","clear-permission-flags",t,a.permission,"user-set"]),{allowFailure:!0}),await c("adb",rn(e,["shell","pm","clear-permission-flags",t,a.permission,"user-fixed"]),{allowFailure:!0}))),await c("adb",rn(e,["shell","appops","set",t,a.appOps,"grant"===r?"allow":"deny"===r?"deny":"default"]))}async function a8(e){let t=await c("adb",rn(e,["shell","getprop","ro.build.version.sdk"]),{allowFailure:!0});if(0!==t.exitCode)return null;let r=Number.parseInt(t.stdout.trim(),10);return!Number.isFinite(r)||r<=0?null:r}async function a6(e,t,r){let a="string"==typeof r.action&&r.action.trim()?r.action.trim():`${t}.TEST_PUSH`,i=["shell","am","broadcast","-a",a,"-p",t],n="string"==typeof r.receiver?r.receiver.trim():"";n&&i.push("-n",n);let o=r.extras;if(void 0!==o&&("object"!=typeof o||null===o||Array.isArray(o)))throw new h("INVALID_ARGS","Android push payload extras must be an object");let s=0;for(let[e,t]of Object.entries(o??{}))e&&(function(e,t,r){if("string"==typeof r)return e.push("--es",t,r);if("boolean"==typeof r)return e.push("--ez",t,r?"true":"false");if("number"==typeof r&&Number.isFinite(r))return Number.isInteger(r)?e.push("--ei",t,String(r)):e.push("--ef",t,String(r));throw new h("INVALID_ARGS",`Unsupported Android broadcast extra type for "${t}". Use string, boolean, or number.`)}(i,e,t),s+=1);return await c("adb",rn(e,i)),{action:a,extrasCount:s}}let a5=ev(process.env.AGENT_DEVICE_IOS_BOOT_TIMEOUT_MS,K,5e3),a9=ev(process.env.AGENT_DEVICE_IOS_SIMCTL_LIST_TIMEOUT_MS,J,1e3),a7=ev(process.env.AGENT_DEVICE_IOS_APP_LAUNCH_TIMEOUT_MS,3e4,5e3),ie=ev(process.env.AGENT_DEVICE_IOS_DEVICECTL_TIMEOUT_MS,2e4,1e3),it=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_SCREENSHOT_TIMEOUT_MS,2e4,1e3),ir=ev(process.env.AGENT_DEVICE_IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS,2e4,1e3);async function ia(e,t){let r=["devicectl",...e],a=await c("xcrun",r,{allowFailure:!0,timeoutMs:ie});if(0===a.exitCode)return;let i=String(a.stdout??""),n=String(a.stderr??"");throw new h("COMMAND_FAILED",`Failed to ${t.action}`,{cmd:"xcrun",args:r,exitCode:a.exitCode,stdout:i,stderr:n,deviceId:t.deviceId,hint:is(i,n)??io})}async function ii(e,t){let r=i.join(C.tmpdir(),`agent-device-ios-apps-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),a=["devicectl","device","info","apps","--device",e.id,"--include-all-apps","--json-output",r],n=await c("xcrun",a,{allowFailure:!0,timeoutMs:ie});try{var o,s;if(0!==n.exitCode){let t=String(n.stdout??""),r=String(n.stderr??"");throw new h("COMMAND_FAILED","Failed to list iOS apps",{cmd:"xcrun",args:a,exitCode:n.exitCode,stdout:t,stderr:r,deviceId:e.id,hint:is(t,r)??io})}let i=await E.readFile(r,"utf8");return o=function(e){let t=e?.result?.apps;if(!Array.isArray(t))return[];let r=[];for(let e of t){if(!e||"object"!=typeof e)continue;let t="string"==typeof e.bundleIdentifier?e.bundleIdentifier.trim():"";if(!t)continue;let a="string"==typeof e.name&&e.name.trim().length>0?e.name.trim():t;r.push({bundleId:t,name:a})}return r}(JSON.parse(i)),s=t,"user-installed"===s?o.filter(e=>!e.bundleId.startsWith("com.apple.")):o}catch(t){if(t instanceof h)throw t;throw new h("COMMAND_FAILED","Failed to parse iOS apps list",{deviceId:e.id,cause:String(t)})}finally{await E.unlink(r).catch(()=>{})}}let io="Ensure the iOS device is unlocked, trusted, and available in Xcode > Devices, then retry.";function is(e,t){let r=`${e}
18
+ ${t}`.toLowerCase();return r.includes("device is busy")&&r.includes("connecting")?"iOS device is still connecting. Keep it unlocked and connected by cable until it is fully available in Xcode Devices, then retry.":r.includes("coredeviceservice")&&r.includes("timed out")?"CoreDevice service timed out. Reconnect the device and retry; if it persists restart Xcode and the iOS device.":null}function il(e){if(!(e instanceof h)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{};if(4!==t.exitCode)return!1;let r=String(t.stderr??"").toLowerCase();return r.includes("fbsopenapplicationserviceerrordomain")&&r.includes("the request to open")}async function id(e,t){let r=await c("xcrun",ek(e,["get_app_container",e.id,t]),{allowFailure:!0});if(0!==r.exitCode)return{installed:!1};let a=r.stdout.trim();if(!a)return{installed:!1};let i=await c("plutil",["-extract","CFBundleExecutable","raw","-o","-",`${a}/Info.plist`],{allowFailure:!0});if(0!==i.exitCode||!i.stdout.trim())return{installed:!0};let n=i.stdout.trim(),o=`${a}/${n}`,s=await c("otool",["-l",o],{allowFailure:!0});if(0!==s.exitCode)return{installed:!0};let l=s.stdout.toLowerCase();return{installed:!0,simulatorCompatible:l.includes("iossimulator")||l.includes("platform 7")}}function iu(e,t){if("simulator"!==e.kind)throw new h("UNSUPPORTED_OPERATION",`${t} is only supported on iOS simulators`)}async function ic(){await c("open",["-a","Simulator"],{allowFailure:!0})}async function ip(e){let t,r;if("simulator"!==e.kind||"Booted"===await ih(e))return;let a=Z.fromTimeoutMs(a5);try{await Y(async({deadline:a})=>{if(a?.isExpired())throw new h("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:a5});let i=Math.max(1e3,a?.remainingMs()??a5),n=await c("xcrun",ek(e,["boot",e.id]),{allowFailure:!0,timeoutMs:i});t={stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.exitCode};let o=`${t.stdout}
19
+ ${t.stderr}`.toLowerCase(),s=o.includes("already booted")||o.includes("current state: booted");if(0!==t.exitCode&&!s)throw new h("COMMAND_FAILED","simctl boot failed",{stdout:t.stdout,stderr:t.stderr,exitCode:t.exitCode});let l=await c("xcrun",ek(e,["bootstatus",e.id,"-b"]),{allowFailure:!0,timeoutMs:i});if(r={stdout:String(l.stdout??""),stderr:String(l.stderr??""),exitCode:l.exitCode},0!==r.exitCode)throw new h("COMMAND_FAILED","simctl bootstatus failed",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode});let d=await ih(e);if("Booted"!==d)throw new h("COMMAND_FAILED","Simulator is still booting",{state:d})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let a=ef({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==a&&"CI_RESOURCE_STARVATION_SUSPECTED"!==a}},{deadline:a,phase:"boot",classifyReason:e=>ef({error:e,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(n){let i=ef({error:n,stdout:r?.stdout??t?.stdout,stderr:r?.stderr??t?.stderr,context:{platform:"ios",phase:"boot"}});throw new h("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:e.id,timeoutMs:a5,elapsedMs:a.elapsedMs(),reason:i,hint:em(i),boot:t,bootstatus:r})}}async function im(e){let t=ek(e,["shutdown",e.id]),r=await c("xcrun",t,{allowFailure:!0,timeoutMs:15e3});return{success:0===r.exitCode,exitCode:r.exitCode,stdout:String(r.stdout??""),stderr:String(r.stderr??"")}}async function ih(e){let t="string"==typeof e?e:e.id,r="string"==typeof e?eE(["list","devices","-j"]):ek(e,["list","devices","-j"]),a=await c("xcrun",r,{allowFailure:!0,timeoutMs:a9});if(0!==a.exitCode)return null;try{let e=JSON.parse(String(a.stdout??""));for(let r of Object.values(e.devices??{})){let e=r.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}async function iw(e,t){try{let r=await c("plutil",["-extract",t,"raw","-o","-",e],{allowFailure:!0});if(0===r.exitCode){let e=String(r.stdout??"").trim();if(e.length>0)return e}}catch{}try{let r=await E.readFile(e,"utf8");return function(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=e.match(RegExp(`<key>\\s*${r}\\s*<\\/key>\\s*<string>([\\s\\S]*?)<\\/string>`,"i"));if(!a?.[1])return;let i=a[1].trim().replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&amp;/g,"&");return i.length>0?i:void 0}(r,t)}catch{return}}async function ig(e,t){let r=await rP({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(".app")||t.isFile()&&e.toLowerCase().endsWith(".ipa"),installableLabel:"iOS installable (.app or .ipa)",signal:t?.signal}),a=await iv(r.installablePath,t),i=await iI(a.installPath);return{archivePath:r.archivePath??(r.installablePath.toLowerCase().endsWith(".ipa")?r.installablePath:void 0),installablePath:a.installPath,bundleId:i.bundleId,appName:i.appName,cleanup:async()=>{await a.cleanup(),await r.cleanup()}}}async function iI(e){let t=i.join(e,"Info.plist"),[r,a,n]=await Promise.all([iw(t,"CFBundleIdentifier"),iw(t,"CFBundleDisplayName"),iw(t,"CFBundleName")]);return{bundleId:r,appName:a??n}}async function iv(e,t){if(!e.toLowerCase().endsWith(".ipa"))return{installPath:e,cleanup:async()=>{}};let r=await E.mkdtemp(i.join(C.tmpdir(),"agent-device-ios-ipa-")),a=async()=>{await E.rm(r,{recursive:!0,force:!0})};try{await c("ditto",["-x","-k",e,r]);let n=i.join(r,"Payload"),o=(await E.readdir(n,{withFileTypes:!0}).catch(()=>{throw new h("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:i.join(n,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===o.length)return{installPath:o[0].installPath,cleanup:a};if(0===o.length)throw new h("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await iA(o);let s=t?.appIdentifierHint?.trim();if(s){let e=function(e,t){let r=t.toLowerCase(),a=e.filter(e=>e.bundleName.toLowerCase()===r);if(1===a.length)return a[0];if(a.length>1)throw new h("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()===r);if(1===t.length)return t[0]}}(o,s);if(e)return{installPath:e.installPath,cleanup:a};throw new h("INVALID_ARGS",`Invalid IPA: found ${o.length} .app bundles under Payload and none matched "${s}". Available bundles: ${o.map(iy).join(", ")}`)}throw new h("INVALID_ARGS",`Invalid IPA: found ${o.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${o.map(iy).join(", ")}`)}catch(e){throw await a(),e}}async function iA(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await iI(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function iy(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}function ib(e,t,r){return c("xcrun",ek(e,t),r)}let iN={ensureBooted:ip,captureWithRetry:iD,captureWithRunner:iE,shouldFallbackToRunner:ix};async function i_(e,t,r){if("simulator"===e.kind)return void await iS(e,t,r);try{await ia(["device","screenshot","--device",e.id,t],{action:"capture iOS screenshot",deviceId:e.id});return}catch(t){if(!function(e){if(!(e instanceof h)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",i=`${e.message}
20
20
  ${r}
21
- ${i}`.toLowerCase();return n.includes("unknown option '--device'")||n.includes("unknown subcommand")&&n.includes("screenshot")||n.includes("unrecognized subcommand")&&n.includes("screenshot")}(t))throw t;i0(e,"devicectl_screenshot",t)}await iX(e,t,r)}async function iz(e,t,r,i=iW){if("simulator"!==e.kind)throw new I("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");await i.ensureBooted(e);try{await i.captureWithRetry(e,t);return}catch(t){if(!i.shouldFallbackToRunner(t))throw t;i0(e,"simctl_screenshot",t)}await i.captureWithRunner(e,t,r)}async function iK(e,t){let r=K.fromTimeoutMs(ix);await iG(),await X(async({attempt:r,deadline:i})=>{r>1&&await iG(),await iH(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,i?.remainingMs()??ix)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>i1(e)},{deadline:r,phase:"ios_simulator_screenshot"})}async function iX(e,t,r){let i=(await ta(e,{command:"screenshot",appBundleId:r})).message;if(!i)throw new I("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"simulator"===e.kind?await iZ(e,i,t):await iY(e,i,t)}async function iY(e,t,r){let i=K.fromTimeoutMs(iC),n={exitCode:1,stdout:"",stderr:""};for(let a of eY)if(0===(n=await p("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",r,"--domain-type","appDataContainer","--domain-identifier",a],{allowFailure:!0,timeoutMs:iQ(i,iC,"runner screenshot copy")})).exitCode)return;let a=n.stderr.trim()||n.stdout.trim()||`devicectl exited with code ${n.exitCode}`;throw new I("COMMAND_FAILED",`Failed to capture iOS screenshot: ${a}`)}async function iZ(e,t,r){let i=K.fromTimeoutMs(iC),a="Unable to locate runner container for simulator screenshot";for(let o of eY){let s=await iH(e,["get_app_container",e.id,o,"data"],{allowFailure:!0,timeoutMs:iQ(i,iC,"runner screenshot container lookup")});if(0!==s.exitCode){let e=s.stderr.trim();e&&(a=e);continue}let l=s.stdout.trim();if(!l){a="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let r=n.resolve(e),i=t.trim();if(!i)return[];let a=[],o=new Set,s=e=>{let t=n.normalize(e);o.has(t)||(o.add(t),a.push(t))},l=i.replace(/^\/+/,""),d=l.replace(/\\/g,"/");if(l&&s(n.join(r,l)),n.isAbsolute(i)&&s(n.normalize(i)),d.startsWith("tmp/"))s(n.join(r,d));else{let e=d.lastIndexOf("/tmp/");if(e>=0){let t=d.slice(e+1);s(n.join(r,t))}}let u=n.basename(i);return u&&s(n.join(r,"tmp",u)),a}(l,t))try{await x.copyFile(e,r);return}catch(e){a=e instanceof Error?e.message:String(e)}}throw new I("COMMAND_FAILED",`Failed to capture iOS screenshot: ${a}`)}function iQ(e,t,r){let i=e.remainingMs();if(i>0)return i;throw new I("COMMAND_FAILED",`iOS ${r} timed out after ${t}ms`,{timeoutMs:t,step:r})}function i0(e,t,r){let i=function(e){if(!(e instanceof I))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=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:r}}(r);M({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...i}})}function i1(e){if(!(e instanceof I)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",i="string"==typeof t.stderr?t.stderr:"",n=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",a=`${e.message}
21
+ ${a}`.toLowerCase();return i.includes("unknown option '--device'")||i.includes("unknown subcommand")&&i.includes("screenshot")||i.includes("unrecognized subcommand")&&i.includes("screenshot")}(t))throw t;iM(e,"devicectl_screenshot",t)}await iE(e,t,r)}async function iS(e,t,r,a=iN){if("simulator"!==e.kind)throw new h("UNSUPPORTED_OPERATION","Simulator screenshot fallback flow supports only iOS simulators");await a.ensureBooted(e);try{await a.captureWithRetry(e,t);return}catch(t){if(!a.shouldFallbackToRunner(t))throw t;iM(e,"simctl_screenshot",t)}await a.captureWithRunner(e,t,r)}async function iD(e,t){let r=Z.fromTimeoutMs(it);await ic(),await Y(async({attempt:r,deadline:a})=>{r>1&&await ic(),await ib(e,["io",e.id,"screenshot",t],{timeoutMs:Math.max(1e3,a?.remainingMs()??it)})},{maxAttempts:5,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>ix(e)},{deadline:r,phase:"ios_simulator_screenshot"})}async function iE(e,t,r){let a=(await tl(e,{command:"screenshot",appBundleId:r})).message;if(!a)throw new h("COMMAND_FAILED","Failed to capture iOS screenshot: runner returned no file path");"simulator"===e.kind?await iL(e,a,t):await ik(e,a,t)}async function ik(e,t,r){let a=Z.fromTimeoutMs(ir),i={exitCode:1,stdout:"",stderr:""};for(let n of e0)if(0===(i=await c("xcrun",["devicectl","device","copy","from","--device",e.id,"--source",t,"--destination",r,"--domain-type","appDataContainer","--domain-identifier",n],{allowFailure:!0,timeoutMs:iO(a,ir,"runner screenshot copy")})).exitCode)return;let n=i.stderr.trim()||i.stdout.trim()||`devicectl exited with code ${i.exitCode}`;throw new h("COMMAND_FAILED",`Failed to capture iOS screenshot: ${n}`)}async function iL(e,t,r){let a=Z.fromTimeoutMs(ir),n="Unable to locate runner container for simulator screenshot";for(let o of e0){let s=await ib(e,["get_app_container",e.id,o,"data"],{allowFailure:!0,timeoutMs:iO(a,ir,"runner screenshot container lookup")});if(0!==s.exitCode){let e=s.stderr.trim();e&&(n=e);continue}let l=s.stdout.trim();if(!l){n="simctl get_app_container returned empty output";continue}for(let e of function(e,t){let r=i.resolve(e),a=t.trim();if(!a)return[];let n=[],o=new Set,s=e=>{let t=i.normalize(e);o.has(t)||(o.add(t),n.push(t))},l=a.replace(/^\/+/,""),d=l.replace(/\\/g,"/");if(l&&s(i.join(r,l)),i.isAbsolute(a)&&s(i.normalize(a)),d.startsWith("tmp/"))s(i.join(r,d));else{let e=d.lastIndexOf("/tmp/");if(e>=0){let t=d.slice(e+1);s(i.join(r,t))}}let u=i.basename(a);return u&&s(i.join(r,"tmp",u)),n}(l,t))try{await E.copyFile(e,r);return}catch(e){n=e instanceof Error?e.message:String(e)}}throw new h("COMMAND_FAILED",`Failed to capture iOS screenshot: ${n}`)}function iO(e,t,r){let a=e.remainingMs();if(a>0)return a;throw new h("COMMAND_FAILED",`iOS ${r} timed out after ${t}ms`,{timeoutMs:t,step:r})}function iM(e,t,r){let a=function(e){if(!(e instanceof h))return{reason:e instanceof Error?e.message:String(e)};let t=e.details??{},r=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:r}}(r);D({level:"warn",phase:"ios_screenshot_fallback",data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:"runner",...a}})}function ix(e){if(!(e instanceof h)||"COMMAND_FAILED"!==e.code)return!1;let t=e.details??{},r="string"==typeof t.stdout?t.stdout:"",a="string"==typeof t.stderr?t.stderr:"",i=Array.isArray(t.args)?t.args.filter(e=>"string"==typeof e).join(" "):"",n=`${e.message}
22
22
  ${r}
23
- ${i}
24
- ${n}`.toLowerCase();return a.includes("timeout waiting for screen surfaces")||a.includes("nsposixerrordomain")&&a.includes("code=60")&&a.includes("screenshot")||a.includes("timed out")&&a.includes("screenshot")}let i2={settings:"com.apple.Preferences"},i3=null;function i4(e,t,r){return p("xcrun",e_(e,t),r)}function i8(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function i5(e){let t=n.join(e,"Info.plist");try{let e=await p("plutil",["-extract","CFBundleIdentifier","raw","-o","-",t],{allowFailure:!0});if(0!==e.exitCode)return;let r=String(e.stdout??"").trim();return r.length>0?r:void 0}catch{return}}function i6(e){return e.bundleId?`${e.bundleName}.app (${e.bundleId})`:`${e.bundleName}.app`}async function i9(e){await Promise.all(e.map(async e=>{void 0===e.bundleId&&(e.bundleId=await i5(e.installPath))}))}async function i7(e,t){if(".ipa"!==n.extname(e).toLowerCase())return{installPath:e,cleanup:async()=>{}};let r=await x.mkdtemp(n.join(V.tmpdir(),"agent-device-ios-ipa-")),i=async()=>{await x.rm(r,{recursive:!0,force:!0})};try{await p("ditto",["-x","-k",e,r]);let a=n.join(r,"Payload"),o=(await x.readdir(a,{withFileTypes:!0}).catch(()=>{throw new I("INVALID_ARGS","Invalid IPA: missing Payload directory")})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(".app")).map(e=>({installPath:n.join(a,e.name),bundleName:e.name.replace(/\.app$/i,"")}));if(1===o.length)return{installPath:o[0].installPath,cleanup:i};if(0===o.length)throw new I("INVALID_ARGS","Invalid IPA: expected at least one .app under Payload, found 0");await i9(o);let s=t?.appIdentifierHint?.trim();if(s){let e=s.toLowerCase(),t=o.filter(t=>t.bundleName.toLowerCase()===e);if(1===t.length)return{installPath:t[0].installPath,cleanup:i};if(t.length>1)throw new I("INVALID_ARGS",`Invalid IPA: multiple app bundles matched "${s}" by name. Use a bundle id hint instead.`);if(s.includes(".")){let t=o.filter(t=>t.bundleId?.toLowerCase()===e);if(1===t.length)return{installPath:t[0].installPath,cleanup:i}}throw new I("INVALID_ARGS",`Invalid IPA: found ${o.length} .app bundles under Payload and none matched "${s}". Available bundles: ${o.map(i6).join(", ")}`)}throw new I("INVALID_ARGS",`Invalid IPA: found ${o.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${o.map(i6).join(", ")}`)}catch(e){throw await i(),e}}async function ne(e,t){let r=t.trim();if(r.includes("."))return r;let i=i2[r.toLowerCase()];if(i)return i;let n=("simulator"===e.kind?await np(e):await iT(e,"all")).filter(e=>e.name.toLowerCase()===r.toLowerCase());if(1===n.length)return n[0].bundleId;if(n.length>1)throw new I("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:n});throw new I("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function nt(e,t,r){let i=r?.url?.trim();if(i){if(!t9(i))throw new I("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await iB(e),await iG(),await i4(e,["openurl",e.id,i]);return}let n=t7(r?.appBundleId??await ne(e,t),i);if(!n)throw new I("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await ny(e,n,{payloadUrl:i});return}let n=t.trim();if(t9(n)){if("simulator"===e.kind){await iB(e),await iG(),await i4(e,["openurl",e.id,n]);return}let t=t7(r?.appBundleId,n);if(!t)throw new I("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await ny(e,t,{payloadUrl:n});return}let a=r?.appBundleId??await ne(e,t);"simulator"===e.kind?await nA(e,a):await ny(e,a)}async function nr(e){"simulator"!==e.kind||"Booted"!==await iq(e)&&(await iB(e),await iG())}async function ni(e,t){let r=await ne(e,t);if("simulator"===e.kind){await iB(e);let t=e_(e,["terminate",e.id,r]),i=await p("xcrun",t,{allowFailure:!0});if(0!==i.exitCode){if(i.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new I("COMMAND_FAILED",`xcrun exited with code ${i.exitCode}`,{cmd:"xcrun",args:t,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode})}return}await iR(["device","process","terminate","--device",e.id,r],{action:"terminate iOS app",deviceId:e.id})}async function nn(e,t){let r=await ne(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,r],i=await p("xcrun",t,{allowFailure:!0,timeoutMs:iM});if(0!==i.exitCode){let n=String(i.stdout??""),a=String(i.stderr??"");if(!i8(`${n}
25
- ${a}`.toLowerCase()))throw new I("COMMAND_FAILED",`Failed to uninstall iOS app ${r}`,{cmd:"xcrun",args:t,exitCode:i.exitCode,stdout:n,stderr:a,deviceId:e.id,hint:i$(n,a)??iP})}return{bundleId:r}}await iB(e);let i=await i4(e,["uninstall",e.id,r],{allowFailure:!0});if(0!==i.exitCode&&!i8(`${i.stdout}
26
- ${i.stderr}`.toLowerCase()))throw new I("COMMAND_FAILED",`simctl uninstall failed for ${r}`,{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});return{bundleId:r}}async function na(e,t,r){let{installPath:i,cleanup:n}=await i7(t,r);try{if("simulator"!==e.kind)return void await iR(["device","install","app","--device",e.id,i],{action:"install iOS app",deviceId:e.id});await iB(e),await i4(e,["install",e.id,i])}finally{await n()}}async function no(e,t,r){let{bundleId:i}=await nn(e,t);return await na(e,r,{appIdentifierHint:t}),{bundleId:i}}async function ns(e){iU(e,"clipboard"),await iB(e);let t=await i4(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new I("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 nl(e,t){iU(e,"clipboard"),await iB(e);let r=await i4(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==r.exitCode)throw new I("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function nd(e,t,r){iU(e,"push"),await iB(e);let i=await x.mkdtemp(n.join(V.tmpdir(),"agent-device-ios-push-")),a=n.join(i,"payload.apns");try{await x.writeFile(a,`${JSON.stringify(r)}
27
- `,"utf8"),await i4(e,["push",e.id,t,a])}finally{await x.rm(i,{recursive:!0,force:!0})}}async function nu(e,t,r,i,n){iU(e,"settings"),await iB(e);let a=t.toLowerCase();switch(a){case"wifi":{let t=nf(r);await i4(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(nf(r)?await i4(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await i4(e,["status_bar",e.id,"clear"]));case"location":{let t=nf(r);if(!i)throw new I("INVALID_ARGS","location setting requires an active app in session");await i4(e,["privacy",e.id,t?"grant":"revoke","location",i]);return}case"faceid":case"touchid":{let t=nh[a],i=function(e,t){let r=e.trim().toLowerCase();if("match"===r)return"match";if("nonmatch"===r)return"nonmatch";if("enroll"===r)return"enroll";if("unenroll"===r)return"unenroll";throw new I("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(r,a);await nv(e,i,{settingName:a,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await nm(e,r);await i4(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!i)throw new I("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=ig(r))?"revoke":o,a=function(e,t){let r=iI(e);if("photos"!==r&&t?.trim())throw new I("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return"camera";if("microphone"===r)return"microphone";if("contacts"===r)return"contacts";if("contacts-limited"===r)return"contacts-limited";if("notifications"===r)return"notifications";if("calendar"===r)return"calendar";if("location"===r)return"location";if("location-always"===r)return"location-always";if("media-library"===r)return"media-library";if("motion"===r)return"motion";if("reminders"===r)return"reminders";if("siri"===r)return"siri";if("photos"===r){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new I("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new I("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(n?.permissionTarget,n?.permissionMode);await nw(e,t,a,i);return}default:throw new I("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function nc(e,t="all"){var r;return"simulator"===e.kind?(r=await np(e),"user-installed"===t?r.filter(e=>!e.bundleId.startsWith("com.apple.")):r):await iT(e,t)}async function np(e){let t=(await i4(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let r=null;if(t.startsWith("{"))try{r=JSON.parse(t)}catch{r=null}if(!r&&t.startsWith("{"))try{let e=await p("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>({bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e})):[]}function nf(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new I("INVALID_ARGS",`Invalid setting state: ${e}`)}async function nm(e,t){let r=iv(t);if("toggle"!==r)return r;let i=await i4(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==i.exitCode)throw new I("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode});let n=function(e,t){let r=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
28
- ${t}`);if(!r)return null;let i=r[1].toLowerCase();return"dark"===i?"dark":"light"===i?"light":null}(i.stdout,i.stderr);if(!n)throw new I("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:i.stdout,stderr:i.stderr});return"dark"===n?"light":"dark"}let nh={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function nw(e,t,r,i){let n=await nI(e);if(!n.has(r))throw new I("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:i,hint:`Supported services: ${Array.from(n).sort().join(", ")}`});let a=["privacy",e.id,t,r,i],o="notifications"===r;if(!("reset"===t&&o))try{await i4(e,a);return}catch(t){if(!(o&&ng(t)))throw t;throw new I("UNSUPPORTED_OPERATION","iOS simulator does not support setting notifications permission via simctl privacy on this runtime.",{deviceId:e.id,appBundleId:i,hint:"Use reset notifications for reprompt behavior, or toggle notifications manually in Settings."})}try{await i4(e,a);return}catch(e){if(!ng(e))throw e}try{await i4(e,["privacy",e.id,"reset","all",i])}catch(t){throw new I("COMMAND_FAILED","iOS simulator blocked direct notifications reset. Fallback reset-all also failed.",{deviceId:e.id,appBundleId:i,hint:"Use reinstall to force a fresh notifications prompt, or reset simulator content and settings."},t instanceof Error?t:void 0)}}function ng(e){if(!(e instanceof I)||"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 nI(t){let r=ey(t.simulatorSetPath),i=`${process.env.PATH??""}::${r??""}`;if(i3&&e===i)return i3;let n=await i4(t,["privacy","help"],{allowFailure:!0}),a=function(e){let t=new Set,r=!1;for(let i of e.split("\n")){let e=i.trim();if(!e)continue;if("service"===e){r=!0;continue}if(!r)continue;if(e.startsWith("bundle identifier"))break;let n=/^([a-z-]+)\s+-\s+/.exec(e);n&&t.add(n[1])}return t}(`${n.stdout}
29
- ${n.stderr}`);if(0===a.size)throw new I("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return i3=a,e=i,a}async function nv(e,t,r){let i=function(e,t,r){let i=r.length>0?r:["face"];switch(t){case"match":return i.flatMap(t=>[["biometric",e,"match",t],["biometric","match",e,t]]);case"nonmatch":return i.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,r.modalityAliases),n=[];for(let t of i){let r=e_(e,t),i=await p("xcrun",r,{allowFailure:!0});if(0===i.exitCode)return;n.push({args:r,stderr:i.stderr,stdout:i.stdout,exitCode:i.exitCode})}let a=n.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(n.length>0&&n.every(e=>{var t,r;let i;return t=e.stdout,r=e.stderr,(i=`${t}
30
- ${r}`.toLowerCase()).includes("unrecognized subcommand")||i.includes("unknown subcommand")||i.includes("not supported")||i.includes("unavailable")||i.includes("biometric")&&i.includes("invalid")}))throw new I("UNSUPPORTED_OPERATION",`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:a});throw new I("COMMAND_FAILED",`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:a})}async function nA(e,t){await iB(e),await iG();let r=0,i=K.fromTimeoutMs(iL);try{await X(async({deadline:r})=>{var i;if(r?.isExpired())throw new I("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:iL});let n=(i=["launch",e.id,t],e_(e,i)),a=await p("xcrun",n,{allowFailure:!0});if(0!==a.exitCode)throw new I("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:n,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!iF(e)&&(r+=1)<3},{deadline:i})}catch(r){if(iF(r)){var n;let i=(n=await iV(e,t)).installed?!1===n.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";r.details={...r.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."}}(i)}}throw r}}async function ny(e,t,r){let i=["device","process","launch","--device",e.id,t];r?.payloadUrl&&i.push("--payload-url",r.payloadUrl),await iR(i,{action:"launch iOS app",deviceId:e.id})}let nb=/^[A-Za-z0-9_.:-]{1,64}$/,nN=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function nS(e,t,r,i){if(!Number.isFinite(e)||!Number.isInteger(e)||e<r||e>i)throw new I("INVALID_ARGS",`${t} must be an integer between ${r} and ${i}`);return e}async function n_(e,t,r){for(let i=0;i<e;i+=1)await r(i),i<e-1&&t>0&&await nD(t)}async function nD(e){await new Promise(t=>setTimeout(t,e))}function nE(e,t){let r,i=t?.subject??"Payload",n=e.trim();if(!n)throw new I("INVALID_ARGS",`${i} cannot be empty`);let a=t?.expandPath?t.expandPath(n,t.cwd):n;try{if(!$.statSync(a).isFile())throw new I("INVALID_ARGS",`${i} path is not a file: ${a}`);return{kind:"file",path:a}}catch(t){if(t instanceof I)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new I("INVALID_ARGS",`${i} file is not readable: ${a}`);if(e&&"ENOENT"!==e)throw new I("COMMAND_FAILED",`Unable to read ${i} file: ${a}`,{cause:String(t)})}if((r=n.trim()).startsWith("{")&&r.endsWith("}")||r.startsWith("[")&&r.endsWith("]"))return{kind:"inline",text:n};throw new I("INVALID_ARGS",`${i} file not found: ${a}`)}async function nk(e){let t=nE(e,{subject:"Push payload"}),r="inline"===t.kind?t.text:await nO(t.path);try{let e=JSON.parse(r);if(!e||"object"!=typeof e||Array.isArray(e))throw new I("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof I)throw t;throw new I("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function nO(e){try{return await x.readFile(e,"utf8")}catch(r){let t=r.code;if("ENOENT"===t)throw new I("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new I("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new I("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new I("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(r)})}}let nL=ew(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),nM=/^(iphone|ipad|ipod|appletv)/i,nx=/^appletv/i,nC=["apple tv","appletv","tvos"];function nR(e){return(e??"").trim().toLowerCase()}function nT(e){return nR(e.hardwareProperties?.platform)}function nP(e){return e.includes("tvos")}function n$(e){return nP(nR(e))?"tv":"mobile"}function nF(e){let t=nR(e);return t.includes("ios")||t.includes("tvos")}function nV(e){let t=nR(e);return nC.some(e=>t.includes(e))}function nU(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function nG(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function nB(e={}){let t,r,i=ey(e.simulatorSetPath),n=e.target;try{t=await p("xcrun",eS(["list","devices","-j"],{simulatorSetPath:i}))}catch{return null}try{r=JSON.parse(t.stdout)}catch{return null}let a=null,o=null,s=null;for(let[e,t]of Object.entries(r.devices)){if(!nF(e))continue;let r=n$(e);if(!n||r===n)for(let e of t){if(!e.isAvailable)continue;let t={platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:r,booted:"Booted"===e.state,...i?{simulatorSetPath:i}:{}};t.booted&&(a=a??t),"mobile"===r&&(o=o??t),s=s??t}}return a??o??s}async function nj(e={}){if("darwin"!==process.platform)throw new I("UNSUPPORTED_PLATFORM","iOS tools are only available on macOS");if(!await A("xcrun"))throw new I("TOOL_MISSING","xcrun not found in PATH");let t=[],r=ey(e.simulatorSetPath),i=await p("xcrun",eS(["list","devices","-j"],{simulatorSetPath:r}));try{let e=JSON.parse(i.stdout);for(let[i,n]of Object.entries(e.devices))if(nF(i))for(let e of n)e.isAvailable&&t.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:n$(i),booted:"Booted"===e.state,...r?{simulatorSetPath:r}:{}})}catch(e){throw new I("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(r)return t;let a=null;try{a=n.join(V.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let e=await p("xcrun",["devicectl","list","devices","--json-output",a],{allowFailure:!0,timeoutMs:nL});if(0!==e.exitCode)return t;let r=await x.readFile(a,"utf8"),i=JSON.parse(r);for(let e of i.result?.devices??[])if(function(e){var t;let r=nT(e);return!!(r.includes("ios")||r.includes("tvos"))||(t=nG(e),!!nM.test(t.trim())||nU(e).some(nV))}(e)){let r=e.hardwareProperties?.udid??e.identifier??"",i=e.name??e.deviceProperties?.name??r;if(!r)continue;t.push({platform:"ios",id:r,name:i,kind:"device",target:function(e){var t;return nP(nT(e))?"tv":(t=nG(e),nx.test(t.trim())||nU(e).some(nV))?"tv":"mobile"}(e),booted:!0})}}catch{}finally{a&&await x.rm(a,{force:!0}).catch(()=>{})}return t}async function nq(e,t,r,i){let n,a=!!(t.udid||t.serial||t.deviceName);try{n=await i.selectDevice(e,t,r)}catch(e){if(a||!(e instanceof I)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!a&&(!n||"device"===n.kind)){let e=await i.findBootableSimulator({simulatorSetPath:r.simulatorSetPath,target:t.target});if(e)return e}if(n)return n;throw new I("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function nH(e){let t=ej(e.platform),r=ey(e.iosSimulatorDeviceSet),i=eN(e.androidDeviceAllowlist);return await L("resolve_target_device",async()=>{let n={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(n.target&&!n.platform)throw new I("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|android|apple with --target mobile|tv.");if("android"===n.platform){await t8();let e=await rc({serialAllowlist:i});return await eq(e,n)}if("ios"===n.platform){let e=await nj({simulatorSetPath:r});return await nq(e,n,{simulatorSetPath:r},{selectDevice:eq,findBootableSimulator:nB})}let a=[];try{a.push(...await rc({serialAllowlist:i}))}catch{}try{a.push(...await nj({simulatorSetPath:r}))}catch{}return await eq(a,n,{simulatorSetPath:r})},{platform:t,target:e.target})}async function nW(e,t,r,i,a){let o=function(e,t){switch(e.platform){case"android":return{open:(t,r)=>rL(e,t,r?.activity),openDevice:()=>rx(e),close:t=>rC(e,t),tap:(t,r)=>r1(e,t,r),doubleTap:async(t,r)=>{await r1(e,t,r),await r1(e,t,r)},swipe:(t,r,i,n,a)=>r2(e,t,r,i,n,a),longPress:(t,r,i)=>r5(e,t,r,i),focus:(t,r)=>r9(e,t,r),type:t=>r6(e,t),fill:(t,r,i)=>r7(e,t,r,i),scroll:(t,r)=>ie(e,t,r),scrollIntoView:t=>it(e,t),screenshot:(t,r)=>rX(e,t)};case"ios":var r,i;let n,a;return{open:(t,r)=>nt(e,t,{appBundleId:r?.appBundleId,url:r?.url}),openDevice:()=>nr(e),close:t=>ni(e,t),screenshot:(t,r)=>iJ(e,t,r),...(r=e,n={verbose:(i=t).verbose,logPath:i.logPath,traceLogPath:i.traceLogPath,requestId:i.requestId},a=()=>{if(es(i.requestId))throw el()},{tap:async(e,t)=>{await ta(r,{command:"tap",x:e,y:t,appBundleId:i.appBundleId},n)},doubleTap:async(e,t)=>{await ta(r,{command:"tapSeries",x:e,y:t,count:1,intervalMs:0,doubleTap:!0,appBundleId:i.appBundleId},n)},swipe:async(e,t,a,o,s)=>{await ta(r,{command:"drag",x:e,y:t,x2:a,y2:o,durationMs:s,appBundleId:i.appBundleId},n)},longPress:async(e,t,a)=>{await ta(r,{command:"longPress",x:e,y:t,durationMs:a,appBundleId:i.appBundleId},n)},focus:async(e,t)=>{await ta(r,{command:"tap",x:e,y:t,appBundleId:i.appBundleId},n)},type:async e=>{await ta(r,{command:"type",text:e,appBundleId:i.appBundleId},n)},fill:async(e,t,a)=>{await ta(r,{command:"tap",x:e,y:t,appBundleId:i.appBundleId},n),await ta(r,{command:"type",text:a,clearFirst:!0,appBundleId:i.appBundleId},n)},scroll:async(e,t)=>{if(!["up","down","left","right"].includes(e))throw new I("INVALID_ARGS",`Unknown direction: ${e}`);let a=function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left"}}(e);await ta(r,{command:"swipe",direction:a,appBundleId:i.appBundleId},n)},scrollIntoView:async e=>{let t=await ta(r,{command:"findText",text:e,appBundleId:i.appBundleId},n);if(t?.found)return{attempts:1};for(let t=0;t<12;t+=1){for(let e=0;e<4;e+=1)a(),await ta(r,{command:"swipe",direction:"up",appBundleId:i.appBundleId},n),await new Promise(e=>setTimeout(e,80));a();let o=await ta(r,{command:"findText",text:e,appBundleId:i.appBundleId},n);if(o?.found)return{attempts:t+2}}throw new I("COMMAND_FAILED",`scrollintoview could not find text: ${e}`)}})};default:throw new I("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,{requestId:a?.requestId,appBundleId:a?.appBundleId,verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath});return M({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await L("platform_command",async()=>{switch(t){case"open":{let t=r[0],i=r[1];if(r.length>2)throw new I("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!t)return await o.openDevice(),{app:null};if(void 0!==i){if("ios"!==e.platform)throw new I("INVALID_ARGS","open <app> <url> is supported only on iOS");if(t9(t))throw new I("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!t9(i))throw new I("INVALID_ARGS","open <app> <url> requires a valid URL target");return await o.open(t,{activity:a?.activity,appBundleId:a?.appBundleId,url:i}),{app:t,url:i}}return await o.open(t,{activity:a?.activity,appBundleId:a?.appBundleId}),{app:t}}case"close":{let e=r[0];if(!e)return{closed:"session"};return await o.close(e),{app:e}}case"press":{let[t,i]=r.map(Number);if(Number.isNaN(t)||Number.isNaN(i))throw new I("INVALID_ARGS","press requires x y");let n=nS(a?.count??1,"count",1,200),s=nS(a?.intervalMs??0,"interval-ms",0,1e4),l=nS(a?.holdMs??0,"hold-ms",0,1e4),d=nS(a?.jitterPx??0,"jitter-px",0,100),u=a?.doubleTap===!0;if(u&&l>0)throw new I("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(u&&d>0)throw new I("INVALID_ARGS","double-tap cannot be combined with jitter-px");if("ios"===e.platform&&n>1&&0===l&&0===d)return await ta(e,{command:"tapSeries",x:t,y:i,count:n,intervalMs:s,doubleTap:u,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x:t,y:i,count:n,intervalMs:s,holdMs:l,jitterPx:d,doubleTap:u,timingMode:"runner-series"};return await n_(n,s,async e=>{let[r,n]=function(e,t){if(t<=0)return[0,0];let[r,i]=nN[e%nN.length];return[r*t,i*t]}(e,d),a=t+r,s=i+n;u?await o.doubleTap(a,s):l>0?await o.longPress(a,s,l):await o.tap(a,s)}),{x:t,y:i,count:n,intervalMs:s,holdMs:l,jitterPx:d,doubleTap:u}}case"swipe":{let t=Number(r[0]),i=Number(r[1]),n=Number(r[2]),s=Number(r[3]);if([t,i,n,s].some(Number.isNaN))throw new I("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let l=nS(r[4]?Number(r[4]):250,"durationMs",16,1e4),d="ios"===e.platform?Math.min(60,Math.max(16,Math.round(l))):l,u=nS(a?.count??1,"count",1,200),c=nS(a?.pauseMs??0,"pause-ms",0,1e4),p=a?.pattern??"one-way";if("one-way"!==p&&"ping-pong"!==p)throw new I("INVALID_ARGS",`Invalid pattern: ${p}`);if("ios"===e.platform&&u>1)return await ta(e,{command:"dragSeries",x:t,y:i,x2:n,y2:s,durationMs:d,count:u,pauseMs:c,pattern:p,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{x1:t,y1:i,x2:n,y2:s,durationMs:l,effectiveDurationMs:d,timingMode:"runner-series",count:u,pauseMs:c,pattern:p};return await n_(u,c,async e=>{"ping-pong"===p&&e%2==1?await o.swipe(n,s,t,i,d):await o.swipe(t,i,n,s,d)}),{x1:t,y1:i,x2:n,y2:s,durationMs:l,effectiveDurationMs:d,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:u,pauseMs:c,pattern:p}}case"longpress":{let e=Number(r[0]),t=Number(r[1]),i=r[2]?Number(r[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new I("INVALID_ARGS","longpress requires x y [durationMs]");return await o.longPress(e,t,i),{x:e,y:t,durationMs:i}}case"focus":{let[e,t]=r.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new I("INVALID_ARGS","focus requires x y");return await o.focus(e,t),{x:e,y:t}}case"type":{let e=r.join(" ");if(!e)throw new I("INVALID_ARGS","type requires text");return await o.type(e),{text:e}}case"fill":{let e=Number(r[0]),t=Number(r[1]),i=r.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!i)throw new I("INVALID_ARGS","fill requires x y text");return await o.fill(e,t,i),{x:e,y:t,text:i}}case"scroll":{let e=r[0],t=r[1]?Number(r[1]):void 0;if(!e)throw new I("INVALID_ARGS","scroll requires direction");return await o.scroll(e,t),{direction:e,amount:t}}case"scrollintoview":{let e=r.join(" ").trim();if(!e)throw new I("INVALID_ARGS","scrollintoview requires text");let t=await o.scrollIntoView(e);if(t?.attempts)return{text:e,attempts:t.attempts};return{text:e}}case"pinch":{if("android"===e.platform)throw new I("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");let t=Number(r[0]),i=r[1]?Number(r[1]):void 0,n=r[2]?Number(r[2]):void 0;if(Number.isNaN(t)||t<=0)throw new I("INVALID_ARGS","pinch requires scale > 0");return await ta(e,{command:"pinch",scale:t,x:i,y:n,appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{scale:t,x:i,y:n}}case"trigger-app-event":{let{eventName:t,payload:i}=function(e){let t=e[0]?.trim(),r=e[1]?.trim();if(!t)throw new I("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!nb.test(t))throw new I("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new I("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let i=function(e,t){if(e)try{let r=JSON.parse(e);if(!r||"object"!=typeof r||Array.isArray(r))throw new I("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let i=JSON.stringify(r);if(Buffer.byteLength(i,"utf8")>8192)throw new I("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return r}catch(t){if(t instanceof I)throw t;throw new I("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(r,t);return{eventName:t,payload:i}}(r),n=function(e,t,r){let i,n=(i=("ios"===e?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,i?.trim()||void 0);if(!n)throw new I("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let a=r?JSON.stringify(r):"",o=n.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(a)).replaceAll("{platform}",encodeURIComponent(e));if(o.length>4096)throw new I("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:o.length,maxLength:4096});return o}(e.platform,t,i);return await o.open(n,{appBundleId:a?.appBundleId}),{event:t,eventUrl:n,transport:"deep-link"}}case"screenshot":{let e=r[0]??i??`./screenshot-${Date.now()}.png`;return await x.mkdir(n.dirname(e),{recursive:!0}),await o.screenshot(e,a?.appBundleId),{path:e}}case"back":if("ios"===e.platform)return await ta(e,{command:"back",appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{action:"back"};return await r3(e),{action:"back"};case"home":if("ios"===e.platform)return await ta(e,{command:"home",appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{action:"home"};return await r4(e),{action:"home"};case"app-switcher":if("ios"===e.platform)return await ta(e,{command:"appSwitcher",appBundleId:a?.appBundleId},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{action:"app-switcher"};return await r8(e),{action:"app-switcher"};case"clipboard":{let t=(r[0]??"").toLowerCase();if("read"!==t&&"write"!==t)throw new I("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===t){if(1!==r.length)throw new I("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:t,text:"ios"===e.platform?await ns(e):await ip(e)}}if(r.length<2)throw new I("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let i=r.slice(1).join(" ");return"ios"===e.platform?await nl(e,i):await im(e,i),{action:t,textLength:Array.from(i).length}}case"keyboard":{if("android"!==e.platform)throw new I("UNSUPPORTED_OPERATION","keyboard is currently supported only on Android");let t=(r[0]??"status").toLowerCase();if("status"!==t&&"get"!==t&&"dismiss"!==t)throw new I("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(r.length>1)throw new I("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("dismiss"===t){let t=await ic(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type}}let i=await iu(e);return{platform:"android",action:"status",visible:i.visible,inputType:i.inputType,type:i.type}}case"settings":{let[t,i,n,o,s]=r,l="permission"===t?{permissionTarget:n,permissionMode:o}:void 0;if(M({level:"debug",phase:"settings_apply",data:{setting:t,state:i,target:n,mode:o,platform:e.platform}}),"ios"===e.platform)return await nu(e,t,i,s??a?.appBundleId,l),{setting:t,state:i};return await iA(e,t,i,s??a?.appBundleId,l),{setting:t,state:i}}case"push":{let t=r[0]?.trim(),i=r[1]?.trim();if(!t||!i)throw new I("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let n=await nk(i);if("ios"===e.platform)return await nd(e,t,n),{platform:"ios",bundleId:t};let a=await iE(e,t,n);return{platform:"android",package:t,action:a.action,extrasCount:a.extrasCount}}case"snapshot":{if("ios"===e.platform){let t=await L("snapshot_capture",async()=>await ta(e,{command:"snapshot",appBundleId:a?.appBundleId,interactiveOnly:a?.snapshotInteractiveOnly,compact:a?.snapshotCompact,depth:a?.snapshotDepth,scope:a?.snapshotScope,raw:a?.snapshotRaw},{verbose:a?.verbose,logPath:a?.logPath,traceLogPath:a?.traceLogPath,requestId:a?.requestId}),{backend:"xctest"}),r=t.nodes??[];if(0===r.length&&"simulator"===e.kind)throw new I("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:r,truncated:t.truncated??!1,backend:"xctest"}}let t=await L("snapshot_capture",async()=>await rz(e,{interactiveOnly:a?.snapshotInteractiveOnly,compact:a?.snapshotCompact,depth:a?.snapshotDepth,scope:a?.snapshotScope,raw:a?.snapshotRaw}),{backend:"android"});return{nodes:t.nodes??[],truncated:t.truncated??!1,backend:"android"}}default:throw new I("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}let nJ={alert:{ios:{simulator:!0},android:{}},pinch:{ios:{simulator:!0},android:{}},"app-switcher":{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},apps:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},back:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},boot:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},click:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},clipboard:{ios:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0}},keyboard:{ios:{},android:{emulator:!0,device:!0,unknown:!0}},close:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},fill:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},diff:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},find:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},focus:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},get:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},is:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},home:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},logs:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},network:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},longpress:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},open:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},perf:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},install:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},reinstall:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},press:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},push:{ios:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0}},record:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},screenshot:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},scroll:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},scrollintoview:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},swipe:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},settings:{ios:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0}},snapshot:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},"trigger-app-event":{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},type:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},wait:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}}};function nz(e,t){let r=nJ[e];if(!r)return!0;let i=r[t.platform];return!!i&&!0===i[t.kind??"unknown"]}function nK(e,t,r,i,n){return{requestId:n??O().requestId,appBundleId:r,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:i,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,count:t?.count,intervalMs:t?.intervalMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,doubleTap:t?.doubleTap,pauseMs:t?.pauseMs,pattern:t?.pattern}}let nX=ew(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function nY(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve().then(()=>({ensureBootedSimulator:iB}));await t(e);return}if("device"===e.kind)return void await nZ(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve().then(()=>({waitForAndroidBoot:rI}));await t(e.id)}}async function nZ(e){let t=n.join(V.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=Math.max(1,Math.ceil(nX/1e3));try{let i=await p("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(r)],{allowFailure:!0,timeoutMs:nX+3e3}),n=String(i.stdout??""),a=String(i.stderr??""),o=await nQ(t);if(0===i.exitCode){if(!o.parsed)throw new I("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:n,stderr:a,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new I("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new I("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:n,stderr:a,exitCode:i.exitCode,tunnelState:o?.tunnelState,hint:n0(n,a)})}catch(t){if(t instanceof I&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let r=t.details??{},i=String(r.stdout??""),n=String(r.stderr??""),a=Number(r.timeoutMs??nX),o=`CoreDevice did not respond within ${a}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new I("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:a,stdout:i,stderr:n,hint:i||n?n0(i,n):o},t)}throw new I("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await x.rm(t,{force:!0}).catch(()=>{})}}async function nQ(e){try{let t=await x.readFile(e,"utf8"),r=JSON.parse(t),i=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let r=t.connectionProperties?.tunnelState,i=t.device?.connectionProperties?.tunnelState,n="string"==typeof r?r:"string"==typeof i?i:void 0;return n?{tunnelState:n}:{}}(r);return{parsed:!0,tunnelState:i.tunnelState}}catch{return{parsed:!1}}}function n0(e,t){let r=i$(e,t);return r||(`${e}
31
- ${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":iP)}function n1(e){return e.map((e,t)=>({...e,ref:`e${t+1}`}))}function n2(e){let t=e.trim();return t.startsWith("@")?t.slice(1)||null:t.startsWith("e")?t:null}function n3(e,t){return e.find(e=>e.ref===t)??null}function n4(e){return{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}function n8(e,t){let r=t.toLowerCase();return e.find(e=>{let t=(e.label??"").toLowerCase(),i=(e.value??"").toLowerCase(),n=(e.identifier??"").toLowerCase();return t.includes(r)||i.includes(r)||n.includes(r)})??null}function n5(e,t){let r=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);return r&&n6(r)?r:function(e,t){if(!e.rect)return;let r=e.rect.y+e.rect.height/2,i=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);if(!t||!n6(t))continue;let n=Math.abs(e.rect.y+e.rect.height/2-r);(!i||n<i.distance)&&(i={label:t,distance:n})}return i?.label}(e,t)??(r&&n6(r)?r:void 0)}function n6(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function n9(e){let t=[],r=[];for(let i of e){let e=i.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let n=n7(i.type??""),a=[i.label,i.value,i.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0),o=!!a&&n6(a);if(("group"===n||"ioscontentgroup"===n)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);r.push({...i,depth:s})}return r}function n7(e){let t=e.trim().replace(/XCUIElementType/gi,"").toLowerCase(),r=Math.max(t.lastIndexOf("."),t.lastIndexOf("/"));return -1!==r&&(t=t.slice(r+1)),t}function ae(e,t){let r=n7(e);return!r||("android"===t?r.includes("edittext")||r.includes("autocompletetextview"):r.includes("textfield")||r.includes("securetextfield")||r.includes("searchfield")||r.includes("textview")||r.includes("textarea")||"search"===r)}function at(e){return[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").filter(e=>e.length>0)[0]??""}let ar=new Set(["id","role","text","label","value"]),ai=new Set(["visible","hidden","editable","selected","enabled","hittable"]),an=new Set([...ar,...ai]);function aa(e){let t=e.trim();if(!t)throw new I("INVALID_ARGS","Selector expression cannot be empty");let r=function(e){let t=[],r="",i=null;for(let n=0;n<e.length;n+=1){let a=e[n];if(('"'===a||"'"===a)&&!aN(e,n)){i?i===a&&(i=null):i=a,r+=a;continue}if(!i&&"|"===a&&"|"===e[n+1]){let i=r.trim();if(!i)throw new I("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);t.push(i),r="",n+=1;continue}r+=a}let n=r.trim();if(!n)throw new I("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);return t.push(n),t}(t);if(0===r.length)throw new I("INVALID_ARGS","Selector expression cannot be empty");return{raw:t,selectors:r.map(e=>(function(e){let t=e.trim();if(!t)throw new I("INVALID_ARGS","Selector segment cannot be empty");let r=function(e){let t=[],r="",i=null;for(let n=0;n<e.length;n+=1){let a=e[n];if(('"'===a||"'"===a)&&!aN(e,n)){i?i===a&&(i=null):i=a,r+=a;continue}if(!i&&/\s/.test(a)){r.trim().length>0&&t.push(r.trim()),r="";continue}r+=a}if(i)throw new I("INVALID_ARGS",`Unclosed quote in selector: ${e}`);return r.trim().length>0&&t.push(r.trim()),t}(t);if(0===r.length)throw new I("INVALID_ARGS",`Invalid selector segment: ${e}`);return{raw:t,terms:r.map(ah)}})(e))}}function ao(e){try{return aa(e)}catch{return null}}function as(e,t,r){let i=r.requireRect??!1,n=r.requireUnique??!0,a=r.disambiguateAmbiguous??!1,o=[];for(let s=0;s<t.selectors.length;s+=1){let l=t.selectors[s],d=function(e,t,r){let i=0,n=null,a=null,o=!1;for(let s of e){if(r.requireRect&&!s.rect||!aw(s,t,r.platform))continue;if(i+=1,n||(n=s),!a){a=s;continue}let e=function(e,t){let r=e.depth??0,i=t.depth??0;if(r!==i)return r>i?1:-1;let n=ab(e),a=ab(t);return n!==a?n<a?1:-1:0}(s,a);if(e>0){a=s,o=!1;continue}0===e&&(o=!0)}return{count:i,firstNode:n,disambiguated:o?null:a}}(e,l,{platform:r.platform,requireRect:i});if(o.push({selector:l.raw,matches:d.count}),0!==d.count&&d.firstNode){if(n&&1!==d.count){if(!a)continue;let e=d.disambiguated;if(!e)continue;return{node:e,selector:l,selectorIndex:s,matches:d.count,diagnostics:o}}return{node:d.firstNode,selector:l,selectorIndex:s,matches:d.count,diagnostics:o}}}return null}function al(e,t,r){let i=r.requireRect??!1,n=[];for(let a=0;a<t.selectors.length;a+=1){let o=t.selectors[a],s=function(e,t,r){let i=0;for(let n of e)(!r.requireRect||n.rect)&&aw(n,t,r.platform)&&(i+=1);return i}(e,o,{platform:r.platform,requireRect:i});if(n.push({selector:o.raw,matches:s}),s>0)return{selectorIndex:a,selector:o,matches:s,diagnostics:n}}return null}function ad(e,t,r){let i=r.unique??!0;if(0===t.length)return`Selector did not match: ${e.raw}`;let n=t.map(e=>`${e.selector} -> ${e.matches}`).join(", ");return i?`Selector did not resolve uniquely (${n})`:`Selector did not match (${n})`}function au(e,t={}){if(0===e.length)return null;let r=t.preferTrailingValue??!1,i=0,n=[];for(;i<e.length&&function(e){let t=e.trim();if(!t)return!1;if("||"===t)return!0;let r=t.indexOf("=");if(-1!==r){let e=t.slice(0,r).trim().toLowerCase();return an.has(e)}return an.has(t.toLowerCase())}(e[i]);){i+=1;let t=e.slice(0,i).join(" ").trim();t&&ao(t)&&n.push(i)}if(0===n.length)return null;let a=n[n.length-1];if(r){for(let t=n.length-1;t>=0;t-=1)if(n[t]<e.length){a=n[t];break}}let o=e.slice(0,a).join(" ").trim();return o?{selectorExpression:o,rest:e.slice(a)}:null}function ac(e){let t=e[0]??"",r=au(e.slice(1),{preferTrailingValue:"text"===t});return{predicate:t,split:r}}function ap(e){return!0===e.hittable||!!e.rect&&e.rect.width>0&&e.rect.height>0}function af(e,t){return ae(e.type??"",t)&&!1!==e.enabled}function am(e,t,r={}){let i=[],n=n7(e.type??""),a=ay(e.identifier),o=ay(e.label),s=ay(e.value),l=ay(at(e)),d="fill"===r.action;a&&i.push(`id=${aA(a)}`),n&&o&&i.push(d?`role=${aA(n)} label=${aA(o)} editable=true`:`role=${aA(n)} label=${aA(o)}`),o&&i.push(d?`label=${aA(o)} editable=true`:`label=${aA(o)}`),s&&i.push(d?`value=${aA(s)} editable=true`:`value=${aA(s)}`),l&&l!==o&&l!==s&&i.push(d?`text=${aA(l)} editable=true`:`text=${aA(l)}`),n&&d&&!i.some(e=>e.includes("editable=true"))&&i.push(`role=${aA(n)} editable=true`);let u=tl(i);return 0===u.length&&n&&u.push(d?`role=${aA(n)} editable=true`:`role=${aA(n)}`),0===u.length&&ap(e)&&u.push("visible=true"),u}function ah(e){let t=e.trim();if(!t)throw new I("INVALID_ARGS","Empty selector term");let r=t.indexOf("=");if(-1===r){let r=t.toLowerCase();if(!ai.has(r))throw new I("INVALID_ARGS",`Invalid selector term "${e}", expected key=value`);return{key:r,value:!0}}let i=t.slice(0,r).trim().toLowerCase(),n=t.slice(r+1).trim();if(!an.has(i))throw new I("INVALID_ARGS",`Unknown selector key: ${i}`);if(!n)throw new I("INVALID_ARGS",`Missing selector value for key: ${i}`);if(ai.has(i)){let e,t="true"===(e=ag(n).toLowerCase())||"false"!==e&&null;if(null===t)throw new I("INVALID_ARGS",`Invalid boolean value for ${i}: ${n}`);return{key:i,value:t}}return{key:i,value:ag(n)}}function aw(e,t,r){return t.terms.every(t=>(function(e,t,r){switch(t.key){case"id":return aI(e.identifier,String(t.value));case"role":var i,n;return i=e.type,n=String(t.value),function(e){return n7(e)}(i??"")===function(e){return n7(e)}(n);case"label":return aI(e.label,String(t.value));case"value":return aI(e.value,String(t.value));case"text":{let r=av(String(t.value));return av(at(e))===r}case"visible":return ap(e)===!!t.value;case"hidden":return!ap(e)==!!t.value;case"editable":return af(e,r)===!!t.value;case"selected":return!0===e.selected==!!t.value;case"enabled":return!1!==e.enabled==!!t.value;case"hittable":return!0===e.hittable==!!t.value;default:return!1}})(e,t,r))}function ag(e){let t=e.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\(["'])/g,"$1"):t}function aI(e,t){return av(e??"")===av(t)}function av(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function aA(e){return JSON.stringify(e)}function ay(e){if(!e)return null;let t=e.trim();return t||null}function ab(e){return e.rect?e.rect.width*e.rect.height:1/0}function aN(e,t){let r=0;for(let i=t-1;i>=0&&"\\"===e[i];i-=1)r+=1;return r%2==1}let aS=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b","i"),a_=/https?:\/\/[^\s"'<>\])]+/i,aD=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function aE(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function ak(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return aO(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),i=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(i?.[1])return i[1].trim()}}function aO(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function aL(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function aM(e,t,r,i){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(i,e)):t}let ax="shared_prefs/ReactNativeDevPrefs.xml",aC="debug_http_host",aR="dev_server_https",aT="RCT_jsLocation",aP="RCT_packager_scheme",a$="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",aF='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function aV(e){return void 0!==aU(e)}function aU(e){if(!e)return;let t=aZ(e.metroHost),r=aQ(e.metroPort),i="http",n=aZ(e.bundleUrl);if(n){var a;let e;try{e=new v(n)}catch(e){throw new I("INVALID_ARGS",`Invalid runtime bundle URL: ${n}`,{},e)}("http:"===e.protocol||"https:"===e.protocol)&&(t??=aZ(e.hostname),r??=aQ(e.port.length>0?Number(e.port):"https:"===(a=e.protocol)?443:"http:"===a?80:void 0),i="https:"===e.protocol?"https":"http")}if(t&&r)return{host:t,port:r,scheme:i}}async function aG(e){let{device:t,appId:r,runtime:i}=e;if(!r)return;let n=aU(i);if(n){if("android"===t.platform)return void await aj(t,r,n);"ios"===t.platform&&"simulator"===t.kind&&await aJ(t,r,n)}}async function aB(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await aq(t,r);"ios"===t.platform&&"simulator"===t.kind&&await az(t,r)}}async function aj(e,t,r){var i,n,a,o,s,l;let d,u,c=(i=await aH(e,t),n=aC,a=`${r.host}:${r.port}`,d=` <string name="${a0(n)}">${a0(a)}</string>`,aX(aY(i,n),d));o=c,s=aR,l="https"===r.scheme,u=` <boolean name="${a0(s)}" value="${l?"true":"false"}" />`,c=aX(aY(o,s),u),await aW(e,t,c)}async function aq(e,t){let r=await aH(e,t),i=aY(r,aC),n=aY(i,aR);n!==r&&await aW(e,t,n)}async function aH(e,t){let r=await p("adb",t4(e,["shell","run-as",t,"cat",ax]),{allowFailure:!0});return 0!==r.exitCode?aF:aK(r.stdout)}async function aW(e,t,r){let i=t4(e,["shell","run-as",t,"id"]),n=await p("adb",i,{allowFailure:!0});if(0!==n.exitCode){let e=a1(n.stdout,n.stderr);throw new I("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:i,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode,hint:e?a$:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await p("adb",t4(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await p("adb",t4(e,["shell","run-as",t,"tee",ax]),{stdin:r.trimEnd()})}catch(i){let e=w(i);if("TOOL_MISSING"===e.code)throw e;let r=a1("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new I("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?a$:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function aJ(e,t,r){await p("xcrun",e_(e,["spawn",e.id,"defaults","write",t,aT,"-string",`${r.host}:${r.port}`])),await p("xcrun",e_(e,["spawn",e.id,"defaults","write",t,aP,"-string",r.scheme]))}async function az(e,t){await p("xcrun",e_(e,["spawn",e.id,"defaults","delete",t,aT]),{allowFailure:!0}),await p("xcrun",e_(e,["spawn",e.id,"defaults","delete",t,aP]),{allowFailure:!0})}function aK(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
32
- `:aF}function aX(e,t){return aK(e).replace("</map>",`${t}
33
- </map>`)}function aY(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return aK(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function aZ(e){let t=e?.trim();return t&&t.length>0?t:void 0}function aQ(e){if(Number.isInteger(e)&&!(e<=0)&&!(e>65535))return e}function a0(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function a1(e,t){let r=`${e}
34
- ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}function a2(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),i=au(r?e.slice(0,-1):e.slice());return!i||i.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:i.selectorExpression,selectorTimeout:r?t:null}}function a3(e){return!!e&&!Number.isNaN(Number(e))}async function a4(e){let t,r,i,{deviceName:n,runtime:a,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new I("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await a8({deviceName:n,runtime:a,simctlOpts:u});e?(t=e.udid,r=e.runtime,i=!1):(t=(await a5({deviceName:n,runtime:a,simctlOpts:u})).udid,r=await a6(t,u),i=!0)}else t=(await a5({deviceName:n,runtime:a,simctlOpts:u})).udid,r=await a6(t,u),i=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:n,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:n,runtime:r,created:i,booted:c}}async function a8(e){let{deviceName:t,runtime:r,simctlOpts:i}=e,n=await p("xcrun",eS(["list","devices","-j"],i),{allowFailure:!0,timeoutMs:iO});if(0!==n.exitCode)return null;try{let e=JSON.parse(String(n.stdout??""));for(let[i,n]of Object.entries(e.devices??{}))if(!r||a9(i).includes(a9(r))){for(let e of n)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:i}}return null}catch{return null}}async function a5(e){let{deviceName:t,runtime:r,simctlOpts:i}=e,n=r?["create",t,t,r]:["create",t,t],a=await p("xcrun",eS(n,i),{allowFailure:!0});if(0!==a.exitCode)throw new I("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(a.stdout??""),stderr:String(a.stderr??""),exitCode:a.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(a.stdout??"").trim();if(!o)throw new I("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(a.stdout??""),stderr:String(a.stderr??"")});return{udid:o}}async function a6(e,t){let r=await p("xcrun",eS(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:iO});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,i]of Object.entries(t.devices??{}))if(i.some(t=>t.udid===e))return r;return""}catch{return""}}function a9(e){return e.toLowerCase().replace(/[._-]/g,"")}let a7='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',oe=["platform","target","device","udid","serial","verbose","out"],ot=["platform","target","device","udid","serial","verbose","out"],or=["path","start","stop","doctor","mark","clear"],oi=`logs requires ${or.slice(0,-1).join(", ")}, or ${or.at(-1)}`,on="Not implemented for this platform in this release.",oa="open-command-roundtrip",oo=ew(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),os=ew(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function ol(e){let{sessionName:t,appName:r,appBundleId:i,startup:n,device:a,runtime:o}=e,s={session:t};return r&&(s.appName=r),i&&(s.appBundleId=i),n&&(s.startup=n),o&&od(o)>0&&(s.runtime=o),a?.platform==="ios"&&(s.device_udid=a.id,s.ios_simulator_device_set=a.simulatorSetPath??null),s}function od(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function ou(e){let t=e?.trim();return t&&t.length>0?t:void 0}function oc(e,t,r){let i=e.getRuntimeHints(t);if(i){if(i.platform&&r&&i.platform!==r.platform)throw new I("INVALID_ARGS",`Session runtime hints target ${i.platform}, but session "${t}" is bound to ${r.platform}. Clear the runtime hints or use a different session.`);return r?.platform&&i.platform!==r.platform?{...i,platform:r.platform}:i}}async function op(e){let{runtime:t,device:r,dispatch:i,req:n,logPath:a,appBundleId:o,traceLogPath:s,openPositionals:l}=e,d=t?.launchUrl;if(!d||0===l.length||l.length>1)return;let u=l[0]?.trim();!u||t9(u)||await i(r,"open",[d],n.flags?.out,{...nK(a,n.flags,o,s)})}function of(e,t,r){return{durationMs:Math.max(0,Date.now()-e),measuredAt:new Date().toISOString(),method:oa,appTarget:t,appBundleId:r}}let om=["dump","log"],oh=`network requires ${om.join(" or ")}`,ow=["summary","headers","body","all"],og=`network include mode must be one of: ${ow.join(", ")}`;function oI(e,t,r){return t||ov(r)?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} requires an active session or an explicit device selector (e.g. --platform ios).`}}}function ov(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function oA(e){return"ios"===e.platform&&"simulator"===e.kind}async function oy(e,t){oA(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function ob(e){let{device:t,closeTarget:r,stopIosRunner:i,dispatch:n,outFlag:a,context:o,settleSimulator:s}=e;"ios"===t.platform&&await i(t.id),await n(t,"close",[r],a,o),await s(t,oo)}async function oN(e){let t=ov(e.flags)||!e.session?await e.resolveTargetDeviceFn(e.flags??{}):e.session.device;return!1!==e.ensureReady&&await e.ensureReadyFn(t),t}function oS(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let o_=async({avdName:e,serial:t,headless:r})=>{let{ensureAndroidEmulatorBooted:i}=await Promise.resolve().then(()=>({ensureAndroidEmulatorBooted:rg}));return await i({avdName:e,serial:t,headless:r})};async function oD(e){let{req:t,sessionName:r,logPath:i,sessionStore:n,ensureReady:a,resolveDevice:o,dispatch:s,command:l,positionals:d,recordPositionals:u,deriveNextSession:c}=e,p=n.get(r),f=t.flags??{},m=oI(l,p,f);if(m)return m;let h=await oN({session:p,flags:f,ensureReadyFn:a,resolveTargetDeviceFn:o,ensureReady:!0});if(!nz(l,h))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${l} is not supported on this device`}};let w=await s(h,l,d,t.flags?.out,{...nK(i,t.flags,p?.appBundleId,p?.trace?.outPath)});if(p){let e=c?await c(p,w,h):p;n.recordAction(e,{command:l,positionals:u??d,flags:t.flags??{},result:w??{}}),e!==p&&n.set(r,e)}return{ok:!0,data:w??{}}}let oE={ios:async(e,t,r)=>{let{reinstallIosApp:i}=await Promise.resolve().then(()=>({reinstallIosApp:no}));return await i(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:i}=await Promise.resolve().then(()=>({reinstallAndroidApp:rG}));return await i(e,t,r)}},ok={ios:async(e,t,r)=>{let{installIosApp:i}=await Promise.resolve().then(()=>({installIosApp:na}));await i(e,r,{appIdentifierHint:t});let{bundleId:n}=await oC(e,t);return n?{bundleId:n}:{}},android:async(e,t,r)=>{let{installAndroidApp:i}=await Promise.resolve().then(()=>({installAndroidApp:rU}));await i(e,r);let{package:n}=await oC(e,t);return n?{package:n}:{}}};async function oO(e){let{req:t,command:r,sessionName:i,sessionStore:n,ensureReady:a,resolveDevice:o,deployOps:s}=e,l=n.get(i),d=t.flags??{},u=oI(r,l,d);if(u)return u;let c=t.positionals?.[0]?.trim(),p=t.positionals?.[1]?.trim();if(!c||!p)return{ok:!1,error:{code:"INVALID_ARGS",message:`${r} requires: ${r} <app> <path-to-app-binary>`}};let f=t.meta?.uploadedArtifactId;try{let e,i=f?function(e,t){let r=tT.get(e);if(!r)throw new I("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new I("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}(f,t.meta?.tenantId):tw.expandHome(p);if(!$.existsSync(i))return{ok:!1,error:{code:"INVALID_ARGS",message:`App binary not found: ${i}`}};let u=await oN({session:l,flags:d,ensureReadyFn:a,resolveTargetDeviceFn:o,ensureReady:!1});if(!nz(r,u))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${r} is not supported on this device`}};if("ios"===u.platform){let t=(await s.ios(u,c,i)).bundleId;e=t?{app:c,appPath:i,platform:"ios",appId:t,bundleId:t}:{app:c,appPath:i,platform:"ios"}}else{let t=(await s.android(u,c,i)).package;e=t?{app:c,appPath:i,platform:"android",appId:t,package:t}:{app:c,appPath:i,platform:"android"}}return l&&n.recordAction(l,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:e}),{ok:!0,data:e}}finally{f&&tP(f)}}async function oL(e,t,r){if("ios"===e.platform&&t)return t9(t)?"device"===e.kind?t7(r,t):void 0:await oM(e,t)}async function oM(e,t){try{let{resolveIosApp:r}=await Promise.resolve().then(()=>({resolveIosApp:ne}));return await r(e,t)}catch{return}}async function ox(e,t){if(!("android"!==e.platform||!t||t9(t)))try{let{resolveAndroidApp:r}=await Promise.resolve().then(()=>({resolveAndroidApp:rN})),i=await r(e,t);return"package"===i.type?i.value:void 0}catch{return}}async function oC(e,t){return"ios"===e.platform?{bundleId:await oM(e,t)}:{package:await ox(e,t)}}async function oR(e,t,r,i){return await oL(e,t,r)??await i(e,t)??("android"===e.platform&&t&&t9(t)?r:void 0)}async function oT(e){let{req:t,sessionName:r,sessionStore:i,ensureReady:n,resolveDevice:a}=e,o=i.get(r),s=t.flags??{},l=ej(s.platform);if(!o&&"string"==typeof s?.session&&s.session.trim().length>0)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"ios"===l?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`}};let d=oI("appstate",o,s);if(d)return d;let u=o?.device.platform==="ios"&&function(e,t){if(!t)return!1;if(!ov(e))return!0;let r=ej(e?.platform);return!(r&&r!==t.device.platform||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(s,o);if("ios"===l&&!u)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:a7}};if(u){let e=o.appName??o.appBundleId;return o.appName||o.appBundleId?{ok:!0,data:{platform:"ios",appName:e??"unknown",appBundleId:o.appBundleId,source:"session",device_udid:o.device.id,ios_simulator_device_set:o.device.simulatorSetPath??null}}:{ok:!1,error:{code:"COMMAND_FAILED",message:"No foreground app is tracked for this iOS session. Open an app in the session, then retry appstate."}}}let c=await oN({session:o,flags:s,ensureReadyFn:n,resolveTargetDeviceFn:a,ensureReady:!0});if("ios"===c.platform)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:a7}};let{getAndroidAppState:p}=await Promise.resolve().then(()=>({getAndroidAppState:rk})),f=await p(c);return{ok:!0,data:{platform:"android",package:f.package,activity:f.activity}}}async function oP(e){let{req:t,sessionName:r,logPath:i,sessionStore:n,ensureReady:a,resolveDevice:o,dispatch:s}=e,l=n.get(r),d=t.flags??{},u=oI("clipboard",l,d);if(u)return u;let c=(t.positionals?.[0]??"").toLowerCase();if("read"!==c&&"write"!==c)return{ok:!1,error:{code:"INVALID_ARGS",message:"clipboard requires a subcommand: read or write"}};let p=await oN({session:l,flags:d,ensureReadyFn:a,resolveTargetDeviceFn:o,ensureReady:!0});if(!nz("clipboard",p))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"clipboard is not supported on this device"}};let f=await s(p,"clipboard",t.positionals??[],t.flags?.out,{...nK(i,t.flags,l?.appBundleId,l?.trace?.outPath)});return l&&n.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:f??{}}),{ok:!0,data:{platform:p.platform,...f??{}}}}async function o$(e){var t,r;let{req:i,sessionName:n,logPath:a,sessionStore:o,invoke:s,dispatch:l,ensureReady:d,resolveTargetDevice:u,installOps:c=ok,reinstallOps:p=oE,stopIosRunner:f,appLogOps:m={start:tO,stop:tL},ensureAndroidEmulatorBoot:h=o_,resolveAndroidPackageForOpen:g=ox,applyRuntimeHints:v=aG,clearRuntimeHints:A=aB,settleSimulator:y,shutdownSimulator:b}=e,N=l??nW,S=d??nY,D=u??nH,E=f??e9,k=y??oy,O=i.command;if("session_list"===O)return{ok:!0,data:{sessions:o.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",device:e.device.name,id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("runtime"===O){let e,a=(i.positionals?.[0]??"show").toLowerCase(),s=o.get(n),l=o.getRuntimeHints(n);if(!["set","show","clear"].includes(a))return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime requires set, show, or clear"}};if("clear"===a){aV(l)&&s?.appBundleId&&await A({device:s.device,appId:s.appBundleId});let e=o.clearRuntimeHints(n);return{ok:!0,data:{session:n,cleared:e}}}if("show"===a)return{ok:!0,data:{session:n,configured:!!l,runtime:l}};let d=ej(i.flags?.platform)??l?.platform??s?.device.platform;if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set requires --platform when the session has not been opened yet."}};if(s&&s.device.platform!==d)return{ok:!1,error:{code:"INVALID_ARGS",message:`runtime set targets ${d}, but session "${n}" is already bound to ${s.device.platform}.`}};let u={platform:(t=i.flags,e=t?.metroPort,r={platform:d,metroHost:ou(t?.metroHost),metroPort:Number.isInteger(e)?e:void 0,bundleUrl:ou(t?.bundleUrl),launchUrl:ou(t?.launchUrl)}).platform??l?.platform,metroHost:r.metroHost??l?.metroHost,metroPort:r.metroPort??l?.metroPort,bundleUrl:r.bundleUrl??l?.bundleUrl,launchUrl:r.launchUrl??l?.launchUrl};return 0===od(u)?{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."}}:(o.setRuntimeHints(n,u),{ok:!0,data:{session:n,configured:!0,runtime:u}})}if("ensure-simulator"===O)try{let e=i.flags??{},t=e.device,r=e.runtime,n=ey(e.iosSimulatorDeviceSet);if(!t)return{ok:!1,error:{code:"INVALID_ARGS",message:"ensure-simulator requires --device <name>"}};let a=!0===e.boot,o=!1!==e.reuseExisting,s=await a4({deviceName:t,runtime:r,simulatorSetPath:n,reuseExisting:o,boot:a,ensureReady:S});return{ok:!0,data:{udid:s.udid,device:s.device,runtime:s.runtime,ios_simulator_device_set:n??null,created:s.created,booted:s.booted}}}catch(t){let e=w(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("devices"===O)try{let e=[],t=ey(i.flags?.iosSimulatorDeviceSet),r=eN(i.flags?.androidDeviceAllowlist),n=ej(i.flags?.platform);if("android"===n){let{listAndroidDevices:t}=await Promise.resolve().then(()=>({listAndroidDevices:rc}));e.push(...await t({serialAllowlist:r}))}else if("ios"===n){let{listIosDevices:r}=await Promise.resolve().then(()=>({listIosDevices:nj}));e.push(...await r({simulatorSetPath:t}))}else{let{listAndroidDevices:i}=await Promise.resolve().then(()=>({listAndroidDevices:rc})),{listIosDevices:n}=await Promise.resolve().then(()=>({listIosDevices:nj}));try{e.push(...await i({serialAllowlist:r}))}catch{}try{e.push(...await n({simulatorSetPath:t}))}catch{}}let a=(i.flags?.target?e.filter(e=>(e.target??"mobile")===i.flags?.target):e).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:a}}}catch(t){let e=w(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("apps"===O){let e=o.get(n),t=i.flags??{},r=oI(O,e,t);if(r)return r;let a=await oN({session:e,flags:t,ensureReadyFn:S,resolveTargetDeviceFn:D,ensureReady:!0});if(!nz("apps",a))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"apps is not supported on this device"}};let s=i.flags?.appsFilter??"all";if("ios"===a.platform){let{listIosApps:e}=await Promise.resolve().then(()=>({listIosApps:nc}));return{ok:!0,data:{apps:(await e(a,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await Promise.resolve().then(()=>({listAndroidApps:rS}));return{ok:!0,data:{apps:(await l(a,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}if("boot"===O){let e,t=o.get(n),r=i.flags??{},a=oI(O,t,r);if(a)return a;let s="android"===(ej(r.platform)??t?.device.platform),l=!0===r.headless;if(l&&!s)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};let d=oS({flags:r,sessionDevice:t?.device}),u=s&&!!d,c=!1;try{e=await oN({session:t,flags:r,ensureReadyFn:S,resolveTargetDeviceFn:D,ensureReady:!1})}catch(i){let t=w(i);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw i;e=await h({avdName:d,serial:r.serial,headless:l}),c=!0}if(r.target&&(e.target??"mobile")!==r.target)return{ok:!1,error:{code:"DEVICE_NOT_FOUND",message:`No ${e.platform} device found matching --target ${r.target}.`}};if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};if(!c){let i=oS({flags:r,sessionDevice:t?.device,resolvedDevice:e});if(!i)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};e=await h({avdName:i,serial:r.serial,headless:!0})}await S(e)}else("android"!==e.platform||!0!==e.booted)&&await S(e);return nz("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"boot is not supported on this device"}}}if("appstate"===O)return await oT({req:i,sessionName:n,sessionStore:o,ensureReady:S,resolveDevice:D});if("clipboard"===O)return await oP({req:i,sessionName:n,logPath:a,sessionStore:o,ensureReady:S,resolveDevice:D,dispatch:N});if("keyboard"===O)return await oD({req:i,sessionName:n,logPath:a,sessionStore:o,ensureReady:S,resolveDevice:D,dispatch:N,command:"keyboard",positionals:i.positionals??[]});if("perf"===O){let e,t,r,i=o.get(n);return i?{ok:!0,data:(r=(t=(e=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===oa&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:oa,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}(i.actions)).at(-1))?{available:!0,lastDurationMs:t.durationMs,lastMeasuredAt:t.measuredAt,method:oa,sampleCount:e.length,samples:e}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:oa},{session:i.name,platform:i.device.platform,device:i.device.name,deviceId:i.device.id,metrics:{startup:r,fps:{available:!1,reason:on},memory:{available:!1,reason:on},cpu:{available:!1,reason:on}},sampling:{startup:{method:oa,description:"Elapsed wall-clock time around dispatching the open command for the active session app target.",unit:"ms"}}})}:{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"perf requires an active session. Run open first."}}}if("install"===O||"reinstall"===O)return await oO({req:i,command:O,sessionName:n,sessionStore:o,ensureReady:S,resolveDevice:D,deployOps:"install"===O?c:p});if("push"===O){let e,t=i.positionals?.[0]?.trim(),r=i.positionals?.[1]?.trim();if(!t||!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"push requires <bundle|package> <payload.json|inline-json>"}};let s="file"===(e=nE(r,{subject:"Push payload",cwd:i.meta?.cwd,expandPath:(e,t)=>tw.expandHome(e,t)})).kind?e.path:e.text;return await oD({req:i,sessionName:n,logPath:a,sessionStore:o,ensureReady:S,resolveDevice:D,dispatch:N,command:"push",positionals:[t,s],recordPositionals:[t,r]})}if("trigger-app-event"===O)return await oD({req:i,sessionName:n,logPath:a,sessionStore:o,ensureReady:S,resolveDevice:D,dispatch:N,command:"trigger-app-event",positionals:i.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,i=r?await oR(e.device,r,e.appBundleId,g)??e.appBundleId:e.appBundleId;return{...e,appBundleId:i}}});if("open"===O){let e=i.flags?.relaunch===!0;if(o.has(n)){let t=o.get(n),r=i.positionals?.[0],s=r??(e?t?.appName:void 0);if(!t||!s)return e?{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch requires an app name or an active session app."}}:{ok:!1,error:{code:"INVALID_ARGS",message:"Session already active. Close it first or pass a new --session name."}};if(e&&t9(s))return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch does not support URL targets."}};await S(t.device);let l=oc(o,n,t?.device),d=await oR(t.device,s,t.appBundleId,g),u=r?i.positionals??[]:[s];if(e){let e=d??s;await ob({device:t.device,closeTarget:e,stopIosRunner:E,dispatch:N,outFlag:i.flags?.out,context:{...nK(a,i.flags,d??t.appBundleId,t.trace?.outPath)},settleSimulator:k})}await v({device:t.device,appId:d,runtime:l});let c=Date.now();await N(t.device,"open",u,i.flags?.out,{...nK(a,i.flags,d)}),await op({runtime:l,device:t.device,dispatch:N,req:i,logPath:a,appBundleId:d,traceLogPath:t.trace?.outPath,openPositionals:u});let p=of(c,s,d);await k(t.device,os);let f={...t,appBundleId:d,appName:s,recordSession:t.recordSession||!!i.flags?.saveScript,snapshot:void 0},m=ol({sessionName:n,appName:s,appBundleId:d,startup:p,device:t.device,runtime:l});return o.recordAction(f,{command:O,positionals:u,flags:i.flags??{},result:m}),o.set(n,f),{ok:!0,data:m}}let t=i.positionals?.[0];if(e&&!t)return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch requires an app argument."}};if(e&&t&&t9(t))return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch does not support URL targets."}};let r=await D(i.flags??{});if(e&&"android"===r.platform&&t&&/\.(?:apk|aab)$/i.test(t.trim()))return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch on Android requires an installed package name, not an .apk/.aab path. Install or reinstall the app first, then relaunch by package."}};let s=o.toArray().find(e=>e.device.id===r.id);if(s)return{ok:!1,error:{code:"DEVICE_IN_USE",message:`Device is already in use by session "${s.name}".`,details:{session:s.name,deviceId:r.id,deviceName:r.name}}};await S(r);let l=oc(o,n,r),d=await oR(r,t,void 0,g);if(e&&t){let e=d??t;await ob({device:r,closeTarget:e,stopIosRunner:E,dispatch:N,outFlag:i.flags?.out,context:{...nK(a,i.flags,d)},settleSimulator:k})}await v({device:r,appId:d,runtime:l});let u=Date.now();await N(r,"open",i.positionals??[],i.flags?.out,{...nK(a,i.flags,d)}),await op({runtime:l,device:r,dispatch:N,req:i,logPath:a,appBundleId:d,openPositionals:i.positionals??[]});let c=t?of(u,t,d):void 0;await k(r,os);let p={name:n,device:r,createdAt:Date.now(),appBundleId:d,appName:t,recordSession:!!i.flags?.saveScript,actions:[]},f=ol({sessionName:n,appName:t,appBundleId:d,startup:c,device:r,runtime:l});return o.recordAction(p,{command:O,positionals:i.positionals??[],flags:i.flags??{},result:f}),o.set(n,p),{ok:!0,data:f}}if("replay"===O){let e=i.positionals?.[0];if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay requires a path"}};try{let t=tw.expandHome(e,i.meta?.cwd),r=$.readFileSync(t,"utf8"),l=r.trimStart()[0];if("{"===l||"["===l)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay accepts .ad script files. JSON replay payloads are no longer supported."}};let d=function(e){let t=[];for(let r of e.split(/\r?\n/)){let e=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let r=function(e){let t=[],r=0;for(;r<e.length;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let i=r+1,n=!1;for(;i<e.length;){let t=e[i];if('"'===t&&!n)break;n="\\"===t&&!n,"\\"!==t&&(n=!1),i+=1}if(i>=e.length)throw new I("INVALID_ARGS",`Invalid replay script line: ${e}`);let a=e.slice(r,i+1);t.push(JSON.parse(a)),r=i+1;continue}let i=r;for(;i<e.length&&!/\s/.test(e[i]);)i+=1;t.push(e.slice(r,i)),r=i}return t}(t);if(0===r.length)return null;let[i,...n]=r;if("context"===i)return null;let a={ts:Date.now(),command:i,positionals:[],flags:{}};if("snapshot"===i){a.positionals=[];for(let e=0;e<n.length;e+=1){let t=n[e];if("-i"===t){a.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){a.flags.snapshotCompact=!0;continue}if("--raw"===t){a.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<n.length){let t=Number(n[e+1]);Number.isFinite(t)&&t>=0&&(a.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<n.length){a.flags.snapshotScope=n[e+1],e+=1;continue}if("--backend"===t&&e+1<n.length){e+=1;continue}}return a}if("open"===i){a.positionals=[];for(let e=0;e<n.length;e+=1){let t=n[e];if("--relaunch"===t){a.flags.relaunch=!0;continue}a.positionals.push(t)}return a}if(tp(i)){let e=th(i,n);if(Object.assign(a.flags,e.flags),0===e.positionals.length)return a;let t=e.positionals[0];if(t.startsWith("@"))return a.positionals=[t],e.positionals[1]&&(a.result={refLabel:e.positionals[1]}),a;let r=e.positionals[0],o=e.positionals[1];return a3(r)&&a3(o)&&e.positionals.length>=2?a.positionals=[r,o]:a.positionals=[e.positionals.join(" ")],a}if("fill"===i){if(n.length<2)return a.positionals=n,a;let e=n[0];return e.startsWith("@")?(n.length>=3?(a.positionals=[e,n.slice(2).join(" ")],a.result={refLabel:n[1]}):a.positionals=[e,n[1]],a):(a.positionals=[e,n.slice(1).join(" ")],a)}if("get"===i){if(n.length<2)return a.positionals=n,a;let e=n[0],t=n[1];return t.startsWith("@")?(a.positionals=[e,t],n[2]&&(a.result={refLabel:n[2]})):a.positionals=[e,n.slice(1).join(" ")],a}if("swipe"===i){let e=th(i,n);return Object.assign(a.flags,e.flags),a.positionals=e.positionals,a}return a.positionals=n,a}(r);e&&t.push(e)}return t}(r),u=i.flags?.replayUpdate===!0,c=0;for(let e=0;e<d.length;e+=1){let r=d[e];if(!r||"replay"===r.command)continue;let l=await s({token:i.token,session:n,command:r.command,positionals:r.positionals??[],flags:oG(i.flags,r.flags),meta:i.meta});if(l.ok)continue;if(!u)return oU(l,r,e,t);let p=await oB({action:r,sessionName:n,logPath:a,sessionStore:o,dispatch:N});if(!p)return oU(l,r,e,t);if(d[e]=p,!(l=await s({token:i.token,session:n,command:p.command,positionals:p.positionals??[],flags:oG(i.flags,p.flags),meta:i.meta})).ok)return oU(l,p,e,t);c+=1}if(u&&c>0){let e=o.get(n);!function(e,t,r){let i=[];if(r){let e=r.device.name.replace(/"/g,'\\"'),t=r.device.kind?` kind=${r.device.kind}`:"",n=r.device.target?` target=${r.device.target}`:"";i.push(`context platform=${r.device.platform}${n} device="${e}"${t} theme=unknown`)}for(let e of t)i.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tf(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command){for(let r of e.positionals??[])t.push(tf(r));return e.flags?.relaunch&&t.push("--relaunch"),t.join(" ")}for(let r of e.positionals??[])t.push(tf(r));return tm(t,e),t.join(" ")}(e));let n=`${i.join("\n")}
35
- `,a=`${e}.tmp-${process.pid}-${Date.now()}`;$.writeFileSync(a,n),$.renameSync(a,e)}(t,d,e)}return{ok:!0,data:{replayed:d.length,healed:c,session:n}}}catch(t){let e=w(t);return{ok:!1,error:{code:e.code,message:e.message}}}}if("logs"===O){let e=o.get(n);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"logs requires an active session"}};let t=(i.positionals?.[0]??"path").toLowerCase(),r=!!i.flags?.restart;if(!or.includes(t))return{ok:!1,error:{code:"INVALID_ARGS",message:oi}};if(r&&"clear"!==t)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs --restart is only supported with logs clear"}};if("path"===t){let t=o.resolveAppLogPath(n),r=function(e){if(!$.existsSync(e))return{exists:!1,sizeBytes:0};let t=$.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(t),i=e.appLog?.backend??("ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android");return{ok:!0,data:{path:t,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:i,sizeBytes:r.sizeBytes,modifiedAt:r.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}if("doctor"===t){let t=o.resolveAppLogPath(n),r=await tM(e.device,e.appBundleId);return{ok:!0,data:{path:t,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:r.checks,notes:r.notes}}}if("mark"===t){let e,t=i.positionals?.slice(1).join(" ")??"",r=o.resolveAppLogPath(n);return tk(r),e=`[agent-device][mark][${new Date().toISOString()}] ${t.trim()||"marker"}
36
- `,$.appendFileSync(r,e,"utf8"),{ok:!0,data:{path:r,marked:!0}}}if("clear"===t){if(e.appLog&&!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear requires logs to be stopped first; run logs stop"}};if(r){if(!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear --restart requires an app session; run open <app> first"}};if(!nz("logs",e.device))return{ok:!1,error:_(new I("UNSUPPORTED_OPERATION","logs is not supported on this device"))}}let t=o.resolveAppLogPath(n);if(r){e.appLog&&await m.stop(e.appLog);let r=tx(t),i=o.resolveAppLogPidPath(n);try{let a=await m.start(e.device,e.appBundleId,t,i),s={...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:t,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}};return o.set(n,s),{ok:!0,data:{...r,restarted:!0}}}catch(r){let t=_(r);return o.set(n,{...e,appLog:void 0}),{ok:!1,error:t}}}return{ok:!0,data:tx(t)}}if("start"===t){if(e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"app log already streaming; run logs stop first"}};if(!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs start requires an app session; run open <app> first"}};if(!nz("logs",e.device))return{ok:!1,error:_(new I("UNSUPPORTED_OPERATION","logs is not supported on this device"))};let t=o.resolveAppLogPath(n),r=o.resolveAppLogPidPath(n);try{let i=await m.start(e.device,e.appBundleId,t,r),a={...e,appLog:{platform:e.device.platform,backend:i.backend,outPath:t,startedAt:i.startedAt,getState:i.getState,stop:i.stop,wait:i.wait}};return o.set(n,a),{ok:!0,data:{path:t,started:!0}}}catch(e){return{ok:!1,error:_(e)}}}if("stop"===t){if(!e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"no app log stream active"}};let t=e.appLog.outPath;return await m.stop(e.appLog),o.set(n,{...e,appLog:void 0}),{ok:!0,data:{path:t,stopped:!0}}}}if("network"===O){let e=o.get(n);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"network requires an active session"}};let t=(i.positionals?.[0]??"dump").toLowerCase();if(!om.includes(t))return{ok:!1,error:{code:"INVALID_ARGS",message:oh}};let r=i.positionals?.[1],a=r?Number.parseInt(r,10):25;if(!Number.isInteger(a)||a<1||a>200)return{ok:!1,error:{code:"INVALID_ARGS",message:"network dump limit must be an integer in range 1..200"}};let s=(i.positionals?.[2]??"summary").toLowerCase();if(!ow.includes(s))return{ok:!1,error:{code:"INVALID_ARGS",message:og}};let l=function(e,t){let r=aM(t?.maxEntries,25,1,200),i=t?.include??"summary",n=aM(t?.maxPayloadChars,2048,64,16384),a=aM(t?.maxScanLines,4e3,100,2e4);if(!$.existsSync(e))return{path:e,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:a}};let o=$.readFileSync(e,"utf8").split("\n"),s=Math.max(0,o.length-a),l=o.slice(s),d=[];for(let e=l.length-1;e>=0&&d.length<r;e-=1){let t=l[e]?.trim();if(!t)continue;let r=function(e,t,r,i){let n=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let i=e.slice(t,r+1);try{let e=JSON.parse(i);return e&&"object"==typeof e?e:null}catch{return null}}(e),a=aE(n,["method","httpMethod"]),o=aE(n,["url","requestUrl"]),s=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(n,["status","statusCode","responseCode"]),l=aS.exec(e),d=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(e),u=(a??d?.[1]??l?.[1])?.toUpperCase(),c=a_.exec(e),p=o??c?.[0];if(!p)return null;let f={method:u,url:p,status:s??function(e){for(let t of aD){let r=t.exec(e);if(!r)continue;let i=Number.parseInt(r[1]??"",10);if(Number.isInteger(i))return i}return null}(e)??void 0,timestamp:function(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);return t?.[0]}(e),raw:aL(e,i),line:t};if("headers"===r||"all"===r){let t=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return aO(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(e,n);t&&(f.headers=aL(t,i))}if("body"===r||"all"===r){let t=ak(e,n,["requestBody","body","payload","request"]),r=ak(e,n,["responseBody","response"]);t&&(f.requestBody=aL(t,i)),r&&(f.responseBody=aL(r,i))}return f}(t,s+e+1,i,n);r&&d.push(r)}return{path:e,exists:!0,scannedLines:l.length,matchedLines:d.length,entries:d,include:i,limits:{maxEntries:r,maxPayloadChars:n,maxScanLines:a}}}(o.resolveAppLogPath(n),{maxEntries:a,include:s,maxPayloadChars:2048,maxScanLines:4e3}),d=e.appLog?.backend??("ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android"),u=[];return e.appLog||u.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."),0===l.entries.length&&u.push("No HTTP(s) entries were found in recent session app logs."),{ok:!0,data:{...l,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:d,notes:u}}}if("batch"===O)return await oF(i,n,s);if("close"===O){let e=o.get(n);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session"}};if(e.appLog&&await m.stop(e.appLog),i.positionals&&i.positionals.length>0&&("ios"===e.device.platform&&await E(e.device.id),await N(e.device,"close",i.positionals,i.flags?.out,{...nK(a,i.flags,e.appBundleId,e.trace?.outPath)}),await k(e.device,oo)),"ios"===e.device.platform&&await E(e.device.id),aV(o.getRuntimeHints(n))&&e.appBundleId&&await A({device:e.device,appId:e.appBundleId}).catch(()=>{}),o.recordAction(e,{command:O,positionals:i.positionals??[],flags:i.flags??{},result:{session:n}}),i.flags?.saveScript&&(e.recordSession=!0),o.writeSessionLog(e),o.delete(n),i.flags?.shutdown&&oA(e.device)){let t;try{t=await (b??ij)(e.device)}catch(r){let e=_(r);t={success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}return{ok:!0,data:{session:n,shutdown:t}}}return{ok:!0,data:{session:n}}}return null}async function oF(e,t,r){let i=e.flags?.batchOnError??"stop";if("stop"!==i)return{ok:!1,error:{code:"INVALID_ARGS",message:`Unsupported batch on-error mode: ${i}.`}};let n=e.flags?.batchMaxSteps??C;if(!Number.isInteger(n)||n<1||n>1e3)return{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`}};try{let i=c(e.flags?.batchSteps,n),a=Date.now(),o=[];for(let n=0;n<i.length;n+=1){let a=i[n],s=await oV(e,t,a,r,n+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${a.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:a.command,positionals:a.positionals,executed:n,total:i.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:i.length,executed:i.length,totalDurationMs:Date.now()-a,results:o}}}catch(t){let e=w(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}async function oV(e,t,r,i,n){let a=Date.now(),o=await i({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:function(e,t){let r={...t??{}};delete r.batchSteps,delete r.batchOnError,delete r.batchMaxSteps;let i=e??{};for(let e of oe)void 0===r[e]&&void 0!==i[e]&&(r[e]=i[e]);return r}(e.flags,r.flags),meta:e.meta}),s=Date.now()-a;return o.ok?{ok:!0,step:n,result:{step:n,command:r.command,ok:!0,data:o.data??{},durationMs:s}}:{ok:!1,step:n,error:o.error}}function oU(e,t,r,i){if(e.ok)return e;let n=r+1,a=function(e){let t;return t=(e.positionals??[]).map(e=>tf(e)),[e.command,...t].join(" ")}(t),o={...e.error.details??{},replayPath:i,step:n,action:t.command,positionals:t.positionals??[]};return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${n} (${a}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:o}}}function oG(e,t){let r={...t??{}},i=e??{};for(let e of ot)void 0===r[e]&&void 0!==i[e]&&(r[e]=i[e]);return r}async function oB(e){let{action:t,sessionName:r,logPath:i,sessionStore:n,dispatch:a}=e;if(!(tp(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let o=n.get(r);if(!o)return null;let s=tp(t.command)||"fill"===t.command,l=tp(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await oj(o,t,i,s,a,n);for(let e of function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),tp(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=ac(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=a2(e.positionals??[]);r&&t.push(r)}let i="string"==typeof e.result?.refLabel?e.result.refLabel.trim():"";if(i.length>0){let r=JSON.stringify(i);"fill"===e.command?(t.push(`id=${r} editable=true`),t.push(`label=${r} editable=true`),t.push(`text=${r} editable=true`),t.push(`value=${r} editable=true`)):(t.push(`id=${r}`),t.push(`label=${r}`),t.push(`text=${r}`),t.push(`value=${r}`))}return tl(t).filter(e=>e.trim().length>0)}(t)){let r=ao(e);if(!r)continue;let i=as(d.nodes,r,{platform:o.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!i)continue;let n=am(i.node,o.device.platform,{action:tp(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(tp(t.command))return{...t,positionals:[n]};if("fill"===t.command){let e=ts(t);if(!e)continue;return{...t,positionals:[n,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,n]}}if("is"===t.command){let{predicate:e,split:r}=ac(t.positionals);if(!e)continue;let i=r?.rest.join(" ").trim()??"",a=[e,n];return"text"===e&&i.length>0&&a.push(i),{...t,positionals:a}}if("wait"===t.command){let{selectorTimeout:e}=a2(t.positionals??[]),r=[n];return e&&r.push(e),{...t,positionals:r}}}let u=function(e,t,r){if("get"!==e.command||e.positionals?.[0]!=="text")return null;let i=e.positionals?.[1];if(!i)return null;let n=ao(i);if(!n)return null;let a=new Set,o=!1;for(let e of n.selectors)for(let t of e.terms)"role"===t.key&&"string"==typeof t.value&&a.add(n7(t.value)),("text"===t.key||"label"===t.key||"value"===t.key)&&"string"==typeof t.value&&/^\d+$/.test(t.value.trim())&&(o=!0);if(!o)return null;let s=t.nodes.filter(e=>{let t=at(e).trim();return!!/^\d+$/.test(t)&&(0===a.size||a.has(n7(e.type??"")))});if(0===s.length||1!==tl(s.map(e=>at(e).trim())).length)return null;let l=s[0];if(!l)return null;let d=am(l,r.device.platform,{action:"get"});return 0===d.length?null:{...e,positionals:["text",d.join(" || ")]}}(t,d,o);return u||null}async function oj(e,t,r,i,n,a){let o=await n(e.device,"snapshot",[],t.flags?.out,{...nK(r,{...t.flags??{},snapshotInteractiveOnly:i,snapshotCompact:i},e.appBundleId,e.trace?.outPath)}),s=o?.nodes??[],l={nodes:n1(t.flags?.snapshotRaw?s:n9(s)),truncated:o?.truncated,createdAt:Date.now(),backend:o?.backend};return e.snapshot=l,a.set(e.name,e),l}function oq(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function oH(e,t){let r=S(e.type??"Element"),i=m(e,r),n=!1===e.enabled?"disabled":"enabled",a=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),r,i,n,a,o].join("|")}function oW(e,t){return t.flatten?e.map(e=>({text:i(e,0,!1),comparable:oH(e,0)})):y(e).map(e=>({text:e.text,comparable:oH(e.node,e.depth)}))}function oJ(e,t){return e.get(t)??0}async function oz(e){let{req:t,sessionName:r,logPath:i,sessionStore:n}=e,a=e.dispatchSnapshotCommand??nW,o=e.runnerCommand??ta,s=t.command;if("snapshot"===s){let{session:e,device:o}=await oY(n,r,t.flags);if(!nz("snapshot",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"snapshot is not supported on this device"}};let s=oX(t.flags?.snapshotScope,e);return s.ok?await oZ(e,o,async()=>{let l=e?.appBundleId,d=await oK({dispatchSnapshotCommand:a,device:o,session:e,req:t,logPath:i,snapshotScope:s.scope}),u=e?{...e,snapshot:d.snapshot}:{name:r,device:o,createdAt:Date.now(),appBundleId:l,snapshot:d.snapshot,actions:[]};return oQ(n,u,t,{nodes:d.snapshot.nodes.length,truncated:d.snapshot.truncated??!1}),n.set(r,u),{ok:!0,data:{nodes:d.snapshot.nodes,truncated:d.snapshot.truncated??!1,appName:u.appBundleId?u.appName??u.appBundleId:void 0,appBundleId:u.appBundleId}}}):s.response}if("diff"===s){if(t.positionals?.[0]!=="snapshot")return{ok:!1,error:{code:"INVALID_ARGS",message:"diff currently supports only: diff snapshot"}};let{session:e,device:o}=await oY(n,r,t.flags);if(!nz("diff",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"diff is not supported on this device"}};let s=oX(t.flags?.snapshotScope,e);if(!s.ok)return s.response;let l=t.flags?.snapshotInteractiveOnly===!0;return await oZ(e,o,async()=>{let d=e?.appBundleId,u=(await oK({dispatchSnapshotCommand:a,device:o,session:e,req:t,logPath:i,snapshotScope:s.scope})).snapshot;if(!e?.snapshot){let i=function(e,t={}){return oW(e,t).length}(u.nodes,{flatten:l}),a=e?{...e,snapshot:u}:{name:r,device:o,createdAt:Date.now(),appBundleId:d,snapshot:u,actions:[]};return oQ(n,a,t,{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:i}}),n.set(r,a),{ok:!0,data:{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:i},lines:[]}}}let c=function(e,t,r={}){let i=function(e,t){let r=e.length,i=t.length,n=r+i,a=new Map,o=[];a.set(1,0);for(let s=0;s<=n;s+=1){o.push(new Map(a));for(let n=-s;n<=s;n+=2){let l=n===-s||n!==s&&oJ(a,n-1)<oJ(a,n+1)?oJ(a,n+1):oJ(a,n-1)+1,d=l-n;for(;l<r&&d<i&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(a.set(n,l),l>=r&&d>=i)return function(e,t,r,i,n){let a=[],o=i,s=n;for(let i=e.length-1;i>=0;i-=1){let n=e[i],l=o-s,d=l===-i||l!==i&&oJ(n,l-1)<oJ(n,l+1)?l+1:l-1,u=oJ(n,d),c=u-d;for(;o>u&&s>c;)a.push({kind:"unchanged",text:r[s-1].text}),o-=1,s-=1;if(0===i)break;o===u?(a.push({kind:"added",text:r[c].text}),s=c):(a.push({kind:"removed",text:t[u].text}),o=u)}return a.reverse(),a}(o,e,t,r,i)}}return[]}(oW(e,r),oW(t,r)),n={additions:0,removals:0,unchanged:0};for(let e of i)"added"===e.kind&&(n.additions+=1),"removed"===e.kind&&(n.removals+=1),"unchanged"===e.kind&&(n.unchanged+=1);return{summary:n,lines:i}}(e.snapshot.nodes,u.nodes,{flatten:l}),p={...e,snapshot:u};return oQ(n,p,t,{mode:"snapshot",baselineInitialized:!1,summary:c.summary}),n.set(r,p),{ok:!0,data:{mode:"snapshot",baselineInitialized:!1,summary:c.summary,lines:c.lines}}})}if("wait"===s){let{session:e,device:o}=await oY(n,r,t.flags),s=function(e){if(0===e.length)return null;let t=oq(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=oq(e[e.length-1]);return{kind:"text",text:(null!==t?e.slice(1,-1).join(" "):e.slice(1).join(" ")).trim(),timeoutMs:t}}if(e[0].startsWith("@")){let t=oq(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let r=oq(e[e.length-1]),i=au(null!==r?e.slice(0,-1):e.slice());if(i&&0===i.rest.length){let e=ao(i.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:i.selectorExpression,timeoutMs:r}}return{kind:"text",text:(null!==r?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:r}}(t.positionals??[]);return s?"sleep"===s.kind?(await new Promise(e=>setTimeout(e,s.durationMs)),oQ(n,e,t,{waitedMs:s.durationMs}),{ok:!0,data:{waitedMs:s.durationMs}}):nz("wait",o)?await oZ(e,o,async()=>{let l,d;if("selector"===s.kind){let l=s.timeoutMs??1e4,d=Date.now();for(;Date.now()-d<l;){let l=await a(o,"snapshot",[],t.flags?.out,{...nK(i,{...t.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},e?.appBundleId,e?.trace?.outPath)}),u=l?.nodes??[],c=n1(t.flags?.snapshotRaw?u:n9(u));e&&(e.snapshot={nodes:c,truncated:l?.truncated,createdAt:Date.now(),backend:l?.backend},n.set(r,e));let p=al(c,s.selector,{platform:o.platform});if(p)return oQ(n,e,t,{selector:p.selector.raw,waitedMs:Date.now()-d}),{ok:!0,data:{selector:p.selector.raw,waitedMs:Date.now()-d}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:`wait timed out for selector: ${s.selectorExpression}`}}}if("ref"===s.kind){if(!e?.snapshot)return{ok:!1,error:{code:"INVALID_ARGS",message:"Ref wait requires an existing snapshot in session."}};let t=n2(s.rawRef);if(!t)return{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref: ${s.rawRef}`}};let r=n3(e.snapshot.nodes,t),i=r?n5(r,e.snapshot.nodes):void 0;if(!i)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${s.rawRef} not found or has no label`}};l=i,d=s.timeoutMs}else l=s.text,d=s.timeoutMs;if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires text"}};let u=d??1e4,c=Date.now();for(;Date.now()-c<u;){if("ios"===o.platform){let r=await ta(o,{command:"findText",text:l,appBundleId:e?.appBundleId},{verbose:t.flags?.verbose,logPath:i,traceLogPath:e?.trace?.outPath,requestId:t.meta?.requestId});if(r?.found)return oQ(n,e,t,{text:l,waitedMs:Date.now()-c}),{ok:!0,data:{text:l,waitedMs:Date.now()-c}}}else if("android"===o.platform&&n8(n1((await rz(o,{scope:l})).nodes??[]),l))return oQ(n,e,t,{text:l,waitedMs:Date.now()-c}),{ok:!0,data:{text:l,waitedMs:Date.now()-c}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:`wait timed out for text: ${l}`}}}):{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"wait is not supported on this device"}}:{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires a duration or text"}}}if("alert"===s){let{session:e,device:a}=await oY(n,r,t.flags),s=(t.positionals?.[0]??"get").toLowerCase();return nz("alert",a)?await oZ(e,a,async()=>{if("wait"===s){let r=oq(t.positionals?.[1])??1e4,s=Date.now();for(;Date.now()-s<r;){try{let r=await o(a,{command:"alert",action:"get",appBundleId:e?.appBundleId},{verbose:t.flags?.verbose,logPath:i,traceLogPath:e?.trace?.outPath,requestId:t.meta?.requestId});return oQ(n,e,t,r),{ok:!0,data:r}}catch{}await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"alert wait timed out"}}}let r="accept"===s||"dismiss"===s?s:"get",l={verbose:t.flags?.verbose,logPath:i,traceLogPath:e?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===r||"dismiss"===r){let i,s=Date.now();for(;Date.now()-s<2e3;){try{let i=await o(a,{command:"alert",action:r,appBundleId:e?.appBundleId},l);return oQ(n,e,t,i),{ok:!0,data:i}}catch(t){i=t;let e=String(t?.message??"").toLowerCase();if(!e.includes("alert not found")&&!e.includes("no alert"))break}await new Promise(e=>setTimeout(e,300))}throw i}let d=await o(a,{command:"alert",action:r,appBundleId:e?.appBundleId},l);return oQ(n,e,t,d),{ok:!0,data:d}}):{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"alert is only supported on iOS simulators"}}}if("settings"===s){let e=t.positionals?.[0]?.toLowerCase(),a=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase();if(!e||!a||"permission"===e&&!o)return{ok:!1,error:{code:"INVALID_ARGS",message:f}};let{session:s,device:l}=await oY(n,r,t.flags);return nz("settings",l)?await oZ(s,l,async()=>{let r=s?.appBundleId,d="permission"===e?[e,a,o,t.positionals?.[3]??"",r??""]:[e,a,r??""],u=await nW(l,"settings",d,t.flags?.out,{...nK(i,t.flags,r,s?.trace?.outPath)});return oQ(n,s,t,u??{setting:e,state:a}),{ok:!0,data:u??{setting:e,state:a}}}):{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"settings is not supported on this device"}}}return null}async function oK(e){let{dispatchSnapshotCommand:t,device:r,session:i,req:n,logPath:a,snapshotScope:o}=e,s=await t(r,"snapshot",[],n.flags?.out,{...nK(a,{...n.flags,snapshotScope:o},i?.appBundleId,i?.trace?.outPath)}),l=s?.nodes??[];return{snapshot:{nodes:n1(n.flags?.snapshotRaw?l:n9(l)),truncated:s?.truncated,createdAt:Date.now(),backend:s?.backend}}}function oX(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"Ref scope requires an existing snapshot in session."}}};let r=n2(e.trim());if(!r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref scope: ${e}`}}};let i=n3(t.snapshot.nodes,r),n=i?n5(i,t.snapshot.nodes):void 0;return n?{ok:!0,scope:n}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${e} not found or has no label`}}}}async function oY(e,t,r){let i=e.get(t),n=i?.device??await nH(r??{});return i||await nY(n),{session:i,device:n}}async function oZ(e,t,r){let i=!e&&"ios"===t.platform;try{return await r()}finally{i&&await e9(t.id)}}function oQ(e,t,r,i){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:i})}function o0(e,t,r,i={}){let n=o2(r);if(!n)return{matches:[],score:0};let a=0,o=[];for(let r of e){if(i.requireRect&&!r.rect)continue;let e=function(e,t,r){switch(t){case"role":return function(e,t){let r=function(e){let t=e.trim();return t?t=(t.split(".").pop()??t).replace(/XCUIElementType/gi,"").toLowerCase():""}(e??"");return r?r===t?2:+!!r.includes(t):0}(e.type,r);case"label":return o1(e.label,r);case"value":return o1(e.value,r);case"id":return o1(e.identifier,r);default:return Math.max(o1(e.label,r),o1(e.value,r),o1(e.identifier,r))}}(r,t,n);if(!(e<=0)){if(e>a){a=e,o.length=0,o.push(r);continue}e===a&&o.push(r)}}return{matches:o,score:a}}function o1(e,t){let r=o2(e??"");return r?r===t?2:+!!r.includes(t):0}function o2(e){return e.trim().toLowerCase().replace(/\s+/g," ")}async function o3(e){let{req:t,sessionName:r,logPath:i,sessionStore:n,invoke:a}=e,o=e.dispatch??nW,s=t.command;if("find"!==s)return null;let l=t.positionals??[];if(0===l.length)return{ok:!1,error:{code:"INVALID_ARGS",message:"find requires a locator or text"}};let{locator:d,query:u,action:c,value:p,timeoutMs:f}=function(e){let t="any",r=0;["text","label","value","role","id"].includes(e[0])&&(t=e[0],r=1);let i=e[r]??"",n=e.slice(r+1);if(0===n.length)return{locator:t,query:i,action:"click"};let a=n[0].toLowerCase();if("get"===a){let e=n[1]?.toLowerCase();if("text"===e)return{locator:t,query:i,action:"get_text"};if("attrs"===e)return{locator:t,query:i,action:"get_attrs"};throw new I("INVALID_ARGS","find get only supports text or attrs")}if("wait"===a)return{locator:t,query:i,action:"wait",timeoutMs:oq(n[1])??void 0};if("exists"===a)return{locator:t,query:i,action:"exists"};if("click"===a)return{locator:t,query:i,action:"click"};if("focus"===a)return{locator:t,query:i,action:"focus"};if("fill"===a)return{locator:t,query:i,action:"fill",value:n.slice(1).join(" ")};if("type"===a)return{locator:t,query:i,action:"type",value:n.slice(1).join(" ")};throw new I("INVALID_ARGS",`Unsupported find action: ${n[0]}`)}(l);if(!u)return{ok:!1,error:{code:"INVALID_ARGS",message:"find requires a value"}};let m=n.get(r);if(!m&&"exists"!==c&&"wait"!==c&&"get_text"!==c&&"get_attrs"!==c)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let h=m?.device??await nH(t.flags??{});m||await nY(h);let w=m?.appBundleId,g="role"!==d?u:void 0,v="click"===c||"focus"===c||"fill"===c||"type"===c,A=0,y=null,b=async()=>{let e=Date.now();if(y&&e-A<750)return{nodes:y};let a=await o(h,"snapshot",[],t.flags?.out,{...nK(i,{...t.flags,snapshotScope:g,snapshotInteractiveOnly:v,snapshotCompact:v},w,m?.trace?.outPath)}),s=a?.nodes??[],l=n1(t.flags?.snapshotRaw?s:n9(s));return A=e,y=l,m&&(m.snapshot={nodes:l,truncated:a?.truncated,createdAt:Date.now(),backend:a?.backend},n.set(r,m)),{nodes:l,truncated:a?.truncated,backend:a?.backend}};if("wait"===c){let e=f??1e4,r=Date.now();for(;Date.now()-r<e;){let{nodes:e}=await b();if(o0(e,d,u,{requireRect:!1}).matches[0])return m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0,waitedMs:Date.now()-r}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-r}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"find wait timed out"}}}let{nodes:N}=await b(),S=o0(N,d,u,{requireRect:v});if(v&&S.matches.length>1){let e=S.matches.slice(0,8).map(e=>{let t=at(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`});return{ok:!1,error:{code:"AMBIGUOUS_MATCH",message:`find matched ${S.matches.length} elements for ${d} "${u}". Use a more specific locator or selector.`,details:{locator:d,query:u,matches:S.matches.length,candidates:e}}}}let _=S.matches[0]??null;if(!_)return{ok:!1,error:{code:"COMMAND_FAILED",message:"find did not match any element"}};let D="click"===c||"focus"===c||"fill"===c||"type"===c?function(e,t){if(t.hittable)return t;let r=t,i=new Set;for(;void 0!==r.parentIndex&&!i.has(r.ref);){i.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(t.hittable)return t;r=t}return null}(N,_)??_:_,E=`@${D.ref}`,k={...t.flags??{},noRecord:!0};if("exists"===c)return m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}};if("get_text"===c){let e=at(_);return m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"get text",text:e}}),{ok:!0,data:{ref:E,text:e,node:_}}}if("get_attrs"===c)return m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"get attrs"}}),{ok:!0,data:{ref:E,node:_}};if("click"===c){let e=await a({token:t.token,session:r,command:"click",positionals:[E],flags:k});if(!e.ok)return e;let i=D.rect?n4(D.rect):null,o={ref:E,locator:d,query:u};return i&&(o.x=i.x,o.y=i.y),m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"click",locator:d,query:u}}),{ok:!0,data:o}}if("fill"===c){if(!p)return{ok:!1,error:{code:"INVALID_ARGS",message:"find fill requires text"}};let e=await a({token:t.token,session:r,command:"fill",positionals:[E,p],flags:k});return e.ok&&m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"fill"}}),e}if("focus"===c){let e=_.rect?n4(_.rect):null;if(!e)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};let r=await o(h,"focus",[String(e.x),String(e.y)],t.flags?.out,{...nK(i,t.flags,m?.appBundleId,m?.trace?.outPath)});return m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"focus"}}),{ok:!0,data:r??{ref:E}}}if("type"===c){if(!p)return{ok:!1,error:{code:"INVALID_ARGS",message:"find type requires text"}};let e=_.rect?n4(_.rect):null;if(!e)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};await o(h,"focus",[String(e.x),String(e.y)],t.flags?.out,{...nK(i,t.flags,m?.appBundleId,m?.trace?.outPath)});let r=await o(h,"type",[p],t.flags?.out,{...nK(i,t.flags,m?.appBundleId,m?.trace?.outPath)});return m&&n.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"type"}}),{ok:!0,data:r??{ref:E}}}return null}function o4(e){return e instanceof Error?e.message:String(e)}function o8(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function o5(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function o6(e){let{req:t,sessionName:r,sessionStore:i,logPath:a}=e,o=e.deps??{runCmd:p,runCmdBackground:d,runIosRunnerCommand:ta},s=t.command;if("record"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"record requires start|stop"}};let d=i.get(r),c=d?.device??await nH(t.flags??{});d||await nY(c);let p=d??{name:r,device:c,createdAt:Date.now(),actions:[]};if("start"===e){if(p.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"recording already in progress"}};let e=t.flags?.fps;if(void 0!==e&&(!Number.isInteger(e)||e<1||e>120))return{ok:!1,error:{code:"INVALID_ARGS",message:"fps must be an integer between 1 and 120"}};let d=t.positionals?.[1]??`./recording-${Date.now()}.mp4`;if(!nz("record",c))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"record is not supported on this device"}};let f="ios"===c.platform&&"device"===c.kind?o8(p):void 0;if("ios"===c.platform&&"device"===c.kind&&!f)return{ok:!1,error:{code:"INVALID_ARGS",message:"record on physical iOS devices requires an active app session; run open <app> first"}};let m=tw.expandHome(d,t.meta?.cwd),h=t.meta?.clientArtifactPaths?.outPath;$.mkdirSync(n.dirname(m),{recursive:!0});let w=o5(t,a,p);if("ios"===c.platform&&"device"===c.kind){let t=`agent-device-recording-${Date.now()}.mp4`,r=`tmp/${t}`,n=async()=>{await o.runIosRunnerCommand(c,{command:"recordStart",outPath:t,fps:e,appBundleId:f},w)};try{await n()}catch(e){if(!o4(e).toLowerCase().includes("recording already in progress"))return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${o4(e)}`}};{var l,u;M({level:"warn",phase:"record_start_runner_desynced",data:{platform:c.platform,kind:c.kind,deviceId:c.id,session:p.name,error:o4(e)}});let t=(l=c.id,u=p.name,i.toArray().find(e=>e.name!==u&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===l&&e.recording?.platform==="ios-device-runner"));if(t)return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: recording already in progress in session '${t.name}'`}};try{await o.runIosRunnerCommand(c,{command:"recordStop",appBundleId:f},w)}catch{}try{await n()}catch(e){return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${o4(e)}`}}}}}p.recording={platform:"ios-device-runner",outPath:m,clientOutPath:h,remotePath:r}}else if("ios"===c.platform){let{child:e,wait:t}=o.runCmdBackground("xcrun",e_(c,["io",c.id,"recordVideo",m]),{allowFailure:!0});p.recording={platform:"ios",outPath:m,clientOutPath:h,child:e,wait:t}}else{let e=`/sdcard/agent-device-recording-${Date.now()}.mp4`,{child:t,wait:r}=o.runCmdBackground("adb",["-s",c.id,"shell","screenrecord",e],{allowFailure:!0});p.recording={platform:"android",outPath:m,clientOutPath:h,remotePath:e,child:t,wait:r}}return i.set(r,p),i.recordAction(p,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start"}}),{ok:!0,data:{recording:"started",outPath:h??d}}}if(!p.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"no active recording"}};let f=p.recording;if("ios-device-runner"===f.platform){let e=o8(p);try{await o.runIosRunnerCommand(c,{command:"recordStop",appBundleId:e},o5(t,a,p))}catch(e){M({level:"warn",phase:"record_stop_runner_failed",data:{platform:c.platform,kind:c.kind,deviceId:c.id,session:p.name,error:o4(e)}})}let r={stdout:"",stderr:"",exitCode:1};for(let e of eY)if(0===(r=await o.runCmd("xcrun",["devicectl","device","copy","from","--device",c.id,"--source",f.remotePath,"--destination",f.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(p.recording=void 0,0!==r.exitCode){let e=r.stderr.trim()||r.stdout.trim()||`devicectl exited with code ${r.exitCode}`;return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to copy recording from device: ${e}`}}}}else{f.child.kill("SIGINT");try{await f.wait}catch{}if("android"===f.platform&&f.remotePath)try{await o.runCmd("adb",["-s",c.id,"pull",f.remotePath,f.outPath],{allowFailure:!0}),await o.runCmd("adb",["-s",c.id,"shell","rm","-f",f.remotePath],{allowFailure:!0})}catch{}p.recording=void 0}i.recordAction(p,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:f.outPath}});let m=[{field:"outPath",path:f.outPath,localPath:f.clientOutPath,fileName:n.basename(f.clientOutPath??f.outPath)}];return{ok:!0,data:{recording:"stopped",outPath:f.outPath,artifacts:m}}}if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"trace requires start|stop"}};let a=i.get(r);if(!a)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session"}};if("start"===e){if(a.trace)return{ok:!1,error:{code:"INVALID_ARGS",message:"trace already in progress"}};let e=t.positionals?.[1]??i.defaultTracePath(a),r=tw.expandHome(e);return $.mkdirSync(n.dirname(r),{recursive:!0}),$.appendFileSync(r,""),a.trace={outPath:r,startedAt:Date.now()},i.recordAction(a,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!a.trace)return{ok:!1,error:{code:"INVALID_ARGS",message:"no active trace"}};let o=a.trace.outPath;if(t.positionals?.[1]){let e=tw.expandHome(t.positionals[1]);$.mkdirSync(n.dirname(e),{recursive:!0}),$.existsSync(o)?$.renameSync(o,e):$.appendFileSync(e,""),o=e}return a.trace=void 0,i.recordAction(a,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:o}}),{ok:!0,data:{trace:"stopped",outPath:o}}}return null}function o9(e,t,r){return t>=e.x&&t<=e.x+e.width&&r>=e.y&&r<=e.y+e.height}function o7(e){let t=null,r=-1;for(let i of e){let e=i.width*i.height;e>r&&(t=i,r=e)}return t}function se(e,t,r){return Math.min(r,Math.max(t,Math.round(e)))}async function st(e){let{req:t,sessionName:r,sessionStore:i,contextFromFlags:n}=e,a=e.dispatch??nW,o=t.command;if("press"===o){let e=i.get(r);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nz("press",e.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"press is not supported on this device"}};let s=function(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}(t.positionals??[]);if(s){let r=await a(e.device,"press",[String(s.x),String(s.y)],t.flags?.out,{...n(t.flags,e.appBundleId,e.trace?.outPath)});return i.recordAction(e,{command:o,positionals:t.positionals??[String(s.x),String(s.y)],flags:t.flags??{},result:r??{x:s.x,y:s.y}}),{ok:!0,data:r??{x:s.x,y:s.y}}}let l="click",d=t.positionals?.[0]??"";if(d.startsWith("@")){let r=sn("press",t.flags);if(r)return r;let s=t.positionals.length>1?t.positionals.slice(1).join(" ").trim():"",u=sa({session:e,refInput:d,fallbackLabel:s,requireRect:!0,invalidRefMessage:`${o} requires a ref like @e2`,notFoundMessage:`Ref ${d} not found or has no bounds`});if(!u.ok)return u.response;let{ref:c}=u.target,p=u.target.node,f=u.target.snapshotNodes,m=so(p.rect);if(!m){let r=await sr(e,t.flags,i,n,{interactiveOnly:!0},a),o=n3(r.nodes,c),l=s.length>0?n8(r.nodes,s):null,d=so(l?.rect),u=so(o?.rect)?o:d?l:o??l,h=so(u?.rect);u&&h&&(p=u,f=r.nodes,m=h)}if(!m)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${d} not found or has invalid bounds`}};let h=n5(p,f),w=am(p,e.device.platform,{action:l}),{x:g,y:I}=m,v=await a(e.device,"press",[String(g),String(I)],t.flags?.out,{...n(t.flags,e.appBundleId,e.trace?.outPath)});return i.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:c,x:g,y:I,refLabel:h,selectorChain:w}}),{ok:!0,data:{...v??{},ref:c,x:g,y:I}}}let u=(t.positionals??[]).join(" ").trim();if(!u)return{ok:!1,error:{code:"INVALID_ARGS",message:`${o} requires @ref, selector expression, or x y coordinates`}};let c=aa(u),p=await sr(e,t.flags,i,n,{interactiveOnly:!0},a),f=await L("selector_resolve",()=>as(p.nodes,c,{platform:e.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:o});if(!f||!f.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:ad(c,f?.diagnostics??[],{unique:!0})}};let m=so(f.node.rect);if(!m)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Selector ${f.selector.raw} resolved to invalid bounds`}};let{x:h,y:w}=m,g=await a(e.device,"press",[String(h),String(w)],t.flags?.out,{...n(t.flags,e.appBundleId,e.trace?.outPath)}),I=am(f.node,e.device.platform,{action:l}),v=n5(f.node,p.nodes);return i.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{x:h,y:w,selector:f.selector.raw,selectorChain:I,refLabel:v}}),{ok:!0,data:{...g??{},selector:f.selector.raw,x:h,y:w}}}if("fill"===o){let e=i.get(r);if(e&&!nz("fill",e.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"fill is not supported on this device"}};if(t.positionals?.[0]?.startsWith("@")){if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let r=sn("fill",t.flags);if(r)return r;let s=t.positionals.length>=3?t.positionals[1]:"",l=t.positionals.length>=3?t.positionals.slice(2).join(" "):t.positionals.slice(1).join(" ");if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after ref"}};let d=sa({session:e,refInput:t.positionals[0],fallbackLabel:s,requireRect:!0,invalidRefMessage:"fill requires a ref like @e2",notFoundMessage:`Ref ${t.positionals[0]} not found or has no bounds`});if(!d.ok)return d.response;let{ref:u,node:c,snapshotNodes:p}=d.target;if(!c.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${t.positionals[0]} not found or has no bounds`}};let f=c.type??"",m=f&&!ae(f,e.device.platform)?`fill target ${t.positionals[0]} resolved to "${f}", attempting fill anyway.`:void 0,h=n5(c,p),w=am(c,e.device.platform,{action:"fill"}),{x:g,y:I}=n4(c.rect),v={...await a(e.device,"fill",[String(g),String(I),l],t.flags?.out,{...n(t.flags,e.appBundleId,e.trace?.outPath)})??{ref:u,x:g,y:I}};return m&&(v.warning=m),i.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{...v,refLabel:h,selectorChain:w}}),{ok:!0,data:v}}if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let s=au(t.positionals??[],{preferTrailingValue:!0});if(s){if(0===s.rest.length)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let r=s.rest.join(" ").trim();if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let l=aa(s.selectorExpression),d=await sr(e,t.flags,i,n,{interactiveOnly:!0},a),u=await L("selector_resolve",()=>as(d.nodes,l,{platform:e.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:o});if(!u||!u.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:ad(l,u?.diagnostics??[],{unique:!0})}};let c=u.node,p=c.type??"",f=p&&!ae(p,e.device.platform)?`fill target ${u.selector.raw} resolved to "${p}", attempting fill anyway.`:void 0,{x:m,y:h}=n4(u.node.rect),w=await a(e.device,"fill",[String(m),String(h),r],t.flags?.out,{...n(t.flags,e.appBundleId,e.trace?.outPath)}),g=am(c,e.device.platform,{action:"fill"}),I={...w??{x:m,y:h,text:r},selector:u.selector.raw,selectorChain:g,refLabel:n5(c,d.nodes)};return f&&(I.warning=f),i.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:I}),{ok:!0,data:I}}return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires x y text, @ref text, or selector text"}}}if("get"===o){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)return{ok:!1,error:{code:"INVALID_ARGS",message:"get only supports text or attrs"}};let s=i.get(r);if(!s)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nz("get",s.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"get is not supported on this device"}};let l=t.positionals?.[1]??"";if(l.startsWith("@")){let r=sn("get",t.flags);if(r)return r;let n=sa({session:s,refInput:l,fallbackLabel:t.positionals.length>2?t.positionals.slice(2).join(" ").trim():"",requireRect:!1,invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${l} not found`});if(!n.ok)return n.response;let{ref:a,node:d}=n.target,u=am(d,s.device.platform,{action:"get"});if("attrs"===e)return i.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:a,selectorChain:u}}),{ok:!0,data:{ref:a,node:d}};let c=at(d);return i.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:a,text:c,refLabel:c||void 0,selectorChain:u}}),{ok:!0,data:{ref:a,text:c,node:d}}}let d=t.positionals.slice(1).join(" ").trim();if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"get requires @ref or selector expression"}};let u=aa(d),c=await sr(s,t.flags,i,n,{interactiveOnly:!1},a),p=await L("selector_resolve",()=>as(c.nodes,u,{platform:s.device.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:"text"===e}),{command:o});if(!p)return{ok:!1,error:{code:"COMMAND_FAILED",message:ad(u,[],{unique:!0})}};let f=p.node,m=am(f,s.device.platform,{action:"get"});if("attrs"===e)return i.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{selector:p.selector.raw,selectorChain:m}}),{ok:!0,data:{selector:p.selector.raw,node:f}};let h=at(f);return i.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{text:h,refLabel:h||void 0,selector:p.selector.raw,selectorChain:m}}),{ok:!0,data:{selector:p.selector.raw,text:h,node:f}}}if("is"===o){let e=(t.positionals?.[0]??"").toLowerCase();if(!["visible","hidden","exists","editable","selected","text"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires predicate: visible|hidden|exists|editable|selected|text"}};let s=i.get(r);if(!s)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nz("is",s.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"is is not supported on this device"}};let{split:l}=ac(t.positionals);if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires a selector expression"}};let d=l.rest.join(" ").trim();if("text"===e&&!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"is text requires expected text value"}};if("text"!==e&&l.rest.length>0)return{ok:!1,error:{code:"INVALID_ARGS",message:`is ${e} does not accept trailing values`}};let u=aa(l.selectorExpression),c=await sr(s,t.flags,i,n,{interactiveOnly:!1},a);if("exists"===e){let r=al(c.nodes,u,{platform:s.device.platform});return r?(i.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:e,selector:r.selector.raw,selectorChain:u.selectors.map(e=>e.raw),pass:!0,matches:r.matches}}),{ok:!0,data:{predicate:e,pass:!0,selector:r.selector.raw,matches:r.matches}}):{ok:!1,error:{code:"COMMAND_FAILED",message:ad(u,[],{unique:!1})}}}let p=await L("selector_resolve",()=>as(c.nodes,u,{platform:s.device.platform,requireUnique:!0}),{command:"is",predicate:e});if(!p)return{ok:!1,error:{code:"COMMAND_FAILED",message:ad(u,[],{unique:!0})}};let f=function(e){let{predicate:t,node:r,expectedText:i,platform:n}=e,a=at(r),o=!1;switch(t){case"visible":o=ap(r);break;case"hidden":o=!ap(r);break;case"editable":o=af(r,n);break;case"selected":o=!0===r.selected;break;case"text":o=a===(i??"")}let s="text"===t?`expected="${i??""}" actual="${a}"`:`actual=${JSON.stringify({visible:ap(r),editable:af(r,n),selected:!0===r.selected})}`;return{pass:o,actualText:a,details:s}}({predicate:e,node:p.node,expectedText:d,platform:s.device.platform});return f.pass?(i.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:e,selector:p.selector.raw,selectorChain:u.selectors.map(e=>e.raw),pass:!0,text:"text"===e?f.actualText:void 0}}),{ok:!0,data:{predicate:e,pass:!0,selector:p.selector.raw}}):{ok:!1,error:{code:"COMMAND_FAILED",message:`is ${e} failed for selector ${p.selector.raw}: ${f.details}`}}}if("scrollintoview"===o){let e=i.get(r);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nz("scrollintoview",e.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"scrollintoview is not supported on this device"}};let s=t.positionals?.[0]??"";if(!s.startsWith("@"))return null;let l=sn("scrollintoview",t.flags);if(l)return l;let d=sa({session:e,refInput:s,fallbackLabel:t.positionals&&t.positionals.length>1?t.positionals.slice(1).join(" ").trim():"",requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${s} not found or has no bounds`});if(!d.ok)return d.response;let{ref:u,node:c,snapshotNodes:p}=d.target;if(!c.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${s} not found or has no bounds`}};let f=function(e,t){let r=n4(t),i=e.filter(e=>{var t;return!!(t=e.rect)&&Number.isFinite(t.x)&&Number.isFinite(t.y)&&Number.isFinite(t.width)&&Number.isFinite(t.height)}),n=i.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),a=o7(n.map(e=>e.rect).filter(e=>o9(e,r.x,r.y)));if(a)return a;let o=o7(n.map(e=>e.rect));if(o)return o;let s=o7(i.map(e=>e.rect).filter(e=>o9(e,r.x,r.y)));return s||null}(p,c.rect);if(!f)return{ok:!1,error:{code:"COMMAND_FAILED",message:`scrollintoview could not infer viewport for ${s}`}};let m=function(e,t){var r,i;let n=Math.max(1,t.height),a=Math.max(1,t.width),o=t.y,s=t.y+n,l=t.x,d=t.x+a,u=o+.25*n,c=s-.25*n,p=Math.max(8,.1*a),f=e.y+e.height/2,m=e.x+e.width/2;if(f>=u&&f<=c)return null;let h=Math.round((r=m,i=l+p,Math.min(d-p,Math.max(i,r)))),w=Math.round(o+.86*n),g=Math.round(o+.14*n),I=Math.max(1,Math.abs(w-g));return f>c?{x:h,startY:w,endY:g,count:se(Math.ceil((f-c)/I),1,50),direction:"down"}:{x:h,startY:g,endY:w,count:se(Math.ceil((u-f)/I),1,50),direction:"up"}}(c.rect,f),h=n5(c,p),w=am(c,e.device.platform,{action:"get"});if(!m)return i.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:u,attempts:0,alreadyVisible:!0,refLabel:h,selectorChain:w}}),{ok:!0,data:{ref:u,attempts:0,alreadyVisible:!0}};let g=await a(e.device,"swipe",[String(m.x),String(m.startY),String(m.x),String(m.endY),"16"],t.flags?.out,{...n(t.flags,e.appBundleId,e.trace?.outPath),count:m.count,pauseMs:0,pattern:"one-way"});return i.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{...g??{},ref:u,attempts:m.count,direction:m.direction,refLabel:h,selectorChain:w}}),{ok:!0,data:{...g??{},ref:u,attempts:m.count,direction:m.direction}}}return null}async function sr(e,t,r,i,n,a=nW){let o=await a(e.device,"snapshot",[],t?.out,{...i({...t??{},snapshotInteractiveOnly:n.interactiveOnly,snapshotCompact:n.interactiveOnly},e.appBundleId,e.trace?.outPath)}),s=o?.nodes??[];return e.snapshot={nodes:n1(t?.snapshotRaw?s:n9(s)),truncated:o?.truncated,createdAt:Date.now(),backend:o?.backend},r.set(e.name,e),e.snapshot}let si=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function sn(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,i]of si)void 0!==e[r]&&t.push(i);return t}(t);return 0===r.length?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} @ref does not support ${r.join(", ")}.`}}}function sa(e){let{session:t,refInput:r,fallbackLabel:i,requireRect:n,invalidRefMessage:a,notFoundMessage:o}=e;if(!t.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"No snapshot in session. Run snapshot first."}}};let s=n2(r);if(!s)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:a}}};let l=n3(t.snapshot.nodes,s);return((!l||n&&!l.rect)&&i.length>0&&(l=n8(t.snapshot.nodes,i)),l&&(!n||l.rect))?{ok:!0,target:{ref:s,node:l,snapshotNodes:t.snapshot.nodes}}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:o}}}}function so(e){let t=function(e){if(!e)return null;let t=Number(e.x),r=Number(e.y),i=Number(e.width),n=Number(e.height);return Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(i)&&Number.isFinite(n)&&!(i<0)&&!(n<0)?{x:t,y:r,width:i,height:n}:null}(e);if(!t)return null;let r=n4(t);return Number.isFinite(r.x)&&Number.isFinite(r.y)?r:null}function ss(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function sl(e){let{req:t,leaseRegistry:r}=e,i=ss(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:i.tenantId??"",runId:i.runId??"",backend:i.leaseBackend,ttlMs:i.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:i.leaseId??"",tenantId:i.tenantId,runId:i.runId,ttlMs:i.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:i.leaseId??"",tenantId:i.tenantId,runId:i.runId})};default:return null}}let sd=new Set(["session_list","devices","ensure-simulator"]),su=new Set(["session_list","devices","ensure-simulator","lease_allocate","lease_heartbeat","lease_release"]);function sc(e,t,r,i){let n=O().requestId;return{...nK(e,t,r,i,n),requestId:n}}function sp(e){$.existsSync(e)&&$.unlinkSync(e)}function sf(e){if(!$.existsSync(e))return null;try{let t=JSON.parse($.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function sm(e){let t=sf(e);if(!t||t.pid===process.pid)try{$.existsSync(e)&&$.unlinkSync(e)}catch{}}function sh(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:sw,infoPath:sg,lockPath:sI,logPath:sv,sessionsDir:sA}=B(process.env.AGENT_DEVICE_STATE_DIR),sy=G(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var sb=sA;if($.existsSync(sb))for(let e of $.readdirSync(sb,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=n.join(sb,e.name,"app-log.pid");if($.existsSync(t))try{let e=function(e){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t))return{pid:Number.parseInt(t,10)};try{let e=JSON.parse(t);if(!Number.isInteger(e.pid)||e.pid<=0)return null;return e}catch{return null}}($.readFileSync(t,"utf8"));if(e&&function(e){let t,r=T(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let i=a(e.pid);return!!i&&!!((t=i.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||i===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{tI(t)}}let sN=new tw(sA),sS=new t3({maxActiveSimulatorLeases:sh(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:sh(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:sh(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:sh(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),s_=E(),sD=u.randomBytes(24).toString("hex"),sE=T(process.pid)??void 0,sk=function(){let e=process.argv[1];if(!e)return"unknown";try{let t=$.statSync(e),r=k(),i=n.relative(r,e)||e;return`${i}:${t.size}:${Math.trunc(t.mtimeMs)}`}catch{return"unknown"}}(),sO=function(e){let{logPath:t,token:r,sessionStore:i,leaseRegistry:a,trackDownloadableArtifact:s}=e;async function l(e){let d="click"===e.command?{...e,command:"press"}:e,u=!!(d.meta?.debug||d.flags?.verbose);return await P({session:d.session,requestId:d.meta?.requestId,command:d.command,debug:u,logPath:t},async()=>{if(d.token!==r)return{ok:!1,error:_(new I("UNAUTHORIZED","Invalid token"))};try{let e=function(e){let t=D(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,i=o(r);if(r&&!i)throw new I("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!i)throw new I("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");return{...e,session:`${i}:${e.session||"default"}`,meta:{...e.meta,tenantId:i,sessionIsolation:t}}}(d);M({level:"info",phase:"request_start",data:{session:e.session,command:e.command,tenant:e.meta?.tenantId,isolation:e.meta?.sessionIsolation}});let r=e.command,u=t=>(function(e,t,r){let i=O();if(!t.ok){M({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=F({force:!0})??void 0;return{ok:!1,error:_(new I(t.error.code,t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:i.diagnosticId,logPath:e})}}return M({level:"info",phase:"request_success"}),F(),{ok:!0,data:function(e,t,r){var i,a;let o;if(!t)return t;let s=(i=e,a=t,o=Array.isArray(a.artifacts)?[...a.artifacts]:[],"screenshot"!==i.command||o.some(e=>e?.field==="path")||"string"!=typeof a.path||o.push({field:"path",path:a.path,localPath:i.meta?.clientArtifactPaths?.path,fileName:n.basename(i.meta?.clientArtifactPaths?.path??a.path)}),o.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let i=t.path;return{field:t.field,artifactId:r({artifactPath:i,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(e,t,s),c=ss(e);su.has(r)||e.meta?.sessionIsolation!=="tenant"||a.assertLeaseAdmission({tenantId:c.tenantId,runId:c.runId,leaseId:c.leaseId,backend:c.leaseBackend});let p=function(e,t){var r;let i,n=e.session||"default";if(r=e,i=r.flags?.session,"string"==typeof i&&i.trim().length>0||"default"!==n||t.has(n))return n;let a=t.toArray();return 1===a.length?a[0].name:n}(e,i),f=i.get(p);f&&!sd.has(r)&&function(e,t){if(!t)return;let r=[],i=e.device,n=ej(t.platform);if(n&&n!==i.platform&&r.push(`--platform=${t.platform}`),t.target&&t.target!==(i.target??"mobile")&&r.push(`--target=${t.target}`),t.udid&&("ios"!==i.platform||t.udid!==i.id)&&r.push(`--udid=${t.udid}`),t.serial&&("android"!==i.platform||t.serial!==i.id)&&r.push(`--serial=${t.serial}`),t.device&&t.device.trim().toLowerCase()!==i.name.trim().toLowerCase()&&r.push(`--device=${t.device}`),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),n=i.simulatorSetPath?.trim();("ios"!==i.platform||"simulator"!==i.kind||e!==n)&&r.push(`--ios-simulator-device-set=${t.iosSimulatorDeviceSet}`)}if(t.androidDeviceAllowlist){let e=eb(t.androidDeviceAllowlist);"android"===i.platform&&e.has(i.id)||r.push(`--android-device-allowlist=${t.androidDeviceAllowlist}`)}if(0!==r.length){var a;let t,i,n;throw new I("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(a=e).device.platform,i=a.device.name.trim(),n=a.device.id,`${t} device "${i}" (${n})`)} and cannot be used with ${r.join(", ")}. Use a different --session name or close this session first.`)}}(f,e.flags);let m=await sl({req:e,leaseRegistry:a});if(m)return u(m);let h=await o$({req:e,sessionName:p,logPath:t,sessionStore:i,invoke:l});if(h)return u(h);let w=await oz({req:e,sessionName:p,logPath:t,sessionStore:i});if(w)return u(w);let g=await o6({req:e,sessionName:p,sessionStore:i,logPath:t});if(g)return u(g);let v=await o3({req:e,sessionName:p,logPath:t,sessionStore:i,invoke:l});if(v)return u(v);let A=await st({req:e,sessionName:p,sessionStore:i,contextFromFlags:(e,r,i)=>sc(t,e,r,i)});if(A)return u(A);let y=i.get(p);if(!y)return u({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});if(!nz(r,y.device))return u({ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${r} is not supported on this device`}});let b=await nW(y.device,r,e.positionals??[],e.flags?.out,{...sc(t,e.flags,y.appBundleId,y.trace?.outPath)});return i.recordAction(y,{command:r,positionals:e.positionals??[],flags:e.flags??{},result:b??{}}),u({ok:!0,data:b??{}})}catch(r){M({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=O(),t=F({force:!0})??void 0;return{ok:!1,error:_(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return l}({logPath:sv,token:sD,sessionStore:sN,leaseRegistry:sS,trackDownloadableArtifact:function(e){let t=u.randomUUID(),r=setTimeout(()=>{tR(t)},9e5);return tC.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){$.existsSync(e)||$.mkdirSync(e,{recursive:!0});let i=JSON.stringify(r,null,2),n=()=>{try{return $.writeFileSync(t,i,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(n())return!0;let a=sf(t);if(a?.pid&&a.pid!==process.pid&&s(a.pid,a.processStartTime))return!1;try{$.unlinkSync(t)}catch{}return n()}(sw,sI,{pid:process.pid,version:s_,startedAt:Date.now(),processStartTime:sE})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var i;let n;if("socket"===sy||"dual"===sy){let t=U.createServer(e=>{let t="",r=0,i=new Set,n=!1,a=()=>{if(!n&&0!==r){for(let e of(n=!0,i))ea(e);M({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await e7(),!(r<=0));)await new Promise(e=>setTimeout(e,200))})()}};e.setEncoding("utf8"),e.on("close",a),e.on("error",a),e.on("data",async n=>{let a=(t+=n).indexOf("\n");for(;-1!==a;){let n,o,s=t.slice(0,a).trim();if(t=t.slice(a+1),0===s.length){a=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=ei(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},i.add(o),en(o),es(o))throw el();n=await sO(e)}catch(e){n={ok:!1,error:_(e)}}finally{r-=1,o&&(i.delete(o),eo(o))}e.destroyed||e.write(`${JSON.stringify(n)}
37
- `),a=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let i=t.address();"object"==typeof i&&i?.port?e(i.port):r(new I("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===sy||"dual"===sy){let e=await tX({handleRequest:sO,token:sD});r.push(e),t=await new Promise((t,r)=>{e.once("error",r),e.listen(0,"127.0.0.1",()=>{e.off("error",r);let i=e.address();"object"==typeof i&&i?.port?t(i.port):r(new I("COMMAND_FAILED","Failed to bind HTTP server"))})})}i={socketPort:e,httpPort:t,token:sD,version:s_,codeSignature:sk,processStartTime:sE},$.existsSync(sw)||$.mkdirSync(sw,{recursive:!0}),$.writeFileSync(sv,""),n=i.socketPort&&i.httpPort?"dual":i.httpPort?"http":"socket",$.writeFileSync(sg,JSON.stringify({port:i.socketPort,httpPort:i.httpPort,transport:n,token:i.token,pid:process.pid,version:i.version,codeSignature:i.codeSignature,processStartTime:i.processStartTime,stateDir:sw},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
23
+ ${a}
24
+ ${i}`.toLowerCase();return n.includes("timeout waiting for screen surfaces")||n.includes("nsposixerrordomain")&&n.includes("code=60")&&n.includes("screenshot")||n.includes("timed out")&&n.includes("screenshot")}let iC={settings:"com.apple.Preferences"},iR=null;function iT(e,t,r){return c("xcrun",ek(e,t),r)}function iP(e){return e.includes("not installed")||e.includes("not found")||e.includes("no such file")}async function i$(e,t){let r=t.trim();if(r.includes("."))return r;let a=iC[r.toLowerCase()];if(a)return a;let i=("simulator"===e.kind?await iX(e):await ii(e,"all")).filter(e=>e.name.toLowerCase()===r.toLowerCase());if(1===i.length)return i[0].bundleId;if(i.length>1)throw new h("INVALID_ARGS",`Multiple apps matched "${t}"`,{matches:i});throw new h("APP_NOT_INSTALLED",`No app found matching "${t}"`)}async function iF(e,t,r){let a=r?.url?.trim();if(a){if(!rd(a))throw new h("INVALID_ARGS","open <app> <url> requires a valid URL target");if("simulator"===e.kind){await ip(e),await ic(),await iT(e,["openurl",e.id,a]);return}let i=ru(r?.appBundleId??await i$(e,t),a);if(!i)throw new h("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await i8(e,i,{payloadUrl:a});return}let i=t.trim();if(rd(i)){if("simulator"===e.kind){await ip(e),await ic(),await iT(e,["openurl",e.id,i]);return}let t=ru(r?.appBundleId,i);if(!t)throw new h("INVALID_ARGS","Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.");await i8(e,t,{payloadUrl:i});return}let n=r?.appBundleId??await i$(e,t);"simulator"===e.kind?await i4(e,n):await i8(e,n)}async function iU(e){"simulator"!==e.kind||"Booted"!==await ih(e)&&(await ip(e),await ic())}async function iV(e,t){let r=await i$(e,t);if("simulator"===e.kind){await ip(e);let t=ek(e,["terminate",e.id,r]),a=await c("xcrun",t,{allowFailure:!0});if(0!==a.exitCode){if(a.stderr.toLowerCase().includes("found nothing to terminate"))return;throw new h("COMMAND_FAILED",`xcrun exited with code ${a.exitCode}`,{cmd:"xcrun",args:t,stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode})}return}await ia(["device","process","terminate","--device",e.id,r],{action:"terminate iOS app",deviceId:e.id})}async function iG(e,t){let r=await i$(e,t);if("simulator"!==e.kind){let t=["devicectl","device","uninstall","app","--device",e.id,r],a=await c("xcrun",t,{allowFailure:!0,timeoutMs:ie});if(0!==a.exitCode){let i=String(a.stdout??""),n=String(a.stderr??"");if(!iP(`${i}
25
+ ${n}`.toLowerCase()))throw new h("COMMAND_FAILED",`Failed to uninstall iOS app ${r}`,{cmd:"xcrun",args:t,exitCode:a.exitCode,stdout:i,stderr:n,deviceId:e.id,hint:is(i,n)??io})}return{bundleId:r}}await ip(e);let a=await iT(e,["uninstall",e.id,r],{allowFailure:!0});if(0!==a.exitCode&&!iP(`${a.stdout}
26
+ ${a.stderr}`.toLowerCase()))throw new h("COMMAND_FAILED",`simctl uninstall failed for ${r}`,{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});return{bundleId:r}}async function ij(e,t,r){let a=await ig({kind:"path",path:t},r);try{return await iq(e,a.installablePath),{archivePath:a.archivePath,installablePath:a.installablePath,bundleId:a.bundleId,appName:a.appName,launchTarget:a.bundleId}}finally{await a.cleanup()}}async function iB(e,t,r){let{bundleId:a}=await iG(e,t);return await ij(e,r,{appIdentifierHint:t}),{bundleId:a}}async function iq(e,t){"simulator"!==e.kind?await ia(["device","install","app","--device",e.id,t],{action:"install iOS app",deviceId:e.id}):(await ip(e),await iT(e,["install",e.id,t]))}async function iH(e){iu(e,"clipboard"),await ip(e);let t=await iT(e,["pbpaste",e.id],{allowFailure:!0});if(0!==t.exitCode)throw new h("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 iW(e,t){iu(e,"clipboard"),await ip(e);let r=await iT(e,["pbcopy",e.id],{allowFailure:!0,stdin:t});if(0!==r.exitCode)throw new h("COMMAND_FAILED","Failed to write iOS simulator clipboard",{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode})}async function iz(e,t,r){iu(e,"push"),await ip(e);let a=await E.mkdtemp(i.join(C.tmpdir(),"agent-device-ios-push-")),n=i.join(a,"payload.apns");try{await E.writeFile(n,`${JSON.stringify(r)}
27
+ `,"utf8"),await iT(e,["push",e.id,t,n])}finally{await E.rm(a,{recursive:!0,force:!0})}}async function iJ(e,t,r,a,i){iu(e,"settings"),await ip(e);let n=t.toLowerCase();switch(n){case"wifi":{let t=iZ(r);await iT(e,["status_bar",e.id,"override","--wifiMode",t?"active":"failed"]);return}case"airplane":return void(iZ(r)?await iT(e,["status_bar",e.id,"override","--dataNetwork","hide","--wifiMode","failed","--wifiBars","0","--cellularMode","failed","--cellularBars","0","--operatorName",""]):await iT(e,["status_bar",e.id,"clear"]));case"location":{let t=iZ(r);if(!a)throw new h("INVALID_ARGS","location setting requires an active app in session");await iT(e,["privacy",e.id,t?"grant":"revoke","location",a]);return}case"faceid":case"touchid":{let t=iQ[n],a=function(e,t){let r=e.trim().toLowerCase();if("match"===r)return"match";if("nonmatch"===r)return"nonmatch";if("enroll"===r)return"enroll";if("unenroll"===r)return"unenroll";throw new h("INVALID_ARGS",`Invalid ${t} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}(r,n);await i3(e,a,{settingName:n,label:t.label,modalityAliases:t.modalityAliases});return}case"appearance":{let t=await iY(e,r);await iT(e,["ui",e.id,"appearance",t]);return}case"permission":{var o;if(!a)throw new h("INVALID_ARGS","permission setting requires an active app in session");let t="deny"===(o=aX(r))?"revoke":o,n=function(e,t){let r=aZ(e);if("photos"!==r&&t?.trim())throw new h("INVALID_ARGS",`Permission mode is only supported for photos. Received: ${t}.`);if("camera"===r)return"camera";if("microphone"===r)return"microphone";if("contacts"===r)return"contacts";if("contacts-limited"===r)return"contacts-limited";if("notifications"===r)return"notifications";if("calendar"===r)return"calendar";if("location"===r)return"location";if("location-always"===r)return"location-always";if("media-library"===r)return"media-library";if("motion"===r)return"motion";if("reminders"===r)return"reminders";if("siri"===r)return"siri";if("photos"===r){let e=t?.trim().toLowerCase();if(!e||"full"===e)return"photos";if("limited"===e)return"photos-add";throw new h("INVALID_ARGS",`Invalid photos mode: ${t}. Use full|limited.`)}throw new h("INVALID_ARGS",`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}(i?.permissionTarget,i?.permissionMode);await i0(e,t,n,a);return}default:throw new h("INVALID_ARGS",`Unsupported setting: ${t}`)}}async function iK(e,t="all"){var r;return"simulator"===e.kind?(r=await iX(e),"user-installed"===t?r.filter(e=>!e.bundleId.startsWith("com.apple.")):r):await ii(e,t)}async function iX(e){let t=(await iT(e,["listapps",e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let r=null;if(t.startsWith("{"))try{r=JSON.parse(t)}catch{r=null}if(!r&&t.startsWith("{"))try{let e=await c("plutil",["-convert","json","-o","-","-"],{allowFailure:!0,stdin:t});0===e.exitCode&&e.stdout.trim().startsWith("{")&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>({bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e})):[]}function iZ(e){let t=e.toLowerCase();if("on"===t||"true"===t||"1"===t)return!0;if("off"===t||"false"===t||"0"===t)return!1;throw new h("INVALID_ARGS",`Invalid setting state: ${e}`)}async function iY(e,t){let r=aY(t);if("toggle"!==r)return r;let a=await iT(e,["ui",e.id,"appearance"],{allowFailure:!0});if(0!==a.exitCode)throw new h("COMMAND_FAILED","Failed to read current iOS appearance",{stdout:a.stdout,stderr:a.stderr,exitCode:a.exitCode});let i=function(e,t){let r=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}
28
+ ${t}`);if(!r)return null;let a=r[1].toLowerCase();return"dark"===a?"dark":"light"===a?"light":null}(a.stdout,a.stderr);if(!i)throw new h("COMMAND_FAILED","Unable to determine current iOS appearance for toggle",{stdout:a.stdout,stderr:a.stderr});return"dark"===i?"light":"dark"}let iQ={faceid:{label:"Face ID",modalityAliases:["face"]},touchid:{label:"Touch ID",modalityAliases:["finger","touch"]}};async function i0(e,t,r,a){let i=await i2(e);if(!i.has(r))throw new h("UNSUPPORTED_OPERATION",`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:a,hint:`Supported services: ${Array.from(i).sort().join(", ")}`});let n=["privacy",e.id,t,r,a],o="notifications"===r;if(!("reset"===t&&o))try{await iT(e,n);return}catch(t){if(!(o&&i1(t)))throw t;throw new h("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 iT(e,n);return}catch(e){if(!i1(e))throw e}try{await iT(e,["privacy",e.id,"reset","all",a])}catch(t){throw new h("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 i1(e){if(!(e instanceof h)||"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 i2(t){let r=e_(t.simulatorSetPath),a=`${process.env.PATH??""}::${r??""}`;if(iR&&e===a)return iR;let i=await iT(t,["privacy","help"],{allowFailure:!0}),n=function(e){let t=new Set,r=!1;for(let a of e.split("\n")){let e=a.trim();if(!e)continue;if("service"===e){r=!0;continue}if(!r)continue;if(e.startsWith("bundle identifier"))break;let i=/^([a-z-]+)\s+-\s+/.exec(e);i&&t.add(i[1])}return t}(`${i.stdout}
29
+ ${i.stderr}`);if(0===n.size)throw new h("COMMAND_FAILED","Unable to determine supported simctl privacy services",{stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:"Run `xcrun simctl privacy help` manually to verify available services for this runtime."});return iR=n,e=a,n}async function i3(e,t,r){let a=function(e,t,r){let a=r.length>0?r:["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,r.modalityAliases),i=[];for(let t of a){let r=ek(e,t),a=await c("xcrun",r,{allowFailure:!0});if(0===a.exitCode)return;i.push({args:r,stderr:a.stderr,stdout:a.stdout,exitCode:a.exitCode})}let n=i.map(e=>({args:e.args.join(" "),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}));if(i.length>0&&i.every(e=>{var t,r;let a;return t=e.stdout,r=e.stderr,(a=`${t}
30
+ ${r}`.toLowerCase()).includes("unrecognized subcommand")||a.includes("unknown subcommand")||a.includes("not supported")||a.includes("unavailable")||a.includes("biometric")&&a.includes("invalid")}))throw new h("UNSUPPORTED_OPERATION",`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:n});throw new h("COMMAND_FAILED",`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:t,setting:r.settingName,attempts:n})}async function i4(e,t){await ip(e),await ic();let r=0,a=Z.fromTimeoutMs(a7);try{await Y(async({deadline:r})=>{var a;if(r?.isExpired())throw new h("COMMAND_FAILED","App launch deadline exceeded",{timeoutMs:a7});let i=(a=["launch",e.id,t],ek(e,a)),n=await c("xcrun",i,{allowFailure:!0});if(0!==n.exitCode)throw new h("COMMAND_FAILED",`xcrun exited with code ${n.exitCode}`,{cmd:"xcrun",args:i,stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode})},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry:e=>!!il(e)&&(r+=1)<3},{deadline:a})}catch(r){if(il(r)){var i;let a=(i=await id(e,t)).installed?!1===i.simulatorCompatible?"ARCH_MISMATCH":"PERSISTENT_LAUNCH_FAIL":"APP_NOT_INSTALLED";r.details={...r.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 r}}async function i8(e,t,r){let a=["device","process","launch","--device",e.id,t];r?.payloadUrl&&a.push("--payload-url",r.payloadUrl),await ia(a,{action:"launch iOS app",deviceId:e.id})}let i6=/^[A-Za-z0-9_.:-]{1,64}$/,i5=[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1]];function i9(e,t,r,a){if(!Number.isFinite(e)||!Number.isInteger(e)||e<r||e>a)throw new h("INVALID_ARGS",`${t} must be an integer between ${r} and ${a}`);return e}async function i7(e,t,r){for(let a=0;a<e;a+=1)await r(a),a<e-1&&t>0&&await ne(t)}async function ne(e){await new Promise(t=>setTimeout(t,e))}function nt(e,t){let r,a=t?.subject??"Payload",i=e.trim();if(!i)throw new h("INVALID_ARGS",`${a} cannot be empty`);let n=t?.expandPath?t.expandPath(i,t.cwd):i;try{if(!M.statSync(n).isFile())throw new h("INVALID_ARGS",`${a} path is not a file: ${n}`);return{kind:"file",path:n}}catch(t){if(t instanceof h)throw t;let e=t.code;if("EACCES"===e||"EPERM"===e)throw new h("INVALID_ARGS",`${a} file is not readable: ${n}`);if(e&&"ENOENT"!==e)throw new h("COMMAND_FAILED",`Unable to read ${a} file: ${n}`,{cause:String(t)})}if((r=i.trim()).startsWith("{")&&r.endsWith("}")||r.startsWith("[")&&r.endsWith("]"))return{kind:"inline",text:i};throw new h("INVALID_ARGS",`${a} file not found: ${n}`)}async function nr(e){let t=nt(e,{subject:"Push payload"}),r="inline"===t.kind?t.text:await na(t.path);try{let e=JSON.parse(r);if(!e||"object"!=typeof e||Array.isArray(e))throw new h("INVALID_ARGS","push payload must be a JSON object");return e}catch(t){if(t instanceof h)throw t;throw new h("INVALID_ARGS",`Invalid push payload JSON: ${e}`)}}async function na(e){try{return await E.readFile(e,"utf8")}catch(r){let t=r.code;if("ENOENT"===t)throw new h("INVALID_ARGS",`Push payload file not found: ${e}`);if("EISDIR"===t)throw new h("INVALID_ARGS",`Push payload path is not a file: ${e}`);if("EACCES"===t||"EPERM"===t)throw new h("INVALID_ARGS",`Push payload file is not readable: ${e}`);throw new h("COMMAND_FAILED",`Unable to read push payload file: ${e}`,{cause:String(r)})}}let ni=ev(process.env.AGENT_DEVICE_IOS_DEVICECTL_LIST_TIMEOUT_MS,8e3,500),nn=/^(iphone|ipad|ipod|appletv)/i,no=/^appletv/i,ns=["apple tv","appletv","tvos"];function nl(e){return(e??"").trim().toLowerCase()}function nd(e){return nl(e.hardwareProperties?.platform)}function nu(e){return e.includes("tvos")}function nc(e){return nu(nl(e))?"tv":"mobile"}function np(e){let t=nl(e);return t.includes("ios")||t.includes("tvos")}function nf(e){let t=nl(e);return ns.some(e=>t.includes(e))}function nm(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function nh(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function nw(e={}){let t,r,a=e_(e.simulatorSetPath),i=e.target;try{t=await c("xcrun",eE(["list","devices","-j"],{simulatorSetPath:a}))}catch{return null}try{r=JSON.parse(t.stdout)}catch{return null}let n=null,o=null,s=null;for(let[e,t]of Object.entries(r.devices)){if(!np(e))continue;let r=nc(e);if(!i||r===i)for(let e of t){if(!e.isAvailable)continue;let t={platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:r,booted:"Booted"===e.state,...a?{simulatorSetPath:a}:{}};t.booted&&(n=n??t),"mobile"===r&&(o=o??t),s=s??t}}return n??o??s}async function ng(e={}){if("darwin"!==process.platform)throw new h("UNSUPPORTED_PLATFORM","iOS tools are only available on macOS");if(!await g("xcrun"))throw new h("TOOL_MISSING","xcrun not found in PATH");let t=[],r=e_(e.simulatorSetPath),a=await c("xcrun",eE(["list","devices","-j"],{simulatorSetPath:r}));try{let e=JSON.parse(a.stdout);for(let[a,i]of Object.entries(e.devices))if(np(a))for(let e of i)e.isAvailable&&t.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:nc(a),booted:"Booted"===e.state,...r?{simulatorSetPath:r}:{}})}catch(e){throw new h("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(r)return t;let n=null;try{n=i.join(C.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let e=await c("xcrun",["devicectl","list","devices","--json-output",n],{allowFailure:!0,timeoutMs:ni});if(0!==e.exitCode)return t;let r=await E.readFile(n,"utf8"),a=JSON.parse(r);for(let e of a.result?.devices??[])if(function(e){var t;let r=nd(e);return!!(r.includes("ios")||r.includes("tvos"))||(t=nh(e),!!nn.test(t.trim())||nm(e).some(nf))}(e)){let r=e.hardwareProperties?.udid??e.identifier??"",a=e.name??e.deviceProperties?.name??r;if(!r)continue;t.push({platform:"ios",id:r,name:a,kind:"device",target:function(e){var t;return nu(nd(e))?"tv":(t=nh(e),no.test(t.trim())||nm(e).some(nf))?"tv":"mobile"}(e),booted:!0})}}catch{}finally{n&&await E.rm(n,{force:!0}).catch(()=>{})}return t}async function nI(e,t,r,a){let i,n=!!(t.udid||t.serial||t.deviceName);try{i=await a.selectDevice(e,t,r)}catch(e){if(n||!(e instanceof h)||"DEVICE_NOT_FOUND"!==e.code)throw e}if(!n&&(!i||"device"===i.kind)){let e=await a.findBootableSimulator({simulatorSetPath:r.simulatorSetPath,target:t.target});if(e)return e}if(i)return i;throw new h("DEVICE_NOT_FOUND","No devices found",{selector:t})}async function nv(e){let t=eW(e.platform),r=e_(e.iosSimulatorDeviceSet),a=eD(e.androidDeviceAllowlist);return await S("resolve_target_device",async()=>{let i={platform:t,target:e.target,deviceName:e.device,udid:e.udid,serial:e.serial};if(i.target&&!i.platform)throw new h("INVALID_ARGS","Device target selector requires --platform. Use --platform ios|android|apple with --target mobile|tv.");if("android"===i.platform){await ro();let e=await rb({serialAllowlist:a});return await ez(e,i)}if("ios"===i.platform){let e=await ng({simulatorSetPath:r});return await nI(e,i,{simulatorSetPath:r},{selectDevice:ez,findBootableSimulator:nw})}let n=[];try{n.push(...await rb({serialAllowlist:a}))}catch{}try{n.push(...await ng({simulatorSetPath:r}))}catch{}return await ez(n,i,{simulatorSetPath:r})},{platform:t,target:e.target})}async function nA(e,t,r,a,n){let o=function(e,t){switch(e.platform){case"android":return{open:(t,r)=>r9(e,t,r?.activity),openDevice:()=>ae(e),close:t=>at(e,t),tap:(t,r)=>aD(e,t,r),doubleTap:async(t,r)=>{await aD(e,t,r),await aD(e,t,r)},swipe:(t,r,a,i,n)=>aE(e,t,r,a,i,n),longPress:(t,r,a)=>aM(e,t,r,a),focus:(t,r)=>aC(e,t,r),type:t=>ax(e,t),fill:(t,r,a)=>aR(e,t,r,a),scroll:(t,r)=>aT(e,t,r),scrollIntoView:t=>aP(e,t),screenshot:(t,r)=>ay(e,t)};case"ios":var r,a;let i,n;return{open:(t,r)=>iF(e,t,{appBundleId:r?.appBundleId,url:r?.url}),openDevice:()=>iU(e),close:t=>iV(e,t),screenshot:(t,r)=>i_(e,t,r),...(r=e,i={verbose:(a=t).verbose,logPath:a.logPath,traceLogPath:a.traceLogPath,requestId:a.requestId},n=()=>{if(ed(a.requestId))throw ec()},{tap:async(e,t)=>{await tl(r,{command:"tap",x:e,y:t,appBundleId:a.appBundleId},i)},doubleTap:async(e,t)=>{await tl(r,{command:"tapSeries",x:e,y:t,count:1,intervalMs:0,doubleTap:!0,appBundleId:a.appBundleId},i)},swipe:async(e,t,n,o,s)=>{await tl(r,{command:"drag",x:e,y:t,x2:n,y2:o,durationMs:s,appBundleId:a.appBundleId},i)},longPress:async(e,t,n)=>{await tl(r,{command:"longPress",x:e,y:t,durationMs:n,appBundleId:a.appBundleId},i)},focus:async(e,t)=>{await tl(r,{command:"tap",x:e,y:t,appBundleId:a.appBundleId},i)},type:async e=>{await tl(r,{command:"type",text:e,appBundleId:a.appBundleId},i)},fill:async(e,t,n)=>{await tl(r,{command:"tap",x:e,y:t,appBundleId:a.appBundleId},i),await tl(r,{command:"type",text:n,clearFirst:!0,appBundleId:a.appBundleId},i)},scroll:async(e,t)=>{if(!["up","down","left","right"].includes(e))throw new h("INVALID_ARGS",`Unknown direction: ${e}`);let n=function(e){switch(e){case"up":return"down";case"down":return"up";case"left":return"right";case"right":return"left"}}(e);await tl(r,{command:"swipe",direction:n,appBundleId:a.appBundleId},i)},scrollIntoView:async e=>{let t=await tl(r,{command:"findText",text:e,appBundleId:a.appBundleId},i);if(t?.found)return{attempts:1};for(let t=0;t<12;t+=1){for(let e=0;e<4;e+=1)n(),await tl(r,{command:"swipe",direction:"up",appBundleId:a.appBundleId},i),await new Promise(e=>setTimeout(e,80));n();let o=await tl(r,{command:"findText",text:e,appBundleId:a.appBundleId},i);if(o?.found)return{attempts:t+2}}throw new h("COMMAND_FAILED",`scrollintoview could not find text: ${e}`)}})};default:throw new h("UNSUPPORTED_PLATFORM",`Unsupported platform: ${e.platform}`)}}(e,{requestId:n?.requestId,appBundleId:n?.appBundleId,verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath});return D({level:"debug",phase:"platform_command_prepare",data:{command:t,platform:e.platform,kind:e.kind}}),await S("platform_command",async()=>{switch(t){case"open":{let t=r[0],a=r[1];if(r.length>2)throw new h("INVALID_ARGS","open accepts at most two arguments: <app|url> [url]");if(!t)return await o.openDevice(),{app:null};if(void 0!==a){if("ios"!==e.platform)throw new h("INVALID_ARGS","open <app> <url> is supported only on iOS");if(rd(t))throw new h("INVALID_ARGS","open <app> <url> requires an app target as the first argument");if(!rd(a))throw new h("INVALID_ARGS","open <app> <url> requires a valid URL target");return await o.open(t,{activity:n?.activity,appBundleId:n?.appBundleId,url:a}),{app:t,url:a}}return await o.open(t,{activity:n?.activity,appBundleId:n?.appBundleId}),{app:t}}case"close":{let e=r[0];if(!e)return{closed:"session"};return await o.close(e),{app:e}}case"press":{let[t,a]=r.map(Number);if(Number.isNaN(t)||Number.isNaN(a))throw new h("INVALID_ARGS","press requires x y");let i=i9(n?.count??1,"count",1,200),s=i9(n?.intervalMs??0,"interval-ms",0,1e4),l=i9(n?.holdMs??0,"hold-ms",0,1e4),d=i9(n?.jitterPx??0,"jitter-px",0,100),u=n?.doubleTap===!0;if(u&&l>0)throw new h("INVALID_ARGS","double-tap cannot be combined with hold-ms");if(u&&d>0)throw new h("INVALID_ARGS","double-tap cannot be combined with jitter-px");if("ios"===e.platform&&i>1&&0===l&&0===d)return await tl(e,{command:"tapSeries",x:t,y:a,count:i,intervalMs:s,doubleTap:u,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{x:t,y:a,count:i,intervalMs:s,holdMs:l,jitterPx:d,doubleTap:u,timingMode:"runner-series"};return await i7(i,s,async e=>{let[r,i]=function(e,t){if(t<=0)return[0,0];let[r,a]=i5[e%i5.length];return[r*t,a*t]}(e,d),n=t+r,s=a+i;u?await o.doubleTap(n,s):l>0?await o.longPress(n,s,l):await o.tap(n,s)}),{x:t,y:a,count:i,intervalMs:s,holdMs:l,jitterPx:d,doubleTap:u}}case"swipe":{let t=Number(r[0]),a=Number(r[1]),i=Number(r[2]),s=Number(r[3]);if([t,a,i,s].some(Number.isNaN))throw new h("INVALID_ARGS","swipe requires x1 y1 x2 y2 [durationMs]");let l=i9(r[4]?Number(r[4]):250,"durationMs",16,1e4),d="ios"===e.platform?Math.min(60,Math.max(16,Math.round(l))):l,u=i9(n?.count??1,"count",1,200),c=i9(n?.pauseMs??0,"pause-ms",0,1e4),p=n?.pattern??"one-way";if("one-way"!==p&&"ping-pong"!==p)throw new h("INVALID_ARGS",`Invalid pattern: ${p}`);if("ios"===e.platform&&u>1)return await tl(e,{command:"dragSeries",x:t,y:a,x2:i,y2:s,durationMs:d,count:u,pauseMs:c,pattern:p,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{x1:t,y1:a,x2:i,y2:s,durationMs:l,effectiveDurationMs:d,timingMode:"runner-series",count:u,pauseMs:c,pattern:p};return await i7(u,c,async e=>{"ping-pong"===p&&e%2==1?await o.swipe(i,s,t,a,d):await o.swipe(t,a,i,s,d)}),{x1:t,y1:a,x2:i,y2:s,durationMs:l,effectiveDurationMs:d,timingMode:"ios"===e.platform?"safe-normalized":"direct",count:u,pauseMs:c,pattern:p}}case"longpress":{let e=Number(r[0]),t=Number(r[1]),a=r[2]?Number(r[2]):void 0;if(Number.isNaN(e)||Number.isNaN(t))throw new h("INVALID_ARGS","longpress requires x y [durationMs]");return await o.longPress(e,t,a),{x:e,y:t,durationMs:a}}case"focus":{let[e,t]=r.map(Number);if(Number.isNaN(e)||Number.isNaN(t))throw new h("INVALID_ARGS","focus requires x y");return await o.focus(e,t),{x:e,y:t}}case"type":{let e=r.join(" ");if(!e)throw new h("INVALID_ARGS","type requires text");return await o.type(e),{text:e}}case"fill":{let e=Number(r[0]),t=Number(r[1]),a=r.slice(2).join(" ");if(Number.isNaN(e)||Number.isNaN(t)||!a)throw new h("INVALID_ARGS","fill requires x y text");return await o.fill(e,t,a),{x:e,y:t,text:a}}case"scroll":{let e=r[0],t=r[1]?Number(r[1]):void 0;if(!e)throw new h("INVALID_ARGS","scroll requires direction");return await o.scroll(e,t),{direction:e,amount:t}}case"scrollintoview":{let e=r.join(" ").trim();if(!e)throw new h("INVALID_ARGS","scrollintoview requires text");let t=await o.scrollIntoView(e);if(t?.attempts)return{text:e,attempts:t.attempts};return{text:e}}case"pinch":{if("android"===e.platform)throw new h("UNSUPPORTED_OPERATION","Android pinch is not supported in current adb backend; requires instrumentation-based backend.");let t=Number(r[0]),a=r[1]?Number(r[1]):void 0,i=r[2]?Number(r[2]):void 0;if(Number.isNaN(t)||t<=0)throw new h("INVALID_ARGS","pinch requires scale > 0");return await tl(e,{command:"pinch",scale:t,x:a,y:i,appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{scale:t,x:a,y:i}}case"trigger-app-event":{let{eventName:t,payload:a}=function(e){let t=e[0]?.trim(),r=e[1]?.trim();if(!t)throw new h("INVALID_ARGS","trigger-app-event requires <event> [payloadJson]");if(!i6.test(t))throw new h("INVALID_ARGS",`Invalid trigger-app-event event name: ${t}`,{hint:"Use 1-64 chars: letters, numbers, underscore, dot, colon, or dash."});if(e.length>2)throw new h("INVALID_ARGS","trigger-app-event accepts at most two arguments: <event> [payloadJson]");let a=function(e,t){if(e)try{let r=JSON.parse(e);if(!r||"object"!=typeof r||Array.isArray(r))throw new h("INVALID_ARGS",`trigger-app-event payload for "${t}" must be a JSON object`);let a=JSON.stringify(r);if(Buffer.byteLength(a,"utf8")>8192)throw new h("INVALID_ARGS",`trigger-app-event payload for "${t}" exceeds 8192 bytes`);return r}catch(t){if(t instanceof h)throw t;throw new h("INVALID_ARGS",`Invalid trigger-app-event payload JSON: ${e}`)}}(r,t);return{eventName:t,payload:a}}(r),i=function(e,t,r){let a,i=(a=("ios"===e?process.env.AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE:process.env.AGENT_DEVICE_ANDROID_APP_EVENT_URL_TEMPLATE)??process.env.AGENT_DEVICE_APP_EVENT_URL_TEMPLATE,a?.trim()||void 0);if(!i)throw new h("UNSUPPORTED_OPERATION",`No app event URL template configured for ${e}.`,{hint:`Set AGENT_DEVICE_${e.toUpperCase()}_APP_EVENT_URL_TEMPLATE or AGENT_DEVICE_APP_EVENT_URL_TEMPLATE, for example "myapp://agent-device/event?name={event}&payload={payload}".`});let n=r?JSON.stringify(r):"",o=i.replaceAll("{event}",encodeURIComponent(t)).replaceAll("{payload}",encodeURIComponent(n)).replaceAll("{platform}",encodeURIComponent(e));if(o.length>4096)throw new h("INVALID_ARGS","trigger-app-event URL exceeds maximum supported length",{hint:"Reduce payload size or shorten AGENT_DEVICE_*_APP_EVENT_URL_TEMPLATE.",length:o.length,maxLength:4096});return o}(e.platform,t,a);return await o.open(i,{appBundleId:n?.appBundleId}),{event:t,eventUrl:i,transport:"deep-link"}}case"screenshot":{let e=r[0]??a??`./screenshot-${Date.now()}.png`;return await E.mkdir(i.dirname(e),{recursive:!0}),await o.screenshot(e,n?.appBundleId),{path:e}}case"back":if("ios"===e.platform)return await tl(e,{command:"back",appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{action:"back"};return await ak(e),{action:"back"};case"home":if("ios"===e.platform)return await tl(e,{command:"home",appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{action:"home"};return await aL(e),{action:"home"};case"app-switcher":if("ios"===e.platform)return await tl(e,{command:"appSwitcher",appBundleId:n?.appBundleId},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{action:"app-switcher"};return await aO(e),{action:"app-switcher"};case"clipboard":{let t=(r[0]??"").toLowerCase();if("read"!==t&&"write"!==t)throw new h("INVALID_ARGS","clipboard requires a subcommand: read or write");if("read"===t){if(1!==r.length)throw new h("INVALID_ARGS","clipboard read does not accept additional arguments");return{action:t,text:"ios"===e.platform?await iH(e):await aW(e)}}if(r.length<2)throw new h("INVALID_ARGS",'clipboard write requires text (use "" to clear clipboard)');let a=r.slice(1).join(" ");return"ios"===e.platform?await iW(e,a):await az(e,a),{action:t,textLength:Array.from(a).length}}case"keyboard":{if("android"!==e.platform)throw new h("UNSUPPORTED_OPERATION","keyboard is currently supported only on Android");let t=(r[0]??"status").toLowerCase();if("status"!==t&&"get"!==t&&"dismiss"!==t)throw new h("INVALID_ARGS","keyboard requires a subcommand: status, get, or dismiss");if(r.length>1)throw new h("INVALID_ARGS","keyboard accepts at most one subcommand argument");if("dismiss"===t){let t=await aH(e);return{platform:"android",action:"dismiss",attempts:t.attempts,wasVisible:t.wasVisible,dismissed:t.dismissed,visible:t.visible,inputType:t.inputType,type:t.type}}let a=await aq(e);return{platform:"android",action:"status",visible:a.visible,inputType:a.inputType,type:a.type}}case"settings":{let[t,a,i,o,s]=r,l="permission"===t?{permissionTarget:i,permissionMode:o}:void 0;if(D({level:"debug",phase:"settings_apply",data:{setting:t,state:a,target:i,mode:o,platform:e.platform}}),"ios"===e.platform)return await iJ(e,t,a,s??n?.appBundleId,l),{setting:t,state:a};return await aQ(e,t,a,s??n?.appBundleId,l),{setting:t,state:a}}case"push":{let t=r[0]?.trim(),a=r[1]?.trim();if(!t||!a)throw new h("INVALID_ARGS","push requires <bundle|package> <payload.json|inline-json>");let i=await nr(a);if("ios"===e.platform)return await iz(e,t,i),{platform:"ios",bundleId:t};let n=await a6(e,t,i);return{platform:"android",package:t,action:n.action,extrasCount:n.extrasCount}}case"snapshot":{if("ios"===e.platform){let t=await S("snapshot_capture",async()=>await tl(e,{command:"snapshot",appBundleId:n?.appBundleId,interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw},{verbose:n?.verbose,logPath:n?.logPath,traceLogPath:n?.traceLogPath,requestId:n?.requestId}),{backend:"xctest"}),r=t.nodes??[];if(0===r.length&&"simulator"===e.kind)throw new h("COMMAND_FAILED","XCTest snapshot returned 0 nodes on iOS simulator.");return{nodes:r,truncated:t.truncated??!1,backend:"xctest"}}let t=await S("snapshot_capture",async()=>await av(e,{interactiveOnly:n?.snapshotInteractiveOnly,compact:n?.snapshotCompact,depth:n?.snapshotDepth,scope:n?.snapshotScope,raw:n?.snapshotRaw}),{backend:"android"});return{nodes:t.nodes??[],truncated:t.truncated??!1,backend:"android"}}default:throw new h("INVALID_ARGS",`Unknown command: ${t}`)}},{command:t,platform:e.platform})}let ny={alert:{ios:{simulator:!0},android:{}},pinch:{ios:{simulator:!0},android:{}},"app-switcher":{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},apps:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},back:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},boot:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},click:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},clipboard:{ios:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0}},keyboard:{ios:{},android:{emulator:!0,device:!0,unknown:!0}},close:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},fill:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},diff:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},find:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},focus:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},get:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},is:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},home:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},logs:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},network:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},longpress:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},open:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},perf:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},install:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},reinstall:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},press:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},push:{ios:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0}},record:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},screenshot:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},scroll:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},scrollintoview:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},swipe:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},settings:{ios:{simulator:!0},android:{emulator:!0,device:!0,unknown:!0}},snapshot:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},"trigger-app-event":{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},type:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}},wait:{ios:{simulator:!0,device:!0},android:{emulator:!0,device:!0,unknown:!0}}};function nb(e,t){let r=ny[e];if(!r)return!0;let a=r[t.platform];return!!a&&!0===a[t.kind??"unknown"]}function nN(e,t,r,a,i){return{requestId:i??_().requestId,appBundleId:r,activity:t?.activity,verbose:t?.verbose,logPath:e,traceLogPath:a,snapshotInteractiveOnly:t?.snapshotInteractiveOnly,snapshotCompact:t?.snapshotCompact,snapshotDepth:t?.snapshotDepth,snapshotScope:t?.snapshotScope,snapshotRaw:t?.snapshotRaw,count:t?.count,intervalMs:t?.intervalMs,holdMs:t?.holdMs,jitterPx:t?.jitterPx,doubleTap:t?.doubleTap,pauseMs:t?.pauseMs,pattern:t?.pattern}}let n_=ev(process.env.AGENT_DEVICE_IOS_DEVICE_READY_TIMEOUT_MS,15e3,1e3);async function nS(e){if("ios"===e.platform){if("simulator"===e.kind){let{ensureBootedSimulator:t}=await Promise.resolve().then(()=>({ensureBootedSimulator:ip}));await t(e);return}if("device"===e.kind)return void await nD(e.id)}if("android"===e.platform){let{waitForAndroidBoot:t}=await Promise.resolve().then(()=>({waitForAndroidBoot:rL}));await t(e.id)}}async function nD(e){let t=i.join(C.tmpdir(),`agent-device-ready-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`),r=Math.max(1,Math.ceil(n_/1e3));try{let a=await c("xcrun",["devicectl","device","info","details","--device",e,"--json-output",t,"--timeout",String(r)],{allowFailure:!0,timeoutMs:n_+3e3}),i=String(a.stdout??""),n=String(a.stderr??""),o=await nE(t);if(0===a.exitCode){if(!o.parsed)throw new h("COMMAND_FAILED","iOS device readiness probe failed",{kind:"probe_inconclusive",deviceId:e,stdout:i,stderr:n,hint:"CoreDevice returned success but readiness JSON output was missing or invalid. Retry; if it persists restart Xcode and the iOS device."});let t=o?.tunnelState?.toLowerCase();if("connecting"===t)throw new h("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,tunnelState:t,hint:"Device tunnel is still connecting. Keep the device unlocked and connected by cable until it is fully available in Xcode Devices, then retry."});return}throw new h("COMMAND_FAILED","iOS device is not ready for automation",{kind:"not_ready",deviceId:e,stdout:i,stderr:n,exitCode:a.exitCode,tunnelState:o?.tunnelState,hint:nk(i,n)})}catch(t){if(t instanceof h&&"COMMAND_FAILED"===t.code){if("not_ready"===("string"==typeof t.details?.kind?t.details.kind:""))throw t;let r=t.details??{},a=String(r.stdout??""),i=String(r.stderr??""),n=Number(r.timeoutMs??n_),o=`CoreDevice did not respond within ${n}ms. Keep the device unlocked and trusted, then retry; if it persists restart Xcode and the iOS device.`;throw new h("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,cause:t.message,timeoutMs:n,stdout:a,stderr:i,hint:a||i?nk(a,i):o},t)}throw new h("COMMAND_FAILED","iOS device readiness probe failed",{deviceId:e,hint:"Reconnect the device, keep it unlocked, and retry."},t instanceof Error?t:void 0)}finally{await E.rm(t,{force:!0}).catch(()=>{})}}async function nE(e){try{let t=await E.readFile(e,"utf8"),r=JSON.parse(t),a=function(e){let t=e?.result;if(!t||"object"!=typeof t)return{};let r=t.connectionProperties?.tunnelState,a=t.device?.connectionProperties?.tunnelState,i="string"==typeof r?r:"string"==typeof a?a:void 0;return i?{tunnelState:i}:{}}(r);return{parsed:!0,tunnelState:a.tunnelState}}catch{return{parsed:!1}}}function nk(e,t){let r=is(e,t);return r||(`${e}
31
+ ${t}`.toLowerCase().includes("timed out waiting for all destinations")?"Xcode destination did not become available in time. Keep device unlocked and retry.":io)}function nL(e){return e.map((e,t)=>({...e,ref:`e${t+1}`}))}function nO(e){let t=e.trim();return t.startsWith("@")?t.slice(1)||null:t.startsWith("e")?t:null}function nM(e,t){return e.find(e=>e.ref===t)??null}function nx(e){return{x:Math.round(e.x+e.width/2),y:Math.round(e.y+e.height/2)}}function nC(e,t){let r=t.toLowerCase();return e.find(e=>{let t=(e.label??"").toLowerCase(),a=(e.value??"").toLowerCase(),i=(e.identifier??"").toLowerCase();return t.includes(r)||a.includes(r)||i.includes(r)})??null}function nR(e,t){let r=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);return r&&nT(r)?r:function(e,t){if(!e.rect)return;let r=e.rect.y+e.rect.height/2,a=null;for(let e of t){if(!e.rect)continue;let t=[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0);if(!t||!nT(t))continue;let i=Math.abs(e.rect.y+e.rect.height/2-r);(!a||i<a.distance)&&(a={label:t,distance:i})}return a?.label}(e,t)??(r&&nT(r)?r:void 0)}function nT(e){let t=e.trim();return!(!t||/^(true|false)$/i.test(t)||/^\d+$/.test(t))}function nP(e){let t=[],r=[];for(let a of e){let e=a.depth??0;for(;t.length>0&&e<=t[t.length-1];)t.pop();let i=n$(a.type??""),n=[a.label,a.value,a.identifier].map(e=>"string"==typeof e?e.trim():"").find(e=>e&&e.length>0),o=!!n&&nT(n);if(("group"===i||"ioscontentgroup"===i)&&!o){t.push(e);continue}let s=Math.max(0,e-t.length);r.push({...a,depth:s})}return r}function n$(e){let t=e.trim().replace(/XCUIElementType/gi,"").toLowerCase(),r=Math.max(t.lastIndexOf("."),t.lastIndexOf("/"));return -1!==r&&(t=t.slice(r+1)),t}function nF(e,t){let r=n$(e);return!r||("android"===t?r.includes("edittext")||r.includes("autocompletetextview"):r.includes("textfield")||r.includes("securetextfield")||r.includes("searchfield")||r.includes("textview")||r.includes("textarea")||"search"===r)}function nU(e){return[e.label,e.value,e.identifier].map(e=>"string"==typeof e?e.trim():"").filter(e=>e.length>0)[0]??""}let nV=new Set(["id","role","text","label","value"]),nG=new Set(["visible","hidden","editable","selected","enabled","hittable"]),nj=new Set([...nV,...nG]);function nB(e){let t=e.trim();if(!t)throw new h("INVALID_ARGS","Selector expression cannot be empty");let r=function(e){let t=[],r="",a=null;for(let i=0;i<e.length;i+=1){let n=e[i];if(('"'===n||"'"===n)&&!n5(e,i)){a?a===n&&(a=null):a=n,r+=n;continue}if(!a&&"|"===n&&"|"===e[i+1]){let a=r.trim();if(!a)throw new h("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);t.push(a),r="",i+=1;continue}r+=n}let i=r.trim();if(!i)throw new h("INVALID_ARGS",`Invalid selector fallback expression: ${e}`);return t.push(i),t}(t);if(0===r.length)throw new h("INVALID_ARGS","Selector expression cannot be empty");return{raw:t,selectors:r.map(e=>(function(e){let t=e.trim();if(!t)throw new h("INVALID_ARGS","Selector segment cannot be empty");let r=function(e){let t=[],r="",a=null;for(let i=0;i<e.length;i+=1){let n=e[i];if(('"'===n||"'"===n)&&!n5(e,i)){a?a===n&&(a=null):a=n,r+=n;continue}if(!a&&/\s/.test(n)){r.trim().length>0&&t.push(r.trim()),r="";continue}r+=n}if(a)throw new h("INVALID_ARGS",`Unclosed quote in selector: ${e}`);return r.trim().length>0&&t.push(r.trim()),t}(t);if(0===r.length)throw new h("INVALID_ARGS",`Invalid selector segment: ${e}`);return{raw:t,terms:r.map(nQ)}})(e))}}function nq(e){try{return nB(e)}catch{return null}}function nH(e,t,r){let a=r.requireRect??!1,i=r.requireUnique??!0,n=r.disambiguateAmbiguous??!1,o=[];for(let s=0;s<t.selectors.length;s+=1){let l=t.selectors[s],d=function(e,t,r){let a=0,i=null,n=null,o=!1;for(let s of e){if(r.requireRect&&!s.rect||!n0(s,t,r.platform))continue;if(a+=1,i||(i=s),!n){n=s;continue}let e=function(e,t){let r=e.depth??0,a=t.depth??0;if(r!==a)return r>a?1:-1;let i=n6(e),n=n6(t);return i!==n?i<n?1:-1:0}(s,n);if(e>0){n=s,o=!1;continue}0===e&&(o=!0)}return{count:a,firstNode:i,disambiguated:o?null:n}}(e,l,{platform:r.platform,requireRect:a});if(o.push({selector:l.raw,matches:d.count}),0!==d.count&&d.firstNode){if(i&&1!==d.count){if(!n)continue;let e=d.disambiguated;if(!e)continue;return{node:e,selector:l,selectorIndex:s,matches:d.count,diagnostics:o}}return{node:d.firstNode,selector:l,selectorIndex:s,matches:d.count,diagnostics:o}}}return null}function nW(e,t,r){let a=r.requireRect??!1,i=[];for(let n=0;n<t.selectors.length;n+=1){let o=t.selectors[n],s=function(e,t,r){let a=0;for(let i of e)(!r.requireRect||i.rect)&&n0(i,t,r.platform)&&(a+=1);return a}(e,o,{platform:r.platform,requireRect:a});if(i.push({selector:o.raw,matches:s}),s>0)return{selectorIndex:n,selector:o,matches:s,diagnostics:i}}return null}function nz(e,t,r){let a=r.unique??!0;if(0===t.length)return`Selector did not match: ${e.raw}`;let i=t.map(e=>`${e.selector} -> ${e.matches}`).join(", ");return a?`Selector did not resolve uniquely (${i})`:`Selector did not match (${i})`}function nJ(e,t={}){if(0===e.length)return null;let r=t.preferTrailingValue??!1,a=0,i=[];for(;a<e.length&&function(e){let t=e.trim();if(!t)return!1;if("||"===t)return!0;let r=t.indexOf("=");if(-1!==r){let e=t.slice(0,r).trim().toLowerCase();return nj.has(e)}return nj.has(t.toLowerCase())}(e[a]);){a+=1;let t=e.slice(0,a).join(" ").trim();t&&nq(t)&&i.push(a)}if(0===i.length)return null;let n=i[i.length-1];if(r){for(let t=i.length-1;t>=0;t-=1)if(i[t]<e.length){n=i[t];break}}let o=e.slice(0,n).join(" ").trim();return o?{selectorExpression:o,rest:e.slice(n)}:null}function nK(e){let t=e[0]??"",r=nJ(e.slice(1),{preferTrailingValue:"text"===t});return{predicate:t,split:r}}function nX(e){return!0===e.hittable||!!e.rect&&e.rect.width>0&&e.rect.height>0}function nZ(e,t){return nF(e.type??"",t)&&!1!==e.enabled}function nY(e,t,r={}){let a=[],i=n$(e.type??""),n=n8(e.identifier),o=n8(e.label),s=n8(e.value),l=n8(nU(e)),d="fill"===r.action;n&&a.push(`id=${n4(n)}`),i&&o&&a.push(d?`role=${n4(i)} label=${n4(o)} editable=true`:`role=${n4(i)} label=${n4(o)}`),o&&a.push(d?`label=${n4(o)} editable=true`:`label=${n4(o)}`),s&&a.push(d?`value=${n4(s)} editable=true`:`value=${n4(s)}`),l&&l!==o&&l!==s&&a.push(d?`text=${n4(l)} editable=true`:`text=${n4(l)}`),i&&d&&!a.some(e=>e.includes("editable=true"))&&a.push(`role=${n4(i)} editable=true`);let u=tc(a);return 0===u.length&&i&&u.push(d?`role=${n4(i)} editable=true`:`role=${n4(i)}`),0===u.length&&nX(e)&&u.push("visible=true"),u}function nQ(e){let t=e.trim();if(!t)throw new h("INVALID_ARGS","Empty selector term");let r=t.indexOf("=");if(-1===r){let r=t.toLowerCase();if(!nG.has(r))throw new h("INVALID_ARGS",`Invalid selector term "${e}", expected key=value`);return{key:r,value:!0}}let a=t.slice(0,r).trim().toLowerCase(),i=t.slice(r+1).trim();if(!nj.has(a))throw new h("INVALID_ARGS",`Unknown selector key: ${a}`);if(!i)throw new h("INVALID_ARGS",`Missing selector value for key: ${a}`);if(nG.has(a)){let e,t="true"===(e=n1(i).toLowerCase())||"false"!==e&&null;if(null===t)throw new h("INVALID_ARGS",`Invalid boolean value for ${a}: ${i}`);return{key:a,value:t}}return{key:a,value:n1(i)}}function n0(e,t,r){return t.terms.every(t=>(function(e,t,r){switch(t.key){case"id":return n2(e.identifier,String(t.value));case"role":var a,i;return a=e.type,i=String(t.value),function(e){return n$(e)}(a??"")===function(e){return n$(e)}(i);case"label":return n2(e.label,String(t.value));case"value":return n2(e.value,String(t.value));case"text":{let r=n3(String(t.value));return n3(nU(e))===r}case"visible":return nX(e)===!!t.value;case"hidden":return!nX(e)==!!t.value;case"editable":return nZ(e,r)===!!t.value;case"selected":return!0===e.selected==!!t.value;case"enabled":return!1!==e.enabled==!!t.value;case"hittable":return!0===e.hittable==!!t.value;default:return!1}})(e,t,r))}function n1(e){let t=e.trim();return t.startsWith('"')&&t.endsWith('"')||t.startsWith("'")&&t.endsWith("'")?t.slice(1,-1).replace(/\\(["'])/g,"$1"):t}function n2(e,t){return n3(e??"")===n3(t)}function n3(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function n4(e){return JSON.stringify(e)}function n8(e){if(!e)return null;let t=e.trim();return t||null}function n6(e){return e.rect?e.rect.width*e.rect.height:1/0}function n5(e,t){let r=0;for(let a=t-1;a>=0&&"\\"===e[a];a-=1)r+=1;return r%2==1}let n9=RegExp("\\b(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\b","i"),n7=/https?:\/\/[^\s"'<>\])]+/i,oe=[/\bstatus(?:Code)?["'=: ]+([1-5]\d{2})\b/i,/\bresponse(?:\s+code)?["'=: ]+([1-5]\d{2})\b/i,/\bHTTP\/[0-9.]+\s+([1-5]\d{2})\b/i];function ot(e,t){if(e)for(let r of t){let t=e[r];if("string"==typeof t&&t.trim().length>0)return t.trim()}}function or(e,t,r){if(t){for(let e of r)if(void 0!==t[e])return oa(t[e])}for(let t of r){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=RegExp(`\\b${r}["'=: ]+(.+)$`,"i").exec(e);if(a?.[1])return a[1].trim()}}function oa(e){if("string"==typeof e)return e;try{return JSON.stringify(e)}catch{return String(e)}}function oi(e,t){return e.length<=t?e:`${e.slice(0,t)}...<truncated>`}function on(e,t,r,a){return void 0!==e&&Number.isInteger(e)?Math.max(r,Math.min(a,e)):t}let oo="shared_prefs/ReactNativeDevPrefs.xml",os="debug_http_host",ol="dev_server_https",od="RCT_jsLocation",ou="RCT_packager_scheme",oc="React Native runtime hints require adb run-as access to the app sandbox. Verify the app is debuggable and the selected package/device are correct.",op='<?xml version="1.0" encoding="utf-8" standalone="yes" ?>\n<map>\n</map>\n';function of(e){return void 0!==om(e)}function om(e){if(!e)return;let t=oD(e.metroHost),r=ok(e.metroPort),a="http",i=oD(e.bundleUrl);if(i){var n;let e;try{e=new w(i)}catch(e){throw new h("INVALID_ARGS",`Invalid runtime bundle URL: ${i}`,{},e)}("http:"===e.protocol||"https:"===e.protocol)&&(t??=oD(e.hostname),r??=ok(e.port.length>0?Number(e.port):"https:"===(n=e.protocol)?443:"http:"===n?80:void 0),a="https:"===e.protocol?"https":"http")}if(t&&r)return{host:t,port:r,scheme:a}}async function oh(e){let{device:t,appId:r,runtime:a}=e;if(!r)return;let i=om(a);if(i){if("android"===t.platform)return void await og(t,r,i);"ios"===t.platform&&"simulator"===t.kind&&await oy(t,r,i)}}async function ow(e){let{device:t,appId:r}=e;if(r){if("android"===t.platform)return void await oI(t,r);"ios"===t.platform&&"simulator"===t.kind&&await ob(t,r)}}async function og(e,t,r){var a,i,n,o,s,l;let d,u;oE(t);let c=(a=await ov(e,t),i=os,n=`${r.host}:${r.port}`,d=` <string name="${oL(i)}">${oL(n)}</string>`,o_(oS(a,i),d));o=c,s=ol,l="https"===r.scheme,u=` <boolean name="${oL(s)}" value="${l?"true":"false"}" />`,c=o_(oS(o,s),u),await oA(e,t,c)}async function oI(e,t){oE(t);let r=await ov(e,t),a=oS(r,os),i=oS(a,ol);i!==r&&await oA(e,t,i)}async function ov(e,t){let r=await c("adb",rn(e,["shell","run-as",t,"cat",oo]),{allowFailure:!0});return 0!==r.exitCode?op:oN(r.stdout)}async function oA(e,t,r){let a=rn(e,["shell","run-as",t,"id"]),i=await c("adb",a,{allowFailure:!0});if(0!==i.exitCode){let e=oO(i.stdout,i.stderr);throw new h("COMMAND_FAILED",e?`Failed to access Android app sandbox for ${t}`:`Failed to probe Android app sandbox for ${t}`,{package:t,cmd:"adb",args:a,stdout:i.stdout,stderr:i.stderr,exitCode:i.exitCode,hint:e?oc:"adb shell run-as probe failed. Check adb connectivity and that the device is reachable. Inspect stderr/details for more information."})}try{await c("adb",rn(e,["shell","run-as",t,"mkdir","-p","shared_prefs"])),await c("adb",rn(e,["shell","run-as",t,"tee",oo]),{stdin:r.trimEnd()})}catch(a){let e=f(a);if("TOOL_MISSING"===e.code)throw e;let r=oO("string"==typeof e.details?.stdout?e.details.stdout:"","string"==typeof e.details?.stderr?e.details.stderr:"");throw new h("COMMAND_FAILED",r?`Failed to access Android app sandbox for ${t}`:`Failed to write Android runtime hints for ${t}`,{...e.details??{},package:t,cmd:"adb",phase:"write-runtime-hints",hint:r?oc:"adb run-as succeeded, but writing ReactNativeDevPrefs.xml failed. Inspect stderr/details for the failing shell command."},e)}}async function oy(e,t,r){await c("xcrun",ek(e,["spawn",e.id,"defaults","write",t,od,"-string",`${r.host}:${r.port}`])),await c("xcrun",ek(e,["spawn",e.id,"defaults","write",t,ou,"-string",r.scheme]))}async function ob(e,t){await c("xcrun",ek(e,["spawn",e.id,"defaults","delete",t,od]),{allowFailure:!0}),await c("xcrun",ek(e,["spawn",e.id,"defaults","delete",t,ou]),{allowFailure:!0})}function oN(e){let t=e.trim();return t.includes("<map")&&t.includes("</map>")?`${t}
32
+ `:op}function o_(e,t){return oN(e).replace("</map>",`${t}
33
+ </map>`)}function oS(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return oN(e).replace(RegExp(`^\\s*<string name="${r}">[\\s\\S]*?<\\/string>\\n?`,"m"),"").replace(RegExp(`^\\s*<boolean name="${r}" value="(?:true|false)"\\s*\\/?>\\n?`,"m"),"")}function oD(e){let t=e?.trim();return t&&t.length>0?t:void 0}function oE(e){if("binary"!==rx(e))return;let t=rC(e);throw new h("INVALID_ARGS",t,{package:e,hint:t})}function ok(e){if(Number.isInteger(e)&&!(e<=0)&&!(e>65535))return e}function oL(e){return e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function oO(e,t){let r=`${e}
34
+ ${t}`.toLowerCase();return["run-as: package not debuggable","run-as: permission denied","run-as: package is unknown","run-as: unknown package","is unknown","is not an application","could not set capabilities"].some(e=>r.includes(e))}function oM(e){if(0===e.length)return{selectorExpression:null,selectorTimeout:null};let t=e[e.length-1],r=/^\d+$/.test(t??""),a=nJ(r?e.slice(0,-1):e.slice());return!a||a.rest.length>0?{selectorExpression:null,selectorTimeout:null}:{selectorExpression:a.selectorExpression,selectorTimeout:r?t:null}}function ox(e){return!!e&&!Number.isNaN(Number(e))}let oC=ev(process.env.AGENT_DEVICE_INSTALL_SOURCE_RETAIN_TTL_MS,9e5,5e3),oR=new Map;async function oT(e){let t=await a.mkdtemp(i.join(C.tmpdir(),"agent-device-materialized-"));try{let r=await oF(e.installablePath,i.join(t,"installable")),a=e.archivePath?await oF(e.archivePath,i.join(t,"archive")):void 0,n=u.randomUUID(),o=e.ttlMs??oC,s=Date.now()+o,l=setTimeout(()=>{oP(n)},o);return oR.set(n,{rootPath:t,installablePath:r,archivePath:a,tenantId:e.tenantId,sessionName:e.sessionName,expiresAt:s,timer:l}),{materializationId:n,installablePath:r,...a?{archivePath:a}:{},expiresAt:new Date(s).toISOString()}}catch(e){throw await a.rm(t,{recursive:!0,force:!0}),e}}async function oP(e,t){let r=oR.get(e);if(!r)throw new h("INVALID_ARGS",`Materialized paths not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new h("UNAUTHORIZED","Materialized paths belong to a different tenant");clearTimeout(r.timer),oR.delete(e),await a.rm(r.rootPath,{recursive:!0,force:!0})}async function o$(e){let t=Array.from(oR.entries()).filter(([,t])=>t.sessionName===e).map(([e])=>e);await Promise.all(t.map(async e=>{await oP(e)}))}async function oF(e,t){let r=await a.stat(e);await a.mkdir(t,{recursive:!0});let n=i.join(t,i.basename(e));return r.isDirectory()?await a.cp(e,n,{recursive:!0}):await a.copyFile(e,n),n}async function oU(e){var t;let r="ios"===(t=e.flags?.platform)||"android"===t?t:void 0;if(e.session){if(r&&e.session.device.platform!==r)throw new h("INVALID_ARGS",`install_from_source requested platform ${r}, but session is bound to ${e.session.device.platform}`);return await nS(e.session.device),e.session.device}if(!r)throw new h("INVALID_ARGS",'install_from_source requires platform "ios" or "android" when no session is provided');let a=await nv(e.flags??{});return await nS(a),a}async function oV(e){let{req:t,sessionName:r,sessionStore:a}=e,i=a.get(r);try{let e,n=function(e){let t=e.meta?.installSource;if(!t)throw new h("INVALID_ARGS","install_from_source requires a source payload");if("url"===t.kind){if(!t.url||0===t.url.trim().length)throw new h("INVALID_ARGS","install_from_source url source requires a non-empty url");return t}if(!t.path||0===t.path.trim().length)throw new h("INVALID_ARGS","install_from_source path source requires a non-empty path");return t}(t),o=function(e){let t=e.meta?.retainMaterializedPaths===!0,r=e.meta?.materializedPathRetentionMs;if(!t)return{enabled:!1};if(void 0!==r&&r<=0)throw new h("INVALID_ARGS","install_from_source retentionMs must be a positive integer");return{enabled:!0,ttlMs:r}}(t),s=await oU({session:i,flags:t.flags});if(!nb("install",s))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"install_from_source is not supported on this device"}};let l=eu(t.meta?.requestId);if("ios"===s.platform){let e,{installIosInstallablePath:d}=await Promise.resolve().then(()=>({installIosInstallablePath:iq})),{prepareIosInstallArtifact:u}=await Promise.resolve().then(()=>({prepareIosInstallArtifact:ig})),c=await u(n,{signal:l});try{if(o.enabled&&(e=await oT({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:o.ttlMs})),await d(s,c.installablePath),!c.bundleId)throw new h("COMMAND_FAILED","Installed iOS app identity could not be resolved from the artifact");let n={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},bundleId:c.bundleId,...c.appName?{appName:c.appName}:{},launchTarget:c.bundleId,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}};return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:n}),{ok:!0,data:n}}catch(r){throw e&&await oP(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup()}}let{installAndroidInstallablePath:d}=await Promise.resolve().then(()=>({installAndroidInstallablePath:au})),{prepareAndroidInstallArtifact:u}=await Promise.resolve().then(()=>({prepareAndroidInstallArtifact:rJ})),c=await u(n,{signal:l});try{if(o.enabled&&(e=await oT({archivePath:c.archivePath,installablePath:c.installablePath,tenantId:t.meta?.tenantId,sessionName:i?r:void 0,ttlMs:o.ttlMs})),await d(s,c.installablePath),!c.packageName)throw new h("COMMAND_FAILED","Installed Android package identity could not be resolved from the artifact");let{inferAndroidAppName:n}=await Promise.resolve().then(()=>({inferAndroidAppName:r8})),l={...e?.archivePath?{archivePath:e.archivePath}:{},...e?{installablePath:e.installablePath}:{},packageName:c.packageName,appName:n(c.packageName),launchTarget:c.packageName,...e?{materializationId:e.materializationId,materializationExpiresAt:e.expiresAt}:{}};return i&&a.recordAction(i,{command:"install_source",positionals:[],flags:t.flags??{},result:l}),{ok:!0,data:l}}catch(r){throw e&&await oP(e.materializationId,t.meta?.tenantId).catch(()=>{}),r}finally{await c.cleanup()}}catch(e){return{ok:!1,error:A(e)}}}async function oG(e){let{req:t}=e;try{let e=t.meta?.materializationId?.trim();if(!e)throw new h("INVALID_ARGS","release_materialized_paths requires a materializationId");return await oP(e,t.meta?.tenantId),{ok:!0,data:{released:!0,materializationId:e}}}catch(e){return{ok:!1,error:A(e)}}}async function oj(e){let t,r,a,{deviceName:i,runtime:n,simulatorSetPath:o,reuseExisting:s,boot:l,ensureReady:d}=e;if("darwin"!==process.platform)throw new h("UNSUPPORTED_PLATFORM","ensure-simulator is only available on macOS");let u={simulatorSetPath:o??void 0};if(s){let e=await oB({deviceName:i,runtime:n,simctlOpts:u});e?(t=e.udid,r=e.runtime,a=!1):(t=(await oq({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await oH(t,u),a=!0)}else t=(await oq({deviceName:i,runtime:n,simctlOpts:u})).udid,r=await oH(t,u),a=!0;let c=!1;if(l){let e={platform:"ios",id:t,name:i,kind:"simulator",target:"mobile",...o?{simulatorSetPath:o}:{}};await d(e),c=!0}return{udid:t,device:i,runtime:r,created:a,booted:c}}async function oB(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=await c("xcrun",eE(["list","devices","-j"],a),{allowFailure:!0,timeoutMs:a9});if(0!==i.exitCode)return null;try{let e=JSON.parse(String(i.stdout??""));for(let[a,i]of Object.entries(e.devices??{}))if(!r||oW(a).includes(oW(r))){for(let e of i)if(e.isAvailable&&e.name.toLowerCase()===t.toLowerCase())return{udid:e.udid,runtime:a}}return null}catch{return null}}async function oq(e){let{deviceName:t,runtime:r,simctlOpts:a}=e,i=r?["create",t,t,r]:["create",t,t],n=await c("xcrun",eE(i,a),{allowFailure:!0});if(0!==n.exitCode)throw new h("COMMAND_FAILED","Failed to create iOS simulator",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??""),exitCode:n.exitCode,hint:"Ensure the device type and runtime identifiers are valid. Run `xcrun simctl list devicetypes` and `xcrun simctl list runtimes` to see available options."});let o=String(n.stdout??"").trim();if(!o)throw new h("COMMAND_FAILED","simctl create returned no UDID",{deviceName:t,runtime:r,stdout:String(n.stdout??""),stderr:String(n.stderr??"")});return{udid:o}}async function oH(e,t){let r=await c("xcrun",eE(["list","devices","-j"],t),{allowFailure:!0,timeoutMs:a9});if(0!==r.exitCode)return"";try{let t=JSON.parse(String(r.stdout??""));for(let[r,a]of Object.entries(t.devices??{}))if(a.some(t=>t.udid===e))return r;return""}catch{return""}}function oW(e){return e.toLowerCase().replace(/[._-]/g,"")}let oz='iOS appstate requires an active session on the target device. Run open first (for example: open --session sim --platform ios --device "<name>" <app>).',oJ=["platform","target","device","udid","serial","verbose","out"],oK=["platform","target","device","udid","serial","verbose","out"],oX=["path","start","stop","doctor","mark","clear"],oZ=`logs requires ${oX.slice(0,-1).join(", ")}, or ${oX.at(-1)}`,oY="Not implemented for this platform in this release.",oQ="open-command-roundtrip",o0=["platform","metroHost","metroPort","bundleUrl","launchUrl"],o1=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_CLOSE_SETTLE_MS,300,0),o2=ev(process.env.AGENT_DEVICE_IOS_SIMULATOR_POST_OPEN_SETTLE_MS,300,0);function o3(e){return e?[e.metroHost,e.metroPort,e.bundleUrl,e.launchUrl].filter(e=>void 0!==e&&""!==e).length:0}function o4(e){let t=e?.trim();return t&&t.length>0?t:void 0}function o8(e,t){if(void 0!==e){if("string"!=typeof e)throw new h("INVALID_ARGS",`Invalid open runtime ${t}: expected string.`);return o4(e)}}function o6(e){if(void 0!==e){if(!Number.isInteger(e)||e<1||e>65535)throw new h("INVALID_ARGS",`Invalid runtime metroPort: ${String(e)}. Use an integer between 1 and 65535.`);return e}}function o5(e){try{return{ok:!0,data:function(e){let{req:t,sessionStore:r,sessionName:a,device:i}=e,n=r.getRuntimeHints(a),o=function(e){let{runtime:t,sessionName:r,platform:a}=e;if(void 0===t)return;if(!t||"object"!=typeof t||Array.isArray(t))throw new h("INVALID_ARGS","open runtime must be an object.");let i=Object.keys(t).find(e=>!o0.includes(e));if(i)throw new h("INVALID_ARGS",`Invalid open runtime field: ${i}. Supported fields are ${o0.join(", ")}.`);return{platform:function(e,t,r){if(void 0===e)return r;if("ios"!==e&&"android"!==e)throw new h("INVALID_ARGS",`Invalid open runtime platform: ${String(e)}. Use "ios" or "android".`);if(r&&e!==r)throw new h("INVALID_ARGS",`open runtime targets ${e}, but session "${t}" is bound to ${r}.`);return e}(t.platform,r,a),metroHost:o8(t.metroHost,"metroHost"),metroPort:function(e){if(void 0!==e){if("number"!=typeof e)throw new h("INVALID_ARGS","Invalid open runtime metroPort: expected integer.");return o6(e)}}(t.metroPort),bundleUrl:o8(t.bundleUrl,"bundleUrl"),launchUrl:o8(t.launchUrl,"launchUrl")}}({runtime:t.runtime,sessionName:a,platform:i.platform});return void 0===t.runtime?{runtime:function(e,t,r){let a=e.getRuntimeHints(t);if(a){if(a.platform&&r&&a.platform!==r.platform)throw new h("INVALID_ARGS",`Session runtime hints target ${a.platform}, but session "${t}" is bound to ${r.platform}. Clear the runtime hints or use a different session.`);return r?.platform&&a.platform!==r.platform?{...a,platform:r.platform}:a}}(r,a,i),previousRuntime:n,replacedStoredRuntime:!1}:{runtime:o&&o3(o)>0?o:void 0,previousRuntime:n,replacedStoredRuntime:!0}}(e)}}catch(t){let e=f(t);return{ok:!1,response:{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}}async function o9(e){let{replacedStoredRuntime:t,previousRuntime:r,runtime:a,session:i,clearRuntimeHints:n}=e;!t||!i?.appBundleId||!of(r)||of(a)||await n({device:i.device,appId:i.appBundleId})}async function o7(e){var t,r,a,i,n,o;let{req:s,sessionName:l,sessionStore:d,logPath:u,device:c,dispatch:p,applyRuntimeHints:f,stopIosRunner:m,settleSimulator:h,openTarget:w,openPositionals:g,appBundleId:I,runtime:v,existingSession:A}=e,y=s.flags?.relaunch===!0,b=A?.trace?.outPath;if(y&&w){let e=I??w;await sc({device:c,closeTarget:e,stopIosRunner:m,dispatch:p,outFlag:s.flags?.out,context:{...nN(u,s.flags,I??A?.appBundleId,b)},settleSimulator:h})}await f({device:c,appId:I,runtime:v});let N=Date.now();await p(c,"open",g,s.flags?.out,{...nN(u,s.flags,I)}),await se({runtime:v,device:c,dispatch:p,req:s,logPath:u,appBundleId:I,traceLogPath:b,openPositionals:g});let _=w?(t=N,r=w,a=I,{durationMs:Math.max(0,Date.now()-t),measuredAt:new Date().toISOString(),method:oQ,appTarget:r,appBundleId:a}):void 0;await h(c,o2);let S=function(e){let{existingSession:t,sessionName:r,device:a,appBundleId:i,openTarget:n,saveScript:o}=e;return t?{...t,appBundleId:i,appName:n,recordSession:t.recordSession||o,snapshot:void 0}:{name:r,device:a,createdAt:Date.now(),appBundleId:i,appName:n,recordSession:o,actions:[]}}({existingSession:A,sessionName:l,device:c,appBundleId:I,openTarget:w,saveScript:!!s.flags?.saveScript});void 0!==s.runtime&&(i=d,n=l,(o=v)&&(0===o3(o)?i.clearRuntimeHints(n):i.setRuntimeHints(n,o)));let D=function(e){let{sessionName:t,appName:r,appBundleId:a,startup:i,device:n,runtime:o}=e,s={session:t};return r&&(s.appName=r),a&&(s.appBundleId=a),i&&(s.startup=i),o&&o3(o)>0&&(s.runtime=o),n&&(s.platform=n.platform,s.target=n.target??"mobile",s.device=n.name,s.id=n.id,s.kind=n.kind,"android"===n.platform&&(s.serial=n.id)),n?.platform==="ios"&&(s.device_udid=n.id,s.ios_simulator_device_set=n.simulatorSetPath??null),s}({sessionName:l,appName:w,appBundleId:I,startup:_,device:c,runtime:v});return!function(e){let{req:t,sessionStore:r,session:a,sessionName:i,runtime:n}=e;if(void 0!==t.runtime){if(n)return r.recordAction(a,{command:"runtime",positionals:["set"],flags:{...t.flags??{},platform:a.device.platform,metroHost:n.metroHost,metroPort:n.metroPort,bundleUrl:n.bundleUrl,launchUrl:n.launchUrl},result:{session:i,configured:!0,runtime:n}});r.recordAction(a,{command:"runtime",positionals:["clear"],flags:t.flags??{},result:{session:i,cleared:!0}})}}({req:s,sessionStore:d,session:S,sessionName:l,runtime:v}),d.recordAction(S,{command:"open",positionals:g,flags:s.flags??{},result:D}),d.set(l,S),{ok:!0,data:D}}async function se(e){let{runtime:t,device:r,dispatch:a,req:i,logPath:n,appBundleId:o,traceLogPath:s,openPositionals:l}=e,d=t?.launchUrl;if(!d||0===l.length||l.length>1)return;let u=l[0]?.trim();!u||rd(u)||await a(r,"open",[d],i.flags?.out,{...nN(n,i.flags,o,s)})}let st=["dump","log"],sr=`network requires ${st.join(" or ")}`,sa=["summary","headers","body","all"],si=`network include mode must be one of: ${sa.join(", ")}`;function sn(e,t,r){return t||so(r)?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} requires an active session or an explicit device selector (e.g. --platform ios).`}}}function so(e){return!!(e?.platform||e?.target||e?.device||e?.udid||e?.serial)}function ss(e){return"ios"===e.platform&&"simulator"===e.kind}async function sl(e,t){ss(e)&&!(t<=0)&&await new Promise(e=>setTimeout(e,t))}async function sd(e){let t=await c("adb",["-s",e.id,"emu","kill"],{allowFailure:!0,timeoutMs:15e3});return{success:0===t.exitCode,exitCode:t.exitCode,stdout:String(t.stdout??""),stderr:String(t.stderr??"")}}async function su(e){let{device:t,shutdownRequested:r,shutdownSimulator:a,shutdownAndroidEmulator:i}=e;if(r&&(ss(t)||"android"===t.platform&&"emulator"===t.kind))try{return ss(t)?await a(t):await i(t)}catch(t){let e=A(t);return{success:!1,exitCode:-1,stdout:"",stderr:e.message,error:e}}}async function sc(e){let{device:t,closeTarget:r,stopIosRunner:a,dispatch:i,outFlag:n,context:o,settleSimulator:s}=e;"ios"===t.platform&&await a(t.id),await i(t,"close",[r],n,o),await s(t,o1)}async function sp(e){let t=so(e.flags)||!e.session?await e.resolveTargetDeviceFn(e.flags??{}):e.session.device;return!1!==e.ensureReady&&await e.ensureReadyFn(t),t}function sf(e){let t=e.flags?.device?.trim();return t||(e.resolvedDevice?.platform==="android"&&"emulator"===e.resolvedDevice.kind?e.resolvedDevice.name:e.sessionDevice?.platform==="android"&&"emulator"===e.sessionDevice.kind?e.sessionDevice.name:void 0)}let sm=async({avdName:e,serial:t,headless:r})=>{let{ensureAndroidEmulatorBooted:a}=await Promise.resolve().then(()=>({ensureAndroidEmulatorBooted:rk}));return await a({avdName:e,serial:t,headless:r})};async function sh(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,ensureReady:n,resolveDevice:o,dispatch:s,command:l,positionals:d,recordPositionals:u,deriveNextSession:c}=e,p=i.get(r),f=t.flags??{},m=sn(l,p,f);if(m)return m;let h=await sp({session:p,flags:f,ensureReadyFn:n,resolveTargetDeviceFn:o,ensureReady:!0});if(!nb(l,h))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${l} is not supported on this device`}};let w=await s(h,l,d,t.flags?.out,{...nN(a,t.flags,p?.appBundleId,p?.trace?.outPath)});if(p){let e=c?await c(p,w,h):p;i.recordAction(e,{command:l,positionals:u??d,flags:t.flags??{},result:w??{}}),e!==p&&i.set(r,e)}return{ok:!0,data:w??{}}}let sw={ios:async(e,t,r)=>{let{reinstallIosApp:a}=await Promise.resolve().then(()=>({reinstallIosApp:iB}));return await a(e,t,r)},android:async(e,t,r)=>{let{reinstallAndroidApp:a}=await Promise.resolve().then(()=>({reinstallAndroidApp:ap}));return await a(e,t,r)}},sg={ios:async(e,t,r)=>{let{installIosApp:a}=await Promise.resolve().then(()=>({installIosApp:ij})),i=await a(e,r,{appIdentifierHint:t});return{bundleId:i.bundleId,appName:i.appName,launchTarget:i.launchTarget}},android:async(e,t,r)=>{let{installAndroidApp:a}=await Promise.resolve().then(()=>({installAndroidApp:ac})),i=await a(e,r);return{package:i.packageName,appName:i.appName,launchTarget:i.launchTarget}}};async function sI(e){let{req:t,command:r,sessionName:a,sessionStore:i,ensureReady:n,resolveDevice:o,deployOps:s}=e,l=i.get(a),d=t.flags??{},u=sn(r,l,d);if(u)return u;let c=t.positionals?.[0]?.trim(),p=t.positionals?.[1]?.trim();if(!c||!p)return{ok:!1,error:{code:"INVALID_ARGS",message:`${r} requires: ${r} <app> <path-to-app-binary>`}};let f=t.meta?.uploadedArtifactId;try{let e,a=f?function(e,t){let r=tG.get(e);if(!r)throw new h("INVALID_ARGS",`Uploaded artifact not found: ${e}`);if(r.tenantId&&r.tenantId!==t)throw new h("UNAUTHORIZED","Uploaded artifact belongs to a different tenant");return clearTimeout(r.timer),r.artifactPath}(f,t.meta?.tenantId):tb.expandHome(p);if(!M.existsSync(a))return{ok:!1,error:{code:"INVALID_ARGS",message:`App binary not found: ${a}`}};let u=await sp({session:l,flags:d,ensureReadyFn:n,resolveTargetDeviceFn:o,ensureReady:!1});if(!nb(r,u))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${r} is not supported on this device`}};if("ios"===u.platform){let t=await s.ios(u,c,a),r=t.bundleId;e=r?{app:c,appPath:a,platform:"ios",appId:r,bundleId:r,appName:t.appName,launchTarget:t.launchTarget}:{app:c,appPath:a,platform:"ios",appName:t.appName,launchTarget:t.launchTarget}}else{let t=await s.android(u,c,a),r=t.package;e=r?{app:c,appPath:a,platform:"android",appId:r,package:r,packageName:r,appName:t.appName,launchTarget:t.launchTarget}:{app:c,appPath:a,platform:"android",appName:t.appName,launchTarget:t.launchTarget}}return l&&i.recordAction(l,{command:r,positionals:t.positionals??[],flags:t.flags??{},result:e}),{ok:!0,data:e}}finally{f&&tj(f)}}async function sv(e,t,r){if("ios"===e.platform&&t)return rd(t)?"device"===e.kind?ru(r,t):void 0:await sA(e,t)}async function sA(e,t){try{let{resolveIosApp:r}=await Promise.resolve().then(()=>({resolveIosApp:i$}));return await r(e,t)}catch{return}}async function sy(e,t){if(!("android"!==e.platform||!t||rd(t)))try{let{resolveAndroidApp:r}=await Promise.resolve().then(()=>({resolveAndroidApp:r0})),a=await r(e,t);return"package"===a.type?a.value:void 0}catch{return}}async function sb(e,t,r,a){return await sv(e,t,r)??await a(e,t)??("android"===e.platform&&t&&rd(t)?r:void 0)}async function sN(e){let{req:t,sessionName:r,sessionStore:a,ensureReady:i,resolveDevice:n}=e,o=a.get(r),s=t.flags??{},l=eW(s.platform);if(!o&&"string"==typeof s?.session&&s.session.trim().length>0)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"ios"===l?`No active session "${r}". Run open with --session ${r} first.`:`No active session "${r}". Run open with --session ${r} first, or omit --session to query by device selector.`}};let d=sn("appstate",o,s);if(d)return d;let u=o?.device.platform==="ios"&&function(e,t){if(!t)return!1;if(!so(e))return!0;let r=eW(e?.platform);return!(r&&r!==t.device.platform||e?.target&&e.target!==(t.device.target??"mobile")||e?.udid&&e.udid!==t.device.id||e?.serial&&e.serial!==t.device.id)&&(!e?.device||e.device.trim().toLowerCase()===t.device.name.trim().toLowerCase())}(s,o);if("ios"===l&&!u)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:oz}};if(u){let e=o.appName??o.appBundleId;return o.appName||o.appBundleId?{ok:!0,data:{platform:"ios",appName:e??"unknown",appBundleId:o.appBundleId,source:"session",device_udid:o.device.id,ios_simulator_device_set:o.device.simulatorSetPath??null}}:{ok:!1,error:{code:"COMMAND_FAILED",message:"No foreground app is tracked for this iOS session. Open an app in the session, then retry appstate."}}}let c=await sp({session:o,flags:s,ensureReadyFn:i,resolveTargetDeviceFn:n,ensureReady:!0});if("ios"===c.platform)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:oz}};let{getAndroidAppState:p}=await Promise.resolve().then(()=>({getAndroidAppState:r6})),f=await p(c);return{ok:!0,data:{platform:"android",package:f.package,activity:f.activity}}}async function s_(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,ensureReady:n,resolveDevice:o,dispatch:s}=e,l=i.get(r),d=t.flags??{},u=sn("clipboard",l,d);if(u)return u;let c=(t.positionals?.[0]??"").toLowerCase();if("read"!==c&&"write"!==c)return{ok:!1,error:{code:"INVALID_ARGS",message:"clipboard requires a subcommand: read or write"}};let p=await sp({session:l,flags:d,ensureReadyFn:n,resolveTargetDeviceFn:o,ensureReady:!0});if(!nb("clipboard",p))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"clipboard is not supported on this device"}};let f=await s(p,"clipboard",t.positionals??[],t.flags?.out,{...nN(a,t.flags,l?.appBundleId,l?.trace?.outPath)});return l&&i.recordAction(l,{command:t.command,positionals:t.positionals??[],flags:t.flags??{},result:f??{}}),{ok:!0,data:{platform:p.platform,...f??{}}}}async function sS(e){var t,r;let{req:a,sessionName:i,logPath:n,sessionStore:o,invoke:s,dispatch:l,ensureReady:d,resolveTargetDevice:u,installOps:c=sg,reinstallOps:p=sw,stopIosRunner:m,appLogOps:w={start:tT,stop:tP},ensureAndroidEmulatorBoot:g=sm,resolveAndroidPackageForOpen:I=sy,applyRuntimeHints:v=oh,clearRuntimeHints:y=ow,settleSimulator:b,shutdownSimulator:N,shutdownAndroidEmulator:_}=e,S=l??nA,D=d??nS,E=u??nv,k=m??tt,L=b??sl,O=a.command;if("session_list"===O)return{ok:!0,data:{sessions:o.toArray().map(e=>({name:e.name,platform:e.device.platform,target:e.device.target??"mobile",device:e.device.name,id:e.device.id,createdAt:e.createdAt,..."ios"===e.device.platform&&{device_udid:e.device.id,ios_simulator_device_set:e.device.simulatorSetPath??null}}))}};if("runtime"===O){let e=(a.positionals?.[0]??"show").toLowerCase(),n=o.get(i),s=o.getRuntimeHints(i);if(!["set","show","clear"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime requires set, show, or clear"}};if("clear"===e){of(s)&&n?.appBundleId&&await y({device:n.device,appId:n.appBundleId});let e=o.clearRuntimeHints(i);return{ok:!0,data:{session:i,cleared:e}}}if("show"===e)return{ok:!0,data:{session:i,configured:!!s,runtime:s}};let l=eW(a.flags?.platform)??s?.platform??n?.device.platform;if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set requires --platform when the session has not been opened yet."}};if(n&&n.device.platform!==l)return{ok:!1,error:{code:"INVALID_ARGS",message:`runtime set targets ${l}, but session "${i}" is already bound to ${n.device.platform}.`}};let d={platform:(t=a.flags,r={platform:l,metroHost:o4(t?.metroHost),metroPort:o6(t?.metroPort),bundleUrl:o4(t?.bundleUrl),launchUrl:o4(t?.launchUrl)}).platform??s?.platform,metroHost:r.metroHost??s?.metroHost,metroPort:r.metroPort??s?.metroPort,bundleUrl:r.bundleUrl??s?.bundleUrl,launchUrl:r.launchUrl??s?.launchUrl};return 0===o3(d)?{ok:!1,error:{code:"INVALID_ARGS",message:"runtime set requires at least one hint such as --metro-host, --metro-port, --bundle-url, or --launch-url."}}:(o.setRuntimeHints(i,d),{ok:!0,data:{session:i,configured:!0,runtime:d}})}if("ensure-simulator"===O)try{let e=a.flags??{},t=e.device,r=e.runtime,i=e_(e.iosSimulatorDeviceSet);if(!t)return{ok:!1,error:{code:"INVALID_ARGS",message:"ensure-simulator requires --device <name>"}};let n=!0===e.boot,o=!1!==e.reuseExisting,s=await oj({deviceName:t,runtime:r,simulatorSetPath:i,reuseExisting:o,boot:n,ensureReady:D});return{ok:!0,data:{udid:s.udid,device:s.device,runtime:s.runtime,ios_simulator_device_set:i??null,created:s.created,booted:s.booted}}}catch(t){let e=f(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("devices"===O)try{let e=[],t=e_(a.flags?.iosSimulatorDeviceSet),r=eD(a.flags?.androidDeviceAllowlist),i=eW(a.flags?.platform);if("android"===i){let{listAndroidDevices:t}=await Promise.resolve().then(()=>({listAndroidDevices:rb}));e.push(...await t({serialAllowlist:r}))}else if("ios"===i){let{listIosDevices:r}=await Promise.resolve().then(()=>({listIosDevices:ng}));e.push(...await r({simulatorSetPath:t}))}else{let{listAndroidDevices:a}=await Promise.resolve().then(()=>({listAndroidDevices:rb})),{listIosDevices:i}=await Promise.resolve().then(()=>({listIosDevices:ng}));try{e.push(...await a({serialAllowlist:r}))}catch{}try{e.push(...await i({simulatorSetPath:t}))}catch{}}let n=(a.flags?.target?e.filter(e=>(e.target??"mobile")===a.flags?.target):e).map(({simulatorSetPath:e,...t})=>t);return{ok:!0,data:{devices:n}}}catch(t){let e=f(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}if("apps"===O){let e=o.get(i),t=a.flags??{},r=sn(O,e,t);if(r)return r;let n=await sp({session:e,flags:t,ensureReadyFn:D,resolveTargetDeviceFn:E,ensureReady:!0});if(!nb("apps",n))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"apps is not supported on this device"}};let s=a.flags?.appsFilter??"all";if("ios"===n.platform){let{listIosApps:e}=await Promise.resolve().then(()=>({listIosApps:iK}));return{ok:!0,data:{apps:(await e(n,s)).map(e=>e.name&&e.name!==e.bundleId?`${e.name} (${e.bundleId})`:e.bundleId)}}}let{listAndroidApps:l}=await Promise.resolve().then(()=>({listAndroidApps:r1}));return{ok:!0,data:{apps:(await l(n,s)).map(e=>e.name&&e.name!==e.package?`${e.name} (${e.package})`:e.package)}}}if("boot"===O){let e,t=o.get(i),r=a.flags??{},n=sn(O,t,r);if(n)return n;let s="android"===(eW(r.platform)??t?.device.platform),l=!0===r.headless;if(l&&!s)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};let d=sf({flags:r,sessionDevice:t?.device}),u=s&&!!d,c=!1;try{e=await sp({session:t,flags:r,ensureReadyFn:D,resolveTargetDeviceFn:E,ensureReady:!1})}catch(a){let t=f(a);if(s&&l&&!d&&"DEVICE_NOT_FOUND"===t.code)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};if(!u||"DEVICE_NOT_FOUND"!==t.code||!d)throw a;e=await g({avdName:d,serial:r.serial,headless:l}),c=!0}if(r.target&&(e.target??"mobile")!==r.target)return{ok:!1,error:{code:"DEVICE_NOT_FOUND",message:`No ${e.platform} device found matching --target ${r.target}.`}};if(s&&l){if("android"!==e.platform||"emulator"!==e.kind)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless is supported only for Android emulators."}};if(!c){let a=sf({flags:r,sessionDevice:t?.device,resolvedDevice:e});if(!a)return{ok:!1,error:{code:"INVALID_ARGS",message:"boot --headless requires --device <avd-name> (or an Android emulator session target)."}};e=await g({avdName:a,serial:r.serial,headless:!0})}await D(e)}else("android"!==e.platform||!0!==e.booted)&&await D(e);return nb("boot",e)?{ok:!0,data:{platform:e.platform,target:e.target??"mobile",device:e.name,id:e.id,kind:e.kind,booted:!0}}:{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"boot is not supported on this device"}}}if("appstate"===O)return await sN({req:a,sessionName:i,sessionStore:o,ensureReady:D,resolveDevice:E});if("clipboard"===O)return await s_({req:a,sessionName:i,logPath:n,sessionStore:o,ensureReady:D,resolveDevice:E,dispatch:S});if("keyboard"===O)return await sh({req:a,sessionName:i,logPath:n,sessionStore:o,ensureReady:D,resolveDevice:E,dispatch:S,command:"keyboard",positionals:a.positionals??[]});if("perf"===O){let e,t,r,a=o.get(i);return a?{ok:!0,data:(r=(t=(e=function(e){let t=[];for(let r of e){if("open"!==r.command)continue;let e=r.result?.startup;e&&"object"==typeof e&&"number"==typeof e.durationMs&&Number.isFinite(e.durationMs)&&"string"==typeof e.measuredAt&&0!==e.measuredAt.trim().length&&e.method===oQ&&t.push({durationMs:Math.max(0,Math.round(e.durationMs)),measuredAt:e.measuredAt,method:oQ,appTarget:"string"==typeof e.appTarget&&e.appTarget.length>0?e.appTarget:void 0,appBundleId:"string"==typeof e.appBundleId&&e.appBundleId.length>0?e.appBundleId:void 0})}return t.slice(-20)}(a.actions)).at(-1))?{available:!0,lastDurationMs:t.durationMs,lastMeasuredAt:t.measuredAt,method:oQ,sampleCount:e.length,samples:e}:{available:!1,reason:"No startup sample captured yet. Run open <app|url> in this session first.",method:oQ},{session:a.name,platform:a.device.platform,device:a.device.name,deviceId:a.device.id,metrics:{startup:r,fps:{available:!1,reason:oY},memory:{available:!1,reason:oY},cpu:{available:!1,reason:oY}},sampling:{startup:{method:oQ,description:"Elapsed wall-clock time around dispatching the open command for the active session app target.",unit:"ms"}}})}:{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"perf requires an active session. Run open first."}}}if("install"===O||"reinstall"===O)return await sI({req:a,command:O,sessionName:i,sessionStore:o,ensureReady:D,resolveDevice:E,deployOps:"install"===O?c:p});if("install_source"===O)return await oV({req:a,sessionName:i,sessionStore:o});if("release_materialized_paths"===O)return await oG({req:a});if("push"===O){let e,t=a.positionals?.[0]?.trim(),r=a.positionals?.[1]?.trim();if(!t||!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"push requires <bundle|package> <payload.json|inline-json>"}};let s="file"===(e=nt(r,{subject:"Push payload",cwd:a.meta?.cwd,expandPath:(e,t)=>tb.expandHome(e,t)})).kind?e.path:e.text;return await sh({req:a,sessionName:i,logPath:n,sessionStore:o,ensureReady:D,resolveDevice:E,dispatch:S,command:"push",positionals:[t,s],recordPositionals:[t,r]})}if("trigger-app-event"===O)return await sh({req:a,sessionName:i,logPath:n,sessionStore:o,ensureReady:D,resolveDevice:E,dispatch:S,command:"trigger-app-event",positionals:a.positionals??[],deriveNextSession:async(e,t)=>{let r="string"==typeof t?.eventUrl?t.eventUrl:void 0,a=r?await sb(e.device,r,e.appBundleId,I)??e.appBundleId:e.appBundleId;return{...e,appBundleId:a}}});if("open"===O){let e=a.flags?.relaunch===!0;if(o.has(i)){let t=o.get(i),r=a.positionals?.[0],s=r??(e?t?.appName:void 0);if(!t||!s)return e?{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch requires an app name or an active session app."}}:{ok:!1,error:{code:"INVALID_ARGS",message:"Session already active. Close it first or pass a new --session name."}};if(e&&rd(s))return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch does not support URL targets."}};if(e&&"android"===t.device.platform&&"binary"===rx(s))return{ok:!1,error:{code:"INVALID_ARGS",message:rC(s)}};await D(t.device);let l=await sb(t.device,s,t.appBundleId,I),d=o5({req:a,sessionStore:o,sessionName:i,device:t.device});if(!d.ok)return d.response;let{runtime:u,previousRuntime:c,replacedStoredRuntime:p}=d.data;await o9({replacedStoredRuntime:p,previousRuntime:c,runtime:u,session:t,clearRuntimeHints:y});let f=r?a.positionals??[]:[s];return await o7({req:a,sessionName:i,sessionStore:o,logPath:n,device:t.device,dispatch:S,applyRuntimeHints:v,stopIosRunner:k,settleSimulator:L,openTarget:s,openPositionals:f,appBundleId:l,runtime:u,existingSession:t})}let t=a.positionals?.[0];if(e&&!t)return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch requires an app argument."}};if(e&&t&&rd(t))return{ok:!1,error:{code:"INVALID_ARGS",message:"open --relaunch does not support URL targets."}};let r=await E(a.flags??{});if(e&&"android"===r.platform&&t&&"binary"===rx(t))return{ok:!1,error:{code:"INVALID_ARGS",message:rC(t)}};let s=o.toArray().find(e=>e.device.id===r.id);if(s)return{ok:!1,error:{code:"DEVICE_IN_USE",message:`Device is already in use by session "${s.name}".`,details:{session:s.name,deviceId:r.id,deviceName:r.name}}};await D(r);let l=await sb(r,t,void 0,I),d=o5({req:a,sessionStore:o,sessionName:i,device:r});if(!d.ok)return d.response;let{runtime:u}=d.data;return await o7({req:a,sessionName:i,sessionStore:o,logPath:n,device:r,dispatch:S,applyRuntimeHints:v,stopIosRunner:k,settleSimulator:L,openTarget:t,openPositionals:a.positionals??[],appBundleId:l,runtime:u})}if("replay"===O){let e=a.positionals?.[0];if(!e)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay requires a path"}};try{let t=tb.expandHome(e,a.meta?.cwd),r=M.readFileSync(t,"utf8"),l=r.trimStart()[0];if("{"===l||"["===l)return{ok:!1,error:{code:"INVALID_ARGS",message:"replay accepts .ad script files. JSON replay payloads are no longer supported."}};let d=function(e){let t=[];for(let r of e.split(/\r?\n/)){let e=function(e){let t=e.trim();if(0===t.length||t.startsWith("#"))return null;let r=function(e){let t=[],r=0;for(;r<e.length;){for(;r<e.length&&/\s/.test(e[r]);)r+=1;if(r>=e.length)break;if('"'===e[r]){let a=r+1,i=!1;for(;a<e.length;){let t=e[a];if('"'===t&&!i)break;i="\\"===t&&!i,"\\"!==t&&(i=!1),a+=1}if(a>=e.length)throw new h("INVALID_ARGS",`Invalid replay script line: ${e}`);let n=e.slice(r,a+1);t.push(JSON.parse(n)),r=a+1;continue}let a=r;for(;a<e.length&&!/\s/.test(e[a]);)a+=1;t.push(e.slice(r,a)),r=a}return t}(t);if(0===r.length)return null;let[a,...i]=r;if("context"===a)return null;let n={ts:Date.now(),command:a,positionals:[],flags:{}};if("snapshot"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("-i"===t){n.flags.snapshotInteractiveOnly=!0;continue}if("-c"===t){n.flags.snapshotCompact=!0;continue}if("--raw"===t){n.flags.snapshotRaw=!0;continue}if(("-d"===t||"--depth"===t)&&e+1<i.length){let t=Number(i[e+1]);Number.isFinite(t)&&t>=0&&(n.flags.snapshotDepth=Math.floor(t)),e+=1;continue}if(("-s"===t||"--scope"===t)&&e+1<i.length){n.flags.snapshotScope=i[e+1],e+=1;continue}if("--backend"===t&&e+1<i.length){e+=1;continue}}return n}if("open"===a){n.positionals=[];for(let e=0;e<i.length;e+=1){let t=i[e];if("--relaunch"===t){n.flags.relaunch=!0;continue}n.positionals.push(t)}return n}if("runtime"===a){let e=function(e){let t=[],r={};for(let a=0;a<e.length;a+=1){let i=e[a];if("--platform"===i&&a+1<e.length){let t=e[a+1];("ios"===t||"android"===t)&&(r.platform=t),a+=1;continue}if("--metro-host"===i&&a+1<e.length){r.metroHost=e[a+1],a+=1;continue}if("--metro-port"===i&&a+1<e.length){let t=ty(e[a+1]);null!==t&&(r.metroPort=t),a+=1;continue}if("--bundle-url"===i&&a+1<e.length){r.bundleUrl=e[a+1],a+=1;continue}if("--launch-url"===i&&a+1<e.length){r.launchUrl=e[a+1],a+=1;continue}t.push(i)}return{positionals:t,flags:r}}(i);return n.positionals=e.positionals,Object.assign(n.flags,e.flags),n}if(th(a)){let e=tA(a,i);if(Object.assign(n.flags,e.flags),0===e.positionals.length)return n;let t=e.positionals[0];if(t.startsWith("@"))return n.positionals=[t],e.positionals[1]&&(n.result={refLabel:e.positionals[1]}),n;let r=e.positionals[0],o=e.positionals[1];return ox(r)&&ox(o)&&e.positionals.length>=2?n.positionals=[r,o]:n.positionals=[e.positionals.join(" ")],n}if("fill"===a){if(i.length<2)return n.positionals=i,n;let e=i[0];return e.startsWith("@")?(i.length>=3?(n.positionals=[e,i.slice(2).join(" ")],n.result={refLabel:i[1]}):n.positionals=[e,i[1]],n):(n.positionals=[e,i.slice(1).join(" ")],n)}if("get"===a){if(i.length<2)return n.positionals=i,n;let e=i[0],t=i[1];return t.startsWith("@")?(n.positionals=[e,t],i[2]&&(n.result={refLabel:i[2]})):n.positionals=[e,i.slice(1).join(" ")],n}if("swipe"===a){let e=tA(a,i);return Object.assign(n.flags,e.flags),n.positionals=e.positionals,n}return n.positionals=i,n}(r);e&&t.push(e)}return t}(r),u=a.flags?.replayUpdate===!0,c=0;for(let e=0;e<d.length;e+=1){let r=d[e];if(!r||"replay"===r.command)continue;let l=await s({token:a.token,session:i,command:r.command,positionals:r.positionals??[],flags:sL(a.flags,r.flags),meta:a.meta});if(l.ok)continue;if(!u)return sk(l,r,e,t);let p=await sO({action:r,sessionName:i,logPath:n,sessionStore:o,dispatch:S});if(!p)return sk(l,r,e,t);if(d[e]=p,!(l=await s({token:a.token,session:i,command:p.command,positionals:p.positionals??[],flags:sL(a.flags,p.flags),meta:a.meta})).ok)return sk(l,p,e,t);c+=1}if(u&&c>0){let e=o.get(i);!function(e,t,r){let a=[];if(r){let e=r.device.name.replace(/"/g,'\\"'),t=r.device.kind?` kind=${r.device.kind}`:"",i=r.device.target?` target=${r.device.target}`:"";a.push(`context platform=${r.device.platform}${i} device="${e}"${t} theme=unknown`)}for(let e of t)a.push(function(e){let t=[e.command];if("snapshot"===e.command)return e.flags?.snapshotInteractiveOnly&&t.push("-i"),e.flags?.snapshotCompact&&t.push("-c"),"number"==typeof e.flags?.snapshotDepth&&t.push("-d",String(e.flags.snapshotDepth)),e.flags?.snapshotScope&&t.push("-s",tw(e.flags.snapshotScope)),e.flags?.snapshotRaw&&t.push("--raw"),t.join(" ");if("open"===e.command){for(let r of e.positionals??[])t.push(tw(r));return e.flags?.relaunch&&t.push("--relaunch"),t.join(" ")}if("runtime"===e.command){for(let r of e.positionals??[])t.push(tg(r));return tv(t,e.flags),t.join(" ")}for(let r of e.positionals??[])t.push(tw(r));return tI(t,e),t.join(" ")}(e));let i=`${a.join("\n")}
35
+ `,n=`${e}.tmp-${process.pid}-${Date.now()}`;M.writeFileSync(n,i),M.renameSync(n,e)}(t,d,e)}return{ok:!0,data:{replayed:d.length,healed:c,session:i}}}catch(t){let e=f(t);return{ok:!1,error:{code:e.code,message:e.message}}}}if("logs"===O){let e=o.get(i);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"logs requires an active session"}};let t=(a.positionals?.[0]??"path").toLowerCase(),r=!!a.flags?.restart;if(!oX.includes(t))return{ok:!1,error:{code:"INVALID_ARGS",message:oZ}};if(r&&"clear"!==t)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs --restart is only supported with logs clear"}};if("path"===t){let t=o.resolveAppLogPath(i),r=function(e){if(!M.existsSync(e))return{exists:!1,sizeBytes:0};let t=M.statSync(e);return{exists:!0,sizeBytes:t.size,modifiedAt:t.mtime.toISOString()}}(t),a=e.appLog?.backend??("ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android");return{ok:!0,data:{path:t,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:a,sizeBytes:r.sizeBytes,modifiedAt:r.modifiedAt,startedAt:e.appLog?.startedAt?new Date(e.appLog.startedAt).toISOString():void 0,hint:'Grep the file for token-efficient debugging, e.g. grep -n "Error\\|Exception" <path>'}}}if("doctor"===t){let t=o.resolveAppLogPath(i),r=await t$(e.device,e.appBundleId);return{ok:!0,data:{path:t,active:!!e.appLog,state:e.appLog?.getState()??"inactive",checks:r.checks,notes:r.notes}}}if("mark"===t){let e,t=a.positionals?.slice(1).join(" ")??"",r=o.resolveAppLogPath(i);return tR(r),e=`[agent-device][mark][${new Date().toISOString()}] ${t.trim()||"marker"}
36
+ `,M.appendFileSync(r,e,"utf8"),{ok:!0,data:{path:r,marked:!0}}}if("clear"===t){if(e.appLog&&!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear requires logs to be stopped first; run logs stop"}};if(r){if(!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs clear --restart requires an app session; run open <app> first"}};if(!nb("logs",e.device))return{ok:!1,error:A(new h("UNSUPPORTED_OPERATION","logs is not supported on this device"))}}let t=o.resolveAppLogPath(i);if(r){e.appLog&&await w.stop(e.appLog);let r=tF(t),a=o.resolveAppLogPidPath(i);try{let n=await w.start(e.device,e.appBundleId,t,a),s={...e,appLog:{platform:e.device.platform,backend:n.backend,outPath:t,startedAt:n.startedAt,getState:n.getState,stop:n.stop,wait:n.wait}};return o.set(i,s),{ok:!0,data:{...r,restarted:!0}}}catch(r){let t=A(r);return o.set(i,{...e,appLog:void 0}),{ok:!1,error:t}}}return{ok:!0,data:tF(t)}}if("start"===t){if(e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"app log already streaming; run logs stop first"}};if(!e.appBundleId)return{ok:!1,error:{code:"INVALID_ARGS",message:"logs start requires an app session; run open <app> first"}};if(!nb("logs",e.device))return{ok:!1,error:A(new h("UNSUPPORTED_OPERATION","logs is not supported on this device"))};let t=o.resolveAppLogPath(i),r=o.resolveAppLogPidPath(i);try{let a=await w.start(e.device,e.appBundleId,t,r),n={...e,appLog:{platform:e.device.platform,backend:a.backend,outPath:t,startedAt:a.startedAt,getState:a.getState,stop:a.stop,wait:a.wait}};return o.set(i,n),{ok:!0,data:{path:t,started:!0}}}catch(e){return{ok:!1,error:A(e)}}}if("stop"===t){if(!e.appLog)return{ok:!1,error:{code:"INVALID_ARGS",message:"no app log stream active"}};let t=e.appLog.outPath;return await w.stop(e.appLog),o.set(i,{...e,appLog:void 0}),{ok:!0,data:{path:t,stopped:!0}}}}if("network"===O){let e=o.get(i);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"network requires an active session"}};let t=(a.positionals?.[0]??"dump").toLowerCase();if(!st.includes(t))return{ok:!1,error:{code:"INVALID_ARGS",message:sr}};let r=a.positionals?.[1],n=r?Number.parseInt(r,10):25;if(!Number.isInteger(n)||n<1||n>200)return{ok:!1,error:{code:"INVALID_ARGS",message:"network dump limit must be an integer in range 1..200"}};let s=(a.positionals?.[2]??"summary").toLowerCase();if(!sa.includes(s))return{ok:!1,error:{code:"INVALID_ARGS",message:si}};let l=function(e,t){let r=on(t?.maxEntries,25,1,200),a=t?.include??"summary",i=on(t?.maxPayloadChars,2048,64,16384),n=on(t?.maxScanLines,4e3,100,2e4);if(!M.existsSync(e))return{path:e,exists:!1,scannedLines:0,matchedLines:0,entries:[],include:a,limits:{maxEntries:r,maxPayloadChars:i,maxScanLines:n}};let o=M.readFileSync(e,"utf8").split("\n"),s=Math.max(0,o.length-n),l=o.slice(s),d=[];for(let e=l.length-1;e>=0&&d.length<r;e-=1){let t=l[e]?.trim();if(!t)continue;let r=function(e,t,r,a){let i=function(e){let t=e.indexOf("{");if(t<0)return null;let r=e.lastIndexOf("}");if(r<=t)return null;let a=e.slice(t,r+1);try{let e=JSON.parse(a);return e&&"object"==typeof e?e:null}catch{return null}}(e),n=ot(i,["method","httpMethod"]),o=ot(i,["url","requestUrl"]),s=function(e,t){if(!e)return null;for(let r of t){let t=e[r];if("number"==typeof t&&Number.isInteger(t))return t;if("string"==typeof t&&/^\d{3}$/.test(t.trim()))return Number.parseInt(t.trim(),10)}return null}(i,["status","statusCode","responseCode"]),l=n9.exec(e),d=/\bmethod["'=: ]+([A-Z]+)\b/i.exec(e),u=(n??d?.[1]??l?.[1])?.toUpperCase(),c=n7.exec(e),p=o??c?.[0];if(!p)return null;let f={method:u,url:p,status:s??function(e){for(let t of oe){let r=t.exec(e);if(!r)continue;let a=Number.parseInt(r[1]??"",10);if(Number.isInteger(a))return a}return null}(e)??void 0,timestamp:function(e){let t=/\b\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z)?\b/.exec(e);return t?.[0]}(e),raw:oi(e,a),line:t};if("headers"===r||"all"===r){let t=function(e,t){if(t){let e=t.headers??t.requestHeaders??t.responseHeaders;if(void 0!==e)return oa(e)}let r=/\bheaders?["'=: ]+(\{.*\})/i.exec(e);return r?.[1]?.trim()}(e,i);t&&(f.headers=oi(t,a))}if("body"===r||"all"===r){let t=or(e,i,["requestBody","body","payload","request"]),r=or(e,i,["responseBody","response"]);t&&(f.requestBody=oi(t,a)),r&&(f.responseBody=oi(r,a))}return f}(t,s+e+1,a,i);r&&d.push(r)}return{path:e,exists:!0,scannedLines:l.length,matchedLines:d.length,entries:d,include:a,limits:{maxEntries:r,maxPayloadChars:i,maxScanLines:n}}}(o.resolveAppLogPath(i),{maxEntries:n,include:s,maxPayloadChars:2048,maxScanLines:4e3}),d=e.appLog?.backend??("ios"===e.device.platform?"device"===e.device.kind?"ios-device":"ios-simulator":"android"),u=[];return e.appLog||u.push("Capture uses the session app log file. For fresh traffic, run logs clear --restart before reproducing requests."),0===l.entries.length&&u.push("No HTTP(s) entries were found in recent session app logs."),{ok:!0,data:{...l,active:!!e.appLog,state:e.appLog?.getState()??"inactive",backend:d,notes:u}}}if("batch"===O)return await sD(a,i,s);if("close"===O){let e=o.get(i);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session"}};e.appLog&&await w.stop(e.appLog),a.positionals&&a.positionals.length>0&&("ios"===e.device.platform&&await k(e.device.id),await S(e.device,"close",a.positionals,a.flags?.out,{...nN(n,a.flags,e.appBundleId,e.trace?.outPath)}),await L(e.device,o1)),"ios"===e.device.platform&&await k(e.device.id),of(o.getRuntimeHints(i))&&e.appBundleId&&await y({device:e.device,appId:e.appBundleId}).catch(()=>{}),o.recordAction(e,{command:O,positionals:a.positionals??[],flags:a.flags??{},result:{session:i}}),a.flags?.saveScript&&(e.recordSession=!0),o.writeSessionLog(e),await o$(i).catch(()=>{}),o.delete(i);let t=await su({device:e.device,shutdownRequested:a.flags?.shutdown,shutdownSimulator:N??im,shutdownAndroidEmulator:_??sd});return t?{ok:!0,data:{session:i,shutdown:t}}:{ok:!0,data:{session:i}}}return null}async function sD(e,t,r){let a=e.flags?.batchOnError??"stop";if("stop"!==a)return{ok:!1,error:{code:"INVALID_ARGS",message:`Unsupported batch on-error mode: ${a}.`}};let i=e.flags?.batchMaxSteps??U;if(!Number.isInteger(i)||i<1||i>1e3)return{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid batch max-steps: ${String(e.flags?.batchMaxSteps)}`}};try{let a=G(e.flags?.batchSteps,i),n=Date.now(),o=[];for(let i=0;i<a.length;i+=1){let n=a[i],s=await sE(e,t,n,r,i+1);if(!s.ok)return{ok:!1,error:{code:s.error.code,message:`Batch failed at step ${s.step} (${n.command}): ${s.error.message}`,hint:s.error.hint,diagnosticId:s.error.diagnosticId,logPath:s.error.logPath,details:{...s.error.details??{},step:s.step,command:n.command,positionals:n.positionals,executed:i,total:a.length,partialResults:o}}};o.push(s.result)}return{ok:!0,data:{total:a.length,executed:a.length,totalDurationMs:Date.now()-n,results:o}}}catch(t){let e=f(t);return{ok:!1,error:{code:e.code,message:e.message,details:e.details}}}}async function sE(e,t,r,a,i){let n=Date.now(),o=await a({token:e.token,session:t,command:r.command,positionals:r.positionals,flags:function(e,t){let r={...t??{}};delete r.batchSteps,delete r.batchOnError,delete r.batchMaxSteps;let a=e??{};for(let e of oJ)void 0===r[e]&&void 0!==a[e]&&(r[e]=a[e]);return r}(e.flags,r.flags),runtime:r.runtime,meta:e.meta}),s=Date.now()-n;return o.ok?{ok:!0,step:i,result:{step:i,command:r.command,ok:!0,data:o.data??{},durationMs:s}}:{ok:!1,step:i,error:o.error}}function sk(e,t,r,a){if(e.ok)return e;let i=r+1,n=function(e){let t;return t=(e.positionals??[]).map(e=>tw(e)),[e.command,...t].join(" ")}(t),o={...e.error.details??{},replayPath:a,step:i,action:t.command,positionals:t.positionals??[]};return{ok:!1,error:{code:e.error.code,message:`Replay failed at step ${i} (${n}): ${e.error.message}`,hint:e.error.hint,diagnosticId:e.error.diagnosticId,logPath:e.error.logPath,details:o}}}function sL(e,t){let r={...t??{}},a=e??{};for(let e of oK)void 0===r[e]&&void 0!==a[e]&&(r[e]=a[e]);return r}async function sO(e){let{action:t,sessionName:r,logPath:a,sessionStore:i,dispatch:n}=e;if(!(th(t.command)||["fill","get","is","wait"].includes(t.command)))return null;let o=i.get(r);if(!o)return null;let s=th(t.command)||"fill"===t.command,l=th(t.command)||"fill"===t.command||"get"===t.command&&t.positionals?.[0]==="text",d=await sM(o,t,a,s,n,i);for(let e of function(e){let t=[],r=Array.isArray(e.result?.selectorChain)&&e.result?.selectorChain.every(e=>"string"==typeof e)?e.result.selectorChain:[];if(t.push(...r),th(e.command)){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&t.push(e.positionals.join(" "))}if("fill"===e.command){let r=e.positionals?.[0]??"";r&&!r.startsWith("@")&&Number.isNaN(Number(r))&&t.push(r)}if("get"===e.command){let r=e.positionals?.[1]??"";r&&!r.startsWith("@")&&t.push(e.positionals.slice(1).join(" "))}if("is"===e.command){let{split:r}=nK(e.positionals);r&&t.push(r.selectorExpression)}if("wait"===e.command){let{selectorExpression:r}=oM(e.positionals??[]);r&&t.push(r)}let a="string"==typeof e.result?.refLabel?e.result.refLabel.trim():"";if(a.length>0){let r=JSON.stringify(a);"fill"===e.command?(t.push(`id=${r} editable=true`),t.push(`label=${r} editable=true`),t.push(`text=${r} editable=true`),t.push(`value=${r} editable=true`)):(t.push(`id=${r}`),t.push(`label=${r}`),t.push(`text=${r}`),t.push(`value=${r}`))}return tc(t).filter(e=>e.trim().length>0)}(t)){let r=nq(e);if(!r)continue;let a=nH(d.nodes,r,{platform:o.device.platform,requireRect:s,requireUnique:!0,disambiguateAmbiguous:l});if(!a)continue;let i=nY(a.node,o.device.platform,{action:th(t.command)?"click":"fill"===t.command?"fill":"get"}).join(" || ");if(th(t.command))return{...t,positionals:[i]};if("fill"===t.command){let e=tu(t);if(!e)continue;return{...t,positionals:[i,e]}}if("get"===t.command){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)continue;return{...t,positionals:[e,i]}}if("is"===t.command){let{predicate:e,split:r}=nK(t.positionals);if(!e)continue;let a=r?.rest.join(" ").trim()??"",n=[e,i];return"text"===e&&a.length>0&&n.push(a),{...t,positionals:n}}if("wait"===t.command){let{selectorTimeout:e}=oM(t.positionals??[]),r=[i];return e&&r.push(e),{...t,positionals:r}}}let u=function(e,t,r){if("get"!==e.command||e.positionals?.[0]!=="text")return null;let a=e.positionals?.[1];if(!a)return null;let i=nq(a);if(!i)return null;let n=new Set,o=!1;for(let e of i.selectors)for(let t of e.terms)"role"===t.key&&"string"==typeof t.value&&n.add(n$(t.value)),("text"===t.key||"label"===t.key||"value"===t.key)&&"string"==typeof t.value&&/^\d+$/.test(t.value.trim())&&(o=!0);if(!o)return null;let s=t.nodes.filter(e=>{let t=nU(e).trim();return!!/^\d+$/.test(t)&&(0===n.size||n.has(n$(e.type??"")))});if(0===s.length||1!==tc(s.map(e=>nU(e).trim())).length)return null;let l=s[0];if(!l)return null;let d=nY(l,r.device.platform,{action:"get"});return 0===d.length?null:{...e,positionals:["text",d.join(" || ")]}}(t,d,o);return u||null}async function sM(e,t,r,a,i,n){let o=await i(e.device,"snapshot",[],t.flags?.out,{...nN(r,{...t.flags??{},snapshotInteractiveOnly:a,snapshotCompact:a},e.appBundleId,e.trace?.outPath)}),s=o?.nodes??[],l={nodes:nL(t.flags?.snapshotRaw?s:nP(s)),truncated:o?.truncated,createdAt:Date.now(),backend:o?.backend};return e.snapshot=l,n.set(e.name,e),l}function sx(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function sC(e,t){let r=V(e.type??"Element"),a=B(e,r),i=!1===e.enabled?"disabled":"enabled",n=!0===e.selected?"selected":"unselected",o=!0===e.hittable?"hittable":"not-hittable";return[String(t??e.depth??0),r,a,i,n,o].join("|")}function sR(e,t){return t.flatten?e.map(e=>({text:H(e,0,!1),comparable:sC(e,0)})):F(e).map(e=>({text:e.text,comparable:sC(e.node,e.depth)}))}function sT(e,t){return e.get(t)??0}async function sP(e){let{req:t,sessionName:r,logPath:a,sessionStore:i}=e,n=e.dispatchSnapshotCommand??nA,o=e.runnerCommand??tl,s=t.command;if("snapshot"===s){let{session:e,device:o}=await sU(i,r,t.flags);if(!nb("snapshot",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"snapshot is not supported on this device"}};let s=sF(t.flags?.snapshotScope,e);return s.ok?await sV(e,o,async()=>{let l=e?.appBundleId,d=await s$({dispatchSnapshotCommand:n,device:o,session:e,req:t,logPath:a,snapshotScope:s.scope}),u=e?{...e,snapshot:d.snapshot}:{name:r,device:o,createdAt:Date.now(),appBundleId:l,snapshot:d.snapshot,actions:[]};return sG(i,u,t,{nodes:d.snapshot.nodes.length,truncated:d.snapshot.truncated??!1}),i.set(r,u),{ok:!0,data:{nodes:d.snapshot.nodes,truncated:d.snapshot.truncated??!1,appName:u.appBundleId?u.appName??u.appBundleId:void 0,appBundleId:u.appBundleId}}}):s.response}if("diff"===s){if(t.positionals?.[0]!=="snapshot")return{ok:!1,error:{code:"INVALID_ARGS",message:"diff currently supports only: diff snapshot"}};let{session:e,device:o}=await sU(i,r,t.flags);if(!nb("diff",o))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"diff is not supported on this device"}};let s=sF(t.flags?.snapshotScope,e);if(!s.ok)return s.response;let l=t.flags?.snapshotInteractiveOnly===!0;return await sV(e,o,async()=>{let d=e?.appBundleId,u=(await s$({dispatchSnapshotCommand:n,device:o,session:e,req:t,logPath:a,snapshotScope:s.scope})).snapshot;if(!e?.snapshot){let a=function(e,t={}){return sR(e,t).length}(u.nodes,{flatten:l}),n=e?{...e,snapshot:u}:{name:r,device:o,createdAt:Date.now(),appBundleId:d,snapshot:u,actions:[]};return sG(i,n,t,{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:a}}),i.set(r,n),{ok:!0,data:{mode:"snapshot",baselineInitialized:!0,summary:{additions:0,removals:0,unchanged:a},lines:[]}}}let c=function(e,t,r={}){let a=function(e,t){let r=e.length,a=t.length,i=r+a,n=new Map,o=[];n.set(1,0);for(let s=0;s<=i;s+=1){o.push(new Map(n));for(let i=-s;i<=s;i+=2){let l=i===-s||i!==s&&sT(n,i-1)<sT(n,i+1)?sT(n,i+1):sT(n,i-1)+1,d=l-i;for(;l<r&&d<a&&e[l].comparable===t[d].comparable;)l+=1,d+=1;if(n.set(i,l),l>=r&&d>=a)return function(e,t,r,a,i){let n=[],o=a,s=i;for(let a=e.length-1;a>=0;a-=1){let i=e[a],l=o-s,d=l===-a||l!==a&&sT(i,l-1)<sT(i,l+1)?l+1:l-1,u=sT(i,d),c=u-d;for(;o>u&&s>c;)n.push({kind:"unchanged",text:r[s-1].text}),o-=1,s-=1;if(0===a)break;o===u?(n.push({kind:"added",text:r[c].text}),s=c):(n.push({kind:"removed",text:t[u].text}),o=u)}return n.reverse(),n}(o,e,t,r,a)}}return[]}(sR(e,r),sR(t,r)),i={additions:0,removals:0,unchanged:0};for(let e of a)"added"===e.kind&&(i.additions+=1),"removed"===e.kind&&(i.removals+=1),"unchanged"===e.kind&&(i.unchanged+=1);return{summary:i,lines:a}}(e.snapshot.nodes,u.nodes,{flatten:l}),p={...e,snapshot:u};return sG(i,p,t,{mode:"snapshot",baselineInitialized:!1,summary:c.summary}),i.set(r,p),{ok:!0,data:{mode:"snapshot",baselineInitialized:!1,summary:c.summary,lines:c.lines}}})}if("wait"===s){let{session:e,device:o}=await sU(i,r,t.flags),s=function(e){if(0===e.length)return null;let t=sx(e[0]);if(null!==t)return{kind:"sleep",durationMs:t};if("text"===e[0]){let t=sx(e[e.length-1]);return{kind:"text",text:(null!==t?e.slice(1,-1).join(" "):e.slice(1).join(" ")).trim(),timeoutMs:t}}if(e[0].startsWith("@")){let t=sx(e[e.length-1]);return{kind:"ref",rawRef:e[0],timeoutMs:t}}let r=sx(e[e.length-1]),a=nJ(null!==r?e.slice(0,-1):e.slice());if(a&&0===a.rest.length){let e=nq(a.selectorExpression);if(e)return{kind:"selector",selector:e,selectorExpression:a.selectorExpression,timeoutMs:r}}return{kind:"text",text:(null!==r?e.slice(0,-1).join(" "):e.join(" ")).trim(),timeoutMs:r}}(t.positionals??[]);return s?"sleep"===s.kind?(await new Promise(e=>setTimeout(e,s.durationMs)),sG(i,e,t,{waitedMs:s.durationMs}),{ok:!0,data:{waitedMs:s.durationMs}}):nb("wait",o)?await sV(e,o,async()=>{let l,d;if("selector"===s.kind){let l=s.timeoutMs??1e4,d=Date.now();for(;Date.now()-d<l;){let l=await n(o,"snapshot",[],t.flags?.out,{...nN(a,{...t.flags,snapshotInteractiveOnly:!1,snapshotCompact:!1},e?.appBundleId,e?.trace?.outPath)}),u=l?.nodes??[],c=nL(t.flags?.snapshotRaw?u:nP(u));e&&(e.snapshot={nodes:c,truncated:l?.truncated,createdAt:Date.now(),backend:l?.backend},i.set(r,e));let p=nW(c,s.selector,{platform:o.platform});if(p)return sG(i,e,t,{selector:p.selector.raw,waitedMs:Date.now()-d}),{ok:!0,data:{selector:p.selector.raw,waitedMs:Date.now()-d}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:`wait timed out for selector: ${s.selectorExpression}`}}}if("ref"===s.kind){if(!e?.snapshot)return{ok:!1,error:{code:"INVALID_ARGS",message:"Ref wait requires an existing snapshot in session."}};let t=nO(s.rawRef);if(!t)return{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref: ${s.rawRef}`}};let r=nM(e.snapshot.nodes,t),a=r?nR(r,e.snapshot.nodes):void 0;if(!a)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${s.rawRef} not found or has no label`}};l=a,d=s.timeoutMs}else l=s.text,d=s.timeoutMs;if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires text"}};let u=d??1e4,c=Date.now();for(;Date.now()-c<u;){if("ios"===o.platform){let r=await tl(o,{command:"findText",text:l,appBundleId:e?.appBundleId},{verbose:t.flags?.verbose,logPath:a,traceLogPath:e?.trace?.outPath,requestId:t.meta?.requestId});if(r?.found)return sG(i,e,t,{text:l,waitedMs:Date.now()-c}),{ok:!0,data:{text:l,waitedMs:Date.now()-c}}}else if("android"===o.platform&&nC(nL((await av(o,{scope:l})).nodes??[]),l))return sG(i,e,t,{text:l,waitedMs:Date.now()-c}),{ok:!0,data:{text:l,waitedMs:Date.now()-c}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:`wait timed out for text: ${l}`}}}):{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"wait is not supported on this device"}}:{ok:!1,error:{code:"INVALID_ARGS",message:"wait requires a duration or text"}}}if("alert"===s){let{session:e,device:n}=await sU(i,r,t.flags),s=(t.positionals?.[0]??"get").toLowerCase();return nb("alert",n)?await sV(e,n,async()=>{if("wait"===s){let r=sx(t.positionals?.[1])??1e4,s=Date.now();for(;Date.now()-s<r;){try{let r=await o(n,{command:"alert",action:"get",appBundleId:e?.appBundleId},{verbose:t.flags?.verbose,logPath:a,traceLogPath:e?.trace?.outPath,requestId:t.meta?.requestId});return sG(i,e,t,r),{ok:!0,data:r}}catch{}await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"alert wait timed out"}}}let r="accept"===s||"dismiss"===s?s:"get",l={verbose:t.flags?.verbose,logPath:a,traceLogPath:e?.trace?.outPath,requestId:t.meta?.requestId};if("accept"===r||"dismiss"===r){let a,s=Date.now();for(;Date.now()-s<2e3;){try{let a=await o(n,{command:"alert",action:r,appBundleId:e?.appBundleId},l);return sG(i,e,t,a),{ok:!0,data:a}}catch(t){a=t;let e=String(t?.message??"").toLowerCase();if(!e.includes("alert not found")&&!e.includes("no alert"))break}await new Promise(e=>setTimeout(e,300))}throw a}let d=await o(n,{command:"alert",action:r,appBundleId:e?.appBundleId},l);return sG(i,e,t,d),{ok:!0,data:d}}):{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"alert is only supported on iOS simulators"}}}if("settings"===s){let e=t.positionals?.[0]?.toLowerCase(),n=t.positionals?.[1]?.toLowerCase(),o=t.positionals?.[2]?.toLowerCase();if(!e||!n||"permission"===e&&!o)return{ok:!1,error:{code:"INVALID_ARGS",message:j}};let{session:s,device:l}=await sU(i,r,t.flags);return nb("settings",l)?await sV(s,l,async()=>{let r=s?.appBundleId,d="permission"===e?[e,n,o,t.positionals?.[3]??"",r??""]:[e,n,r??""],u=await nA(l,"settings",d,t.flags?.out,{...nN(a,t.flags,r,s?.trace?.outPath)});return sG(i,s,t,u??{setting:e,state:n}),{ok:!0,data:u??{setting:e,state:n}}}):{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"settings is not supported on this device"}}}return null}async function s$(e){let{dispatchSnapshotCommand:t,device:r,session:a,req:i,logPath:n,snapshotScope:o}=e,s=await t(r,"snapshot",[],i.flags?.out,{...nN(n,{...i.flags,snapshotScope:o},a?.appBundleId,a?.trace?.outPath)}),l=s?.nodes??[];return{snapshot:{nodes:nL(i.flags?.snapshotRaw?l:nP(l)),truncated:s?.truncated,createdAt:Date.now(),backend:s?.backend}}}function sF(e,t){if(!e||!e.trim().startsWith("@"))return{ok:!0,scope:e};if(!t?.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"Ref scope requires an existing snapshot in session."}}};let r=nO(e.trim());if(!r)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:`Invalid ref scope: ${e}`}}};let a=nM(t.snapshot.nodes,r),i=a?nR(a,t.snapshot.nodes):void 0;return i?{ok:!0,scope:i}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${e} not found or has no label`}}}}async function sU(e,t,r){let a=e.get(t),i=a?.device??await nv(r??{});return a||await nS(i),{session:a,device:i}}async function sV(e,t,r){let a=!e&&"ios"===t.platform;try{return await r()}finally{a&&await tt(t.id)}}function sG(e,t,r,a){t&&e.recordAction(t,{command:r.command,positionals:r.positionals??[],flags:r.flags??{},result:a})}function sj(e,t,r,a={}){let i=sq(r);if(!i)return{matches:[],score:0};let n=0,o=[];for(let r of e){if(a.requireRect&&!r.rect)continue;let e=function(e,t,r){switch(t){case"role":return function(e,t){let r=function(e){let t=e.trim();return t?t=(t.split(".").pop()??t).replace(/XCUIElementType/gi,"").toLowerCase():""}(e??"");return r?r===t?2:+!!r.includes(t):0}(e.type,r);case"label":return sB(e.label,r);case"value":return sB(e.value,r);case"id":return sB(e.identifier,r);default:return Math.max(sB(e.label,r),sB(e.value,r),sB(e.identifier,r))}}(r,t,i);if(!(e<=0)){if(e>n){n=e,o.length=0,o.push(r);continue}e===n&&o.push(r)}}return{matches:o,score:n}}function sB(e,t){let r=sq(e??"");return r?r===t?2:+!!r.includes(t):0}function sq(e){return e.trim().toLowerCase().replace(/\s+/g," ")}async function sH(e){let{req:t,sessionName:r,logPath:a,sessionStore:i,invoke:n}=e,o=e.dispatch??nA,s=t.command;if("find"!==s)return null;let l=t.positionals??[];if(0===l.length)return{ok:!1,error:{code:"INVALID_ARGS",message:"find requires a locator or text"}};let{locator:d,query:u,action:c,value:p,timeoutMs:f}=function(e){let t="any",r=0;["text","label","value","role","id"].includes(e[0])&&(t=e[0],r=1);let a=e[r]??"",i=e.slice(r+1);if(0===i.length)return{locator:t,query:a,action:"click"};let n=i[0].toLowerCase();if("get"===n){let e=i[1]?.toLowerCase();if("text"===e)return{locator:t,query:a,action:"get_text"};if("attrs"===e)return{locator:t,query:a,action:"get_attrs"};throw new h("INVALID_ARGS","find get only supports text or attrs")}if("wait"===n)return{locator:t,query:a,action:"wait",timeoutMs:sx(i[1])??void 0};if("exists"===n)return{locator:t,query:a,action:"exists"};if("click"===n)return{locator:t,query:a,action:"click"};if("focus"===n)return{locator:t,query:a,action:"focus"};if("fill"===n)return{locator:t,query:a,action:"fill",value:i.slice(1).join(" ")};if("type"===n)return{locator:t,query:a,action:"type",value:i.slice(1).join(" ")};throw new h("INVALID_ARGS",`Unsupported find action: ${i[0]}`)}(l);if(!u)return{ok:!1,error:{code:"INVALID_ARGS",message:"find requires a value"}};let m=i.get(r);if(!m&&"exists"!==c&&"wait"!==c&&"get_text"!==c&&"get_attrs"!==c)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let w=m?.device??await nv(t.flags??{});m||await nS(w);let g=m?.appBundleId,I="role"!==d?u:void 0,v="click"===c||"focus"===c||"fill"===c||"type"===c,A=0,y=null,b=async()=>{let e=Date.now();if(y&&e-A<750)return{nodes:y};let n=await o(w,"snapshot",[],t.flags?.out,{...nN(a,{...t.flags,snapshotScope:I,snapshotInteractiveOnly:v,snapshotCompact:v},g,m?.trace?.outPath)}),s=n?.nodes??[],l=nL(t.flags?.snapshotRaw?s:nP(s));return A=e,y=l,m&&(m.snapshot={nodes:l,truncated:n?.truncated,createdAt:Date.now(),backend:n?.backend},i.set(r,m)),{nodes:l,truncated:n?.truncated,backend:n?.backend}};if("wait"===c){let e=f??1e4,r=Date.now();for(;Date.now()-r<e;){let{nodes:e}=await b();if(sj(e,d,u,{requireRect:!1}).matches[0])return m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0,waitedMs:Date.now()-r}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-r}};await new Promise(e=>setTimeout(e,300))}return{ok:!1,error:{code:"COMMAND_FAILED",message:"find wait timed out"}}}let{nodes:N}=await b(),_=sj(N,d,u,{requireRect:v});if(v&&_.matches.length>1){let e=_.matches.slice(0,8).map(e=>{let t=nU(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`});return{ok:!1,error:{code:"AMBIGUOUS_MATCH",message:`find matched ${_.matches.length} elements for ${d} "${u}". Use a more specific locator or selector.`,details:{locator:d,query:u,matches:_.matches.length,candidates:e}}}}let S=_.matches[0]??null;if(!S)return{ok:!1,error:{code:"COMMAND_FAILED",message:"find did not match any element"}};let D="click"===c||"focus"===c||"fill"===c||"type"===c?function(e,t){if(t.hittable)return t;let r=t,a=new Set;for(;void 0!==r.parentIndex&&!a.has(r.ref);){a.add(r.ref);let t=e[r.parentIndex];if(!t)break;if(t.hittable)return t;r=t}return null}(N,S)??S:S,E=`@${D.ref}`,k={...t.flags??{},noRecord:!0};if("exists"===c)return m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{found:!0}}),{ok:!0,data:{found:!0}};if("get_text"===c){let e=nU(S);return m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"get text",text:e}}),{ok:!0,data:{ref:E,text:e,node:S}}}if("get_attrs"===c)return m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"get attrs"}}),{ok:!0,data:{ref:E,node:S}};if("click"===c){let e=await n({token:t.token,session:r,command:"click",positionals:[E],flags:k});if(!e.ok)return e;let a=D.rect?nx(D.rect):null,o={ref:E,locator:d,query:u};return a&&(o.x=a.x,o.y=a.y),m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"click",locator:d,query:u}}),{ok:!0,data:o}}if("fill"===c){if(!p)return{ok:!1,error:{code:"INVALID_ARGS",message:"find fill requires text"}};let e=await n({token:t.token,session:r,command:"fill",positionals:[E,p],flags:k});return e.ok&&m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"fill"}}),e}if("focus"===c){let e=S.rect?nx(S.rect):null;if(!e)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};let r=await o(w,"focus",[String(e.x),String(e.y)],t.flags?.out,{...nN(a,t.flags,m?.appBundleId,m?.trace?.outPath)});return m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"focus"}}),{ok:!0,data:r??{ref:E}}}if("type"===c){if(!p)return{ok:!1,error:{code:"INVALID_ARGS",message:"find type requires text"}};let e=S.rect?nx(S.rect):null;if(!e)return{ok:!1,error:{code:"COMMAND_FAILED",message:"matched element has no bounds"}};await o(w,"focus",[String(e.x),String(e.y)],t.flags?.out,{...nN(a,t.flags,m?.appBundleId,m?.trace?.outPath)});let r=await o(w,"type",[p],t.flags?.out,{...nN(a,t.flags,m?.appBundleId,m?.trace?.outPath)});return m&&i.recordAction(m,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{ref:E,action:"type"}}),{ok:!0,data:r??{ref:E}}}return null}function sW(e){return e instanceof Error?e.message:String(e)}function sz(e){let t=e.appBundleId?.trim();return t&&t.length>0?t:void 0}function sJ(e,t,r){return{verbose:e.flags?.verbose,logPath:t,traceLogPath:r.trace?.outPath}}async function sK(e){let{req:t,sessionName:r,sessionStore:a,logPath:n}=e,o=e.deps??{runCmd:c,runCmdBackground:d,runIosRunnerCommand:tl},s=t.command;if("record"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"record requires start|stop"}};let d=a.get(r),c=d?.device??await nv(t.flags??{});d||await nS(c);let p=d??{name:r,device:c,createdAt:Date.now(),actions:[]};if("start"===e){if(p.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"recording already in progress"}};let e=t.flags?.fps;if(void 0!==e&&(!Number.isInteger(e)||e<1||e>120))return{ok:!1,error:{code:"INVALID_ARGS",message:"fps must be an integer between 1 and 120"}};let d=t.positionals?.[1]??`./recording-${Date.now()}.mp4`;if(!nb("record",c))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"record is not supported on this device"}};let f="ios"===c.platform&&"device"===c.kind?sz(p):void 0;if("ios"===c.platform&&"device"===c.kind&&!f)return{ok:!1,error:{code:"INVALID_ARGS",message:"record on physical iOS devices requires an active app session; run open <app> first"}};let m=tb.expandHome(d,t.meta?.cwd),h=t.meta?.clientArtifactPaths?.outPath;M.mkdirSync(i.dirname(m),{recursive:!0});let w=sJ(t,n,p);if("ios"===c.platform&&"device"===c.kind){let t=`agent-device-recording-${Date.now()}.mp4`,r=`tmp/${t}`,i=async()=>{await o.runIosRunnerCommand(c,{command:"recordStart",outPath:t,fps:e,appBundleId:f},w)};try{await i()}catch(e){if(!sW(e).toLowerCase().includes("recording already in progress"))return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${sW(e)}`}};{var l,u;D({level:"warn",phase:"record_start_runner_desynced",data:{platform:c.platform,kind:c.kind,deviceId:c.id,session:p.name,error:sW(e)}});let t=(l=c.id,u=p.name,a.toArray().find(e=>e.name!==u&&"ios"===e.device.platform&&"device"===e.device.kind&&e.device.id===l&&e.recording?.platform==="ios-device-runner"));if(t)return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: recording already in progress in session '${t.name}'`}};try{await o.runIosRunnerCommand(c,{command:"recordStop",appBundleId:f},w)}catch{}try{await i()}catch(e){return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to start recording: ${sW(e)}`}}}}}p.recording={platform:"ios-device-runner",outPath:m,clientOutPath:h,remotePath:r}}else if("ios"===c.platform){let{child:e,wait:t}=o.runCmdBackground("xcrun",ek(c,["io",c.id,"recordVideo",m]),{allowFailure:!0});p.recording={platform:"ios",outPath:m,clientOutPath:h,child:e,wait:t}}else{let e=`/sdcard/agent-device-recording-${Date.now()}.mp4`,{child:t,wait:r}=o.runCmdBackground("adb",["-s",c.id,"shell","screenrecord",e],{allowFailure:!0});p.recording={platform:"android",outPath:m,clientOutPath:h,remotePath:e,child:t,wait:r}}return a.set(r,p),a.recordAction(p,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start"}}),{ok:!0,data:{recording:"started",outPath:h??d}}}if(!p.recording)return{ok:!1,error:{code:"INVALID_ARGS",message:"no active recording"}};let f=p.recording;if("ios-device-runner"===f.platform){let e=sz(p);try{await o.runIosRunnerCommand(c,{command:"recordStop",appBundleId:e},sJ(t,n,p))}catch(e){D({level:"warn",phase:"record_stop_runner_failed",data:{platform:c.platform,kind:c.kind,deviceId:c.id,session:p.name,error:sW(e)}})}let r={stdout:"",stderr:"",exitCode:1};for(let e of e0)if(0===(r=await o.runCmd("xcrun",["devicectl","device","copy","from","--device",c.id,"--source",f.remotePath,"--destination",f.outPath,"--domain-type","appDataContainer","--domain-identifier",e],{allowFailure:!0})).exitCode)break;if(p.recording=void 0,0!==r.exitCode){let e=r.stderr.trim()||r.stdout.trim()||`devicectl exited with code ${r.exitCode}`;return{ok:!1,error:{code:"COMMAND_FAILED",message:`failed to copy recording from device: ${e}`}}}}else{f.child.kill("SIGINT");try{await f.wait}catch{}if("android"===f.platform&&f.remotePath)try{await o.runCmd("adb",["-s",c.id,"pull",f.remotePath,f.outPath],{allowFailure:!0}),await o.runCmd("adb",["-s",c.id,"shell","rm","-f",f.remotePath],{allowFailure:!0})}catch{}p.recording=void 0}a.recordAction(p,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:f.outPath}});let m=[{field:"outPath",path:f.outPath,localPath:f.clientOutPath,fileName:i.basename(f.clientOutPath??f.outPath)}];return{ok:!0,data:{recording:"stopped",outPath:f.outPath,artifacts:m}}}if("trace"===s){let e=(t.positionals?.[0]??"").toLowerCase();if(!["start","stop"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"trace requires start|stop"}};let n=a.get(r);if(!n)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session"}};if("start"===e){if(n.trace)return{ok:!1,error:{code:"INVALID_ARGS",message:"trace already in progress"}};let e=t.positionals?.[1]??a.defaultTracePath(n),r=tb.expandHome(e);return M.mkdirSync(i.dirname(r),{recursive:!0}),M.appendFileSync(r,""),n.trace={outPath:r,startedAt:Date.now()},a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"start",outPath:r}}),{ok:!0,data:{trace:"started",outPath:r}}}if(!n.trace)return{ok:!1,error:{code:"INVALID_ARGS",message:"no active trace"}};let o=n.trace.outPath;if(t.positionals?.[1]){let e=tb.expandHome(t.positionals[1]);M.mkdirSync(i.dirname(e),{recursive:!0}),M.existsSync(o)?M.renameSync(o,e):M.appendFileSync(e,""),o=e}return n.trace=void 0,a.recordAction(n,{command:s,positionals:t.positionals??[],flags:t.flags??{},result:{action:"stop",outPath:o}}),{ok:!0,data:{trace:"stopped",outPath:o}}}return null}function sX(e,t,r){return t>=e.x&&t<=e.x+e.width&&r>=e.y&&r<=e.y+e.height}function sZ(e){let t=null,r=-1;for(let a of e){let e=a.width*a.height;e>r&&(t=a,r=e)}return t}function sY(e,t,r){return Math.min(r,Math.max(t,Math.round(e)))}async function sQ(e){let{req:t,sessionName:r,sessionStore:a,contextFromFlags:i}=e,n=e.dispatch??nA,o=t.command;if("press"===o){let e=a.get(r);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nb("press",e.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"press is not supported on this device"}};let s=function(e){if(e.length<2)return null;let t=Number(e[0]),r=Number(e[1]);return Number.isFinite(t)&&Number.isFinite(r)?{x:t,y:r}:null}(t.positionals??[]);if(s){let r=await n(e.device,"press",[String(s.x),String(s.y)],t.flags?.out,{...i(t.flags,e.appBundleId,e.trace?.outPath)});return a.recordAction(e,{command:o,positionals:t.positionals??[String(s.x),String(s.y)],flags:t.flags??{},result:r??{x:s.x,y:s.y}}),{ok:!0,data:r??{x:s.x,y:s.y}}}let l="click",d=t.positionals?.[0]??"";if(d.startsWith("@")){let r=s2("press",t.flags);if(r)return r;let s=t.positionals.length>1?t.positionals.slice(1).join(" ").trim():"",u=s3({session:e,refInput:d,fallbackLabel:s,requireRect:!0,invalidRefMessage:`${o} requires a ref like @e2`,notFoundMessage:`Ref ${d} not found or has no bounds`});if(!u.ok)return u.response;let{ref:c}=u.target,p=u.target.node,f=u.target.snapshotNodes,m=s4(p.rect);if(!m){let r=await s0(e,t.flags,a,i,{interactiveOnly:!0},n),o=nM(r.nodes,c),l=s.length>0?nC(r.nodes,s):null,d=s4(l?.rect),u=s4(o?.rect)?o:d?l:o??l,h=s4(u?.rect);u&&h&&(p=u,f=r.nodes,m=h)}if(!m)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${d} not found or has invalid bounds`}};let h=nR(p,f),w=nY(p,e.device.platform,{action:l}),{x:g,y:I}=m,v=await n(e.device,"press",[String(g),String(I)],t.flags?.out,{...i(t.flags,e.appBundleId,e.trace?.outPath)});return a.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:c,x:g,y:I,refLabel:h,selectorChain:w}}),{ok:!0,data:{...v??{},ref:c,x:g,y:I}}}let u=(t.positionals??[]).join(" ").trim();if(!u)return{ok:!1,error:{code:"INVALID_ARGS",message:`${o} requires @ref, selector expression, or x y coordinates`}};let c=nB(u),p=await s0(e,t.flags,a,i,{interactiveOnly:!0},n),f=await S("selector_resolve",()=>nH(p.nodes,c,{platform:e.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:o});if(!f||!f.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:nz(c,f?.diagnostics??[],{unique:!0})}};let m=s4(f.node.rect);if(!m)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Selector ${f.selector.raw} resolved to invalid bounds`}};let{x:h,y:w}=m,g=await n(e.device,"press",[String(h),String(w)],t.flags?.out,{...i(t.flags,e.appBundleId,e.trace?.outPath)}),I=nY(f.node,e.device.platform,{action:l}),v=nR(f.node,p.nodes);return a.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{x:h,y:w,selector:f.selector.raw,selectorChain:I,refLabel:v}}),{ok:!0,data:{...g??{},selector:f.selector.raw,x:h,y:w}}}if("fill"===o){let e=a.get(r);if(e&&!nb("fill",e.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"fill is not supported on this device"}};if(t.positionals?.[0]?.startsWith("@")){if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let r=s2("fill",t.flags);if(r)return r;let s=t.positionals.length>=3?t.positionals[1]:"",l=t.positionals.length>=3?t.positionals.slice(2).join(" "):t.positionals.slice(1).join(" ");if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after ref"}};let d=s3({session:e,refInput:t.positionals[0],fallbackLabel:s,requireRect:!0,invalidRefMessage:"fill requires a ref like @e2",notFoundMessage:`Ref ${t.positionals[0]} not found or has no bounds`});if(!d.ok)return d.response;let{ref:u,node:c,snapshotNodes:p}=d.target;if(!c.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${t.positionals[0]} not found or has no bounds`}};let f=c.type??"",m=f&&!nF(f,e.device.platform)?`fill target ${t.positionals[0]} resolved to "${f}", attempting fill anyway.`:void 0,h=nR(c,p),w=nY(c,e.device.platform,{action:"fill"}),{x:g,y:I}=nx(c.rect),v={...await n(e.device,"fill",[String(g),String(I),l],t.flags?.out,{...i(t.flags,e.appBundleId,e.trace?.outPath)})??{ref:u,x:g,y:I}};return m&&(v.warning=m),a.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{...v,refLabel:h,selectorChain:w}}),{ok:!0,data:v}}if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};let s=nJ(t.positionals??[],{preferTrailingValue:!0});if(s){if(0===s.rest.length)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let r=s.rest.join(" ").trim();if(!r)return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires text after selector"}};let l=nB(s.selectorExpression),d=await s0(e,t.flags,a,i,{interactiveOnly:!0},n),u=await S("selector_resolve",()=>nH(d.nodes,l,{platform:e.device.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0}),{command:o});if(!u||!u.node.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:nz(l,u?.diagnostics??[],{unique:!0})}};let c=u.node,p=c.type??"",f=p&&!nF(p,e.device.platform)?`fill target ${u.selector.raw} resolved to "${p}", attempting fill anyway.`:void 0,{x:m,y:h}=nx(u.node.rect),w=await n(e.device,"fill",[String(m),String(h),r],t.flags?.out,{...i(t.flags,e.appBundleId,e.trace?.outPath)}),g=nY(c,e.device.platform,{action:"fill"}),I={...w??{x:m,y:h,text:r},selector:u.selector.raw,selectorChain:g,refLabel:nR(c,d.nodes)};return f&&(I.warning=f),a.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:I}),{ok:!0,data:I}}return{ok:!1,error:{code:"INVALID_ARGS",message:"fill requires x y text, @ref text, or selector text"}}}if("get"===o){let e=t.positionals?.[0];if("text"!==e&&"attrs"!==e)return{ok:!1,error:{code:"INVALID_ARGS",message:"get only supports text or attrs"}};let s=a.get(r);if(!s)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nb("get",s.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"get is not supported on this device"}};let l=t.positionals?.[1]??"";if(l.startsWith("@")){let r=s2("get",t.flags);if(r)return r;let i=s3({session:s,refInput:l,fallbackLabel:t.positionals.length>2?t.positionals.slice(2).join(" ").trim():"",requireRect:!1,invalidRefMessage:"get text requires a ref like @e2",notFoundMessage:`Ref ${l} not found`});if(!i.ok)return i.response;let{ref:n,node:d}=i.target,u=nY(d,s.device.platform,{action:"get"});if("attrs"===e)return a.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:n,selectorChain:u}}),{ok:!0,data:{ref:n,node:d}};let c=nU(d);return a.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:n,text:c,refLabel:c||void 0,selectorChain:u}}),{ok:!0,data:{ref:n,text:c,node:d}}}let d=t.positionals.slice(1).join(" ").trim();if(!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"get requires @ref or selector expression"}};let u=nB(d),c=await s0(s,t.flags,a,i,{interactiveOnly:!1},n),p=await S("selector_resolve",()=>nH(c.nodes,u,{platform:s.device.platform,requireRect:!1,requireUnique:!0,disambiguateAmbiguous:"text"===e}),{command:o});if(!p)return{ok:!1,error:{code:"COMMAND_FAILED",message:nz(u,[],{unique:!0})}};let f=p.node,m=nY(f,s.device.platform,{action:"get"});if("attrs"===e)return a.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{selector:p.selector.raw,selectorChain:m}}),{ok:!0,data:{selector:p.selector.raw,node:f}};let h=nU(f);return a.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{text:h,refLabel:h||void 0,selector:p.selector.raw,selectorChain:m}}),{ok:!0,data:{selector:p.selector.raw,text:h,node:f}}}if("is"===o){let e=(t.positionals?.[0]??"").toLowerCase();if(!["visible","hidden","exists","editable","selected","text"].includes(e))return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires predicate: visible|hidden|exists|editable|selected|text"}};let s=a.get(r);if(!s)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nb("is",s.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"is is not supported on this device"}};let{split:l}=nK(t.positionals);if(!l)return{ok:!1,error:{code:"INVALID_ARGS",message:"is requires a selector expression"}};let d=l.rest.join(" ").trim();if("text"===e&&!d)return{ok:!1,error:{code:"INVALID_ARGS",message:"is text requires expected text value"}};if("text"!==e&&l.rest.length>0)return{ok:!1,error:{code:"INVALID_ARGS",message:`is ${e} does not accept trailing values`}};let u=nB(l.selectorExpression),c=await s0(s,t.flags,a,i,{interactiveOnly:!1},n);if("exists"===e){let r=nW(c.nodes,u,{platform:s.device.platform});return r?(a.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:e,selector:r.selector.raw,selectorChain:u.selectors.map(e=>e.raw),pass:!0,matches:r.matches}}),{ok:!0,data:{predicate:e,pass:!0,selector:r.selector.raw,matches:r.matches}}):{ok:!1,error:{code:"COMMAND_FAILED",message:nz(u,[],{unique:!1})}}}let p=await S("selector_resolve",()=>nH(c.nodes,u,{platform:s.device.platform,requireUnique:!0}),{command:"is",predicate:e});if(!p)return{ok:!1,error:{code:"COMMAND_FAILED",message:nz(u,[],{unique:!0})}};let f=function(e){let{predicate:t,node:r,expectedText:a,platform:i}=e,n=nU(r),o=!1;switch(t){case"visible":o=nX(r);break;case"hidden":o=!nX(r);break;case"editable":o=nZ(r,i);break;case"selected":o=!0===r.selected;break;case"text":o=n===(a??"")}let s="text"===t?`expected="${a??""}" actual="${n}"`:`actual=${JSON.stringify({visible:nX(r),editable:nZ(r,i),selected:!0===r.selected})}`;return{pass:o,actualText:n,details:s}}({predicate:e,node:p.node,expectedText:d,platform:s.device.platform});return f.pass?(a.recordAction(s,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{predicate:e,selector:p.selector.raw,selectorChain:u.selectors.map(e=>e.raw),pass:!0,text:"text"===e?f.actualText:void 0}}),{ok:!0,data:{predicate:e,pass:!0,selector:p.selector.raw}}):{ok:!1,error:{code:"COMMAND_FAILED",message:`is ${e} failed for selector ${p.selector.raw}: ${f.details}`}}}if("scrollintoview"===o){let e=a.get(r);if(!e)return{ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}};if(!nb("scrollintoview",e.device))return{ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:"scrollintoview is not supported on this device"}};let s=t.positionals?.[0]??"";if(!s.startsWith("@"))return null;let l=s2("scrollintoview",t.flags);if(l)return l;let d=s3({session:e,refInput:s,fallbackLabel:t.positionals&&t.positionals.length>1?t.positionals.slice(1).join(" ").trim():"",requireRect:!0,invalidRefMessage:"scrollintoview requires a ref like @e2",notFoundMessage:`Ref ${s} not found or has no bounds`});if(!d.ok)return d.response;let{ref:u,node:c,snapshotNodes:p}=d.target;if(!c.rect)return{ok:!1,error:{code:"COMMAND_FAILED",message:`Ref ${s} not found or has no bounds`}};let f=function(e,t){let r=nx(t),a=e.filter(e=>{var t;return!!(t=e.rect)&&Number.isFinite(t.x)&&Number.isFinite(t.y)&&Number.isFinite(t.width)&&Number.isFinite(t.height)}),i=a.filter(e=>{let t=(e.type??"").toLowerCase();return t.includes("application")||t.includes("window")}),n=sZ(i.map(e=>e.rect).filter(e=>sX(e,r.x,r.y)));if(n)return n;let o=sZ(i.map(e=>e.rect));if(o)return o;let s=sZ(a.map(e=>e.rect).filter(e=>sX(e,r.x,r.y)));return s||null}(p,c.rect);if(!f)return{ok:!1,error:{code:"COMMAND_FAILED",message:`scrollintoview could not infer viewport for ${s}`}};let m=function(e,t){var r,a;let i=Math.max(1,t.height),n=Math.max(1,t.width),o=t.y,s=t.y+i,l=t.x,d=t.x+n,u=o+.25*i,c=s-.25*i,p=Math.max(8,.1*n),f=e.y+e.height/2,m=e.x+e.width/2;if(f>=u&&f<=c)return null;let h=Math.round((r=m,a=l+p,Math.min(d-p,Math.max(a,r)))),w=Math.round(o+.86*i),g=Math.round(o+.14*i),I=Math.max(1,Math.abs(w-g));return f>c?{x:h,startY:w,endY:g,count:sY(Math.ceil((f-c)/I),1,50),direction:"down"}:{x:h,startY:g,endY:w,count:sY(Math.ceil((u-f)/I),1,50),direction:"up"}}(c.rect,f),h=nR(c,p),w=nY(c,e.device.platform,{action:"get"});if(!m)return a.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{ref:u,attempts:0,alreadyVisible:!0,refLabel:h,selectorChain:w}}),{ok:!0,data:{ref:u,attempts:0,alreadyVisible:!0}};let g=await n(e.device,"swipe",[String(m.x),String(m.startY),String(m.x),String(m.endY),"16"],t.flags?.out,{...i(t.flags,e.appBundleId,e.trace?.outPath),count:m.count,pauseMs:0,pattern:"one-way"});return a.recordAction(e,{command:o,positionals:t.positionals??[],flags:t.flags??{},result:{...g??{},ref:u,attempts:m.count,direction:m.direction,refLabel:h,selectorChain:w}}),{ok:!0,data:{...g??{},ref:u,attempts:m.count,direction:m.direction}}}return null}async function s0(e,t,r,a,i,n=nA){let o=await n(e.device,"snapshot",[],t?.out,{...a({...t??{},snapshotInteractiveOnly:i.interactiveOnly,snapshotCompact:i.interactiveOnly},e.appBundleId,e.trace?.outPath)}),s=o?.nodes??[];return e.snapshot={nodes:nL(t?.snapshotRaw?s:nP(s)),truncated:o?.truncated,createdAt:Date.now(),backend:o?.backend},r.set(e.name,e),e.snapshot}let s1=[["snapshotDepth","--depth"],["snapshotScope","--scope"],["snapshotRaw","--raw"]];function s2(e,t){let r=function(e){if(!e)return[];let t=[];for(let[r,a]of s1)void 0!==e[r]&&t.push(a);return t}(t);return 0===r.length?null:{ok:!1,error:{code:"INVALID_ARGS",message:`${e} @ref does not support ${r.join(", ")}.`}}}function s3(e){let{session:t,refInput:r,fallbackLabel:a,requireRect:i,invalidRefMessage:n,notFoundMessage:o}=e;if(!t.snapshot)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:"No snapshot in session. Run snapshot first."}}};let s=nO(r);if(!s)return{ok:!1,response:{ok:!1,error:{code:"INVALID_ARGS",message:n}}};let l=nM(t.snapshot.nodes,s);return((!l||i&&!l.rect)&&a.length>0&&(l=nC(t.snapshot.nodes,a)),l&&(!i||l.rect))?{ok:!0,target:{ref:s,node:l,snapshotNodes:t.snapshot.nodes}}:{ok:!1,response:{ok:!1,error:{code:"COMMAND_FAILED",message:o}}}}function s4(e){let t=function(e){if(!e)return null;let t=Number(e.x),r=Number(e.y),a=Number(e.width),i=Number(e.height);return Number.isFinite(t)&&Number.isFinite(r)&&Number.isFinite(a)&&Number.isFinite(i)&&!(a<0)&&!(i<0)?{x:t,y:r,width:a,height:i}:null}(e);if(!t)return null;let r=nx(t);return Number.isFinite(r.x)&&Number.isFinite(r.y)?r:null}function s8(e){return{tenantId:e.meta?.tenantId??e.flags?.tenant,runId:e.meta?.runId??e.flags?.runId,leaseId:e.meta?.leaseId??e.flags?.leaseId,leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend}}async function s6(e){let{req:t,leaseRegistry:r}=e,a=s8(t);switch(t.command){case"lease_allocate":return{ok:!0,data:{lease:r.allocateLease({tenantId:a.tenantId??"",runId:a.runId??"",backend:a.leaseBackend,ttlMs:a.leaseTtlMs})}};case"lease_heartbeat":return{ok:!0,data:{lease:r.heartbeatLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId,ttlMs:a.leaseTtlMs})}};case"lease_release":return{ok:!0,data:r.releaseLease({leaseId:a.leaseId??"",tenantId:a.tenantId,runId:a.runId})};default:return null}}let s5=new Set(["session_list","devices","ensure-simulator","release_materialized_paths"]),s9=new Set(["session_list","devices","ensure-simulator","release_materialized_paths","lease_allocate","lease_heartbeat","lease_release"]);function s7(e,t,r,a){let i=_().requestId;return{...nN(e,t,r,a,i),requestId:i}}function le(e){M.existsSync(e)&&M.unlinkSync(e)}function lt(e){if(!M.existsSync(e))return null;try{let t=JSON.parse(M.readFileSync(e,"utf8"));if(!Number.isInteger(t.pid)||t.pid<=0)return null;return t}catch{return null}}function lr(e){let t=lt(e);if(!t||t.pid===process.pid)try{M.existsSync(e)&&M.unlinkSync(e)}catch{}}function la(e){if(void 0===e)return;let t=Number(e);if(Number.isInteger(t))return t}let{baseDir:li,infoPath:ln,lockPath:lo,logPath:ls,sessionsDir:ll}=P(process.env.AGENT_DEVICE_STATE_DIR),ld=T(process.env.AGENT_DEVICE_DAEMON_SERVER_MODE);var lu=ll;if(M.existsSync(lu))for(let e of M.readdirSync(lu,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=i.join(lu,e.name,"app-log.pid");if(M.existsSync(t))try{let e=function(e){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t))return{pid:Number.parseInt(t,10)};try{let e=JSON.parse(t);if(!Number.isInteger(e.pid)||e.pid<=0)return null;return e}catch{return null}}(M.readFileSync(t,"utf8"));if(e&&function(e){let t,r=L(e.pid);if(!r||e.startTime&&r!==e.startTime)return!1;let a=n(e.pid);return!!a&&!!((t=a.toLowerCase().replaceAll("\\","/")).includes("log stream")||t.includes("logcat")||t.includes("devicectl device log stream"))&&(!e.command||a===e.command)}(e))try{process.kill(e.pid,"SIGTERM")}catch{}}catch{}finally{t_(t)}}let lc=new tb(ll),lp=new ri({maxActiveSimulatorLeases:la(process.env.AGENT_DEVICE_MAX_SIMULATOR_LEASES),defaultLeaseTtlMs:la(process.env.AGENT_DEVICE_LEASE_TTL_MS),minLeaseTtlMs:la(process.env.AGENT_DEVICE_LEASE_MIN_TTL_MS),maxLeaseTtlMs:la(process.env.AGENT_DEVICE_LEASE_MAX_TTL_MS)}),lf=b(),lm=u.randomBytes(24).toString("hex"),lh=L(process.pid)??void 0,lw=function(){let e=process.argv[1];if(!e)return"unknown";try{let t=M.statSync(e),r=N(),a=i.relative(r,e)||e;return`${a}:${t.size}:${Math.trunc(t.mtimeMs)}`}catch{return"unknown"}}(),lg=function(e){let{logPath:t,token:r,sessionStore:a,leaseRegistry:n,trackDownloadableArtifact:s}=e,l=e.dispatchCommand??nA;async function d(e){let u="click"===e.command?{...e,command:"press"}:e,c=!!(u.meta?.debug||u.flags?.verbose);return await O({session:u.session,requestId:u.meta?.requestId,command:u.command,debug:c,logPath:t},async()=>{if(u.token!==r)return{ok:!1,error:A(new h("UNAUTHORIZED","Invalid token"))};try{let e=function(e){let t=y(e.meta?.sessionIsolation??e.flags?.sessionIsolation),r=e.meta?.tenantId??e.flags?.tenant,a=o(r);if(r&&!a)throw new h("INVALID_ARGS","Invalid tenant id. Use 1-128 chars: letters, numbers, dot, underscore, hyphen.");if("tenant"!==t)return e;if(!a)throw new h("INVALID_ARGS","session isolation mode tenant requires --tenant (or meta.tenantId).");return{...e,session:`${a}:${e.session||"default"}`,meta:{...e.meta,tenantId:a,sessionIsolation:t}}}(u);D({level:"info",phase:"request_start",data:{session:e.session,command:e.command,tenant:e.meta?.tenantId,isolation:e.meta?.sessionIsolation}});let r=e.command,c=t=>(function(e,t,r){let a=_();if(!t.ok){D({level:"error",phase:"request_failed",data:{code:t.error.code,message:t.error.message}});let e=x({force:!0})??void 0;return{ok:!1,error:A(new h(t.error.code,t.error.message,{...t.error.details??{},hint:t.error.hint,diagnosticId:t.error.diagnosticId,logPath:t.error.logPath}),{diagnosticId:a.diagnosticId,logPath:e})}}return D({level:"info",phase:"request_success"}),x(),{ok:!0,data:function(e,t,r){var a,n;let o;if(!t)return t;let s=(a=e,n=t,o=Array.isArray(n.artifacts)?[...n.artifacts]:[],"screenshot"!==a.command||o.some(e=>e?.field==="path")||"string"!=typeof n.path||o.push({field:"path",path:n.path,localPath:a.meta?.clientArtifactPaths?.path,fileName:i.basename(a.meta?.clientArtifactPaths?.path??n.path)}),o.filter(e=>!!(e&&"string"==typeof e.field&&"string"==typeof e.path&&"string"==typeof e.localPath&&e.localPath.length>0)));return 0===s.length?t:{...t,artifacts:s.map(t=>{let a=t.path;return{field:t.field,artifactId:r({artifactPath:a,tenantId:e.meta?.tenantId,fileName:t.fileName}),fileName:t.fileName,localPath:t.localPath}})}}(e,t.data,r)}})(e,t,s),p=s8(e);s9.has(r)||e.meta?.sessionIsolation!=="tenant"||n.assertLeaseAdmission({tenantId:p.tenantId,runId:p.runId,leaseId:p.leaseId,backend:p.leaseBackend});let f=function(e,t){var r;let a,i=e.session||"default";if(r=e,a=r.flags?.session,"string"==typeof a&&a.trim().length>0||"default"!==i||t.has(i))return i;let n=t.toArray();return 1===n.length?n[0].name:i}(e,a),m=a.get(f);m&&!s5.has(r)&&function(e,t){if(!t)return;let r=[],a=e.device,i=eW(t.platform);if(i&&i!==a.platform&&r.push(`--platform=${t.platform}`),t.target&&t.target!==(a.target??"mobile")&&r.push(`--target=${t.target}`),t.udid&&("ios"!==a.platform||t.udid!==a.id)&&r.push(`--udid=${t.udid}`),t.serial&&("android"!==a.platform||t.serial!==a.id)&&r.push(`--serial=${t.serial}`),t.device&&t.device.trim().toLowerCase()!==a.name.trim().toLowerCase()&&r.push(`--device=${t.device}`),t.iosSimulatorDeviceSet){let e=t.iosSimulatorDeviceSet.trim(),i=a.simulatorSetPath?.trim();("ios"!==a.platform||"simulator"!==a.kind||e!==i)&&r.push(`--ios-simulator-device-set=${t.iosSimulatorDeviceSet}`)}if(t.androidDeviceAllowlist){let e=eS(t.androidDeviceAllowlist);"android"===a.platform&&e.has(a.id)||r.push(`--android-device-allowlist=${t.androidDeviceAllowlist}`)}if(0!==r.length){var n;let t,a,i;throw new h("INVALID_ARGS",`Session "${e.name}" is bound to ${(t=(n=e).device.platform,a=n.device.name.trim(),i=n.device.id,`${t} device "${a}" (${i})`)} and cannot be used with ${r.join(", ")}. Use a different --session name or close this session first.`)}}(m,e.flags);let w=await s6({req:e,leaseRegistry:n});if(w)return c(w);let g=await sS({req:e,sessionName:f,logPath:t,sessionStore:a,invoke:d});if(g)return c(g);let I=await sP({req:e,sessionName:f,logPath:t,sessionStore:a});if(I)return c(I);let v=await sK({req:e,sessionName:f,sessionStore:a,logPath:t});if(v)return c(v);let b=await sH({req:e,sessionName:f,logPath:t,sessionStore:a,invoke:d});if(b)return c(b);let N=await sQ({req:e,sessionName:f,sessionStore:a,contextFromFlags:(e,r,a)=>s7(t,e,r,a)});if(N)return c(N);let S=a.get(f);if(!S)return c({ok:!1,error:{code:"SESSION_NOT_FOUND",message:"No active session. Run open first."}});if(!nb(r,S.device))return c({ok:!1,error:{code:"UNSUPPORTED_OPERATION",message:`${r} is not supported on this device`}});let E=e.positionals??[],k=e.flags?.out,L="screenshot"===r&&E[0]?[tb.expandHome(E[0],e.meta?.cwd),...E.slice(1)]:E,O="screenshot"===r&&k?tb.expandHome(k,e.meta?.cwd):k,M="screenshot"===r?L:E,C="screenshot"===r&&O?{...e.flags??{},out:O}:e.flags??{},R=await l(S.device,r,L,O,{...s7(t,e.flags,S.appBundleId,S.trace?.outPath)});return a.recordAction(S,{command:r,positionals:M,flags:C,result:R??{}}),c({ok:!0,data:R??{}})}catch(r){D({level:"error",phase:"request_failed",data:{error:r instanceof Error?r.message:String(r)}});let e=_(),t=x({force:!0})??void 0;return{ok:!1,error:A(r,{diagnosticId:e.diagnosticId,logPath:t})}}})}return d}({logPath:ls,token:lm,sessionStore:lc,leaseRegistry:lp,trackDownloadableArtifact:function(e){let t=u.randomUUID(),r=setTimeout(()=>{tV(t)},9e5);return r.unref(),tU.set(t,{artifactPath:e.artifactPath,tenantId:e.tenantId,fileName:e.fileName,deleteAfterDownload:!1!==e.deleteAfterDownload,timer:r}),t}});!async function(){let e,t;if(!function(e,t,r){M.existsSync(e)||M.mkdirSync(e,{recursive:!0});let a=JSON.stringify(r,null,2),i=()=>{try{return M.writeFileSync(t,a,{flag:"wx",mode:384}),!0}catch(e){if("EEXIST"===e.code)return!1;throw e}};if(i())return!0;let n=lt(t);if(n?.pid&&n.pid!==process.pid&&s(n.pid,n.processStartTime))return!1;try{M.unlinkSync(t)}catch{}return i()}(li,lo,{pid:process.pid,version:lf,startedAt:Date.now(),processStartTime:lh})){process.stderr.write("Daemon lock is held by another process; exiting.\n"),process.exit(0);return}let r=[];try{var a;let i;if("socket"===ld||"dual"===ld){let t=R.createServer(e=>{let t="",r=0,a=new Set,i=!1,n=()=>{if(!i&&0!==r){for(let e of(i=!0,a))es(e);D({level:"warn",phase:"request_client_disconnected",data:{inFlightRequests:r}}),(async()=>{let e=Date.now()+15e3;for(;r>0&&Date.now()<e&&(await tr(),!(r<=0));)await new Promise(e=>setTimeout(e,200))})()}};e.setEncoding("utf8"),e.on("close",n),e.on("error",n),e.on("data",async i=>{let n=(t+=i).indexOf("\n");for(;-1!==n;){let i,o,s=t.slice(0,n).trim();if(t=t.slice(n+1),0===s.length){n=t.indexOf("\n");continue}r+=1;try{let e=JSON.parse(s);if(o=en(e.meta?.requestId,"socket"),e.meta={...e.meta,requestId:o},a.add(o),eo(o),ed(o))throw ec();i=await lg(e)}catch(e){i={ok:!1,error:A(e)}}finally{r-=1,o&&(a.delete(o),el(o))}e.destroyed||e.write(`${JSON.stringify(i)}
37
+ `),n=t.indexOf("\n")}})});r.push(t),e=await new Promise((e,r)=>{t.once("error",r),t.listen(0,"127.0.0.1",()=>{t.off("error",r);let a=t.address();"object"==typeof a&&a?.port?e(a.port):r(new h("COMMAND_FAILED","Failed to bind socket server"))})})}if("http"===ld||"dual"===ld){let e=await t5({handleRequest:lg,token:lm});r.push(e),t=await new Promise((t,r)=>{e.once("error",r),e.listen(0,"127.0.0.1",()=>{e.off("error",r);let a=e.address();"object"==typeof a&&a?.port?t(a.port):r(new h("COMMAND_FAILED","Failed to bind HTTP server"))})})}a={socketPort:e,httpPort:t,token:lm,version:lf,codeSignature:lw,processStartTime:lh},M.existsSync(li)||M.mkdirSync(li,{recursive:!0}),M.writeFileSync(ls,""),i=a.socketPort&&a.httpPort?"dual":a.httpPort?"http":"socket",M.writeFileSync(ln,JSON.stringify({port:a.socketPort,httpPort:a.httpPort,transport:i,token:a.token,pid:process.pid,version:a.version,codeSignature:a.codeSignature,processStartTime:a.processStartTime,stateDir:li},null,2),{mode:384}),e&&process.stdout.write(`AGENT_DEVICE_DAEMON_PORT=${e}
38
38
  `),t&&process.stdout.write(`AGENT_DEVICE_DAEMON_HTTP_PORT=${t}
39
- `)}catch(t){let e=w(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
40
- `),r))try{t.close(()=>{})}catch{}sp(sg),sm(sI),process.exit(1);return}let n=!1,a=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},o=async()=>{if(!n){for(let e of(n=!0,await a(),sN.toArray()))sN.writeSessionLog(e);await te(),sp(sg),sm(sI),process.exit(0)}};process.on("SIGINT",()=>{o()}),process.on("SIGTERM",()=>{o()}),process.on("SIGHUP",()=>{o()}),process.on("uncaughtException",e=>{let t=e instanceof I?e:w(e);process.stderr.write(`Daemon error: ${t.message}
39
+ `)}catch(t){let e=f(t);for(let t of(process.stderr.write(`Daemon error: ${e.message}
40
+ `),r))try{t.close(()=>{})}catch{}le(ln),lr(lo),process.exit(1);return}let i=!1,n=async()=>{await Promise.all(r.map(async e=>{await new Promise(t=>{try{e.close(()=>t())}catch{t()}})}))},o=async()=>{if(!i){for(let e of(i=!0,await n(),lc.toArray()))lc.writeSessionLog(e);await ta(),le(ln),lr(lo),process.exit(0)}};process.on("SIGINT",()=>{o()}),process.on("SIGTERM",()=>{o()}),process.on("SIGHUP",()=>{o()}),process.on("uncaughtException",e=>{let t=e instanceof h?e:f(e);process.stderr.write(`Daemon error: ${t.message}
41
41
  `),o()})}();