agent-device 0.19.3 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +62 -70
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.manifest.json +10 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.apk.sha256 +1 -0
  7. package/{android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.manifest.json → android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.manifest.json} +6 -6
  8. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +2 -0
  9. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +5 -0
  10. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +5 -10
  11. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +74 -174
  12. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +113 -19
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +82 -0
  14. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +325 -123
  15. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -2
  16. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +149 -105
  17. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +56 -2
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +73 -0
  19. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +51 -26
  20. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -2
  21. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -107
  22. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +130 -13
  23. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +51 -8
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +24 -0
  25. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +1 -1
  26. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +43 -35
  27. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
  28. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -1
  29. package/dist/src/agent-browser-tool.js +1 -1
  30. package/dist/src/agent-device-client.js +3 -0
  31. package/dist/src/android-adb.d.ts +1 -1
  32. package/dist/src/android-adb.js +1 -1
  33. package/dist/src/android-input-method-overlays.js +1 -0
  34. package/dist/src/android-input-ownership.js +1 -6
  35. package/dist/src/android-system-chrome.js +1 -0
  36. package/dist/src/android.js +1 -1
  37. package/dist/src/app-lifecycle.js +5 -5
  38. package/dist/src/app-log-request-scope.js +1 -0
  39. package/dist/src/app-resolution.js +1 -0
  40. package/dist/src/apple-multitouch-support.js +1 -0
  41. package/dist/src/apps.js +5 -5
  42. package/dist/src/boot-diagnostics.js +2 -0
  43. package/dist/src/cli-config.js +1 -0
  44. package/dist/src/cli-help.js +131 -40
  45. package/dist/src/cli-runner.js +1 -1
  46. package/dist/src/cli.js +15 -11
  47. package/dist/src/command-metadata.js +1 -1
  48. package/dist/src/command-schema.js +3 -3
  49. package/dist/src/compatibility-policy.js +1 -0
  50. package/dist/src/context.js +1 -0
  51. package/dist/src/contracts.d.ts +2 -2
  52. package/dist/src/debug-symbols.js +1 -1
  53. package/dist/src/device-input-state.js +1 -1
  54. package/dist/src/devices2.js +1 -1
  55. package/dist/src/devices4.js +1 -0
  56. package/dist/src/find.js +1 -1
  57. package/dist/src/finders.js +1 -1
  58. package/dist/src/generic.js +1 -1
  59. package/dist/src/helper.js +1 -1
  60. package/dist/src/index.d.ts +533 -279
  61. package/dist/src/index.js +1 -1
  62. package/dist/src/input-actions.js +4 -3
  63. package/dist/src/install-artifact.js +1 -0
  64. package/dist/src/install-source.d.ts +5 -1
  65. package/dist/src/install-source.js +1 -1
  66. package/dist/src/install-source2.js +1 -1
  67. package/dist/src/interaction-snapshot.js +1 -1
  68. package/dist/src/interaction.d.ts +230 -0
  69. package/dist/src/interaction.js +1 -1
  70. package/dist/src/interactor.js +2 -2
  71. package/dist/src/interactor2.js +1 -0
  72. package/dist/src/internal/bin.js +1 -1
  73. package/dist/src/internal/daemon.js +42 -20
  74. package/dist/src/internal/png-worker.d.ts +22 -0
  75. package/dist/src/internal/png-worker.js +1 -1
  76. package/dist/src/launch-console.js +1 -0
  77. package/dist/src/lease-context.js +1 -0
  78. package/dist/src/lease.js +1 -1
  79. package/dist/src/linux.js +1 -1
  80. package/dist/src/logcat.js +5 -0
  81. package/dist/src/method-scope.js +1 -0
  82. package/dist/src/metro-types.d.ts +52 -0
  83. package/dist/src/metro.d.ts +3 -3
  84. package/dist/src/notifications.js +1 -1
  85. package/dist/src/png-worker-contract.js +1 -1
  86. package/dist/src/process-lock.js +1 -0
  87. package/dist/src/react-native.js +1 -1
  88. package/dist/src/record-trace.js +1 -1
  89. package/dist/src/recording-export-quality.js +15 -0
  90. package/dist/src/register-builtins.js +1 -0
  91. package/dist/src/registry.js +24 -24
  92. package/dist/src/remote-config.d.ts +1 -1
  93. package/dist/src/reporting.js +8 -7
  94. package/dist/src/runner-client.js +1 -1
  95. package/dist/src/runner-disposal.js +2 -0
  96. package/dist/src/runner-lease.js +1 -0
  97. package/dist/src/runner-provider.js +1 -1
  98. package/dist/src/runner-sequence.js +1 -1
  99. package/dist/src/runtime.js +3 -3
  100. package/dist/src/runtime2.js +1 -0
  101. package/dist/src/sdk-android-adb.d.ts +97 -33
  102. package/dist/src/sdk-android-adb.js +4 -4
  103. package/dist/src/sdk-batch-runner.d.ts +2 -1
  104. package/dist/src/sdk-batch-runner.js +3 -2
  105. package/dist/src/sdk-contracts.d.ts +70 -149
  106. package/dist/src/sdk-contracts.js +1 -1
  107. package/dist/src/sdk-device.js +1 -1
  108. package/dist/src/sdk-finders.d.ts +5 -4
  109. package/dist/src/sdk-finders.js +1 -1
  110. package/dist/src/sdk-io.d.ts +1 -1
  111. package/dist/src/sdk-remote-config.d.ts +19 -96
  112. package/dist/src/sdk-remote-config.js +1 -1
  113. package/dist/src/sdk-selectors.js +1 -1
  114. package/dist/src/selector-runtime.js +1 -1
  115. package/dist/src/selector-vocabulary.js +1 -0
  116. package/dist/src/selectors.d.ts +12 -3
  117. package/dist/src/selectors.js +1 -1
  118. package/dist/src/server.js +3 -3
  119. package/dist/src/session-target-evidence.js +1 -0
  120. package/dist/src/session.js +8 -10
  121. package/dist/src/simctl.js +1 -1
  122. package/dist/src/simulator.js +1 -1
  123. package/dist/src/snapshot-diagnostics.js +5 -2
  124. package/dist/src/snapshot-quality.js +1 -1
  125. package/dist/src/snapshot.js +1 -1
  126. package/dist/src/snapshot2.js +1 -2
  127. package/dist/src/tool-provider3.js +1 -0
  128. package/dist/src/unsupported-interactor.js +1 -0
  129. package/dist/src/url.js +1 -1
  130. package/dist/src/web.js +1 -1
  131. package/package.json +34 -27
  132. package/server.json +2 -2
  133. package/skills/agent-device/SKILL.md +5 -3
  134. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk +0 -0
  135. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk.sha256 +0 -1
  136. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.manifest.json +0 -10
  137. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk +0 -0
  138. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk.sha256 +0 -1
  139. package/dist/src/apple-runner-options.js +0 -1
  140. package/dist/src/cli-output.js +0 -1
  141. package/dist/src/client.js +0 -3
  142. package/dist/src/handler-utils.js +0 -1
  143. package/dist/src/output-path.js +0 -1
  144. package/dist/src/points.js +0 -4
  145. package/dist/src/provider.js +0 -1
  146. package/dist/src/providers.js +0 -1
  147. package/dist/src/record-trace-recording.js +0 -23
  148. package/dist/src/recording-provider.js +0 -1
  149. package/dist/src/sdk-batch.js +0 -2
  150. package/dist/src/selectors2.js +0 -1
  151. package/dist/src/ttl-memo.js +0 -1
  152. package/dist/src/tv-remote.js +0 -14
  153. package/dist/src/xml.js +0 -2
  154. /package/{macos-helper → apple/macos-helper}/Package.swift +0 -0
  155. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +0 -0
  156. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +0 -0
  157. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/main.swift +0 -0
  158. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
  159. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
  160. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  161. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  162. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  163. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  164. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  165. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  166. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -0
  167. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +0 -0
  168. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  169. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  170. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -0
  171. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +0 -0
  172. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  173. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
  174. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  175. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  176. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  177. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  178. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
  179. /package/{src/platforms/linux → linux}/atspi-dump.py +0 -0
@@ -1,7 +1,7 @@
1
- import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{_ as n,a as r,l as i,n as a,o,v as s,w as c}from"./sdk-android-adb.js";import{t as l}from"./timeouts.js";import{D as u,E as ee,h as d,p as f,u as p}from"./android-input-ownership.js";import{promises as m}from"node:fs";import te from"node:os";import h from"node:path";const ne=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],re=/\bApplication Not Responding:\s*([A-Za-z0-9_.]+)/i,ie=/([^{}]*\bis(?:n't| not)\s+responding[^{}]*)/i,ae=/\b([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+)\b/;function g(e){let t=new Set;for(let n of e.split(`
1
+ import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{_ as n,a as r,c as i,i as a,n as o,v as s,w as c}from"./sdk-android-adb.js";import{t as l}from"./timeouts.js";import{d as u,i as d,l as f,s as p,u as ee}from"./logcat.js";import{promises as m}from"node:fs";import te from"node:os";import h from"node:path";const ne=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],re=/\bApplication Not Responding:\s*([A-Za-z0-9_.]+)/i,ie=/([^{}]*\bis(?:n't| not)\s+responding[^{}]*)/i,ae=/\b([A-Za-z][A-Za-z0-9_]*(?:\.[A-Za-z0-9_]+)+)\b/;function g(e){let t=new Set;for(let n of e.split(`
2
2
  `)){let e=n.trim();if(!e)continue;let r=e.split(/\s+/)[0]??``;if(!r.includes(`/`))continue;let i=r.split(`/`)[0]??``;i.includes(`.`)&&i&&t.add(i)}return Array.from(t)}function _(e){return e.split(`
3
3
  `).map(e=>{let t=e.trim();return t.startsWith(`package:`)?t.slice(8):t}).filter(Boolean)}function v(e){return y(e,e=>ce(e))}function oe(e){return y(e,(e,t)=>se(e,t))}function y(e,t){let n=e.split(`
4
- `);for(let e of ne)for(let r of n){let n=r.indexOf(e);if(n===-1)continue;let i=r.trim(),a=t(r.slice(n+e.length),i);if(a)return a}return null}function se(e,t){let n=e.split(`}`)[0]?.trim()??e.trim(),r=re.exec(n);if(r){let e=r[1];return{package:e,focusedWindow:`Application Not Responding: ${e}`,raw:t}}let i=ie.exec(n);if(!i)return null;let a=i[1];if(a===void 0)return null;let o=a.trim().replace(/\s+/g,` `),s=ae.exec(o)?.[1];return{...s?{package:s}:{},focusedWindow:o,raw:t}}function ce(e){for(let t of e.trim().split(/\s+/)){let e=t.indexOf(`/`);if(e<=0)continue;let n=b(t.slice(0,e),!1),r=b(t.slice(e+1),!0);if(n&&r&&n.length===e)return{package:n,activity:r}}return null}function b(e,t){let n=0;for(;n<e.length&&le(e[n],t);)n+=1;return e.slice(0,n)}function le(e,t){if(!e)return!1;let n=e.charCodeAt(0);return n>=48&&n<=57||n>=65&&n<=90||n>=97&&n<=122||e===`_`||e===`.`||t&&e===`$`}const ue=/\.(?:apk|aab)$/i,de=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function x(e){let t=e.trim();return t.length===0?`other`:ue.test(t)?t.includes(`/`)||t.includes(`\\`)||t.startsWith(`.`)||t.startsWith(`~`)||!S(t)?`binary`:`package`:S(t)?`package`:`other`}function S(e){return de.test(e)}function fe(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}var pe=e({closeAndroidApp:()=>G,getAndroidAppState:()=>N,getAndroidBlockingDialogFocus:()=>P,inferAndroidAppName:()=>M,installAndroidApp:()=>He,installAndroidInstallablePath:()=>Q,installAndroidInstallablePathAndResolvePackageName:()=>$,isAmStartError:()=>H,listAndroidApps:()=>A,openAndroidApp:()=>L,openAndroidDevice:()=>W,parseAndroidLaunchComponent:()=>U,reinstallAndroidApp:()=>Ue,resolveAndroidApp:()=>k});const me={settings:{type:`intent`,value:`android.settings.SETTINGS`}},C=`android.intent.category.LAUNCHER`,w=`android.intent.category.LEANBACK_LAUNCHER`,T=`android.intent.category.DEFAULT`,E=`Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.`,he=new Set([`localhost`,`127.0.0.1`,`::1`,`[::1]`]),D=ee();function O(e){return{platform:`android`,deviceId:e.id,variant:e.target??``}}async function k(e,n){let r=n.trim();if(x(r)===`package`)return{type:`package`,value:r};let i=me[r.toLowerCase()];if(i)return i;let a=O(e),o=D.get(a,r);if(o)return o;let s=(await f(e,[`shell`,`pm`,`list`,`packages`])).stdout.split(`
5
- `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase())),c=s[0];if(c!==void 0&&s.length===1)return D.set(a,r,{type:`package`,value:c});throw s.length>1?new t(`INVALID_ARGS`,`Multiple packages matched "${n}"`,{matches:s,hint:`Run agent-device apps --platform android to see the exact installed package names before retrying open.`}):new t(`APP_NOT_INSTALLED`,`No package found matching "${n}"`,{hint:E})}async function A(e,t){let n=await ge(e);return(t===`user-installed`?(await ve(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:M(e)}))}async function ge(e){let t=new Set;for(let n of j(e,{includeFallbackWhenUnknown:!0})){let r=await f(e,[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,n],{allowFailure:!0});if(!(r.exitCode!==0||r.stdout.trim().length===0))for(let e of g(r.stdout))t.add(e)}return t}function _e(e){return j(e)[0]??C}function j(e,t={}){return e.target===`tv`?[w]:e.target===`mobile`?[C]:t.includeFallbackWhenUnknown?[C,w]:[C]}async function ve(e){return _((await f(e,[`shell`,`pm`,`list`,`packages`,`-3`])).stdout)}function M(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(`.`).flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),r=n[n.length-1]??e;for(let e=n.length-1;e>=0;--e){let i=n[e];if(i&&!t.has(i)){r=i;break}}return r.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}async function N(e){return await F(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await F(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function P(e){return await ye(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])}async function F(e,t){for(let n of t){let t=v((await f(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}async function ye(e,t){for(let n of t){let t=oe((await f(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}function be(e){let t;try{t=new URL(e)}catch{return null}let n=t.hostname.toLowerCase();if(!he.has(n)||!t.port)return null;let r=Number(t.port);return Number.isInteger(r)?`tcp:${r}`:null}async function xe(e,n){let a=be(n);if(!a)return;let o=r(i(e));try{await o.ensure({local:a,remote:a})}catch(e){let n={localPort:a.replace(`tcp:`,``),operation:`adb reverse ${a} ${a}`};throw e instanceof t&&Object.assign(n,{hint:e.details?.hint,diagnosticId:e.details?.diagnosticId,logPath:e.details?.logPath}),new t(`COMMAND_FAILED`,`Failed to ensure Android port reverse ${a} before opening localhost URL`,n,e)}}function Se(e){return/^[A-Za-z0-9_@%+=:,./-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function I(e){return(e.launchArgs??[]).map(Se)}async function L(e,t,n){e.booted||await d(e.id);let r=ke(n),i=r.activity,a=t.trim();if(u(a)){await Ce(e,a,r);return}if(r.url!==void 0){await we(e,t,r);return}let o=await k(e,t),s=_e(e);if(o.type===`intent`){await Te(e,o.value,r);return}if(i){await Ee(e,o.value,i,s,r);return}await De(e,o.value,s,r)}async function Ce(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening a deep link URL`);await xe(e,n),await f(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,n,...Ae(r.appBundleId),...I(r)])}async function we(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening an app-bound deep link URL`);let i=r.url?.trim()??``;if(!u(i))throw new t(`INVALID_ARGS`,`Android app-bound open requires a valid URL target`);await f(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,i,`-p`,await Oe(e,n,`app-bound open`),...I(r)])}async function Te(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override requires a package name, not an intent`);await f(e,[`shell`,`am`,`start`,`-W`,`-a`,n,...I(r)])}async function Ee(e,t,n,r,i){let a=n.includes(`/`)?n:`${t}/${n.startsWith(`.`)?n:`.${n}`}`;try{await f(e,R(a,r,i))}catch(n){throw await je(e,t,n),n}}async function De(e,t,n,r){let i=await f(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,T,`-c`,n,`-p`,t,...I(r)],{allowFailure:!0});if(i.exitCode===0&&!H(i.stdout,i.stderr))return;let o=await Me(e,t);if(!o)throw await B(e,t)?a(`Failed to launch ${t}`,i):z(t);await f(e,R(o,n,r))}function R(e,t,n){return[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,T,`-c`,t,`-n`,e,...I(n)]}async function Oe(e,n,r){let i=await k(e,n);if(i.type===`intent`)throw new t(`INVALID_ARGS`,`Android ${r} requires a package name, not an intent`);return i.value}function ke(e){return typeof e==`string`?{activity:e}:e??{}}function Ae(e){let t=e?.trim();return t?[`-p`,t]:[]}function z(e){return new t(`APP_NOT_INSTALLED`,`No package found matching "${e}"`,{package:e,hint:E})}async function B(e,t){let n=await f(e,[`shell`,`pm`,`path`,t],{allowFailure:!0}),r=`${n.stdout}\n${n.stderr}`;return n.exitCode===0&&/\bpackage:/i.test(r)?!0:(V(r),!1)}async function je(e,n,r){if(V(r instanceof t?`${String(r.details?.stdout??``)}\n${String(r.details?.stderr??``)}`:``)||!await B(e,n))throw z(n)}function V(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function Me(e,t){let n=Array.from(new Set(j(e,{includeFallbackWhenUnknown:!0})));for(let r of n){let n=await f(e,[`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=U(n.stdout);if(i)return i}return null}function H(e,t){let n=`${e}\n${t}`;return/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(n)}function U(e){let t=e.split(`
6
- `).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;--e){let n=t[e];if(n===void 0||!n.includes(`/`))continue;let r=n.split(/\s+/)[0];if(r!==void 0)return r}return null}async function W(e){e.booted||await d(e.id)}async function G(e,n){if(n.trim().toLowerCase()===`settings`){await f(e,[`shell`,`am`,`force-stop`,`com.android.settings`]),await K(e,`com.android.settings`);return}let r=await k(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`Close requires a package name, not an intent`);await f(e,[`shell`,`am`,`force-stop`,r.value]),await K(e,r.value)}async function K(e,t){await Ne(e,t),await Fe(e,t)}async function Ne(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if((await Pe(e))?.package!==t)return;await l(50)}}async function Pe(e){for(let t of[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`],[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]]){let n=v((await f(e,t,{allowFailure:!0})).stdout??``);if(n)return n}return null}async function Fe(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if(!await q(e,t)&&(await l(150),!await q(e,t)))return;await l(50)}}async function q(e,t){return((await f(e,[`shell`,`pidof`,t],{allowFailure:!0})).stdout??``).trim().length>0}async function Ie(e,n){let r=await k(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`);let i=await f(e,[`uninstall`,r.value],{allowFailure:!0});if(i.exitCode!==0){let e=`${i.stdout}\n${i.stderr}`.toLowerCase();if(!e.includes(`unknown package`)&&!e.includes(`not installed`))throw a(`adb uninstall failed for ${r.value}`,i)}return{package:r.value}}let J=null;function Le(){return`${process.env.PATH??``}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Re(){let e=Le();if(J?.key===e)return J.invocation;if(await c(`bundletool`)){let t={cmd:`bundletool`,prefixArgs:[]};return J={key:e,invocation:t},t}let r=await n(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return J={key:e,invocation:i},i}async function Y(e){let t=await Re();await s(t.cmd,[...t.prefixArgs,...e])}function ze(e){return h.extname(e).toLowerCase()===`.aab`}async function Be(e,t){let n=i(e),r=`universal`;if(n.installBundle){await n.installBundle(t,{mode:r});return}let a=await m.mkdtemp(h.join(te.tmpdir(),`agent-device-aab-`)),o=h.join(a,`bundle.apks`);try{await Y([`build-apks`,`--bundle`,t,`--output`,o,`--mode`,r]),await Y([`install-apks`,`--apks`,o,`--device-id`,e.id])}finally{await m.rm(a,{recursive:!0,force:!0})}}async function X(e,t){if(ze(t)){await Be(e,t);return}await o(t,{device:e,replace:!0})}async function Z(e){let t=await f(e,[`shell`,`pm`,`list`,`packages`]);return new Set(t.stdout.split(`
7
- `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}async function Ve(e,t){let n=await Z(e),r=Array.from(n).filter(e=>!t.has(e));if(r.length===1)return r[0]}async function Q(e,t){await D.invalidateWhile(O(e),async()=>{e.booted||await d(e.id),await X(e,t)})}async function $(e,t,n){let r=n?void 0:await Z(e);return await Q(e,t),n??(r?await Ve(e,r):void 0)}async function He(e,t){e.booted||await d(e.id);let n=await p({kind:`path`,path:t});try{let t=await $(e,n.installablePath,n.packageName),r=t?M(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:r,launchTarget:t}}finally{await n.cleanup()}}async function Ue(e,t,n){return await D.invalidateWhile(O(e),async()=>{e.booted||await d(e.id);let{package:r}=await Ie(e,t),i=await p({kind:`path`,path:n},{resolveIdentity:!1});try{await Q(e,i.installablePath)}finally{await i.cleanup()}return{package:r}})}export{M as a,L as c,k as d,x as f,_ as g,g as h,P as i,W as l,v as m,G as n,H as o,fe as p,N as r,A as s,pe as t,U as u};
4
+ `);for(let e of ne)for(let r of n){let n=r.indexOf(e);if(n===-1)continue;let i=r.trim(),a=t(r.slice(n+e.length),i);if(a)return a}return null}function se(e,t){let n=e.split(`}`)[0]?.trim()??e.trim(),r=re.exec(n);if(r){let e=r[1];return{package:e,focusedWindow:`Application Not Responding: ${e}`,raw:t}}let i=ie.exec(n);if(!i)return null;let a=i[1];if(a===void 0)return null;let o=a.trim().replace(/\s+/g,` `),s=ae.exec(o)?.[1];return{...s?{package:s}:{},focusedWindow:o,raw:t}}function ce(e){for(let t of e.trim().split(/\s+/)){let e=t.indexOf(`/`);if(e<=0)continue;let n=b(t.slice(0,e),!1),r=b(t.slice(e+1),!0);if(n&&r&&n.length===e)return{package:n,activity:r}}return null}function b(e,t){let n=0;for(;n<e.length&&le(e[n],t);)n+=1;return e.slice(0,n)}function le(e,t){if(!e)return!1;let n=e.charCodeAt(0);return n>=48&&n<=57||n>=65&&n<=90||n>=97&&n<=122||e===`_`||e===`.`||t&&e===`$`}const ue=/\.(?:apk|aab)$/i,de=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function x(e){let t=e.trim();return t.length===0?`other`:ue.test(t)?t.includes(`/`)||t.includes(`\\`)||t.startsWith(`.`)||t.startsWith(`~`)||!S(t)?`binary`:`package`:S(t)?`package`:`other`}function S(e){return de.test(e)}function fe(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}var pe=e({closeAndroidApp:()=>K,getAndroidAppState:()=>N,getAndroidBlockingDialogFocus:()=>P,inferAndroidAppName:()=>M,installAndroidApp:()=>He,installAndroidInstallablePath:()=>Q,installAndroidInstallablePathAndResolvePackageName:()=>$,isAmStartError:()=>U,listAndroidApps:()=>A,openAndroidApp:()=>R,openAndroidDevice:()=>G,parseAndroidLaunchComponent:()=>W,reinstallAndroidApp:()=>Ue,resolveAndroidApp:()=>k});const me={settings:{type:`intent`,value:`android.settings.SETTINGS`}},C=`android.intent.category.LAUNCHER`,w=`android.intent.category.LEANBACK_LAUNCHER`,T=`android.intent.category.DEFAULT`,E=`Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.`,he=new Set([`localhost`,`127.0.0.1`,`::1`,`[::1]`]),D=ee();function O(e){return{platform:`android`,deviceId:e.id,variant:e.target??``}}async function k(e,n){let r=n.trim();if(x(r)===`package`)return{type:`package`,value:r};let i=me[r.toLowerCase()];if(i)return i;let a=O(e),o=D.get(a,r);if(o)return o;let s=(await p(e,[`shell`,`pm`,`list`,`packages`])).stdout.split(`
5
+ `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean).filter(e=>e.toLowerCase().includes(r.toLowerCase())),c=s[0];if(c!==void 0&&s.length===1)return D.set(a,r,{type:`package`,value:c});throw s.length>1?new t(`INVALID_ARGS`,`Multiple packages matched "${n}"`,{matches:s,hint:`Run agent-device apps --platform android to see the exact installed package names before retrying open.`}):new t(`APP_NOT_INSTALLED`,`No package found matching "${n}"`,{hint:E})}async function A(e,t){let n=await ge(e);return(t===`user-installed`?(await ve(e)).filter(e=>n.has(e)):Array.from(n)).sort((e,t)=>e.localeCompare(t)).map(e=>({package:e,name:M(e)}))}async function ge(e){let t=new Set;for(let n of j(e,{includeFallbackWhenUnknown:!0})){let r=await p(e,[`shell`,`cmd`,`package`,`query-activities`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,n],{allowFailure:!0});if(!(r.exitCode!==0||r.stdout.trim().length===0))for(let e of g(r.stdout))t.add(e)}return t}function _e(e){return j(e)[0]??C}function j(e,t={}){return e.target===`tv`?[w]:e.target===`mobile`?[C]:t.includeFallbackWhenUnknown?[C,w]:[C]}async function ve(e){return _((await p(e,[`shell`,`pm`,`list`,`packages`,`-3`])).stdout)}function M(e){let t=new Set([`com`,`android`,`google`,`app`,`apps`,`service`,`services`,`mobile`,`client`]),n=e.split(`.`).flatMap(e=>e.split(/[_-]+/)).map(e=>e.trim().toLowerCase()).filter(e=>e.length>0),r=n[n.length-1]??e;for(let e=n.length-1;e>=0;--e){let i=n[e];if(i&&!t.has(i)){r=i;break}}return r.split(/[^a-z0-9]+/i).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}async function N(e){return await F(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])||await F(e,[[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]])||{}}async function P(e){return await ye(e,[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`]])}async function F(e,t){for(let n of t){let t=v((await p(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}async function ye(e,t){for(let n of t){let t=oe((await p(e,n,{allowFailure:!0})).stdout??``);if(t)return t}return null}function be(e){let t;try{t=new URL(e)}catch{return null}let n=t.hostname.toLowerCase();if(!he.has(n)||!t.port)return null;let r=Number(t.port);return Number.isInteger(r)?`tcp:${r}`:null}async function I(e,n){let r=be(n);if(!r)return;let o=a(i(e));try{await o.ensure({local:r,remote:r})}catch(e){let n={localPort:r.replace(`tcp:`,``),operation:`adb reverse ${r} ${r}`};throw e instanceof t&&Object.assign(n,{hint:e.details?.hint,diagnosticId:e.details?.diagnosticId,logPath:e.details?.logPath}),new t(`COMMAND_FAILED`,`Failed to ensure Android port reverse ${r} before opening localhost URL`,n,e)}}function xe(e){return/^[A-Za-z0-9_@%+=:,./-]+$/.test(e)?e:`'${e.replace(/'/g,`'\\''`)}'`}function L(e){return(e.launchArgs??[]).map(xe)}async function R(e,t,n){e.booted||await f(e.id);let r=Oe(n),i=r.activity,a=t.trim();if(u(a)){await Se(e,a,r);return}if(r.url!==void 0){await Ce(e,t,r);return}let o=await k(e,t),s=_e(e);if(o.type===`intent`){await we(e,o.value,r);return}if(i){await Te(e,o.value,i,s,r);return}await Ee(e,o.value,s,r)}async function Se(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening a deep link URL`);await I(e,n),await p(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,n,...ke(r.appBundleId),...L(r)])}async function Ce(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override is not supported when opening an app-bound deep link URL`);let i=r.url?.trim()??``;if(!u(i))throw new t(`INVALID_ARGS`,`Android app-bound open requires a valid URL target`);await I(e,i),await p(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.VIEW`,`-d`,i,`-p`,await De(e,n,`app-bound open`),...L(r)])}async function we(e,n,r){if(r.activity)throw new t(`INVALID_ARGS`,`Activity override requires a package name, not an intent`);await p(e,[`shell`,`am`,`start`,`-W`,`-a`,n,...L(r)])}async function Te(e,t,n,r,i){let a=n.includes(`/`)?n:`${t}/${n.startsWith(`.`)?n:`.${n}`}`;try{await p(e,z(a,r,i))}catch(n){throw await Ae(e,t,n),n}}async function Ee(e,t,n,r){let i=await p(e,[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,T,`-c`,n,`-p`,t,...L(r)],{allowFailure:!0});if(i.exitCode===0&&!U(i.stdout,i.stderr))return;let a=await je(e,t);if(!a)throw await V(e,t)?o(`Failed to launch ${t}`,i):B(t);await p(e,z(a,n,r))}function z(e,t,n){return[`shell`,`am`,`start`,`-W`,`-a`,`android.intent.action.MAIN`,`-c`,T,`-c`,t,`-n`,e,...L(n)]}async function De(e,n,r){let i=await k(e,n);if(i.type===`intent`)throw new t(`INVALID_ARGS`,`Android ${r} requires a package name, not an intent`);return i.value}function Oe(e){return typeof e==`string`?{activity:e}:e??{}}function ke(e){let t=e?.trim();return t?[`-p`,t]:[]}function B(e){return new t(`APP_NOT_INSTALLED`,`No package found matching "${e}"`,{package:e,hint:E})}async function V(e,t){let n=await p(e,[`shell`,`pm`,`path`,t],{allowFailure:!0}),r=`${n.stdout}\n${n.stderr}`;return n.exitCode===0&&/\bpackage:/i.test(r)?!0:(H(r),!1)}async function Ae(e,n,r){if(H(r instanceof t?`${String(r.details?.stdout??``)}\n${String(r.details?.stderr??``)}`:``)||!await V(e,n))throw B(n)}function H(e){return/\bunknown package\b/i.test(e)||/\bpackage .* (?:was|is) not found\b/i.test(e)||/\bpackage .* does not exist\b/i.test(e)||/\bcould not find package\b/i.test(e)}async function je(e,t){let n=Array.from(new Set(j(e,{includeFallbackWhenUnknown:!0})));for(let r of n){let n=await p(e,[`shell`,`cmd`,`package`,`resolve-activity`,`--brief`,`-a`,`android.intent.action.MAIN`,`-c`,r,t],{allowFailure:!0});if(n.exitCode!==0)continue;let i=W(n.stdout);if(i)return i}return null}function U(e,t){let n=`${e}\n${t}`;return/Error:.*(?:Activity not started|unable to resolve Intent)/i.test(n)}function W(e){let t=e.split(`
6
+ `).map(e=>e.trim()).filter(Boolean);for(let e=t.length-1;e>=0;--e){let n=t[e];if(n===void 0||!n.includes(`/`))continue;let r=n.split(/\s+/)[0];if(r!==void 0)return r}return null}async function G(e){e.booted||await f(e.id)}async function K(e,n){if(n.trim().toLowerCase()===`settings`){await p(e,[`shell`,`am`,`force-stop`,`com.android.settings`]),await q(e,`com.android.settings`);return}let r=await k(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`Close requires a package name, not an intent`);await p(e,[`shell`,`am`,`force-stop`,r.value]),await q(e,r.value)}async function q(e,t){await Me(e,t),await Pe(e,t)}async function Me(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if((await Ne(e))?.package!==t)return;await l(50)}}async function Ne(e){for(let t of[[`shell`,`dumpsys`,`window`,`windows`],[`shell`,`dumpsys`,`window`],[`shell`,`dumpsys`,`activity`,`activities`],[`shell`,`dumpsys`,`activity`]]){let n=v((await p(e,t,{allowFailure:!0})).stdout??``);if(n)return n}return null}async function Pe(e,t){let n=Date.now()+2e3;for(;Date.now()<n;){if(!await J(e,t)&&(await l(150),!await J(e,t)))return;await l(50)}}async function J(e,t){return((await p(e,[`shell`,`pidof`,t],{allowFailure:!0})).stdout??``).trim().length>0}async function Fe(e,n){let r=await k(e,n);if(r.type===`intent`)throw new t(`INVALID_ARGS`,`App uninstall requires a package name, not an intent`);let i=await p(e,[`uninstall`,r.value],{allowFailure:!0});if(i.exitCode!==0){let e=`${i.stdout}\n${i.stderr}`.toLowerCase();if(!e.includes(`unknown package`)&&!e.includes(`not installed`))throw o(`adb uninstall failed for ${r.value}`,i)}return{package:r.value}}let Y=null;function Ie(){return`${process.env.PATH??``}::${process.env.AGENT_DEVICE_BUNDLETOOL_JAR??``}`}async function Le(){let e=Ie();if(Y?.key===e)return Y.invocation;if(await c(`bundletool`)){let t={cmd:`bundletool`,prefixArgs:[]};return Y={key:e,invocation:t},t}let r=await n(process.env.AGENT_DEVICE_BUNDLETOOL_JAR,`AGENT_DEVICE_BUNDLETOOL_JAR`);if(!r)throw new t(`TOOL_MISSING`,`bundletool not found in PATH. Install bundletool or set AGENT_DEVICE_BUNDLETOOL_JAR to a bundletool-all.jar path.`);let i={cmd:`java`,prefixArgs:[`-jar`,r]};return Y={key:e,invocation:i},i}async function X(e){let t=await Le();await s(t.cmd,[...t.prefixArgs,...e])}function Re(e){return h.extname(e).toLowerCase()===`.aab`}async function ze(e,t){let n=i(e),r=`universal`;if(n.installBundle){await n.installBundle(t,{mode:r});return}let a=await m.mkdtemp(h.join(te.tmpdir(),`agent-device-aab-`)),o=h.join(a,`bundle.apks`);try{await X([`build-apks`,`--bundle`,t,`--output`,o,`--mode`,r]),await X([`install-apks`,`--apks`,o,`--device-id`,e.id])}finally{await m.rm(a,{recursive:!0,force:!0})}}async function Be(e,t){if(Re(t)){await ze(e,t);return}await r(t,{device:e,replace:!0})}async function Z(e){let t=await p(e,[`shell`,`pm`,`list`,`packages`]);return new Set(t.stdout.split(`
7
+ `).map(e=>e.replace(`package:`,``).trim()).filter(Boolean))}async function Ve(e,t){let n=await Z(e),r=Array.from(n).filter(e=>!t.has(e));if(r.length===1)return r[0]}async function Q(e,t){await D.invalidateWhile(O(e),async()=>{e.booted||await f(e.id),await Be(e,t)})}async function $(e,t,n){let r=n?void 0:await Z(e);return await Q(e,t),n??(r?await Ve(e,r):void 0)}async function He(e,t){e.booted||await f(e.id);let n=await d({kind:`path`,path:t});try{let t=await $(e,n.installablePath,n.packageName),r=t?M(t):void 0;return{archivePath:n.archivePath,installablePath:n.installablePath,packageName:t,appName:r,launchTarget:t}}finally{await n.cleanup()}}async function Ue(e,t,n){return await D.invalidateWhile(O(e),async()=>{e.booted||await f(e.id);let{package:r}=await Fe(e,t),i=await d({kind:`path`,path:n},{resolveIdentity:!1});try{await Q(e,i.installablePath)}finally{await i.cleanup()}return{package:r}})}export{M as a,R as c,k as d,x as f,_ as g,g as h,P as i,G as l,v as m,K as n,U as o,fe as p,N as r,A as s,pe as t,W as u};
@@ -0,0 +1 @@
1
+ import{pt as e}from"./internal/daemon.js";export{e as withAppLogProvider};
@@ -0,0 +1 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{c as n,s as r}from"./sdk-device.js";import{d as i,u as a}from"./logcat.js";import{O as o,w as s}from"./runner-disposal.js";import{i as c,r as l,s as u}from"./tool-provider.js";import{n as d}from"./helper.js";import{n as f}from"./setting-state.js";import p from"node:path";import{fileURLToPath as m}from"node:url";const h={settings:`com.apple.systempreferences`},g=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,_={platform:`macos`,deviceId:`host`,variant:`all`},v=a();function y(e){return g.test(e)}async function b(e){let n=e.trim(),r=h[n.toLowerCase()];if(r)return r;if(y(n))return n;let i=v.get(_,n);if(i)return i;let a=(await D(`all`)).filter(e=>e.name.toLowerCase()===n.toLowerCase()),o=a[0];if(o!==void 0&&a.length===1)return v.set(_,n,o.bundleId);throw a.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${e}"`,{matches:a}):new t(`APP_NOT_INSTALLED`,`No app found matching "${e}"`)}async function x(e,n,r){let a=r?.url?.trim();if(a){if(!i(a))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);let e=r?.appBundleId??await b(n);await O().openBundle(e,a);return}let o=n.trim();if(i(o)){await O().openTarget(o);return}let s=r?.appBundleId??await b(o);await O().openBundle(s)}async function S(e,n){let r=await b(n),i=await d(r);if(!(!i.running||i.terminated||i.forceTerminated))throw new t(`COMMAND_FAILED`,`Failed to close macOS app ${n}`,{bundleId:r,running:i.running,terminated:i.terminated,forceTerminated:i.forceTerminated})}async function C(){return await O().readClipboard()}async function w(e){await O().writeClipboard(e)}async function T(){return await O().readDarkMode()}async function E(e){let t=f(e),n=t===`toggle`?!await T():t===`dark`;await O().setDarkMode(n)}async function D(e){return await O().listApps(e)}function O(){let e=l().macosHost;if(!e)throw new t(`UNSUPPORTED_OPERATION`,`macOS host provider is not available`);return e}var k=e({buildAppNotInstalledError:()=>F,findIosSimulatorInstalledApp:()=>I,invalidateIosAppResolutionCache:()=>N,listIosApps:()=>B,resolveIosApp:()=>P,resolveIosAppAlias:()=>L,resolveIosSimulatorDeepLinkBundleId:()=>R});const A={settings:`com.apple.Preferences`},j=a();function M(e){return{platform:`ios`,deviceId:e.id,variant:e.kind}}async function N(e,t){return await j.invalidateWhile(M(e),t)}async function P(e,r){if(n(e))return await b(r);let i=r.trim();if(i.includes(`.`))return i;let a=L(i);if(a!==i)return a;let o=M(e),c=j.get(o,i);if(c)return c;let l=(e.kind===`simulator`?await V(e):await s(e).listApps(e,`all`)).filter(e=>e.name.toLowerCase()===i.toLowerCase()),u=l[0];if(u!==void 0&&l.length===1)return j.set(o,i,u.bundleId);throw l.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${r}"`,{matches:l}):F(r)}function F(e){return new t(`APP_NOT_INSTALLED`,`No app found matching "${e}"`)}async function I(e,t){if(!r(e)||e.kind!==`simulator`||e.booted!==!0)return;let n=L(t.trim());if(!n)return;let i=await V(e);if(n.includes(`.`))return i.find(e=>e.bundleId===n)?.bundleId;let a=i.filter(e=>e.name.toLowerCase()===n.toLowerCase());return a.length===1?a[0]?.bundleId:void 0}function L(e){let t=e.trim();return A[t.toLowerCase()]??e}async function R(e,t){if(!r(e)||e.kind!==`simulator`)return;let n=z(t);if(!n)return;let i=await H(e),a=[];for(let e of i)e.bundleId.startsWith(`com.callstack.agentdevice.runner`)||e.path&&(await W(p.join(e.path,`Info.plist`))).has(n)&&a.push(e);let o=a.filter(e=>e.applicationType===`User`);if(o.length===1)return o[0]?.bundleId;if(!(o.length>1))return a.length===1?a[0]?.bundleId:void 0}function z(e){return/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(e.trim())?.[1]?.toLowerCase()}async function B(e,t){return n(e)?await D(t):e.kind===`simulator`?u(await V(e),t):await s(e).listApps(e,t)}async function V(e){return(await H(e)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function H(e){let t=(await o(e,[`listapps`,e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let n=null;if(t.startsWith(`{`))try{n=JSON.parse(t)}catch{n=null}if(!n&&t.startsWith(`{`))try{let e=await c(`plutil`,[`-convert`,`json`,`-o`,`-`,`-`],{allowFailure:!0,stdin:t});e.exitCode===0&&e.stdout.trim().startsWith(`{`)&&(n=JSON.parse(e.stdout))}catch{n=null}return n?Object.entries(n).map(([e,t])=>{let n=U(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...n?{path:n}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}function U(e){if(e.Path)return e.Path;if(e.Bundle)try{return m(e.Bundle)}catch{return}}async function W(e){let t=await c(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0)return new Set;try{let e=JSON.parse(t.stdout),n=new Set;for(let t of e.CFBundleURLTypes??[])if(Array.isArray(t.CFBundleURLSchemes))for(let e of t.CFBundleURLSchemes)typeof e==`string`&&e.trim()&&n.add(e.trim().toLowerCase());return n}catch{return new Set}}export{P as a,x as c,w as d,B as i,C as l,I as n,R as o,N as r,S as s,k as t,E as u};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";import{o as t,y as n}from"./sdk-device.js";const r={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`},i={visionos:`visionOS uses spatial input and does not support two-finger touch synthesis.`,tvos:`tvOS has no touch input — this gesture is supported on Android and the iOS simulator only.`,macos:`macOS automation has no multi-touch input — this gesture is supported on Android and the iOS simulator only.`};function a(a,s){if(!t(a.platform))throw o(s,a.platform);let c=n(a);if(!((c===`ios`||c===`ipados`)&&a.kind===`simulator`))throw c===`ios`||c===`ipados`?new e(`UNSUPPORTED_OPERATION`,`gesture ${s} is not supported on physical iOS devices`,{hint:`Two-finger gesture synthesis is iOS-simulator only — not available on physical iOS devices.`}):o(s,r[c],i[c])}function o(t,n,r){return new e(`UNSUPPORTED_OPERATION`,`gesture ${t} is not supported on ${n}`,r===void 0?void 0:{hint:r})}export{a as t};
package/dist/src/apps.js CHANGED
@@ -1,5 +1,5 @@
1
- import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{h as n,j as r,p as i,v as a}from"./sdk-android-adb.js";import{Ct as o,Et as s}from"./tv-remote.js";import{c,s as l}from"./sdk-device.js";import{i as u}from"./runtime.js";import{n as ee,t as te}from"./install-source2.js";import{D as d,E as f,O as ne,S as p,k as re,w as m,x as ie}from"./android-input-ownership.js";import{d as h,i as ae}from"./runner-client.js";import{a as g,i as _,r as oe,s as se}from"./tool-provider.js";import{a as ce,n as le}from"./helper.js";import{n as v,r as ue}from"./simctl.js";import{$ as de,$t as fe,G as y,J as pe,K as me,Q as he,U as ge,V as b,Y as x,bt as _e,en as ve,et as ye,tt as be,yt as xe}from"./internal/daemon.js";import{a as Se,i as Ce,n as S,r as C,t as w}from"./setting-state.js";import{i as T,n as we,t as E}from"./simulator.js";import{promises as D}from"node:fs";import O from"node:os";import k from"node:path";import{fileURLToPath as Te}from"node:url";function A(e){if(!(e instanceof t))return{reason:e instanceof Error?e.message:String(e)};let n=e.details??{},r=Array.isArray(n.args)?n.args.filter(e=>typeof e==`string`).join(` `):void 0;return{errorCode:e.code,reason:e.message,timeoutMs:typeof n.timeoutMs==`number`?n.timeoutMs:void 0,exitCode:typeof n.exitCode==`number`?n.exitCode:void 0,stderr:typeof n.stderr==`string`&&n.stderr.trim()?n.stderr:void 0,stdout:typeof n.stdout==`string`&&n.stdout.trim()?n.stdout:void 0,commandArgs:r}}const Ee=[`--time`,`9:41`,`--dataNetwork`,`wifi`,`--wifiMode`,`active`,`--wifiBars`,`3`,`--batteryState`,`charged`,`--batteryLevel`,`100`],De={0:`hide`,1:`wifi`,6:`3g`,7:`4g`,8:`lte`,9:`lte-a`,10:`lte+`,11:`5g`,12:`5g+`,13:`5g-uwb`,14:`5g-uc`},Oe={1:`searching`,2:`failed`,3:`active`},ke={0:`notSupported`,1:`searching`,2:`failed`,3:`active`};function j(e,t,n){return ue(e,t,n)}const M=new Set;async function Ae(e){let t=null,n=!1;if(Me(e))n=!0;else try{t=await Ne(e),n=!0}catch(t){R(e,`snapshot_failed`,t)}try{(!n||t)&&await I(e),await L(e,Ee)}catch(t){R(e,`prepare_failed`,t)}return async()=>{await je(e,n?t:null)}}async function je(e,t){if(await I(e),!t){P(e);return}await L(e,Fe(t)),N(e)}function N(e){M.delete(F(e))}function P(e){M.add(F(e))}function Me(e){return M.has(F(e))}function F(e){return`${e.platform}:${e.kind}:${e.id}`}async function Ne(e){return Pe(n(await j(e,[`status_bar`,e.id,`list`],{allowFailure:!0}),`Failed to read simulator status bar overrides`).stdout)}async function I(e){await j(e,[`status_bar`,e.id,`clear`])}async function L(e,t){t.length!==0&&await j(e,[`status_bar`,e.id,`override`,...t])}function Pe(e){let n={},r=e.split(`
2
- `).map(e=>e.trim()).filter(e=>e.length>0&&e!==`Current Status Bar Overrides:`&&!/^=+$/.test(e));for(let e of r){let r=/^DataNetworkType:\s+(\d+)$/.exec(e);if(r){let e=Number(r[1]),i=De[e];if(!i)throw new t(`COMMAND_FAILED`,`Unsupported simulator data network type: ${e}`);n.dataNetwork=i;continue}let i=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(e);if(i){let e=Oe[Number(i[1])];e&&(n.wifiMode=e),n.wifiBars=i[2];continue}let a=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(e);if(a){let e=Number(a[1]),r=ke[e];if(!r)throw new t(`COMMAND_FAILED`,`Unsupported simulator cellular mode: ${e}`);n.cellularMode=r,n.cellularBars=a[2];continue}let o=/^Operator Name:\s*(.*)$/.exec(e);if(o){n.operatorName=o[1]??``;continue}}return Object.keys(n).length===0?null:n}function Fe(e){let t=[];return e.dataNetwork&&t.push(`--dataNetwork`,e.dataNetwork),e.wifiMode&&t.push(`--wifiMode`,e.wifiMode),e.wifiBars!==void 0&&(e.dataNetwork===`wifi`||e.wifiMode)&&t.push(`--wifiBars`,e.wifiBars),e.cellularMode&&t.push(`--cellularMode`,e.cellularMode),e.cellularBars!==void 0&&(e.cellularMode||Ie(e.dataNetwork)||e.operatorName!==void 0)&&t.push(`--cellularBars`,e.cellularBars),e.operatorName!==void 0&&t.push(`--operatorName`,e.operatorName),t}function Ie(e){return!!(e&&e!==`hide`&&e!==`wifi`)}function R(e,t,n){r({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...A(n)}})}function z(e,t,n){return ue(e,t,n)}const Le={ensureBooted:E,prepareStatusBarForScreenshot:Ae,captureWithRetry:Be,normalizeDensity:Xe,captureWithRunner:V,shouldFallbackToRunner:Je},B=new Map;async function Re(e,t,n={}){if(c(e)){await V(e,t,n.appBundleId,n.fullscreen,n.runnerOptions);return}if(e.kind===`simulator`){await ze(e,t,n);return}try{await y([`device`,`screenshot`,`--device`,e.id,t],{action:`capture iOS screenshot`,deviceId:e.id});return}catch(t){if(!qe(t))throw t;We(e,`devicectl_screenshot`,t)}await V(e,t,n.appBundleId,n.fullscreen,n.runnerOptions)}async function ze(e,n,r={}){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Simulator screenshot fallback flow supports only iOS simulators`);let i={...Le,...r.deps??{}};r.skipIosSimulatorBootCheck||await i.ensureBooted(e);let a=async()=>{};if(r.normalizeStatusBar===!0)try{a=await i.prepareStatusBarForScreenshot(e)}catch(t){Ge(e,`prepare_failed`,t)}try{try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(t){let a=t;if(r.skipIosSimulatorBootCheck&&Ye(t)){await i.ensureBooted(e);try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(e){a=e}}if(!i.shouldFallbackToRunner(a))throw a;We(e,`simctl_screenshot`,a)}await i.captureWithRunner(e,n,r.appBundleId,r.fullscreen,r.runnerOptions),await i.normalizeDensity(e,n,r.pixelDensity)}finally{await a().catch(t=>Ge(e,`restore_failed`,t))}}async function Be(e,t){let n=p.fromTimeoutMs(ye);await m(async({deadline:n})=>{await z(e,[`io`,e.id,`screenshot`,t],{timeoutMs:Math.max(1e3,n?.remainingMs()??2e4)})},{maxAttempts:5,baseDelayMs:he,maxDelayMs:de,jitter:.2,shouldRetry:e=>Je(e)},{deadline:n,phase:`ios_simulator_screenshot`})}async function V(e,n,r,i,a){let o=(await ae(e,{command:`screenshot`,appBundleId:r,fullscreen:i},a)).message;if(!o)throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`);if(c(e)){await D.copyFile(o,n);return}if(e.kind===`simulator`){await He(e,o,n);return}await Ve(e,o,n)}async function Ve(e,n,r){let i=p.fromTimeoutMs(x),a={exitCode:1,stdout:``,stderr:``};for(let t of h)if(a=await g([`devicectl`,`device`,`copy`,`from`,`--device`,e.id,`--source`,n,`--destination`,r,`--domain-type`,`appDataContainer`,`--domain-identifier`,t],{allowFailure:!0,timeoutMs:Ue(i,x,`runner screenshot copy`)}),a.exitCode===0)return;throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: ${a.stderr.trim()||a.stdout.trim()||`devicectl exited with code ${a.exitCode}`}`)}async function He(e,n,r){let i=p.fromTimeoutMs(x),a=`Unable to locate runner container for simulator screenshot`;for(let t of h){let o=await z(e,[`get_app_container`,e.id,t,`data`],{allowFailure:!0,timeoutMs:Ue(i,x,`runner screenshot container lookup`)});if(o.exitCode!==0){let e=o.stderr.trim();e&&(a=e);continue}let s=o.stdout.trim();if(!s){a=`simctl get_app_container returned empty output`;continue}let c=Ke(s,n);for(let e of c)try{await D.copyFile(e,r);return}catch(e){a=e instanceof Error?e.message:String(e)}}throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: ${a}`)}function Ue(e,n,r){let i=e.remainingMs();if(i>0)return i;throw new t(`COMMAND_FAILED`,`iOS ${r} timed out after ${n}ms`,{timeoutMs:n,step:r})}function We(e,t,n){let i=A(n);r({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:`runner`,...i}})}function Ge(e,t,n){r({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...A(n)}})}function Ke(e,t){let n=k.resolve(e),r=t.trim();if(!r)return[];let i=[],a=new Set,o=e=>{let t=k.normalize(e);a.has(t)||(a.add(t),i.push(t))},s=r.replace(/^\/+/,``),c=s.replace(/\\/g,`/`);if(s&&o(k.join(n,s)),k.isAbsolute(r)&&o(k.normalize(r)),c.startsWith(`tmp/`))o(k.join(n,c));else{let e=c.lastIndexOf(`/tmp/`);if(e>=0){let t=c.slice(e+1);o(k.join(n,t))}}let l=k.basename(r);return l&&o(k.join(n,`tmp`,l)),i}function qe(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=H(e);return n.includes(`unknown option '--device'`)||n.includes(`unknown subcommand`)&&n.includes(`screenshot`)||n.includes(`unrecognized subcommand`)&&n.includes(`screenshot`)}function Je(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=H(e);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`)}function Ye(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=H(e);return n.includes(`not booted`)||n.includes(`current state: shutdown`)||n.includes(`current state is shutdown`)||n.includes(`current state=shutdown`)||n.includes(`state: shutdown`)||n.includes(`state=shutdown`)}function H(e){let t=e.details??{},n=typeof t.stdout==`string`?t.stdout:``,r=typeof t.stderr==`string`?t.stderr:``,i=Array.isArray(t.args)?t.args.filter(e=>typeof e==`string`).join(` `):``;return`${e.message}\n${n}\n${r}\n${i}`.toLowerCase()}async function Xe(e,t,n){let r=await Ze(e),i=xe(await _e(t),r,n);i&&await u(t,i.width,i.height)}async function Ze(e){let n=B.get(e.id);if(n!==void 0)return n;let r=await z(e,[`getenv`,e.id,`SIMULATOR_MAINSCREEN_SCALE`],{timeoutMs:5e3}),i=Number(r.stdout.trim());if(!Number.isFinite(i)||i<=0)throw new t(`COMMAND_FAILED`,`Failed to read iOS simulator screenshot scale from SIMULATOR_MAINSCREEN_SCALE`);return B.set(e.id,i),i}const Qe={settings:`com.apple.systempreferences`},$e=/^[a-z0-9-]+(?:\.[a-z0-9-]+)+$/,et={platform:`macos`,deviceId:`host`,variant:`all`},U=f();function tt(e){return $e.test(e)}async function W(e){let n=e.trim(),r=Qe[n.toLowerCase()];if(r)return r;if(tt(n))return n;let i=U.get(et,n);if(i)return i;let a=(await ct(`all`)).filter(e=>e.name.toLowerCase()===n.toLowerCase()),o=a[0];if(o!==void 0&&a.length===1)return U.set(et,n,o.bundleId);throw a.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${e}"`,{matches:a}):new t(`APP_NOT_INSTALLED`,`No app found matching "${e}"`)}async function nt(e,n,r){let i=r?.url?.trim();if(i){if(!d(i))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);let e=r?.appBundleId??await W(n);await G().openBundle(e,i);return}let a=n.trim();if(d(a)){await G().openTarget(a);return}let o=r?.appBundleId??await W(a);await G().openBundle(o)}async function rt(e,n){let r=await W(n),i=await le(r);if(!(!i.running||i.terminated||i.forceTerminated))throw new t(`COMMAND_FAILED`,`Failed to close macOS app ${n}`,{bundleId:r,running:i.running,terminated:i.terminated,forceTerminated:i.forceTerminated})}async function it(){return await G().readClipboard()}async function at(e){await G().writeClipboard(e)}async function ot(){return await G().readDarkMode()}async function st(e){let t=S(e),n=t===`toggle`?!await ot():t===`dark`;await G().setDarkMode(n)}async function ct(e){return await G().listApps(e)}function G(){let e=oe().macosHost;if(!e)throw new t(`UNSUPPORTED_OPERATION`,`macOS host provider is not available`);return e}function K(e,t){return v(e,t)}function q(e,t,n){return g(K(e,t),n)}function lt(e){return e.includes(`not installed`)||e.includes(`not found`)||e.includes(`no such file`)}const ut={settings:`com.apple.Preferences`},J=f();function dt(e){return{platform:`ios`,deviceId:e.id,variant:e.kind}}async function Y(e,t){return await J.invalidateWhile(dt(e),t)}async function X(e,n){if(c(e))return await W(n);let r=n.trim();if(r.includes(`.`))return r;let i=ut[r.toLowerCase()];if(i)return i;let a=dt(e),o=J.get(a,r);if(o)return o;let s=(e.kind===`simulator`?await ht(e):await ge(e,`all`)).filter(e=>e.name.toLowerCase()===r.toLowerCase()),l=s[0];if(l!==void 0&&s.length===1)return J.set(a,r,l.bundleId);throw s.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${n}"`,{matches:s}):new t(`APP_NOT_INSTALLED`,`No app found matching "${n}"`)}async function ft(e,t){if(!l(e)||e.kind!==`simulator`)return;let n=pt(t);if(!n)return;let r=await gt(e),i=[];for(let e of r)e.bundleId.startsWith(`com.callstack.agentdevice.runner`)||e.path&&(await vt(k.join(e.path,`Info.plist`))).has(n)&&i.push(e);let a=i.filter(e=>e.applicationType===`User`);if(a.length===1)return a[0]?.bundleId;if(!(a.length>1))return i.length===1?i[0]?.bundleId:void 0}function pt(e){return/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(e.trim())?.[1]?.toLowerCase()}async function mt(e,t){return c(e)?await ct(t):e.kind===`simulator`?se(await ht(e),t):await ge(e,t)}async function ht(e){return(await gt(e)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function gt(e){let t=(await q(e,[`listapps`,e.id],{allowFailure:!0})).stdout.trim();if(!t)return[];let n=null;if(t.startsWith(`{`))try{n=JSON.parse(t)}catch{n=null}if(!n&&t.startsWith(`{`))try{let e=await _(`plutil`,[`-convert`,`json`,`-o`,`-`,`-`],{allowFailure:!0,stdin:t});e.exitCode===0&&e.stdout.trim().startsWith(`{`)&&(n=JSON.parse(e.stdout))}catch{n=null}return n?Object.entries(n).map(([e,t])=>{let n=_t(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...n?{path:n}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}function _t(e){if(e.Path)return e.Path;if(e.Bundle)try{return Te(e.Bundle)}catch{return}}async function vt(e){let t=await _(`plutil`,[`-convert`,`json`,`-o`,`-`,e],{allowFailure:!0});if(t.exitCode!==0)return new Set;try{let e=JSON.parse(t.stdout),n=new Set;for(let t of e.CFBundleURLTypes??[])if(Array.isArray(t.CFBundleURLSchemes))for(let e of t.CFBundleURLSchemes)typeof e==`string`&&e.trim()&&n.add(e.trim().toLowerCase());return n}catch{return new Set}}function yt(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details??{};if(n.exitCode!==4)return!1;let r=String(n.stderr??``).toLowerCase();return r.includes(`fbsopenapplicationserviceerrordomain`)&&r.includes(`the request to open`)}async function bt(e,t){let n=await g(v(e,[`get_app_container`,e.id,t]),{allowFailure:!0});if(n.exitCode!==0)return{installed:!1};let r=n.stdout.trim();if(!r)return{installed:!1};let i=await _(`plutil`,[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,`${r}/Info.plist`],{allowFailure:!0});if(i.exitCode!==0||!i.stdout.trim())return{installed:!0};let a=await _(`otool`,[`-l`,`${r}/${i.stdout.trim()}`],{allowFailure:!0});if(a.exitCode!==0)return{installed:!0};let o=a.stdout.toLowerCase();return{installed:!0,simulatorCompatible:o.includes(`iossimulator`)||o.includes(`platform 7`)}}function xt(e){return e.installed?e.simulatorCompatible===!1?`ARCH_MISMATCH`:`PERSISTENT_LAUNCH_FAIL`:`APP_NOT_INSTALLED`}function St(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.`}}const Z=25e3;async function Ct(e,n,r){let i=r?.launchConsole?.trim(),a=r?.launchArgs;if(i&&(!l(e)||e.kind!==`simulator`))throw new t(`UNSUPPORTED_OPERATION`,ve);if(c(e)){if(a&&a.length>0)throw new t(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on macOS; launch arguments are currently iOS-only.`);await nt(e,n,r);return}let o=r?.url?.trim();if(o){if(i)throw new t(`INVALID_ARGS`,fe);if(!d(o))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(e.kind===`simulator`){(a||ne(o))&&await Dt(e,r?.appBundleId??await X(e,n),{...a?{launchArgs:a}:{}}),await wt(e,o,void 0);return}let s=re(r?.appBundleId??await X(e,n),o);if(!s)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,s,{payloadUrl:o,launchArgs:a});return}let s=n.trim();if(d(s)){if(i)throw new t(`INVALID_ARGS`,fe);if(e.kind===`simulator`){await wt(e,s,a);return}let n=re(r?.appBundleId,s);if(!n)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,n,{payloadUrl:s,launchArgs:a});return}let u=r?.appBundleId??await X(e,n);if(e.kind===`simulator`){await Dt(e,u,{...i?{launchConsole:i}:{},...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}});return}await Q(e,u,{launchArgs:a})}async function wt(e,n,r){if(r&&r.length>0)throw new t(`INVALID_ARGS`,`--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.`);await E(e),await q(e,[`openurl`,e.id,n])}async function Tt(e){c(e)||e.kind===`simulator`&&await we(e)!==`Booted`&&await E(e)}async function Et(e,n){if(c(e)){await rt(e,n);return}let r=await X(e,n);if(e.kind===`simulator`){await E(e);let n=K(e,[`terminate`,e.id,r]),a=await g(n,{allowFailure:!0,timeoutMs:be});if(a.exitCode!==0){if(a.stderr.toLowerCase().includes(`found nothing to terminate`))return;throw new t(`COMMAND_FAILED`,`xcrun exited with code ${a.exitCode}`,i(a,{cmd:`xcrun`,args:n}))}return}await y([`device`,`process`,`terminate`,`--device`,e.id,r],{action:`terminate iOS app`,deviceId:e.id})}async function Dt(e,n,r){await E(e);let a=0,o=p.fromTimeoutMs(me);try{await m(async({deadline:a})=>{if(a?.isExpired())throw new t(`COMMAND_FAILED`,`App launch deadline exceeded`,{timeoutMs:me});let o=K(e,Ot(e.id,n,r)),s=r?.launchConsole?await kt(o,r.launchConsole):await g(o,{allowFailure:!0});if(s.exitCode!==0)throw new t(`COMMAND_FAILED`,`xcrun exited with code ${s.exitCode}`,i(s,{cmd:`xcrun`,args:o}))},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry(e){return yt(e)?(a+=1,a<3):!1}},{deadline:o})}catch(t){if(yt(t)){let r=t,i=xt(await bt(e,n));r.details={...r.details,hint:St(i)}}throw t}}function Ot(e,t,n){let r=[`launch`];return n?.launchConsole&&r.push(`--console-pty`),n?.terminateRunningApp&&r.push(`--terminate-running-process`),r.push(e,t),n?.launchArgs&&n.launchArgs.length>0&&r.push(...n.launchArgs),r}async function kt(e,n){await D.mkdir(k.dirname(n),{recursive:!0});try{let t=await g(e,{allowFailure:!0,timeoutMs:Z});return await At(n,t.stdout,t.stderr),t}catch(e){let i=(e instanceof t?e:void 0)?.details;if(i?.timeoutMs===Z){let e=typeof i.stdout==`string`?i.stdout:``,t=typeof i.stderr==`string`?i.stderr:``;return await At(n,e,t),r({level:`warn`,phase:`ios_simulator_launch_console_capture_timeout`,data:{timeoutMs:Z,logPath:n,stdoutBytes:Buffer.byteLength(e),stderrBytes:Buffer.byteLength(t)}}),{stdout:e,stderr:t,exitCode:0}}throw e}}async function At(e,t,n){await D.writeFile(e,jt(t,n),`utf8`)}function jt(e,t){return!e||!t||e.endsWith(`
3
- `)||e.endsWith(`\r`)?`${e}${t}`:`${e}\n${t}`}async function Q(e,t,n){let r=[`device`,`process`,`launch`,`--device`,e.id,t];n?.payloadUrl&&r.push(`--payload-url`,n.payloadUrl),n?.launchArgs&&n.launchArgs.length>0&&r.push(`--`,...n.launchArgs),await y(r,{action:`launch iOS app`,deviceId:e.id})}var Mt=e({prepareIosInstallArtifact:()=>Nt});async function Nt(e,n){if(e.kind===`url`&&!te(e.url))throw new t(`INVALID_ARGS`,`iOS install_from_source URL sources are only supported for trusted artifact services such as GitHub Actions and EAS. Use a path source for other hosts.`);let r=await ee({source:e,isInstallablePath:(e,t)=>t.isDirectory()&&e.toLowerCase().endsWith(`.app`)||t.isFile()&&e.toLowerCase().endsWith(`.ipa`),installableLabel:`iOS installable (.app or .ipa)`,allowArchiveExtraction:e.kind!==`url`||te(e.url),signal:n?.signal}),i;try{i=await Ft(r.installablePath,n);let e=i,t=await Pt(e.installPath);return{archivePath:r.archivePath??(r.installablePath.toLowerCase().endsWith(`.ipa`)?r.installablePath:void 0),installablePath:e.installPath,bundleId:t.bundleId,appName:t.appName,cleanup:async()=>{await e.cleanup(),await r.cleanup()}}}catch(e){try{await i?.cleanup()}finally{await r.cleanup()}throw e}}async function Pt(e){let t=k.join(e,`Info.plist`),[n,r,i]=await Promise.all([b(t,`CFBundleIdentifier`),b(t,`CFBundleDisplayName`),b(t,`CFBundleName`)]);return{bundleId:n,appName:r??i}}async function Ft(e,n){if(!e.toLowerCase().endsWith(`.ipa`))return{installPath:e,cleanup:async()=>{}};let r=await D.mkdtemp(k.join(O.tmpdir(),`agent-device-ios-ipa-`)),i=async()=>{await D.rm(r,{recursive:!0,force:!0})};try{await a(`unzip`,[`-q`,e,`-d`,r]);let o=k.join(r,`Payload`),s=(await D.readdir(o,{withFileTypes:!0}).catch(()=>{throw new t(`INVALID_ARGS`,`Invalid IPA: missing Payload directory`)})).filter(e=>e.isDirectory()&&e.name.toLowerCase().endsWith(`.app`)).map(e=>({installPath:k.join(o,e.name),bundleName:e.name.replace(/\.app$/i,``)})),c=s[0];if(c!==void 0&&s.length===1)return{installPath:c.installPath,cleanup:i};if(s.length===0)throw new t(`INVALID_ARGS`,`Invalid IPA: expected at least one .app under Payload, found 0`);await It(s);let l=n?.appIdentifierHint?.trim();if(l){let e=Lt(s,l);if(e)return{installPath:e.installPath,cleanup:i};throw new t(`INVALID_ARGS`,`Invalid IPA: found ${s.length} .app bundles under Payload and none matched "${l}". Available bundles: ${s.map(Rt).join(`, `)}`)}throw new t(`INVALID_ARGS`,`Invalid IPA: found ${s.length} .app bundles under Payload. Pass an app identifier or bundle name matching one of: ${s.map(Rt).join(`, `)}`)}catch(e){throw await i(),e}}async function It(e){await Promise.all(e.map(async e=>{if(e.bundleId&&e.appName)return;let t=await Pt(e.installPath);e.bundleId=e.bundleId??t.bundleId,e.appName=e.appName??t.appName}))}function Lt(e,n){let r=n.toLowerCase(),i=e.filter(e=>e.bundleName.toLowerCase()===r);if(i.length===1)return i[0];if(i.length>1)throw new t(`INVALID_ARGS`,`Invalid IPA: multiple app bundles matched "${n}" by name. Use a bundle id hint instead.`);if(n.includes(`.`)){let t=e.filter(e=>e.bundleId?.toLowerCase()===r);if(t.length===1)return t[0]}}function Rt(e){let t=e.bundleId??e.appName;return t?`${e.bundleName}.app (${t})`:`${e.bundleName}.app`}async function zt(e,n){return await Y(e,async()=>{let r=await X(e,n);if(e.kind!==`simulator`)return await y([`device`,`uninstall`,`app`,`--device`,e.id,r],{action:`uninstall iOS app ${r}`,deviceId:e.id},{tolerateOutput:(e,t)=>lt(`${e}\n${t}`.toLowerCase())}),{bundleId:r};await E(e);let a=await q(e,[`uninstall`,e.id,r],{allowFailure:!0});if(a.exitCode!==0&&!lt(`${a.stdout}\n${a.stderr}`.toLowerCase()))throw new t(`COMMAND_FAILED`,`simctl uninstall failed for ${r}`,i(a));return{bundleId:r}})}async function Bt(e,t,n){let r=await Nt({kind:`path`,path:t},n);try{return await Ht(e,r.installablePath),{archivePath:r.archivePath,installablePath:r.installablePath,bundleId:r.bundleId,appName:r.appName,launchTarget:r.bundleId}}finally{await r.cleanup()}}async function Vt(e,t,n){return await Y(e,async()=>{let{bundleId:r}=await zt(e,t);return await Bt(e,n,{appIdentifierHint:t}),{bundleId:r}})}async function Ht(e,t){await Y(e,async()=>{if(e.kind!==`simulator`){await y([`device`,`install`,`app`,`--device`,e.id,t],{action:`install iOS app`,deviceId:e.id},{timeoutMs:pe});return}await E(e),await q(e,[`install`,e.id,t])})}async function Ut(e){return c(e)?await it():(T(e,`clipboard`),await E(e),n(await q(e,[`pbpaste`,e.id],{allowFailure:!0}),`Failed to read iOS simulator clipboard`).stdout.replace(/\r\n/g,`
4
- `).replace(/\n$/,``))}async function Wt(e,t){if(c(e)){await at(t);return}T(e,`clipboard`),await E(e),n(await q(e,[`pbcopy`,e.id],{allowFailure:!0,stdin:t}),`Failed to write iOS simulator clipboard`)}async function Gt(e,t,n){T(e,`push`),await E(e);let r=await D.mkdtemp(k.join(O.tmpdir(),`agent-device-ios-push-`)),i=k.join(r,`payload.apns`);try{await D.writeFile(i,`${JSON.stringify(n)}\n`,`utf8`),await q(e,[`push`,e.id,t,i])}finally{await D.rm(r,{recursive:!0,force:!0})}}let $=null,Kt;async function qt(e,n,r,i,a){if(c(e)){let e=n.toLowerCase();if(e===`appearance`){await st(r);return}if(e===`permission`){let e=C(r);if(e===`deny`)throw new t(`INVALID_ARGS`,s(`permission`));return await ce(e,Yt(a?.permissionTarget))}throw new t(`INVALID_ARGS`,s(n))}T(e,`settings`),await E(e);let l=n.toLowerCase();switch(l){case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await Jt(e,i);return{bundleId:n.bundleId,containerPath:n.containerPath,cleared:!0}}case`wifi`:{let t=w(r)?`active`:`failed`;await q(e,[`status_bar`,e.id,`override`,`--wifiMode`,t]),N(e);return}case`airplane`:w(r)?(await q(e,[`status_bar`,e.id,`override`,`--dataNetwork`,`hide`,`--wifiMode`,`failed`,`--wifiBars`,`0`,`--cellularMode`,`failed`,`--cellularBars`,`0`,`--operatorName`,``]),N(e)):(await q(e,[`status_bar`,e.id,`clear`]),P(e));return;case`location`:{if(r.toLowerCase()===`set`){let{latitude:t,longitude:n}=o(a);return await q(e,[`location`,e.id,`set`,`${t},${n}`]),{latitude:t,longitude:n}}let n=w(r);if(!i)throw new t(`INVALID_ARGS`,`location setting requires an active app in session`);let s=n?`grant`:`revoke`;await q(e,[`privacy`,e.id,s,`location`,i]);return}case`faceid`:case`touchid`:{let t=l,n=Qt[t];await sn(e,on(r,t),{settingName:t,label:n.label,modalityAliases:n.modalityAliases});return}case`appearance`:{let t=await Xt(e,r);await q(e,[`ui`,e.id,`appearance`,t]);return}case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);await en(e,$t(C(r)),an(a?.permissionTarget,a?.permissionMode),i);return;default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}async function Jt(e,r){if(!l(e)||e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Clearing app state is currently supported only on iOS simulators.`);let i=await X(e,r);await E(e),await Et(e,i);let a=n(await q(e,[`get_app_container`,e.id,i,`data`],{allowFailure:!0}),`simctl get_app_container failed for ${i}`).stdout.trim();if(!a)throw new t(`COMMAND_FAILED`,`simctl get_app_container returned an empty data container path for ${i}`);let o=await D.readdir(a);return await Promise.all(o.map(e=>D.rm(k.join(a,e),{recursive:!0,force:!0}))),{bundleId:i,containerPath:a}}function Yt(e){let n=e?.trim().toLowerCase();if(n===`accessibility`||n===`screen-recording`||n===`input-monitoring`)return n;throw new t(`INVALID_ARGS`,`Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.`)}async function Xt(e,r){let i=S(r);if(i!==`toggle`)return i;let a=n(await q(e,[`ui`,e.id,`appearance`],{allowFailure:!0}),`Failed to read current iOS appearance`),o=Zt(a.stdout,a.stderr);if(!o)throw new t(`COMMAND_FAILED`,`Unable to determine current iOS appearance for toggle`,{stdout:a.stdout,stderr:a.stderr});return o===`dark`?`light`:`dark`}function Zt(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`dark`?`dark`:r===`light`?`light`:null}const Qt={faceid:{label:`Face ID`,modalityAliases:[`face`]},touchid:{label:`Touch ID`,modalityAliases:[`finger`,`touch`]}};function $t(e){return e===`deny`?`revoke`:e}async function en(e,n,r,i){let a=await nn(e);if(!a.has(r))throw new t(`UNSUPPORTED_OPERATION`,`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:i,hint:`Supported services: ${Array.from(a).sort().join(`, `)}`});let o=[`privacy`,e.id,n,r,i],s=r===`notifications`;if(!(n===`reset`&&s))try{await q(e,o);return}catch(n){throw s&&tn(n)?new t(`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.`}):n}try{await q(e,o);return}catch(e){if(!tn(e))throw e}try{await q(e,[`privacy`,e.id,`reset`,`all`,i])}catch(n){throw new t(`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.`},n instanceof Error?n:void 0)}}function tn(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=String(e.details?.stderr??``).toLowerCase();return(n.includes(`failed to grant access`)||n.includes(`failed to revoke access`)||n.includes(`failed to reset access`))&&n.includes(`operation not permitted`)}async function nn(e){let n=ie(e.simulatorSetPath),r=`${process.env.PATH??``}::${n??``}`;if($&&Kt===r)return $;let i=await q(e,[`privacy`,`help`],{allowFailure:!0}),a=rn(`${i.stdout}\n${i.stderr}`);if(a.size===0)throw new t(`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 $=a,Kt=r,a}function rn(e){let t=new Set,n=!1;for(let r of e.split(`
5
- `)){let e=r.trim();if(!e)continue;if(e===`service`){n=!0;continue}if(!n)continue;if(e.startsWith(`bundle identifier`))break;let i=/^([a-z-]+)\s+-\s+/.exec(e)?.[1];i!==void 0&&t.add(i)}return t}function an(e,n){let r=Ce(e);if(r!==`photos`&&n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return`camera`;if(r===`microphone`)return`microphone`;if(r===`contacts`)return`contacts`;if(r===`contacts-limited`)return`contacts-limited`;if(r===`notifications`)return`notifications`;if(r===`calendar`)return`calendar`;if(r===`location`)return`location`;if(r===`location-always`)return`location-always`;if(r===`media-library`)return`media-library`;if(r===`motion`)return`motion`;if(r===`reminders`)return`reminders`;if(r===`siri`)return`siri`;if(r===`photos`){let e=n?.trim().toLowerCase();if(!e||e===`full`)return`photos`;if(e===`limited`)return`photos-add`;throw new t(`INVALID_ARGS`,`Invalid photos mode: ${n}. Use full|limited.`)}throw new t(`INVALID_ARGS`,`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}function on(e,n){let r=e.trim().toLowerCase();if(r===`match`)return`match`;if(r===`nonmatch`)return`nonmatch`;if(r===`enroll`)return`enroll`;if(r===`unenroll`)return`unenroll`;throw new t(`INVALID_ARGS`,`Invalid ${n} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}async function sn(e,n,r){let i=cn(e.id,n,r.modalityAliases),a=[];for(let t of i){let n=K(e,t),r=await g(n,{allowFailure:!0});if(r.exitCode===0)return;a.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let o=Se(a);throw a.length>0&&a.every(e=>ln(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:n,setting:r.settingName,attempts:o}):new t(`COMMAND_FAILED`,`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:n,setting:r.settingName,attempts:o})}function cn(e,t,n){let r=n.length>0?n:[`face`];switch(t){case`match`:return r.flatMap(t=>[[`biometric`,e,`match`,t],[`biometric`,`match`,e,t]]);case`nonmatch`:return r.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`]]}}function ln(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unrecognized subcommand`)||n.includes(`unknown subcommand`)||n.includes(`not supported`)||n.includes(`unavailable`)||n.includes(`biometric`)&&n.includes(`invalid`)}var un=e({installIosApp:()=>Bt,installIosInstallablePath:()=>Ht,listIosApps:()=>mt,pushIosNotification:()=>Gt,reinstallIosApp:()=>Vt,resolveIosApp:()=>X,resolveIosSimulatorDeepLinkBundleId:()=>ft});export{Mt as a,Tt as c,Wt as i,mt as l,qt as n,Et as o,Ut as r,Ct as s,un as t,Re as u};
1
+ import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{h as n,j as r,p as i}from"./sdk-android-adb.js";import{Ct as a,Et as o}from"./recording-export-quality.js";import{c as s,s as c}from"./sdk-device.js";import{a as l}from"./runtime.js";import{d as u,f as ee,p as te}from"./logcat.js";import{l as d,o as ne,s as f}from"./boot-diagnostics.js";import{B as re,D as ie,E as p,H as ae,L as oe,M as m,O as h,P as se,R as ce,T as le,V as ue,k as g,w as _,z as de}from"./runner-disposal.js";import{n as fe,t as v}from"./launch-console.js";import{a as y,i as b}from"./tool-provider.js";import{a as pe}from"./helper.js";import{n as me,r as x}from"./simctl.js";import{a as S}from"./runner-client.js";import{At as he,kt as ge}from"./internal/daemon.js";import{a as _e,i as ve,n as ye,r as C,t as w}from"./setting-state.js";import{i as T,n as be,t as E}from"./simulator.js";import{a as D,c as xe,d as Se,i as Ce,l as we,n as Te,o as Ee,r as O,s as De,u as Oe}from"./app-resolution.js";import{n as ke}from"./install-artifact.js";import{promises as k}from"node:fs";import Ae from"node:os";import A from"node:path";const je=[`--time`,`9:41`,`--dataNetwork`,`wifi`,`--wifiMode`,`active`,`--wifiBars`,`3`,`--batteryState`,`charged`,`--batteryLevel`,`100`],Me={0:`hide`,1:`wifi`,6:`3g`,7:`4g`,8:`lte`,9:`lte-a`,10:`lte+`,11:`5g`,12:`5g+`,13:`5g-uwb`,14:`5g-uc`},Ne={1:`searching`,2:`failed`,3:`active`},Pe={0:`notSupported`,1:`searching`,2:`failed`,3:`active`};function j(e,t,n){return x(e,t,n)}const M=new Set;async function Fe(e){let t=null,n=!1;if(Le(e))n=!0;else try{t=await Re(e),n=!0}catch(t){R(e,`snapshot_failed`,t)}try{(!n||t)&&await I(e),await L(e,je)}catch(t){R(e,`prepare_failed`,t)}return async()=>{await Ie(e,n?t:null)}}async function Ie(e,t){if(await I(e),!t){P(e);return}await L(e,Be(t)),N(e)}function N(e){M.delete(F(e))}function P(e){M.add(F(e))}function Le(e){return M.has(F(e))}function F(e){return`${e.platform}:${e.kind}:${e.id}`}async function Re(e){return ze(n(await j(e,[`status_bar`,e.id,`list`],{allowFailure:!0}),`Failed to read simulator status bar overrides`).stdout)}async function I(e){await j(e,[`status_bar`,e.id,`clear`])}async function L(e,t){t.length!==0&&await j(e,[`status_bar`,e.id,`override`,...t])}function ze(e){let n={},r=e.split(`
2
+ `).map(e=>e.trim()).filter(e=>e.length>0&&e!==`Current Status Bar Overrides:`&&!/^=+$/.test(e));for(let e of r){let r=/^DataNetworkType:\s+(\d+)$/.exec(e);if(r){let e=Number(r[1]),i=Me[e];if(!i)throw new t(`COMMAND_FAILED`,`Unsupported simulator data network type: ${e}`);n.dataNetwork=i;continue}let i=/^WiFi Mode:\s+(\d+),\s+WiFi Bars:\s+(\d+)$/.exec(e);if(i){let e=Ne[Number(i[1])];e&&(n.wifiMode=e),n.wifiBars=i[2];continue}let a=/^Cell Mode:\s+(\d+),\s+Cell Bars:\s+(\d+)$/.exec(e);if(a){let e=Number(a[1]),r=Pe[e];if(!r)throw new t(`COMMAND_FAILED`,`Unsupported simulator cellular mode: ${e}`);n.cellularMode=r,n.cellularBars=a[2];continue}let o=/^Operator Name:\s*(.*)$/.exec(e);if(o){n.operatorName=o[1]??``;continue}}return Object.keys(n).length===0?null:n}function Be(e){let t=[];return e.dataNetwork&&t.push(`--dataNetwork`,e.dataNetwork),e.wifiMode&&t.push(`--wifiMode`,e.wifiMode),e.wifiBars!==void 0&&(e.dataNetwork===`wifi`||e.wifiMode)&&t.push(`--wifiBars`,e.wifiBars),e.cellularMode&&t.push(`--cellularMode`,e.cellularMode),e.cellularBars!==void 0&&(e.cellularMode||Ve(e.dataNetwork)||e.operatorName!==void 0)&&t.push(`--cellularBars`,e.cellularBars),e.operatorName!==void 0&&t.push(`--operatorName`,e.operatorName),t}function Ve(e){return!!(e&&e!==`hide`&&e!==`wifi`)}function R(e,t,n){r({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...p(n)}})}function z(e,t,n){return x(e,t,n)}const He={ensureBooted:E,prepareStatusBarForScreenshot:Fe,captureWithRetry:Ge,normalizeDensity:Ze,captureWithRunner:H,shouldFallbackToRunner:G},B=new Map,V=new Map;async function Ue(e,t,n={}){if(s(e)){await H(e,t,n.appBundleId,n.fullscreen,n.runnerOptions);return}if(e.kind===`simulator`){await We(e,t,n);return}await _(e).captureScreenshot(e,t,{appBundleId:n.appBundleId,fullscreen:n.fullscreen,runnerOptions:n.runnerOptions,runRunnerCommand:S})}async function We(e,n,r={}){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Simulator screenshot fallback flow supports only iOS simulators`);let i={...He,...r.deps??{}};r.skipIosSimulatorBootCheck||await i.ensureBooted(e);let a=async()=>{};if(r.normalizeStatusBar===!0)try{a=await i.prepareStatusBarForScreenshot(e)}catch(t){W(e,`prepare_failed`,t)}try{try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(t){let a=t;if(r.skipIosSimulatorBootCheck&&Xe(t)){await i.ensureBooted(e);try{await i.captureWithRetry(e,n),await i.normalizeDensity(e,n,r.pixelDensity);return}catch(e){a=e}}if(!i.shouldFallbackToRunner(a))throw a;Je(e,`simctl_screenshot`,a)}await i.captureWithRunner(e,n,r.appBundleId,r.fullscreen,r.runnerOptions),await i.normalizeDensity(e,n,r.pixelDensity)}finally{await a().catch(t=>W(e,`restore_failed`,t))}}async function Ge(e,t){let n=f.fromTimeoutMs(re);await d(async({deadline:n})=>{await z(e,[`io`,e.id,`screenshot`,t],{timeoutMs:Math.max(1e3,n?.remainingMs()??2e4)})},{maxAttempts:5,baseDelayMs:oe,maxDelayMs:ce,jitter:.2,shouldRetry:e=>G(e)},{deadline:n,phase:`ios_simulator_screenshot`})}async function H(e,n,r,i,a){if(e.kind===`device`&&!s(e)){await _(e).captureScreenshot(e,n,{appBundleId:r,fullscreen:i,runnerOptions:a,preferRunner:!0,runRunnerCommand:S});return}let o=(await S(e,{command:`screenshot`,appBundleId:r,fullscreen:i,inlineScreenshot:!1},a)).message;if(!o)throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: runner returned no file path`);if(s(e)){await k.copyFile(o,n);return}if(e.kind===`simulator`){await Ke(e,o,n);return}throw new t(`COMMAND_FAILED`,`Unsupported Apple screenshot target`)}async function Ke(e,n,r){let i=f.fromTimeoutMs(se),a=`Unable to locate runner container for simulator screenshot`,o=V.get(e.id);if(o){let t=await U(o,n,r);if(t.copied)return;a=t.error,V.delete(e.id)}for(let t of ae){let o=await z(e,[`get_app_container`,e.id,t,`data`],{allowFailure:!0,timeoutMs:qe(i,se,`runner screenshot container lookup`)});if(o.exitCode!==0){let e=o.stderr.trim();e&&(a=e);continue}let s=o.stdout.trim();if(!s){a=`simctl get_app_container returned empty output`;continue}let c=await U(s,n,r);if(c.copied){V.set(e.id,s);return}a=c.error}throw new t(`COMMAND_FAILED`,`Failed to capture iOS screenshot: ${a}`)}async function U(e,t,n){let r=`Runner screenshot was not found in the simulator container`;for(let i of Ye(e,t))try{return await k.copyFile(i,n),{copied:!0}}catch(e){r=e instanceof Error?e.message:String(e)}return{copied:!1,error:r}}function qe(e,n,r){let i=e.remainingMs();if(i>0)return i;throw new t(`COMMAND_FAILED`,`iOS ${r} timed out after ${n}ms`,{timeoutMs:n,step:r})}function Je(e,t,n){let i=p(n);r({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:`runner`,...i}})}function W(e,t,n){r({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...p(n)}})}function Ye(e,t){let n=A.resolve(e),r=t.trim();if(!r)return[];let i=[],a=new Set,o=e=>{let t=A.normalize(e);a.has(t)||(a.add(t),i.push(t))},s=r.replace(/^\/+/,``),c=s.replace(/\\/g,`/`);if(s&&o(A.join(n,s)),A.isAbsolute(r)&&o(A.normalize(r)),c.startsWith(`tmp/`))o(A.join(n,c));else{let e=c.lastIndexOf(`/tmp/`);if(e>=0){let t=c.slice(e+1);o(A.join(n,t))}}let l=A.basename(r);return l&&o(A.join(n,`tmp`,l)),i}function G(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=le(e);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`)}function Xe(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=le(e);return n.includes(`not booted`)||n.includes(`current state: shutdown`)||n.includes(`current state is shutdown`)||n.includes(`current state=shutdown`)||n.includes(`state: shutdown`)||n.includes(`state=shutdown`)}async function Ze(e,t,n){let r=await Qe(e),i=ge(await he(t),r,n);i&&await l(t,i.width,i.height)}async function Qe(e){let n=B.get(e.id);if(n!==void 0)return n;let r=await z(e,[`getenv`,e.id,`SIMULATOR_MAINSCREEN_SCALE`],{timeoutMs:de}),i=Number(r.stdout.trim());if(!Number.isFinite(i)||i<=0)throw new t(`COMMAND_FAILED`,`Failed to read iOS simulator screenshot scale from SIMULATOR_MAINSCREEN_SCALE`);return B.set(e.id,i),i}function K(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=e.details??{};if(n.exitCode!==4)return!1;let r=String(n.stderr??``).toLowerCase();return r.includes(`fbsopenapplicationserviceerrordomain`)&&r.includes(`the request to open`)}async function $e(e,t){let n=await y(me(e,[`get_app_container`,e.id,t]),{allowFailure:!0});if(n.exitCode!==0)return{installed:!1};let r=n.stdout.trim();if(!r)return{installed:!1};let i=await b(`plutil`,[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,`${r}/Info.plist`],{allowFailure:!0});if(i.exitCode!==0||!i.stdout.trim())return{installed:!0};let a=await b(`otool`,[`-l`,`${r}/${i.stdout.trim()}`],{allowFailure:!0});if(a.exitCode!==0)return{installed:!0};let o=a.stdout.toLowerCase();return{installed:!0,simulatorCompatible:o.includes(`iossimulator`)||o.includes(`platform 7`)}}function et(e){return e.installed?e.simulatorCompatible===!1?`ARCH_MISMATCH`:`PERSISTENT_LAUNCH_FAIL`:`APP_NOT_INSTALLED`}function tt(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.`}}const q=25e3;async function nt(e,n,r){let i=r?.launchConsole?.trim(),a=r?.launchArgs;if(i&&(!c(e)||e.kind!==`simulator`))throw new t(`UNSUPPORTED_OPERATION`,fe);if(s(e)){if(a&&a.length>0)throw new t(`UNSUPPORTED_OPERATION`,`--launch-args is not supported on macOS; launch arguments are currently iOS-only.`);await xe(e,n,r);return}let o=r?.url?.trim();if(o){if(i)throw new t(`INVALID_ARGS`,v);if(!u(o))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(e.kind===`simulator`){(a||ee(o))&&await X(e,r?.appBundleId??await D(e,n),{...a?{launchArgs:a}:{}}),await J(e,o,void 0);return}let s=te(r?.appBundleId??await D(e,n),o);if(!s)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,s,{payloadUrl:o,launchArgs:a,runnerOptions:r?.runnerOptions});return}let l=n.trim();if(u(l)){if(i)throw new t(`INVALID_ARGS`,v);if(e.kind===`simulator`){await J(e,l,a);return}let n=te(r?.appBundleId,l);if(!n)throw new t(`INVALID_ARGS`,`Deep link open on iOS devices requires an active app bundle ID. Open the app first, then open the URL.`);await Q(e,n,{payloadUrl:l,launchArgs:a,runnerOptions:r?.runnerOptions});return}let d=r?.appBundleId??await D(e,n);if(e.kind===`simulator`){await X(e,d,{...i?{launchConsole:i}:{},...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}});return}await Q(e,d,{launchArgs:a,runnerOptions:r?.runnerOptions})}async function J(e,n,r){if(r&&r.length>0)throw new t(`INVALID_ARGS`,`--launch-args is not supported with iOS simulator URL opens (simctl openurl ignores launch args). Launch the app first with --launch-args, then issue the URL open in a separate call.`);await E(e),await h(e,[`openurl`,e.id,n])}async function rt(e){s(e)||e.kind===`simulator`&&await be(e)!==`Booted`&&await E(e)}async function Y(e,n,r){if(s(e)){await De(e,n);return}let a=await D(e,n);if(e.kind===`simulator`){await E(e);let n=g(e,[`terminate`,e.id,a]),r=await y(n,{allowFailure:!0,timeoutMs:ue});if(r.exitCode!==0){if(r.stderr.toLowerCase().includes(`found nothing to terminate`))return;throw new t(`COMMAND_FAILED`,`xcrun exited with code ${r.exitCode}`,i(r,{cmd:`xcrun`,args:n}))}return}await _(e).terminateApp(e,a,{runnerOptions:r,runRunnerCommand:S})}async function X(e,n,r){await E(e);let a=0,o=f.fromTimeoutMs(m);try{await d(async({deadline:a})=>{if(a?.isExpired())throw new t(`COMMAND_FAILED`,`App launch deadline exceeded`,{timeoutMs:m});let o=g(e,it(e.id,n,r)),s=r?.launchConsole?await at(o,r.launchConsole):await y(o,{allowFailure:!0});if(s.exitCode!==0)throw new t(`COMMAND_FAILED`,`xcrun exited with code ${s.exitCode}`,i(s,{cmd:`xcrun`,args:o}))},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry(e){return K(e)?(a+=1,a<3):!1}},{deadline:o})}catch(t){if(K(t)){let r=t,i=et(await $e(e,n));r.details={...r.details,hint:tt(i)}}throw t}}function it(e,t,n){let r=[`launch`];return n?.launchConsole&&r.push(`--console-pty`),n?.terminateRunningApp&&r.push(`--terminate-running-process`),r.push(e,t),n?.launchArgs&&n.launchArgs.length>0&&r.push(...n.launchArgs),r}async function at(e,n){await k.mkdir(A.dirname(n),{recursive:!0});try{let t=await y(e,{allowFailure:!0,timeoutMs:q});return await Z(n,t.stdout,t.stderr),t}catch(e){let i=(e instanceof t?e:void 0)?.details;if(i?.timeoutMs===q){let e=typeof i.stdout==`string`?i.stdout:``,t=typeof i.stderr==`string`?i.stderr:``;return await Z(n,e,t),r({level:`warn`,phase:`ios_simulator_launch_console_capture_timeout`,data:{timeoutMs:q,logPath:n,stdoutBytes:Buffer.byteLength(e),stderrBytes:Buffer.byteLength(t)}}),{stdout:e,stderr:t,exitCode:0}}throw e}}async function Z(e,t,n){await k.writeFile(e,ot(t,n),`utf8`)}function ot(e,t){return!e||!t||e.endsWith(`
3
+ `)||e.endsWith(`\r`)?`${e}${t}`:`${e}\n${t}`}async function Q(e,t,n){await _(e).launchApp(e,t,{...n,runRunnerCommand:S})}async function st(e,n){return await O(e,async()=>{let r=await D(e,n);if(e.kind!==`simulator`)return await _(e).uninstallApp(e,r),{bundleId:r};await E(e);let a=await h(e,[`uninstall`,e.id,r],{allowFailure:!0});if(a.exitCode!==0&&!ie(`${a.stdout}\n${a.stderr}`.toLowerCase()))throw new t(`COMMAND_FAILED`,`simctl uninstall failed for ${r}`,i(a));return{bundleId:r}})}async function ct(e,t,n){e.kind!==`simulator`&&_(e).assertAppInstallationSupported(e);let r=await ke({kind:`path`,path:t},n);try{return await ut(e,r.installablePath),{archivePath:r.archivePath,installablePath:r.installablePath,bundleId:r.bundleId,appName:r.appName,launchTarget:r.bundleId}}finally{await r.cleanup()}}async function lt(e,t,n){return e.kind!==`simulator`&&_(e).assertAppInstallationSupported(e),await O(e,async()=>{let{bundleId:r}=await st(e,t);return await ct(e,n,{appIdentifierHint:t}),{bundleId:r}})}async function ut(e,t){await O(e,async()=>{if(e.kind!==`simulator`){await _(e).installApp(e,t);return}await E(e),await h(e,[`install`,e.id,t])})}async function dt(e){return s(e)?await we():(T(e,`clipboard`),await E(e),n(await h(e,[`pbpaste`,e.id],{allowFailure:!0}),`Failed to read iOS simulator clipboard`).stdout.replace(/\r\n/g,`
4
+ `).replace(/\n$/,``))}async function ft(e,t){if(s(e)){await Se(t);return}T(e,`clipboard`),await E(e),n(await h(e,[`pbcopy`,e.id],{allowFailure:!0,stdin:t}),`Failed to write iOS simulator clipboard`)}async function pt(e,t,n){T(e,`push`),await E(e);let r=await k.mkdtemp(A.join(Ae.tmpdir(),`agent-device-ios-push-`)),i=A.join(r,`payload.apns`);try{await k.writeFile(i,`${JSON.stringify(n)}\n`,`utf8`),await h(e,[`push`,e.id,t,i])}finally{await k.rm(r,{recursive:!0,force:!0})}}let $=null,mt;async function ht(e,n,r,i,c){if(s(e)){let e=n.toLowerCase();if(e===`appearance`){await Oe(r);return}if(e===`permission`){let e=C(r);if(e===`deny`)throw new t(`INVALID_ARGS`,o(`permission`));return await pe(e,_t(c?.permissionTarget))}throw new t(`INVALID_ARGS`,o(n))}T(e,`settings`),await E(e);let l=n.toLowerCase();switch(l){case`clear-app-state`:{if(r.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!i)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await gt(e,i);return{bundleId:n.bundleId,containerPath:n.containerPath,cleared:!0}}case`wifi`:{let t=w(r)?`active`:`failed`;await h(e,[`status_bar`,e.id,`override`,`--wifiMode`,t]),N(e);return}case`airplane`:w(r)?(await h(e,[`status_bar`,e.id,`override`,`--dataNetwork`,`hide`,`--wifiMode`,`failed`,`--wifiBars`,`0`,`--cellularMode`,`failed`,`--cellularBars`,`0`,`--operatorName`,``]),N(e)):(await h(e,[`status_bar`,e.id,`clear`]),P(e));return;case`location`:{if(r.toLowerCase()===`set`){let{latitude:t,longitude:n}=a(c);return await h(e,[`location`,e.id,`set`,`${t},${n}`]),{latitude:t,longitude:n}}let n=w(r);if(!i)throw new t(`INVALID_ARGS`,`location setting requires an active app in session`);let o=n?`grant`:`revoke`;await h(e,[`privacy`,e.id,o,`location`,i]);return}case`faceid`:case`touchid`:{let t=l,n=bt[t];await Ot(e,Dt(r,t),{settingName:t,label:n.label,modalityAliases:n.modalityAliases});return}case`appearance`:{let t=await vt(e,r);await h(e,[`ui`,e.id,`appearance`,t]);return}case`permission`:if(!i)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);await St(e,xt(C(r)),Et(c?.permissionTarget,c?.permissionMode),i);return;default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${n}`)}}async function gt(e,r){if(!c(e)||e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Clearing app state is currently supported only on iOS simulators.`);let i=await D(e,r);await E(e),await Y(e,i);let a=n(await h(e,[`get_app_container`,e.id,i,`data`],{allowFailure:!0}),`simctl get_app_container failed for ${i}`).stdout.trim();if(!a)throw new t(`COMMAND_FAILED`,`simctl get_app_container returned an empty data container path for ${i}`);let o=await k.readdir(a);return await Promise.all(o.map(e=>k.rm(A.join(a,e),{recursive:!0,force:!0}))),{bundleId:i,containerPath:a}}function _t(e){let n=e?.trim().toLowerCase();if(n===`accessibility`||n===`screen-recording`||n===`input-monitoring`)return n;throw new t(`INVALID_ARGS`,`Unsupported macOS permission target. Use accessibility|screen-recording|input-monitoring.`)}async function vt(e,r){let i=ye(r);if(i!==`toggle`)return i;let a=n(await h(e,[`ui`,e.id,`appearance`],{allowFailure:!0}),`Failed to read current iOS appearance`),o=yt(a.stdout,a.stderr);if(!o)throw new t(`COMMAND_FAILED`,`Unable to determine current iOS appearance for toggle`,{stdout:a.stdout,stderr:a.stderr});return o===`dark`?`light`:`dark`}function yt(e,t){let n=/\b(light|dark|unsupported|unknown)\b/i.exec(`${e}\n${t}`);if(!n)return null;let r=n[1]?.toLowerCase();return r===`dark`?`dark`:r===`light`?`light`:null}const bt={faceid:{label:`Face ID`,modalityAliases:[`face`]},touchid:{label:`Touch ID`,modalityAliases:[`finger`,`touch`]}};function xt(e){return e===`deny`?`revoke`:e}async function St(e,n,r,i){let a=await wt(e);if(!a.has(r))throw new t(`UNSUPPORTED_OPERATION`,`iOS simctl privacy does not support service "${r}" on this runtime.`,{deviceId:e.id,appBundleId:i,hint:`Supported services: ${Array.from(a).sort().join(`, `)}`});let o=[`privacy`,e.id,n,r,i],s=r===`notifications`;if(!(n===`reset`&&s))try{await h(e,o);return}catch(n){throw s&&Ct(n)?new t(`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.`}):n}try{await h(e,o);return}catch(e){if(!Ct(e))throw e}try{await h(e,[`privacy`,e.id,`reset`,`all`,i])}catch(n){throw new t(`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.`},n instanceof Error?n:void 0)}}function Ct(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=String(e.details?.stderr??``).toLowerCase();return(n.includes(`failed to grant access`)||n.includes(`failed to revoke access`)||n.includes(`failed to reset access`))&&n.includes(`operation not permitted`)}async function wt(e){let n=ne(e.simulatorSetPath),r=`${process.env.PATH??``}::${n??``}`;if($&&mt===r)return $;let i=await h(e,[`privacy`,`help`],{allowFailure:!0}),a=Tt(`${i.stdout}\n${i.stderr}`);if(a.size===0)throw new t(`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 $=a,mt=r,a}function Tt(e){let t=new Set,n=!1;for(let r of e.split(`
5
+ `)){let e=r.trim();if(!e)continue;if(e===`service`){n=!0;continue}if(!n)continue;if(e.startsWith(`bundle identifier`))break;let i=/^([a-z-]+)\s+-\s+/.exec(e)?.[1];i!==void 0&&t.add(i)}return t}function Et(e,n){let r=ve(e);if(r!==`photos`&&n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(r===`camera`)return`camera`;if(r===`microphone`)return`microphone`;if(r===`contacts`)return`contacts`;if(r===`contacts-limited`)return`contacts-limited`;if(r===`notifications`)return`notifications`;if(r===`calendar`)return`calendar`;if(r===`location`)return`location`;if(r===`location-always`)return`location-always`;if(r===`media-library`)return`media-library`;if(r===`motion`)return`motion`;if(r===`reminders`)return`reminders`;if(r===`siri`)return`siri`;if(r===`photos`){let e=n?.trim().toLowerCase();if(!e||e===`full`)return`photos`;if(e===`limited`)return`photos-add`;throw new t(`INVALID_ARGS`,`Invalid photos mode: ${n}. Use full|limited.`)}throw new t(`INVALID_ARGS`,`Unsupported permission target: ${e}. Use camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri.`)}function Dt(e,n){let r=e.trim().toLowerCase();if(r===`match`)return`match`;if(r===`nonmatch`)return`nonmatch`;if(r===`enroll`)return`enroll`;if(r===`unenroll`)return`unenroll`;throw new t(`INVALID_ARGS`,`Invalid ${n} state: ${e}. Use match|nonmatch|enroll|unenroll.`)}async function Ot(e,n,r){let i=kt(e.id,n,r.modalityAliases),a=[];for(let t of i){let n=g(e,t),r=await y(n,{allowFailure:!0});if(r.exitCode===0)return;a.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let o=_e(a);throw a.length>0&&a.every(e=>At(e.stdout,e.stderr))?new t(`UNSUPPORTED_OPERATION`,`${r.label} simulation is not supported on this simulator runtime.`,{deviceId:e.id,action:n,setting:r.settingName,attempts:o}):new t(`COMMAND_FAILED`,`Failed to simulate ${r.settingName}.`,{deviceId:e.id,action:n,setting:r.settingName,attempts:o})}function kt(e,t,n){let r=n.length>0?n:[`face`];switch(t){case`match`:return r.flatMap(t=>[[`biometric`,e,`match`,t],[`biometric`,`match`,e,t]]);case`nonmatch`:return r.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`]]}}function At(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`unrecognized subcommand`)||n.includes(`unknown subcommand`)||n.includes(`not supported`)||n.includes(`unavailable`)||n.includes(`biometric`)&&n.includes(`invalid`)}var jt=e({findIosSimulatorInstalledApp:()=>Te,installIosApp:()=>ct,installIosInstallablePath:()=>ut,listIosApps:()=>Ce,pushIosNotification:()=>pt,reinstallIosApp:()=>lt,resolveIosApp:()=>D,resolveIosSimulatorDeepLinkBundleId:()=>Ee});export{Y as a,H as c,ft as i,Ue as l,ht as n,nt as o,dt as r,rt as s,jt as t};
@@ -0,0 +1,2 @@
1
+ import{_ as e,v as t}from"./sdk-contracts.js";import{j as n}from"./sdk-android-adb.js";function r(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const i={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var a=class e{startedAtMs;expiresAtMs;constructor(e,t){this.startedAtMs=e,this.expiresAtMs=e+Math.max(0,t)}static fromTimeoutMs(t,n=Date.now()){return new e(n,t)}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 this.remainingMs(e)<=0}};async function o(t,n={},r={}){let a={maxAttempts:n.maxAttempts??i.maxAttempts,baseDelayMs:n.baseDelayMs??i.baseDelayMs,maxDelayMs:n.maxDelayMs??i.maxDelayMs,jitter:n.jitter??i.jitter,shouldRetry:n.shouldRetry},o;for(let n=1;n<=a.maxAttempts;n+=1){if(r.signal?.aborted)throw new e(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});if(r.deadline?.isExpired()&&n>1)break;try{let e=await t({attempt:n,maxAttempts:a.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),l({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),e}catch(e){o=e;let t=r.classifyReason?.(e),i={phase:r.phase,event:`attempt_failed`,attempt:n,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};if(r.onEvent?.(i),l(i),n>=a.maxAttempts||a.shouldRetry&&!a.shouldRetry(e,n))break;let u=s(a.baseDelayMs,a.maxDelayMs,a.jitter,n),d=r.deadline?Math.min(u,r.deadline.remainingMs()):u;if(d<=0)break;let f={phase:r.phase,event:`retry_scheduled`,attempt:n,maxAttempts:a.maxAttempts,delayMs:d,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};r.onEvent?.(f),l(f),await c(d,r.signal)}}let u={phase:r.phase,event:`exhausted`,attempt:a.maxAttempts,maxAttempts:a.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(o)};throw r.onEvent?.(u),l(u),o||new e(`COMMAND_FAILED`,`retry failed`)}function s(e,t,n,r){let i=Math.min(t,e*2**(r-1)),a=i*n;return Math.max(0,i+(Math.random()*2-1)*a)}function c(e,t){return new Promise(n=>{if(t?.aborted){n();return}let r=!1,i=()=>{r||(r=!0,t&&t.removeEventListener(`abort`,o),n())},a=setTimeout(i,e);function o(){clearTimeout(a),i()}t&&t.addEventListener(`abort`,o,{once:!0})})}function l(e){n({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}function u(e){return e?.trim()||void 0}function d(e){return u(e)}function f(e){return new Set(e.split(/[\s,]+/).map(e=>e.trim()).filter(Boolean))}function p(e,t=process.env){let n=u(e)??u(t.AGENT_DEVICE_ANDROID_DEVICE_ALLOWLIST);if(n)return f(n)}const m=new Set([`IOS_BOOT_TIMEOUT`,`IOS_RUNNER_CONNECT_TIMEOUT`,`IOS_TOOL_MISSING`,`ANDROID_BOOT_TIMEOUT`,`ADB_TRANSPORT_UNAVAILABLE`,`CI_RESOURCE_STARVATION_SUSPECTED`]);function h(e){return m.has(e.toUpperCase())}function g(e){let n=e.error?t(e.error):null,r=e.context?.platform,i=e.context?.phase;if(n?.code===`TOOL_MISSING`)return r===`android`?`ADB_TRANSPORT_UNAVAILABLE`:`IOS_TOOL_MISSING`;let a=n?.details??{},o=typeof a.message==`string`?a.message:void 0,s=typeof a.stdout==`string`?a.stdout:void 0,c=typeof a.stderr==`string`?a.stderr:void 0,l=a.boot&&typeof a.boot==`object`?a.boot:null,u=a.bootstatus&&typeof a.bootstatus==`object`?a.bootstatus:null,d=[e.message,n?.message,e.stdout,e.stderr,o,s,c,typeof l?.stdout==`string`?l.stdout:void 0,typeof l?.stderr==`string`?l.stderr:void 0,typeof u?.stdout==`string`?u.stdout:void 0,typeof u?.stderr==`string`?u.stderr:void 0].filter(Boolean).join(`
2
+ `).toLowerCase();return r===`ios`&&(d.includes(`runner did not accept connection`)||i===`connect`&&(d.includes(`timed out`)||d.includes(`timeout`)||d.includes(`econnrefused`)||d.includes(`connection refused`)||d.includes(`fetch failed`)||d.includes(`socket hang up`)))?`IOS_RUNNER_CONNECT_TIMEOUT`:r===`ios`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`IOS_BOOT_TIMEOUT`:r===`android`&&i===`boot`&&(d.includes(`timed out`)||d.includes(`timeout`))?`ANDROID_BOOT_TIMEOUT`:d.includes(`resource temporarily unavailable`)||d.includes(`killed: 9`)||d.includes(`cannot allocate memory`)||d.includes(`system is low on memory`)?`CI_RESOURCE_STARVATION_SUSPECTED`:r===`android`&&(d.includes(`device not found`)||d.includes(`no devices`)||d.includes(`device offline`)||d.includes(`offline`)||d.includes(`unauthorized`)||d.includes(`not authorized`)||d.includes(`unable to locate device`)||d.includes(`invalid device`))?`ADB_TRANSPORT_UNAVAILABLE`:n?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function _(e){switch(e){case`IOS_BOOT_TIMEOUT`:return`Retry simulator boot and inspect simctl bootstatus logs; in CI reduce parallel jobs or use a larger runner.`;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.`}}export{p as a,r as c,f as i,o as l,g as n,d as o,h as r,a as s,_ as t};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";import{E as t,O as n}from"./sdk-android-adb.js";import{ur as r}from"./recording-export-quality.js";import{n as i,t as a}from"./path-resolution.js";import{f as o,t as s,u as c,v as l}from"./registry.js";import{n as u}from"./command-schema.js";import d from"node:fs";import f from"node:path";function p(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}const m=new Set([`config`,`remoteConfig`,`help`,`version`,`batchSteps`,`githubActionsArtifact`]),h=new Set([`appsFilter`,`iosSimulatorDeviceSet`]),g=S(),_=new Map(g.map(e=>[e.key,e]));function v(e){return _.get(e)}function y(e){return g.filter(t=>t.config.enabled&&t.supportsCommand(e))}function b(e,t){return v(e)?.supportsCommand(t)??!1}function x(e,t,r,i){return n(w(e),t,r,i)}function S(){let e=new Map;for(let t of l()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let n=new Map;for(let e of o)n.set(e,new Set([`*`]));for(let e of r()){let t=u(e);for(let r of[...t.allowedFlags??[],...t.supportedFlags??[]]){let t=n.get(r);t&&t.has(`*`)||(t?t.add(e):n.set(r,new Set([e])))}}return[...e.entries()].map(([e,r])=>({key:e,flagDefinitions:r,config:{enabled:!m.has(e),key:e},env:{names:h.has(e)?[]:[t(e)]},supportsCommand(t){let r=n.get(e);return r?r.has(`*`)?!0:t?r.has(t):!1:!1}})).sort((e,t)=>e.key.localeCompare(t.key))}function C(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}function w(e){let t=e.flagDefinitions.find(e=>e.setValue===void 0);if(t)return t;let n=C(e);if(n.type===`enum`){let t=n.enumValues??e.flagDefinitions.map(e=>e.setValue).filter(e=>e!==void 0);return{...n,setValue:void 0,enumValues:t}}return n}const T=s();function E(e){return T[e.name]?.({input:e.input??{},result:e.result})}function D(e){let t=e.env??process.env;return p(p({},j(O(e.cwd,e.cliFlags.config,t))),P(t,e.command))}function O(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:A(r,e,n),required:!0}]:[{path:k(n),required:!1},{path:f.resolve(e,`agent-device.json`),required:!1}]}function k(e){return f.join(a(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return i(e,{cwd:t,env:n})}function j(e){let t={};for(let n of e)p(t,M(n.path,n.required));return t}function M(t,n){if(!d.existsSync(t)){if(n)throw new e(`INVALID_ARGS`,`Config file not found: ${t}`);return{}}let r;try{r=d.readFileSync(t,`utf8`)}catch(n){throw new e(`INVALID_ARGS`,`Failed to read config file: ${t}`,{cause:n instanceof Error?n.message:String(n)})}let i;try{i=JSON.parse(r)}catch(n){throw new e(`INVALID_ARGS`,`Invalid JSON in config file: ${t}`,{cause:n instanceof Error?n.message:String(n)})}if(!i||typeof i!=`object`||Array.isArray(i))throw new e(`INVALID_ARGS`,`Config file must contain a JSON object: ${t}`);return N(i,`config file ${t}`)}function N(t,n){let r={};for(let[i,a]of Object.entries(t)){if(i===`installSource`){r.installSource=c(a,n);continue}let t=i,o=v(t);if(!o)throw new e(`INVALID_ARGS`,`Unknown config key "${i}" in ${n}.`);if(!o.config.enabled)throw new e(`INVALID_ARGS`,`Unsupported config key "${i}" in ${n}.`);r[t]=x(o,a,n,i)}return r}function P(e,t){let n={};for(let r of y(t)){if(r.key===`installSource`)continue;let t=r.env.names.map(t=>({name:t,value:e[t]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(n[r.key]=x(r,t.value,`environment variable ${t.name}`,t.name))}return n}export{p as i,E as n,b as r,D as t};