agent-device 0.20.9 → 0.20.10

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 (140) hide show
  1. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.apk → agent-device-android-ime-helper-0.20.10.apk} +0 -0
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.10.apk.sha256 +1 -0
  3. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.9.manifest.json → agent-device-android-ime-helper-0.20.10.manifest.json} +4 -4
  4. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.apk → agent-device-android-snapshot-helper-0.20.10.apk} +0 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.10.apk.sha256 +1 -0
  6. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.9.manifest.json → agent-device-android-snapshot-helper-0.20.10.manifest.json} +6 -6
  7. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +6 -5
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +4 -4
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +94 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +22 -23
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +3 -23
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +10 -11
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+PrivateAXPresentation.swift +30 -12
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +8 -5
  15. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +133 -63
  16. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +13 -12
  17. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentation.swift +183 -0
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotPresentationTests.swift +0 -0
  19. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +20 -18
  20. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextInputCandidatePolicy.swift +19 -0
  21. package/dist/src/agent-device-client.js +2 -2
  22. package/dist/src/ai-sdk.d.ts +61 -0
  23. package/dist/src/ai-sdk.js +1 -0
  24. package/dist/src/android-adb.d.ts +1 -1
  25. package/dist/src/app-lifecycle.js +1 -1
  26. package/dist/src/app-log-reconnect.js +1 -1
  27. package/dist/src/app-log-runtime.js +3 -3
  28. package/dist/src/app-resolution.js +2 -2
  29. package/dist/src/apps.js +5 -5
  30. package/dist/src/audio-probe.js +1 -1
  31. package/dist/src/boot-diagnostics.js +2 -2
  32. package/dist/src/cli-config.js +1 -1
  33. package/dist/src/cli-help.js +30 -23
  34. package/dist/src/cli-runner.js +1 -1
  35. package/dist/src/cli.js +7 -7
  36. package/dist/src/client-metro.js +1 -1
  37. package/dist/src/client-types.d.ts +1582 -0
  38. package/dist/src/command-tools.js +2 -0
  39. package/dist/src/connection-runtime.js +1 -1
  40. package/dist/src/contracts.d.ts +1 -1
  41. package/dist/src/contracts.js +1 -1
  42. package/dist/src/daemon-shutdown-report.js +1 -1
  43. package/dist/src/daemon.js +1 -1
  44. package/dist/src/debug-symbols.js +1 -1
  45. package/dist/src/device-input-state.js +1 -1
  46. package/dist/src/dispatch.js +1 -1
  47. package/dist/src/find.js +1 -1
  48. package/dist/src/finders.js +1 -1
  49. package/dist/src/generic-settle.js +1 -1
  50. package/dist/src/generic.js +1 -1
  51. package/dist/src/helper-package-install.js +1 -1
  52. package/dist/src/helper.js +1 -1
  53. package/dist/src/ime-lifecycle.js +1 -1
  54. package/dist/src/ime-recovery-marker.js +1 -1
  55. package/dist/src/index.d.ts +2 -1578
  56. package/dist/src/index.js +1 -1
  57. package/dist/src/input-actions.js +1 -1
  58. package/dist/src/input-actions3.js +1 -1
  59. package/dist/src/install-source2.js +1 -1
  60. package/dist/src/interaction-common.js +1 -1
  61. package/dist/src/interaction-runtime.js +1 -1
  62. package/dist/src/interaction-snapshot.js +1 -1
  63. package/dist/src/interaction.js +1 -1
  64. package/dist/src/interaction2.js +1 -1
  65. package/dist/src/interactor.js +2 -2
  66. package/dist/src/interactor2.js +1 -1
  67. package/dist/src/interactors.js +1 -1
  68. package/dist/src/internal/bin.js +2 -2
  69. package/dist/src/internal/daemon.js +4 -4
  70. package/dist/src/internal/png-worker.js +1 -1
  71. package/dist/src/lease-context.js +1 -1
  72. package/dist/src/lease.js +1 -1
  73. package/dist/src/limrun.d.ts +10 -2
  74. package/dist/src/linux.js +1 -1
  75. package/dist/src/location-coordinates.js +1 -1
  76. package/dist/src/{screenshot-geometry.js → mobile-snapshot-semantics.js} +1 -1
  77. package/dist/src/perf.js +1 -1
  78. package/dist/src/platform-runtime-open-target.js +1 -1
  79. package/dist/src/platform-runtime-operation-host.js +4 -4
  80. package/dist/src/platform-runtime.js +1 -1
  81. package/dist/src/platform-runtime2.js +1 -1
  82. package/dist/src/png-resize.js +1 -1
  83. package/dist/src/provider.js +1 -1
  84. package/dist/src/proxy.js +1 -1
  85. package/dist/src/react-native.js +1 -1
  86. package/dist/src/record-runtime.js +1 -1
  87. package/dist/src/registry.js +27 -27
  88. package/dist/src/remote-config2.js +1 -1
  89. package/dist/src/replay.js +2 -2
  90. package/dist/src/reporting.js +5 -5
  91. package/dist/src/runner-client.js +1 -1
  92. package/dist/src/runner-disposal.js +1 -1
  93. package/dist/src/runner-sequence.js +1 -1
  94. package/dist/src/runtime.js +3 -3
  95. package/dist/src/runtime2.js +4 -4
  96. package/dist/src/runtime3.js +1 -1
  97. package/dist/src/runtime4.js +3 -3
  98. package/dist/src/runtime5.js +1 -1
  99. package/dist/src/runtime6.js +1 -1
  100. package/dist/src/runtime7.js +1 -1
  101. package/dist/src/runtime8.js +1 -1
  102. package/dist/src/runtime9.js +1 -1
  103. package/dist/src/screenshot-result.js +4 -4
  104. package/dist/src/screenshot.js +1 -1
  105. package/dist/src/script-source-bundle.js +16 -0
  106. package/dist/src/sdk-android-adb.d.ts +40 -40
  107. package/dist/src/sdk-android-adb.js +4 -4
  108. package/dist/src/sdk-batch-runner.js +3 -3
  109. package/dist/src/sdk-contracts.d.ts +122 -85
  110. package/dist/src/sdk-contracts.js +2 -2
  111. package/dist/src/sdk-finders.d.ts +1 -1
  112. package/dist/src/sdk-finders.js +1 -1
  113. package/dist/src/sdk-selectors.d.ts +89 -77
  114. package/dist/src/sdk-selectors.js +1 -1
  115. package/dist/src/selector-runtime.js +1 -1
  116. package/dist/src/selectors.js +1 -1
  117. package/dist/src/server.js +10 -3
  118. package/dist/src/session-target-evidence.js +1 -1
  119. package/dist/src/session2.js +7 -8
  120. package/dist/src/shared.js +1 -1
  121. package/dist/src/snapshot-runtime.js +1 -1
  122. package/dist/src/snapshot-scope.js +1 -0
  123. package/dist/src/snapshot.js +6 -6
  124. package/dist/src/snapshot2.js +1 -1
  125. package/dist/src/snapshot3.js +1 -1
  126. package/dist/src/src.js +1 -1
  127. package/dist/src/src2.js +1 -1
  128. package/dist/src/src3.js +1 -1
  129. package/dist/src/src4.js +1 -0
  130. package/dist/src/tool-provider2.js +1 -1
  131. package/dist/src/tool-provider3.js +1 -0
  132. package/dist/src/verified-file.js +1 -1
  133. package/dist/src/web.js +1 -1
  134. package/package.json +21 -8
  135. package/server.json +2 -2
  136. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.9.apk.sha256 +0 -1
  137. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.9.apk.sha256 +0 -1
  138. package/dist/src/cancel.js +0 -1
  139. package/dist/src/prepare-kind.js +0 -15
  140. package/dist/src/selector-vocabulary.js +0 -1
@@ -1,4 +1,4 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n}from"./sdk-contracts.js";import{K as r}from"./sdk-batch-runner.js";import{_ as i,n as a,o,r as s,s as c}from"./sdk-android-adb.js";import{n as l}from"./shell-quote.js";import{t as u}from"./timeouts.js";import"./sdk.js";import{i as ee,n as d,o as te,t as ne}from"./boot-diagnostics.js";const re=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],f=/\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 p(e){let t=new Set;for(let n of e.split(`
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n}from"./sdk-contracts.js";import{J as r}from"./sdk-batch-runner.js";import{_ as i,n as a,o,r as s,s as c}from"./sdk-android-adb.js";import{n as l}from"./shell-quote.js";import{t as u}from"./timeouts.js";import"./sdk.js";import{i as ee,n as d,o as te,t as ne}from"./boot-diagnostics.js";const re=[`mCurrentFocus=Window{`,`mFocusedApp=AppWindowToken{`,`mResumedActivity:`,`ResumedActivity:`],f=/\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 p(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 m(e){return e.split(`
3
3
  `).map(e=>{let t=e.trim();return t.startsWith(`package:`)?t.slice(8):t}).filter(Boolean)}function oe(e){return se(e,(e,t)=>ce(e,t))}function se(e,t){let n=e.split(`
4
4
  `);for(let e of re)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 ce(e,t){let n=e.split(`}`)[0]?.trim()??e.trim(),r=f.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 h(e={}){let t=e.ttlMs??3e4,n=e.nowMs??Date.now,r=new Map,i=e=>{let t=le(e);for(let e of r.keys())e.startsWith(t)&&r.delete(e)};return{get(e,t){let i=g(e,t),a=r.get(i);if(a){if(a.expiresAtMs<=n()){r.delete(i);return}return a.value}},set(e,i,a){return r.set(g(e,i),{value:a,expiresAtMs:n()+t}),a},clear(e){i(e)},async invalidateWhile(e,t){i(e);try{return await t()}finally{i(e)}}}}function g(e,t){return[e.platform,e.deviceId,e.variant??``,t.trim().toLowerCase()].join(`\0`)}function le(e){return[e.platform,e.deviceId,``].join(`\0`)}var _=e({isClipboardShellUnsupported:()=>y,runAndroidAdb:()=>v});async function v(e,t,n){return await o(e)(t,n)}function y(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`no shell command implementation`)||n.includes(`unknown command`)}var ue=e({classifyAndroidAppTarget:()=>b,formatAndroidInstalledPackageRequiredMessage:()=>pe});const de=/\.(?:apk|aab)$/i,fe=/^[A-Za-z_][\w]*(\.[A-Za-z_][\w]*)+$/;function b(e){let t=e.trim();return t.length===0?`other`:de.test(t)?t.includes(`/`)||t.includes(`\\`)||t.startsWith(`.`)||t.startsWith(`~`)||!x(t)?`binary`:`package`:x(t)?`package`:`other`}function x(e){return fe.test(e)}function pe(e){return`Android runtime hints require an installed package name, not "${e}". Install or reinstall the app first, then relaunch by package.`}var me=e({androidAppsDiscoveryHint:()=>S,inferAndroidAppName:()=>E,resolveAndroidApp:()=>T,withAndroidAppResolutionCacheInvalidated:()=>ge});const he={settings:{type:`intent`,value:`android.settings.SETTINGS`}},S=`Run agent-device apps --platform android to discover the installed package name, then retry open with that exact package.`,C=h();function w(e){return{platform:`android`,deviceId:e.id,variant:e.target??``}}async function ge(e,t){return await C.invalidateWhile(w(e),t)}async function T(e,n){let r=n.trim();if(b(r)===`package`)return{type:`package`,value:r};let i=he[r.toLowerCase()];if(i)return i;let a=w(e),o=C.get(a,r);if(o)return o;let s=(await v(e,[`shell`,`pm`,`list`,`packages`])).stdout.split(`
@@ -1 +1 @@
1
- import{ut as e}from"./sdk-batch-runner.js";import{NotFoundError as t}from"@limrun/api";import{createInstanceClient as n}from"@limrun/api/instance-client";import{createInstanceClient as r}from"@limrun/api/ios-client";async function i(e){try{return e.descriptor.platform===`ios`?await a(e):await o(e)}catch(e){if(e instanceof t)return{status:`missing`};throw e}}async function a(e){let t=await s(async()=>await e.limrun.iosInstances.get(e.descriptor.instanceId,{timeout:5e3,maxRetries:0,signal:e.signal}),e.descriptor);if(t.status!==`active`)return t;let{instance:n}=t,i=await r({apiUrl:t.apiUrl,token:n.status.token,logLevel:`warn`});return{status:`opened`,reader:{platform:`ios`,leaseId:e.descriptor.leaseId,instanceId:e.descriptor.instanceId,readLogs:async(e,t)=>await i.appLogTail(e,t),[Symbol.asyncDispose]:async()=>i.disconnect()}}}async function o(t){let r=await s(async()=>await t.limrun.androidInstances.get(t.descriptor.instanceId,{timeout:5e3,maxRetries:0,signal:t.signal}),t.descriptor);if(r.status!==`active`)return r;let{instance:i}=r;if(!i.status.adbWebSocketUrl)return{status:`missing`};let a=await n({apiUrl:r.apiUrl,adbUrl:i.status.adbWebSocketUrl,token:i.status.token,logLevel:`warn`}),o=new e,c=!1;o.defer(async()=>{c||a.disconnect()});try{let e=await a.startAdbTunnel();o.defer(async()=>{c||e.close()});let n=`${e.address.address}:${e.address.port}`,r=async(e,r)=>await t.dependencies.host.runAdb([`-s`,n,...e],r),i={platform:`android`,leaseId:t.descriptor.leaseId,instanceId:t.descriptor.instanceId,readLogs:async(e,n)=>await t.dependencies.android.readLogs(r,n),[Symbol.asyncDispose]:async()=>{await t.dependencies.host.runAdb([`disconnect`,n],{allowFailure:!0,timeoutMs:1e4}).catch(()=>void 0);let r=(await Promise.allSettled([Promise.resolve().then(()=>e.close()),Promise.resolve().then(()=>a.disconnect())])).flatMap(e=>e.status===`rejected`?[e.reason]:[]);if(r.length===1)throw r[0];if(r.length>1)throw AggregateError(r,`Limrun Android app-log reader cleanup failed`)}};return c=!0,{status:`opened`,reader:i}}finally{await o[Symbol.asyncDispose]()}}async function s(e,t){let n=await e();return c(n.metadata.labels,t)?n.status.state===`terminated`||!n.status.apiUrl?{status:`missing`}:{status:`active`,instance:n,apiUrl:n.status.apiUrl}:{status:`ownership-lost`}}function c(e,t){return e?.provider===`limrun`&&e.leaseId===t.leaseId}export{i as reconnectLimrunAppLogReader};
1
+ import{ht as e}from"./sdk-batch-runner.js";import{NotFoundError as t}from"@limrun/api";import{createInstanceClient as n}from"@limrun/api/instance-client";import{createInstanceClient as r}from"@limrun/api/ios-client";async function i(e){try{return e.descriptor.platform===`ios`?await a(e):await o(e)}catch(e){if(e instanceof t)return{status:`missing`};throw e}}async function a(e){let t=await s(async()=>await e.limrun.iosInstances.get(e.descriptor.instanceId,{timeout:5e3,maxRetries:0,signal:e.signal}),e.descriptor);if(t.status!==`active`)return t;let{instance:n}=t,i=await r({apiUrl:t.apiUrl,token:n.status.token,logLevel:`warn`});return{status:`opened`,reader:{platform:`ios`,leaseId:e.descriptor.leaseId,instanceId:e.descriptor.instanceId,readLogs:async(e,t)=>await i.appLogTail(e,t),[Symbol.asyncDispose]:async()=>i.disconnect()}}}async function o(t){let r=await s(async()=>await t.limrun.androidInstances.get(t.descriptor.instanceId,{timeout:5e3,maxRetries:0,signal:t.signal}),t.descriptor);if(r.status!==`active`)return r;let{instance:i}=r;if(!i.status.adbWebSocketUrl)return{status:`missing`};let a=await n({apiUrl:r.apiUrl,adbUrl:i.status.adbWebSocketUrl,token:i.status.token,logLevel:`warn`}),o=new e,c=!1;o.defer(async()=>{c||a.disconnect()});try{let e=await a.startAdbTunnel();o.defer(async()=>{c||e.close()});let n=`${e.address.address}:${e.address.port}`,r=async(e,r)=>await t.dependencies.host.runAdb([`-s`,n,...e],r),i={platform:`android`,leaseId:t.descriptor.leaseId,instanceId:t.descriptor.instanceId,readLogs:async(e,n)=>await t.dependencies.android.readLogs(r,n),[Symbol.asyncDispose]:async()=>{await t.dependencies.host.runAdb([`disconnect`,n],{allowFailure:!0,timeoutMs:1e4}).catch(()=>void 0);let r=(await Promise.allSettled([Promise.resolve().then(()=>e.close()),Promise.resolve().then(()=>a.disconnect())])).flatMap(e=>e.status===`rejected`?[e.reason]:[]);if(r.length===1)throw r[0];if(r.length>1)throw AggregateError(r,`Limrun Android app-log reader cleanup failed`)}};return c=!0,{status:`opened`,reader:i}}finally{await o[Symbol.asyncDispose]()}}async function s(e,t){let n=await e();return c(n.metadata.labels,t)?n.status.state===`terminated`||!n.status.apiUrl?{status:`missing`}:{status:`active`,instance:n,apiUrl:n.status.apiUrl}:{status:`ownership-lost`}}function c(e,t){return e?.provider===`limrun`&&e.leaseId===t.leaseId}export{i as reconnectLimrunAppLogReader};
@@ -1,4 +1,4 @@
1
- import{_ as e}from"./sdk-contracts.js";import{B as t,R as n,St as r,at as i,it as a,ot as o,tt as s,ut as c,wt as l}from"./sdk-batch-runner.js";import{a as u,i as d,s as f}from"./src.js";import{c as p,g as m,h,m as g,n as _,s as v,v as y,x as b}from"./src3.js";const x=Object.freeze({resourceKind:s,version:1,encode:e=>({...e}),decode:e=>e.transport!==`limrun-log-poller`||e.platform!==`ios`&&e.platform!==`android`||!C(e.leaseId)||!C(e.instanceId)||!C(e.appBundleId)||!C(e.outputPath)?{status:`invalid`,message:`Invalid Limrun app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:`limrun-log-poller`,platform:e.platform,leaseId:e.leaseId,instanceId:e.instanceId,appBundleId:e.appBundleId,outputPath:e.outputPath})}});function S(e){if(e.device.platform===`apple`&&!e.device.appleOs)throw TypeError(`Limrun Apple app-log persistence requires an explicit appleOs identity`);return y({resourceKind:s,sessionId:e.sessionId,device:{id:e.device.id,family:e.device.platform,...e.device.appleOs===void 0?{}:{appleOs:e.device.appleOs},kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:b(x,e.descriptor)})}function C(e){return typeof e==`string`&&e.trim().length>0}async function w(e){let t=new c,n=!1;t.defer(async()=>{n||await e.reader[Symbol.asyncDispose]()});try{let r=await e.host.outputs.readTail(e.outputPath,256*1024),i=await e.host.outputs.openAppend(e.outputPath);t.defer(async()=>{n||await i[Symbol.asyncDispose]()});let a=T(e,i,ie(r));return n=!0,a}finally{await t[Symbol.asyncDispose]()}}function T(e,t,n){let r=D(e.reader),i=e.host.clock.now(),a=`active`,o=!1,s=n,c=(async()=>{for(;!o;){try{let n=await ee(e);if(n.status===`timeout`){a=`failed`;return}if(o)return;let r=te(s,n.text);s=n.text,r&&await t.write(r.endsWith(`
2
- `)?r:`${r}\n`),a=`active`}catch{if(o)return;a=`recovering`}await e.host.clock.sleep(1e3)}})(),l;return g({inspect:()=>({backend:r,state:a,startedAt:i}),finish:async()=>l??=(async()=>(o=!0,await c,(await E([e.reader,t])).length>0?(a=`failed`,{status:`cleanup-pending`,reason:`transport-failed`,message:`Limrun app-log cleanup did not settle every owned resource`}):(a=`ended`,{status:`completed`,result:{backend:r,outputPath:e.outputPath,completedAt:e.host.clock.now()}})))()})}async function ee(e){let t=new AbortController,n=d(e.reader.readLogs(e.appBundleId,1e3),t.signal,`App-log provider read aborted`).then(e=>({status:`read`,text:e}));try{let r=await Promise.race([n,e.host.clock.sleep(5e3,t.signal).then(()=>({status:`timeout`}))]);return r.status===`timeout`&&(t.abort(),await n.catch(()=>void 0)),r}finally{t.abort()}}function te(e,t){if(!e||!t)return t;let n=ne(t),r=Math.min(e.length,t.length),i=e.slice(e.length-r);return t.slice(re(i,t,n))}function ne(e){let t=new Uint32Array(e.length),n=0;for(let r=1;r<e.length;r+=1){for(;n>0&&e[r]!==e[n];)n=t[n-1];e[r]===e[n]&&(n+=1),t[r]=n}return t}function re(e,t,n){let r=0;for(let i=0;i<e.length;i+=1){for(;r>0&&e[i]!==t[r];)r=n[r-1];e[i]===t[r]&&(r+=1),r===t.length&&i<e.length-1&&(r=n[r-1])}return r}function ie(e){return e.split(`
1
+ import{_ as e}from"./sdk-contracts.js";import{At as t,B as n,H as r,Ot as i,ct as a,dt as o,ht as s,lt as c,ot as l,rt as u,ut as d}from"./sdk-batch-runner.js";import{c as ee}from"./sdk-device.js";import{a as f,i as te,s as p}from"./src.js";import{c as ne,g as m,h,m as g,n as _,s as v,v as y,x as b}from"./src3.js";const x=Object.freeze({resourceKind:u,version:1,encode:e=>({...e}),decode:e=>e.transport!==`limrun-log-poller`||e.platform!==`ios`&&e.platform!==`android`||!S(e.leaseId)||!S(e.instanceId)||!S(e.appBundleId)||!S(e.outputPath)?{status:`invalid`,message:`Invalid Limrun app-log descriptor`}:{status:`decoded`,descriptor:Object.freeze({transport:`limrun-log-poller`,platform:e.platform,leaseId:e.leaseId,instanceId:e.instanceId,appBundleId:e.appBundleId,outputPath:e.outputPath})}});function re(e){if(e.device.platform===`apple`&&!e.device.appleOs)throw TypeError(`Limrun Apple app-log persistence requires an explicit appleOs identity`);return y({resourceKind:u,sessionId:e.sessionId,device:{id:e.device.id,family:e.device.platform,...e.device.appleOs===void 0?{}:{appleOs:e.device.appleOs},kind:e.device.kind,...e.device.target===void 0?{}:{target:e.device.target},...e.device.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:e.device.iosPhysicalDeviceBackend}},owner:e.owner,fence:e.fence,lifecycle:`open`,descriptor:b(x,e.descriptor)})}function S(e){return typeof e==`string`&&e.trim().length>0}async function C(e){let t=new s,n=!1;t.defer(async()=>{n||await e.reader[Symbol.asyncDispose]()});try{let r=await e.host.outputs.readTail(e.outputPath,256*1024),i=await e.host.outputs.openAppend(e.outputPath);t.defer(async()=>{n||await i[Symbol.asyncDispose]()});let a=ie(e,i,T(r));return n=!0,a}finally{await t[Symbol.asyncDispose]()}}function ie(e,t,n){let r=D(e.reader),i=e.host.clock.now(),a=`active`,o=!1,s=n,c=(async()=>{for(;!o;){try{let n=await ae(e);if(n.status===`timeout`){a=`failed`;return}if(o)return;let r=oe(s,n.text);s=n.text,r&&await t.write(r.endsWith(`
2
+ `)?r:`${r}\n`),a=`active`}catch{if(o)return;a=`recovering`}await e.host.clock.sleep(1e3)}})(),l;return g({inspect:()=>({backend:r,state:a,startedAt:i}),finish:async()=>l??=(async()=>(o=!0,await c,(await E([e.reader,t])).length>0?(a=`failed`,{status:`cleanup-pending`,reason:`transport-failed`,message:`Limrun app-log cleanup did not settle every owned resource`}):(a=`ended`,{status:`completed`,result:{backend:r,outputPath:e.outputPath,completedAt:e.host.clock.now()}})))()})}async function ae(e){let t=new AbortController,n=te(e.reader.readLogs(e.appBundleId,1e3),t.signal,`App-log provider read aborted`).then(e=>({status:`read`,text:e}));try{let r=await Promise.race([n,e.host.clock.sleep(5e3,t.signal).then(()=>({status:`timeout`}))]);return r.status===`timeout`&&(t.abort(),await n.catch(()=>void 0)),r}finally{t.abort()}}function oe(e,t){if(!e||!t)return t;let n=se(t),r=Math.min(e.length,t.length),i=e.slice(e.length-r);return t.slice(w(i,t,n))}function se(e){let t=new Uint32Array(e.length),n=0;for(let r=1;r<e.length;r+=1){for(;n>0&&e[r]!==e[n];)n=t[n-1];e[r]===e[n]&&(n+=1),t[r]=n}return t}function w(e,t,n){let r=0;for(let i=0;i<e.length;i+=1){for(;r>0&&e[i]!==t[r];)r=n[r-1];e[i]===t[r]&&(r+=1),r===t.length&&i<e.length-1&&(r=n[r-1])}return r}function T(e){return e.split(`
3
3
  `).filter(e=>!e.startsWith(`[agent-device][mark]`)).join(`
4
- `)}async function E(e){return(await Promise.allSettled(e.map(async e=>await e[Symbol.asyncDispose]()))).flatMap(e=>e.status===`rejected`?[e.reason]:[])}function D(e){return e.platform===`ios`?`ios-simulator`:`android`}function O(e){return n({owner:`Limrun`,openTargetIdentity:`bundle-id`,closeBeforeRelaunch:!0,configureProviderPortReverse:async t=>await e.configurePortReverse(t),binding:t({device:e.device,signal:e.signal,resolveInteractor:t=>e.getInteractor(e.device,t)})})}function k(e){let t=f(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0:e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}const A=Object.freeze({available:!0}),j=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The Limrun provider session is no longer active for this device.`}),M=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Push notifications are unavailable for Limrun provider-owned devices.`});function N(e,t){let n=F(e,t);return Object.freeze({deployApp:n,materializeAppSource:n,deployMaterializedApp:n,sendPushNotification:I(e,t)?M:j})}function P(e,t,n,r){let i=e.deployApp,a=e.deployMaterializedApp;return!N(e,t).deployApp.available||!i||!a?Object.freeze({}):Object.freeze({deployApp:async e=>R(await i(t,e,n,r)),materializeAppSource:async r=>await L(e.host,t,r,n),deployMaterializedApp:async e=>R(await a(t,e,n,r))})}function F(e,t){return k(t)&&I(e,t)&&e.deployApp&&e.deployMaterializedApp?A:j}function I(e,t){return e.isSessionActive?.(t)??e.ownsDevice(t)}async function L(e,t,n,r){return await(t.platform===`apple`?e.appleDeployment:e.androidDeployment).prepareArtifact(n,{signal:r})}function R(t){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The Limrun provider session is no longer active.`);return t}function z(e){return{...e,isSessionActive:e.hasLiveSession}}const B=Object.freeze({available:!0}),V=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun does not expose an exact-owner screen-recording runtime.`}),ae=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Headless boot is unavailable for provider-owned devices.`}),H=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`Limrun requires a matching live provider session for this device.`}),U=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Apple runner preparation is unavailable for Limrun-owned devices.`}),W=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun open requires a Limrun-owned iOS simulator or Android emulator.`}),G=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun close requires a Limrun-owned iOS simulator or Android emulator.`}),K=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Runtime hints are not applied to provider-owned devices.`}),q=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun port reverse requires an active Android Limrun session.`});function J(e,t){let n=oe(e,t),r=se(e,t),a=ce(e,t);return i({resolveOpenTarget:n,prepareApplicationOpen:n,openApplication:n,applyRuntimeHints:K,clearRuntimeHints:K,closeApplication:r,finalizeApplicationClose:r,prepareAppleRunner:U,configureProviderPortReverse:a})}function oe(e,t){return $(e)?t?B:H:W}function se(e,t){return $(e)?t?B:H:G}function ce(e,t){return t?e.platform===`android`?B:q:H}function le(t){let n=r(`limrun`,t.runtimeInstance),i=e=>$(e)&&t.ownsDevice(e),o=e=>i(e)&&t.hasLiveSession(e);return Object.freeze({owner:n,ownsDevice:i,inspectFacts:async e=>o(e)?X(t,e):a(e,n,{appLog:H,appState:H,appDeployment:H,network:H,readiness:H,shutdown:H,lifecycle:J(e,!1)}),bind:async r=>{if(r.intent.kind===`exact-owner`&&!l(r.intent.owner,n))throw new e(`UNSUPPORTED_OPERATION`,`Limrun app-log owner identity does not match`);if(!$(r.device))throw new e(`UNSUPPORTED_PLATFORM`,`Limrun app logs require an iOS simulator or Android emulator device identity`);let i=o(r.device);if(r.intent.kind!==`exact-owner`&&!i)throw new e(`UNSUPPORTED_OPERATION`,`Limrun provider session is no longer live for the selected device`,{reason:`provider-session-unavailable`});return ue(t,n,r.device,r.scope.signal,!i)},shutdown:async()=>void 0})}function ue(t,n,r,i,a){let s=a?de(t,r):X(t,r),c=u(),l=h({codec:x,reattach:async(e,n)=>{if(!Q(e,r)||!v(t.host,n.sessionId,e))return{status:`unreattachable`,reason:`descriptor-invalid`,message:`Limrun app-log descriptor does not match the bound device or owning session`};let a=await t.reconnect(e,i);return a.status===`missing`?{status:`missing`}:a.status===`ownership-lost`?{status:`unreattachable`,reason:`ownership-fence-lost`}:{status:`active`,handle:await w({host:t.host,reader:a.reader,appBundleId:e.appBundleId,outputPath:e.outputPath})}},cleanup:async(e,n)=>Q(e,r)&&v(t.host,n.sessionId,e)?{status:`cleaned`}:{status:`cleanup-pending`,reason:`ownership-fence-lost`,message:`Limrun app-log descriptor does not match the bound device or owning session`}}),d={appLogInspect:async()=>({backend:Z(r)}),appLogDoctor:async()=>({backend:Z(r),checks:{limrunSessionAvailable:await Y(t,r,i)},notes:[]}),appLogStart:async a=>{p(t.host,a),i.throwIfAborted();let o=await t.openCurrent(r);if(!o)throw new e(`UNSUPPORTED_OPERATION`,`Limrun app logs require an active instance`);let s={transport:`limrun-log-poller`,platform:o.platform,leaseId:o.leaseId,instanceId:o.instanceId,appBundleId:a.appBundleId,outputPath:a.outputPath},c=!1;try{i.throwIfAborted();let e=S({sessionId:a.sessionId,device:r,owner:n,fence:a.fence,descriptor:s});return c=!0,m(await w({host:t.host,reader:o,appBundleId:a.appBundleId,outputPath:a.outputPath}),e)}catch(e){throw c||await o[Symbol.asyncDispose](),e}},...l,networkDump:async e=>{let n=await t.host.appLogs.readRecent(e.sessionId,e.maxScanLines),i=Z(r),a=_(n.text,{...e,path:n.path,exists:n.exists,lineNumberOffset:n.skippedLines,backend:i}),o=a.entries.length===0?[`No HTTP(s) entries were found in recent session app logs.`]:[];return Object.freeze({source:`app-log`,backend:i,dump:a,notes:o})},ensureReady:async()=>({...r,booted:!0}),bootTarget:async()=>({...r,booted:!0}),listApps:async e=>await t.listApps(e.device,e.filter,i),...r.platform===`android`?{appState:async()=>await t.getAppState(r,i)}:{},...o(O({device:r,signal:i,getInteractor:t.getInteractor,configurePortReverse:t.configurePortReverse}),s.operations),...P(z(t),r,i,c)};return Object.freeze({device:r,owner:n,facts:s,operations:Object.freeze(a?{appLogReattach:l.appLogReattach,appLogCleanup:l.appLogCleanup}:d),[Symbol.asyncDispose]:async()=>await c[Symbol.asyncDispose]()})}async function Y(e,t,n){n.throwIfAborted();let r=await e.openCurrent(t);if(!r)return!1;try{n.throwIfAborted()}finally{await r[Symbol.asyncDispose]()}return!0}function X(e,t){let n=N(z(e),t);return Object.freeze({device:{family:t.platform,...t.appleOs===void 0?{}:{appleOs:t.appleOs},kind:t.kind,...t.target===void 0?{}:{target:t.target},...t.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:t.iosPhysicalDeviceBackend},providerMode:`provider-runtime`},operations:{appLogInspect:B,appLogDoctor:B,appLogStart:B,appLogReattach:B,appLogCleanup:B,...n,appState:t.platform===`android`?B:{available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS appstate is session-owned; no sessionless provider foreground probe is exposed.`},networkDump:B,screenRecordingStart:V,screenRecordingReattach:V,screenRecordingCleanup:V,ensureReady:B,bootTarget:B,bootTargetHeadless:ae,listApps:B,shutdownTarget:{available:!1,reason:`unsupported-provider-mode`,hint:`Limrun owns the target lifecycle for provider-owned devices.`},...J(t,!0)}})}function de(e,t){let n=X(e,t);return Object.freeze({device:n.device,operations:{...n.operations,appLogInspect:H,appLogDoctor:H,appLogStart:H,appLogReattach:B,appLogCleanup:B,appState:H,networkDump:H,screenRecordingStart:H,screenRecordingReattach:H,screenRecordingCleanup:H,ensureReady:H,bootTarget:H,bootTargetHeadless:H,listApps:H,deployApp:H,materializeAppSource:H,deployMaterializedApp:H,sendPushNotification:H,shutdownTarget:H,...J(t,!1)}})}function Z(e){return e.platform===`apple`?`ios-simulator`:`android`}function Q(e,t){if(!$(t))return!1;let n=f(t.id);return n!==void 0&&n.leaseId===e.leaseId&&n.platform===e.platform&&(t.platform===`apple`?e.platform===`ios`:e.platform===`android`)}function $(e){let t=f(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?fe(e):pe(e)}function fe(e){return e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0}function pe(e){return e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}export{le as createLimrunPlatformRuntimeOwner};
4
+ `)}async function E(e){return(await Promise.allSettled(e.map(async e=>await e[Symbol.asyncDispose]()))).flatMap(e=>e.status===`rejected`?[e.reason]:[])}function D(e){return e.platform===`ios`?`ios-simulator`:`android`}function O(e){return n({owner:`Limrun`,openTargetIdentity:`bundle-id`,closeBeforeRelaunch:!0,configureProviderPortReverse:async t=>await e.configurePortReverse(t),binding:r({device:e.device,signal:e.signal,resolveInteractor:t=>e.getInteractor(e.device,t)})})}function k(e){let t=p(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0:e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}const A=Object.freeze({available:!0}),j=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`The Limrun provider session is no longer active for this device.`}),M=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Push notifications are unavailable for Limrun provider-owned devices.`});function N(e,t){let n=F(e,t);return Object.freeze({deployApp:n,materializeAppSource:n,deployMaterializedApp:n,sendPushNotification:I(e,t)?M:j})}function P(e,t,n,r){let i=e.deployApp,a=e.deployMaterializedApp;return!N(e,t).deployApp.available||!i||!a?Object.freeze({}):Object.freeze({deployApp:async e=>R(await i(t,e,n,r)),materializeAppSource:async r=>await L(e.host,t,r,n),deployMaterializedApp:async e=>R(await a(t,e,n,r))})}function F(e,t){return k(t)&&I(e,t)&&e.deployApp&&e.deployMaterializedApp?A:j}function I(e,t){return e.isSessionActive?.(t)??e.ownsDevice(t)}async function L(e,t,n,r){return await(t.platform===`apple`?e.appleDeployment:e.androidDeployment).prepareArtifact(n,{signal:r})}function R(t){if(!t)throw new e(`UNSUPPORTED_OPERATION`,`The Limrun provider session is no longer active.`);return t}function z(e){return{...e,isSessionActive:e.hasLiveSession}}const B=Object.freeze({available:!0}),V=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Custom snapshot actions are available only for Limrun iOS simulator sessions.`}),H=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun does not expose an exact-owner screen-recording runtime.`}),U=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Headless boot is unavailable for provider-owned devices.`}),W=Object.freeze({available:!1,reason:`owner-capability-missing`,hint:`Limrun requires a matching live provider session for this device.`}),G=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Apple runner preparation is unavailable for Limrun-owned devices.`}),K=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun open requires a Limrun-owned iOS simulator or Android emulator.`}),ce=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun close requires a Limrun-owned iOS simulator or Android emulator.`}),q=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Runtime hints are not applied to provider-owned devices.`}),le=Object.freeze({available:!1,reason:`unsupported-provider-mode`,hint:`Limrun port reverse requires an active Android Limrun session.`});function J(e,t){let n=ue(e,t),r=de(e,t),i=fe(e,t);return d({resolveOpenTarget:n,prepareApplicationOpen:n,openApplication:n,applyRuntimeHints:q,clearRuntimeHints:q,closeApplication:r,finalizeApplicationClose:r,prepareAppleRunner:G,configureProviderPortReverse:i})}function ue(e,t){return Q(e)?t?B:W:K}function de(e,t){return Q(e)?t?B:W:ce}function fe(e,t){return t?e.platform===`android`?B:le:W}function pe(n){let r=i(`limrun`,n.runtimeInstance),a=e=>Q(e)&&n.ownsDevice(e),o=e=>a(e)&&n.hasLiveSession(e);return Object.freeze({owner:r,ownsDevice:a,inspectFacts:async e=>o(e)?Y(n,e):l(e,r,{appLog:W,appState:W,appDeployment:W,network:W,readiness:W,shutdown:W,lifecycle:J(e,!1)}),bind:async i=>{if(i.intent.kind===`exact-owner`&&!t(i.intent.owner,r))throw new e(`UNSUPPORTED_OPERATION`,`Limrun app-log owner identity does not match`);if(!Q(i.device))throw new e(`UNSUPPORTED_PLATFORM`,`Limrun app logs require an iOS simulator or Android emulator device identity`);let a=o(i.device);if(i.intent.kind!==`exact-owner`&&!a)throw new e(`UNSUPPORTED_OPERATION`,`Limrun provider session is no longer live for the selected device`,{reason:`provider-session-unavailable`});return me(n,r,i.device,i.scope.signal,!a)},shutdown:async()=>void 0})}function me(t,n,r,i,s){let c=s?ge(t,r):Y(t,r),l=f(),u=h({codec:x,reattach:async(e,n)=>{if(!Z(e,r)||!v(t.host,n.sessionId,e))return{status:`unreattachable`,reason:`descriptor-invalid`,message:`Limrun app-log descriptor does not match the bound device or owning session`};let a=await t.reconnect(e,i);return a.status===`missing`?{status:`missing`}:a.status===`ownership-lost`?{status:`unreattachable`,reason:`ownership-fence-lost`}:{status:`active`,handle:await C({host:t.host,reader:a.reader,appBundleId:e.appBundleId,outputPath:e.outputPath})}},cleanup:async(e,n)=>Z(e,r)&&v(t.host,n.sessionId,e)?{status:`cleaned`}:{status:`cleanup-pending`,reason:`ownership-fence-lost`,message:`Limrun app-log descriptor does not match the bound device or owning session`}}),d={appLogInspect:async()=>({backend:X(r)}),appLogDoctor:async()=>({backend:X(r),checks:{limrunSessionAvailable:await he(t,r,i)},notes:[]}),appLogStart:async a=>{ne(t.host,a),i.throwIfAborted();let o=await t.openCurrent(r);if(!o)throw new e(`UNSUPPORTED_OPERATION`,`Limrun app logs require an active instance`);let s={transport:`limrun-log-poller`,platform:o.platform,leaseId:o.leaseId,instanceId:o.instanceId,appBundleId:a.appBundleId,outputPath:a.outputPath},c=!1;try{i.throwIfAborted();let e=re({sessionId:a.sessionId,device:r,owner:n,fence:a.fence,descriptor:s});return c=!0,m(await C({host:t.host,reader:o,appBundleId:a.appBundleId,outputPath:a.outputPath}),e)}catch(e){throw c||await o[Symbol.asyncDispose](),e}},...u,networkDump:async e=>{let n=await t.host.appLogs.readRecent(e.sessionId,e.maxScanLines),i=X(r),a=_(n.text,{...e,path:n.path,exists:n.exists,lineNumberOffset:n.skippedLines,backend:i}),o=a.entries.length===0?[`No HTTP(s) entries were found in recent session app logs.`]:[];return Object.freeze({source:`app-log`,backend:i,dump:a,notes:o})},ensureReady:async()=>({...r,booted:!0}),bootTarget:async()=>({...r,booted:!0}),listApps:async e=>await t.listApps(e.device,e.filter,i),...r.platform===`android`?{appState:async()=>await t.getAppState(r,i)}:{},...o(O({device:r,signal:i,getInteractor:t.getInteractor,configurePortReverse:t.configurePortReverse}),c.operations),...a({device:r,signal:i,resolveInteractor:e=>t.getInteractor(r,e)}),...P(z(t),r,i,l)};return Object.freeze({device:r,owner:n,facts:c,operations:Object.freeze(s?{appLogReattach:u.appLogReattach,appLogCleanup:u.appLogCleanup}:d),[Symbol.asyncDispose]:async()=>await l[Symbol.asyncDispose]()})}async function he(e,t,n){n.throwIfAborted();let r=await e.openCurrent(t);if(!r)return!1;try{n.throwIfAborted()}finally{await r[Symbol.asyncDispose]()}return!0}function Y(e,t){let n=N(z(e),t);return Object.freeze({device:{family:t.platform,...t.appleOs===void 0?{}:{appleOs:t.appleOs},kind:t.kind,...t.target===void 0?{}:{target:t.target},...t.iosPhysicalDeviceBackend===void 0?{}:{iosPhysicalDeviceBackend:t.iosPhysicalDeviceBackend},providerMode:`provider-runtime`},operations:{appLogInspect:B,appLogDoctor:B,appLogStart:B,appLogReattach:B,appLogCleanup:B,...n,appState:t.platform===`android`?B:{available:!1,reason:`unsupported-provider-mode`,hint:`Limrun iOS appstate is session-owned; no sessionless provider foreground probe is exposed.`},networkDump:B,screenRecordingStart:H,screenRecordingReattach:H,screenRecordingCleanup:H,...c({capture:B,customActions:ee(t)&&t.kind===`simulator`?B:V,withoutActiveApp:B}),ensureReady:B,bootTarget:B,bootTargetHeadless:U,listApps:B,shutdownTarget:{available:!1,reason:`unsupported-provider-mode`,hint:`Limrun owns the target lifecycle for provider-owned devices.`},...J(t,!0)}})}function ge(e,t){let n=Y(e,t);return Object.freeze({device:n.device,operations:{...n.operations,appLogInspect:W,appLogDoctor:W,appLogStart:W,appLogReattach:B,appLogCleanup:B,appState:W,networkDump:W,screenRecordingStart:W,screenRecordingReattach:W,screenRecordingCleanup:W,...c({capture:W,customActions:W,withoutActiveApp:W}),ensureReady:W,bootTarget:W,bootTargetHeadless:W,listApps:W,deployApp:W,materializeAppSource:W,deployMaterializedApp:W,sendPushNotification:W,shutdownTarget:W,...J(t,!1)}})}function X(e){return e.platform===`apple`?`ios-simulator`:`android`}function Z(e,t){if(!Q(t))return!1;let n=p(t.id);return n!==void 0&&n.leaseId===e.leaseId&&n.platform===e.platform&&(t.platform===`apple`?e.platform===`ios`:e.platform===`android`)}function Q(e){let t=p(e.id);return!t||e.target!==`mobile`?!1:t.platform===`ios`?$(e):_e(e)}function $(e){return e.platform===`apple`&&e.appleOs===`ios`&&e.kind===`simulator`&&e.iosPhysicalDeviceBackend===void 0}function _e(e){return e.platform===`android`&&e.appleOs===void 0&&e.kind===`emulator`&&e.iosPhysicalDeviceBackend===void 0}export{pe as createLimrunPlatformRuntimeOwner};
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{K as n}from"./sdk-batch-runner.js";import{c as r,l as i}from"./sdk-device.js";import{_ as a}from"./app-lifecycle.js";import{t as o}from"./appearance.js";import{i as s,r as c,s as l}from"./tool-provider.js";import{n as u}from"./helper.js";import{a as d,n as f}from"./physical-device-control.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,r,i){let a=i?.url?.trim();if(a){if(!n(a))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);let e=i?.appBundleId??await b(r);await O().openBundle(e,a);return}let o=r.trim();if(n(o)){await O().openTarget(o);return}let s=i?.appBundleId??await b(o);await O().openBundle(s)}async function S(e,n){let r=await b(n),i=await u(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=o(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=c().macosHost;if(!e)throw new t(`UNSUPPORTED_OPERATION`,`macOS host provider is not available`);return e}var k=e({buildAppNotInstalledError:()=>F,detectSoleRunningIosSimulatorApp:()=>B,findIosSimulatorInstalledApp:()=>I,invalidateIosAppResolutionCache:()=>N,listIosApps:()=>W,resolveIosApp:()=>P,resolveIosAppAlias:()=>L,resolveIosSimulatorDeepLinkBundleId:()=>H});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,n){if(i(e))return await b(n);let r=n.trim();if(r.includes(`.`))return r;let a=L(r);if(a!==r)return a;let o=M(e),s=j.get(o,r);if(s)return s;let c=(e.kind===`simulator`?await G(e):await f(e).listApps(e,`all`)).filter(e=>e.name.toLowerCase()===r.toLowerCase()),l=c[0];if(l!==void 0&&c.length===1)return j.set(o,r,l.bundleId);throw c.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${n}"`,{matches:c}):F(n)}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 G(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}const R=3e3,z=/UIKitApplication:([^[\s]+)\[/;async function B(e){if(!(!r(e)||e.kind!==`simulator`||e.booted!==!0))try{let[t,n]=await Promise.all([V(e),G(e,{timeoutMs:R})]);if(t.length===0)return;let r=new Map(n.map(e=>[e.bundleId,e])),i=new Map;for(let e of t){let t=r.get(e);t&&i.set(t.bundleId,t)}return i.size===1?[...i.values()][0]:void 0}catch{return}}async function V(e){let t=await d(e,[`spawn`,e.id,`launchctl`,`list`],{allowFailure:!0,timeoutMs:R});if(t.exitCode!==0)return[];let n=[];for(let e of t.stdout.split(`
2
- `)){let t=z.exec(e);t?.[1]&&n.push(t[1])}return n}async function H(e,t){if(!r(e)||e.kind!==`simulator`)return;let n=U(t);if(!n)return;let i=await K(e),a=[];for(let e of i)e.bundleId.startsWith(`com.callstack.agentdevice.runner`)||e.path&&(await J(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 U(e){return/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(e.trim())?.[1]?.toLowerCase()}async function W(e,t){return i(e)?await D(t):e.kind===`simulator`?l(await G(e),t):await f(e).listApps(e,t)}async function G(e,t){return(await K(e,t)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function K(e,t){let n=(await d(e,[`listapps`,e.id],{allowFailure:!0,timeoutMs:t?.timeoutMs})).stdout.trim();if(!n)return[];let r=null;if(n.startsWith(`{`))try{r=JSON.parse(n)}catch{r=null}if(!r&&n.startsWith(`{`))try{let e=await s(`plutil`,[`-convert`,`json`,`-o`,`-`,`-`],{allowFailure:!0,stdin:n,timeoutMs:t?.timeoutMs});e.exitCode===0&&e.stdout.trim().startsWith(`{`)&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>{let n=q(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...n?{path:n}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}function q(e){if(e.Path)return e.Path;if(e.Bundle)try{return m(e.Bundle)}catch{return}}async function J(e){let t=await s(`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{H as a,C as c,P as i,E as l,I as n,S as o,W as r,x as s,k as t,w as u};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{J as n}from"./sdk-batch-runner.js";import{c as r,l as i}from"./sdk-device.js";import{_ as a}from"./app-lifecycle.js";import{t as o}from"./appearance.js";import{i as s,r as c,s as l}from"./tool-provider.js";import{a as u,n as d}from"./physical-device-control.js";import{n as f}from"./helper.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,r,i){let a=i?.url?.trim();if(a){if(!n(a))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);let e=i?.appBundleId??await b(r);await O().openBundle(e,a);return}let o=r.trim();if(n(o)){await O().openTarget(o);return}let s=i?.appBundleId??await b(o);await O().openBundle(s)}async function S(e,n){let r=await b(n),i=await f(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=o(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=c().macosHost;if(!e)throw new t(`UNSUPPORTED_OPERATION`,`macOS host provider is not available`);return e}var k=e({buildAppNotInstalledError:()=>F,detectSoleRunningIosSimulatorApp:()=>B,findIosSimulatorInstalledApp:()=>I,invalidateIosAppResolutionCache:()=>N,listIosApps:()=>W,resolveIosApp:()=>P,resolveIosAppAlias:()=>L,resolveIosSimulatorDeepLinkBundleId:()=>H});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,n){if(i(e))return await b(n);let r=n.trim();if(r.includes(`.`))return r;let a=L(r);if(a!==r)return a;let o=M(e),s=j.get(o,r);if(s)return s;let c=(e.kind===`simulator`?await G(e):await d(e).listApps(e,`all`)).filter(e=>e.name.toLowerCase()===r.toLowerCase()),l=c[0];if(l!==void 0&&c.length===1)return j.set(o,r,l.bundleId);throw c.length>1?new t(`INVALID_ARGS`,`Multiple apps matched "${n}"`,{matches:c}):F(n)}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 G(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}const R=3e3,z=/UIKitApplication:([^[\s]+)\[/;async function B(e){if(!(!r(e)||e.kind!==`simulator`||e.booted!==!0))try{let[t,n]=await Promise.all([V(e),G(e,{timeoutMs:R})]);if(t.length===0)return;let r=new Map(n.map(e=>[e.bundleId,e])),i=new Map;for(let e of t){let t=r.get(e);t&&i.set(t.bundleId,t)}return i.size===1?[...i.values()][0]:void 0}catch{return}}async function V(e){let t=await u(e,[`spawn`,e.id,`launchctl`,`list`],{allowFailure:!0,timeoutMs:R});if(t.exitCode!==0)return[];let n=[];for(let e of t.stdout.split(`
2
+ `)){let t=z.exec(e);t?.[1]&&n.push(t[1])}return n}async function H(e,t){if(!r(e)||e.kind!==`simulator`)return;let n=U(t);if(!n)return;let i=await K(e),a=[];for(let e of i)e.bundleId.startsWith(`com.callstack.agentdevice.runner`)||e.path&&(await J(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 U(e){return/^([A-Za-z][A-Za-z0-9+.-]*):/.exec(e.trim())?.[1]?.toLowerCase()}async function W(e,t){return i(e)?await D(t):e.kind===`simulator`?l(await G(e),t):await d(e).listApps(e,t)}async function G(e,t){return(await K(e,t)).map(e=>({bundleId:e.bundleId,name:e.name}))}async function K(e,t){let n=(await u(e,[`listapps`,e.id],{allowFailure:!0,timeoutMs:t?.timeoutMs})).stdout.trim();if(!n)return[];let r=null;if(n.startsWith(`{`))try{r=JSON.parse(n)}catch{r=null}if(!r&&n.startsWith(`{`))try{let e=await s(`plutil`,[`-convert`,`json`,`-o`,`-`,`-`],{allowFailure:!0,stdin:n,timeoutMs:t?.timeoutMs});e.exitCode===0&&e.stdout.trim().startsWith(`{`)&&(r=JSON.parse(e.stdout))}catch{r=null}return r?Object.entries(r).map(([e,t])=>{let n=q(t);return{bundleId:e,name:t.CFBundleDisplayName??t.CFBundleName??e,...n?{path:n}:{},...t.ApplicationType?{applicationType:t.ApplicationType}:{}}}):[]}function q(e){if(e.Path)return e.Path;if(e.Bundle)try{return m(e.Bundle)}catch{return}}async function J(e){let t=await s(`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{H as a,C as c,P as i,E as l,I as n,S as o,W as r,x as s,k as t,w as u};
package/dist/src/apps.js CHANGED
@@ -1,5 +1,5 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{a as n,c as r,n as i,s as a}from"./location-coordinates.js";import{G as o,J as s,K as c,W as l,q as ee}from"./sdk-batch-runner.js";import{c as u,l as d}from"./sdk-device.js";import"./observability.js";import{A as f,f as p,h as m}from"./sdk-android-adb.js";import{i as h,o as te}from"./boot-diagnostics.js";import{n as ne,t as g}from"./setting-state.js";import{t as re}from"./appearance.js";import{n as ie,r as _,s as ae}from"./simctl.js";import{a as v,i as oe}from"./tool-provider.js";import{i as se}from"./helper.js";import{t as ce}from"./png-resize.js";import{i as le,n as ue}from"./screenshot-density.js";import{a as y,i as b,l as de,n as x,o as S,r as C}from"./physical-device-control.js";import{a as w,c as fe,d as pe,f as me,l as he,t as T,u as ge}from"./config.js";import{n as E}from"./runner-client.js";import{n as _e,r as D,t as O}from"./simulator.js";import{a as ve,c as ye,i as k,l as be,n as xe,o as Se,r as Ce,s as we,u as Te}from"./app-resolution.js";import A from"node:path";import{promises as j}from"node:fs";import"node:os";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 M(e,t,n){return _(e,t,n)}const N=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 Pe(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 Pe(e),!t){F(e);return}await L(e,Ie(t)),P(e)}function P(e){N.delete(I(e))}function F(e){N.add(I(e))}function Me(e){return N.has(I(e))}function I(e){return`${e.platform}:${e.kind}:${e.id}`}async function Ne(e){return Fe(m(await M(e,[`status_bar`,e.id,`list`],{allowFailure:!0}),`Failed to read simulator status bar overrides`).stdout)}async function Pe(e){await M(e,[`status_bar`,e.id,`clear`])}async function L(e,t){t.length!==0&&await M(e,[`status_bar`,e.id,`override`,...t])}function Fe(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 Ie(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||Le(e.dataNetwork)||e.operatorName!==void 0)&&t.push(`--cellularBars`,e.cellularBars),e.operatorName!==void 0&&t.push(`--operatorName`,e.operatorName),t}function Le(e){return!!(e&&e!==`hide`&&e!==`wifi`)}function R(e,t,n){f({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...b(n)}})}function z(e,t,n){return _(e,t,n)}const Re={ensureBooted:O,prepareStatusBarForScreenshot:Ae,captureWithRetry:Ve,normalizeDensity:qe,captureWithRunner:H,shouldFallbackToRunner:G},B=new Map,V=new Map;async function ze(e,t,n={}){if(d(e)){await H(e,t,n.appBundleId,n.fullscreen,n.runnerOptions);return}if(e.kind===`simulator`){await Be(e,t,n);return}await x(e).captureScreenshot(e,t,{appBundleId:n.appBundleId,fullscreen:n.fullscreen,runnerOptions:n.runnerOptions,runRunnerCommand:E})}async function Be(e,n,r={}){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Simulator screenshot fallback flow supports only iOS simulators`);let i={...Re,...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&&Ke(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=>W(e,`restore_failed`,t))}}async function Ve(e,t){let n=h.fromTimeoutMs(pe);await te(async({deadline:n})=>{await z(e,[`io`,e.id,`screenshot`,t],{timeoutMs:Math.max(1e3,n?.remainingMs()??2e4)})},{maxAttempts:5,baseDelayMs:fe,maxDelayMs:he,jitter:.2,shouldRetry:e=>G(e)},{deadline:n,phase:`ios_simulator_screenshot`})}async function H(e,n,r,i,a){if(e.kind===`device`&&!d(e)){await x(e).captureScreenshot(e,n,{appBundleId:r,fullscreen:i,runnerOptions:a,preferRunner:!0,runRunnerCommand:E});return}let o=(await E(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(d(e)){await j.copyFile(o,n);return}if(e.kind===`simulator`){await He(e,o,n);return}throw new t(`COMMAND_FAILED`,`Unsupported Apple screenshot target`)}async function He(e,n,r){let i=h.fromTimeoutMs(w),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 de){let o=await z(e,[`get_app_container`,e.id,t,`data`],{allowFailure:!0,timeoutMs:Ue(i,w,`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 Ge(e,t))try{return await j.copyFile(i,n),{copied:!0}}catch(e){r=e instanceof Error?e.message:String(e)}return{copied:!1,error:r}}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 r=b(n);f({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:`runner`,...r}})}function W(e,t,n){f({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...b(n)}})}function Ge(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=C(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 Ke(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=C(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 qe(e,t,n){let r=await Je(e),i=ue(await le(t),r,n);i&&await ce(t,i.width,i.height)}async function Je(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:ge}),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 Ye(e,t){let n=await v(ie(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 oe(`plutil`,[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,`${r}/Info.plist`],{allowFailure:!0});if(i.exitCode!==0||!i.stdout.trim())return{installed:!0};let a=await oe(`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 Xe(e){return e.installed?e.simulatorCompatible===!1?`ARCH_MISMATCH`:`PERSISTENT_LAUNCH_FAIL`:`APP_NOT_INSTALLED`}function Ze(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 Qe(e,n,r){let i=r?.launchConsole?.trim(),a=r?.launchArgs;if(i&&(!u(e)||e.kind!==`simulator`))throw new t(`UNSUPPORTED_OPERATION`,o);if(d(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 we(e,n,r);return}let f=r?.url?.trim();if(f){if(i)throw new t(`INVALID_ARGS`,l);if(!c(f))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(e.kind===`simulator`){let t=!!a||ee(f);if(r?.terminateRunningApp||t){let i=r?.appBundleId??await k(e,n);t?await Z(e,i,{...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}}):await X(e,i)}await J(e,f,void 0);return}let o=s(r?.appBundleId??await k(e,n),f);if(!o)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,o,{payloadUrl:f,launchArgs:a,runnerOptions:r?.runnerOptions});return}let p=n.trim();if(c(p)){if(i)throw new t(`INVALID_ARGS`,l);if(e.kind===`simulator`){await J(e,p,a);return}let n=s(r?.appBundleId,p);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:p,launchArgs:a,runnerOptions:r?.runnerOptions});return}let m=r?.appBundleId??await k(e,n);if(e.kind===`simulator`){await Z(e,m,{...i?{launchConsole:i}:{},...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}});return}await Q(e,m,{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 O(e),await y(e,[`openurl`,e.id,n])}async function $e(e){d(e)||e.kind===`simulator`&&await _e(e)!==`Booted`&&await O(e)}async function Y(e,t,n){if(d(e)){await Se(e,t);return}let r=await k(e,t);if(e.kind===`simulator`){await X(e,r);return}await x(e).terminateApp(e,r,{runnerOptions:n,runRunnerCommand:E})}async function X(e,n){await O(e);let r=S(e,[`terminate`,e.id,n]),i=await v(r,{allowFailure:!0,timeoutMs:me});if(i.exitCode!==0&&!i.stderr.toLowerCase().includes(`found nothing to terminate`))throw new t(`COMMAND_FAILED`,`xcrun exited with code ${i.exitCode}`,p(i,{cmd:`xcrun`,args:r}))}async function Z(e,n,r){await O(e);let i=0,a=h.fromTimeoutMs(T);try{await te(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`App launch deadline exceeded`,{timeoutMs:T});let a=S(e,et(e.id,n,r)),o=r?.launchConsole?await tt(a,r.launchConsole):await v(a,{allowFailure:!0});if(o.exitCode!==0)throw new t(`COMMAND_FAILED`,`xcrun exited with code ${o.exitCode}`,p(o,{cmd:`xcrun`,args:a}))},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry(e){return K(e)?(i+=1,i<3):!1}},{deadline:a})}catch(t){if(K(t)){let r=t,i=Xe(await Ye(e,n));r.details={...r.details,hint:Ze(i)}}throw t}}function et(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 tt(e,n){await j.mkdir(A.dirname(n),{recursive:!0});try{let t=await v(e,{allowFailure:!0,timeoutMs:q});return await nt(n,t.stdout,t.stderr),t}catch(e){let r=(e instanceof t?e:void 0)?.details;if(r?.timeoutMs===q){let e=typeof r.stdout==`string`?r.stdout:``,t=typeof r.stderr==`string`?r.stderr:``;return await nt(n,e,t),f({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 nt(e,t,n){await j.writeFile(e,rt(t,n),`utf8`)}function rt(e,t){return!e||!t||e.endsWith(`
3
- `)||e.endsWith(`\r`)?`${e}${t}`:`${e}\n${t}`}async function Q(e,t,n){await x(e).launchApp(e,t,{...n,runRunnerCommand:E})}async function it(e){return d(e)?await ye():(D(e,`clipboard`),await O(e),m(await y(e,[`pbpaste`,e.id],{allowFailure:!0}),`Failed to read iOS simulator clipboard`).stdout.replace(/\r\n/g,`
4
- `).replace(/\n$/,``))}async function at(e,t){if(d(e)){await Te(t);return}D(e,`clipboard`),await O(e),m(await y(e,[`pbcopy`,e.id],{allowFailure:!0,stdin:t}),`Failed to write iOS simulator clipboard`)}let $=null,ot;async function st(e,r,o,s,c){if(d(e)){let e=r.toLowerCase();if(e===`appearance`){await be(o);return}if(e===`permission`){let e=a(o);if(e===`deny`)throw new t(`INVALID_ARGS`,n(`permission`));return await se(e,lt(c?.permissionTarget))}throw new t(`INVALID_ARGS`,n(r))}D(e,`settings`),await O(e);let l=r.toLowerCase();switch(l){case`clear-app-state`:{if(o.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!s)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await ct(e,s);return{bundleId:n.bundleId,containerPath:n.containerPath,cleared:!0}}case`wifi`:{let t=g(o)?`active`:`failed`;await y(e,[`status_bar`,e.id,`override`,`--wifiMode`,t]),P(e);return}case`airplane`:g(o)?(await y(e,[`status_bar`,e.id,`override`,`--dataNetwork`,`hide`,`--wifiMode`,`failed`,`--wifiBars`,`0`,`--cellularMode`,`failed`,`--cellularBars`,`0`,`--operatorName`,``]),P(e)):(await y(e,[`status_bar`,e.id,`clear`]),F(e));return;case`location`:{if(o.toLowerCase()===`set`){let{latitude:t,longitude:n}=i(c);return await y(e,[`location`,e.id,`set`,`${t},${n}`]),{latitude:t,longitude:n}}let n=g(o);if(!s)throw new t(`INVALID_ARGS`,`location setting requires an active app in session`);let r=n?`grant`:`revoke`;await y(e,[`privacy`,e.id,r,`location`,s]);return}case`faceid`:case`touchid`:{let t=l,n=ft[t];await bt(e,yt(o,t),{settingName:t,label:n.label,modalityAliases:n.modalityAliases});return}case`appearance`:{let t=await ut(e,o);await y(e,[`ui`,e.id,`appearance`,t]);return}case`permission`:if(!s)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);await mt(e,pt(a(o)),vt(c?.permissionTarget,c?.permissionMode),s);return;default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${r}`)}}async function ct(e,n){if(!u(e)||e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Clearing app state is currently supported only on iOS simulators.`);let r=await k(e,n);await O(e),await Y(e,r);let i=m(await y(e,[`get_app_container`,e.id,r,`data`],{allowFailure:!0}),`simctl get_app_container failed for ${r}`).stdout.trim();if(!i)throw new t(`COMMAND_FAILED`,`simctl get_app_container returned an empty data container path for ${r}`);let a=await j.readdir(i);return await Promise.all(a.map(e=>j.rm(A.join(i,e),{recursive:!0,force:!0}))),{bundleId:r,containerPath:i}}function lt(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 ut(e,n){let r=re(n);if(r!==`toggle`)return r;let i=m(await y(e,[`ui`,e.id,`appearance`],{allowFailure:!0}),`Failed to read current iOS appearance`),a=dt(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current iOS appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`dark`?`light`:`dark`}function dt(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 ft={faceid:{label:`Face ID`,modalityAliases:[`face`]},touchid:{label:`Touch ID`,modalityAliases:[`finger`,`touch`]}};function pt(e){return e===`deny`?`revoke`:e}async function mt(e,n,r,i){let a=await gt(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 y(e,o);return}catch(n){throw s&&ht(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 y(e,o);return}catch(e){if(!ht(e))throw e}try{await y(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 ht(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 gt(e){let n=ae(e.simulatorSetPath),r=`${process.env.PATH??``}::${n??``}`;if($&&ot===r)return $;let i=await y(e,[`privacy`,`help`],{allowFailure:!0}),a=_t(`${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,ot=r,a}function _t(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 vt(e,n){let i=r(e);if(i!==`photos`&&n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(i===`camera`)return`camera`;if(i===`microphone`)return`microphone`;if(i===`contacts`)return`contacts`;if(i===`contacts-limited`)return`contacts-limited`;if(i===`notifications`)return`notifications`;if(i===`calendar`)return`calendar`;if(i===`location`)return`location`;if(i===`location-always`)return`location-always`;if(i===`media-library`)return`media-library`;if(i===`motion`)return`motion`;if(i===`reminders`)return`reminders`;if(i===`siri`)return`siri`;if(i===`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 yt(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 bt(e,n,r){let i=xt(e.id,n,r.modalityAliases),a=[];for(let t of i){let n=S(e,t),r=await v(n,{allowFailure:!0});if(r.exitCode===0)return;a.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let o=ne(a);throw a.length>0&&a.every(e=>St(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 xt(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 St(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 Ct=e({findIosSimulatorInstalledApp:()=>xe,listIosApps:()=>Ce,resolveIosApp:()=>k,resolveIosSimulatorDeepLinkBundleId:()=>ve});export{Y as a,H as c,at as i,ze as l,st as n,Qe as o,it as r,$e as s,Ct as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{a as n,c as r,n as i,s as a}from"./location-coordinates.js";import{J as o,K as s,X as c,Y as l,q as u}from"./sdk-batch-runner.js";import{c as d,l as f}from"./sdk-device.js";import"./observability.js";import{A as p,f as m,h}from"./sdk-android-adb.js";import{i as g,o as ee}from"./boot-diagnostics.js";import{n as te,t as _}from"./setting-state.js";import{t as ne}from"./appearance.js";import{n as re,r as ie,s as ae}from"./simctl.js";import{t as oe}from"./png-resize.js";import{i as se,n as ce}from"./screenshot-density.js";import{a as v,i as y}from"./tool-provider.js";import{a as b,i as x,l as le,n as S,o as C,r as w}from"./physical-device-control.js";import{a as T,c as ue,d as de,f as fe,l as pe,t as E,u as me}from"./config.js";import{n as D}from"./runner-client.js";import{n as he,r as O,t as k}from"./simulator.js";import{i as ge}from"./helper.js";import{a as _e,c as ve,i as A,l as ye,n as be,o as xe,r as Se,s as Ce,u as we}from"./app-resolution.js";import j from"node:path";import{promises as M}from"node:fs";import"node:os";const Te=[`--time`,`9:41`,`--dataNetwork`,`wifi`,`--wifiMode`,`active`,`--wifiBars`,`3`,`--batteryState`,`charged`,`--batteryLevel`,`100`],Ee={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`},De={1:`searching`,2:`failed`,3:`active`},Oe={0:`notSupported`,1:`searching`,2:`failed`,3:`active`};function N(e,t,n){return ie(e,t,n)}const P=new Set;async function ke(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 Pe(e),await L(e,Te)}catch(t){R(e,`prepare_failed`,t)}return async()=>{await Ae(e,n?t:null)}}async function Ae(e,t){if(await Pe(e),!t){je(e);return}await L(e,Ie(t)),F(e)}function F(e){P.delete(I(e))}function je(e){P.add(I(e))}function Me(e){return P.has(I(e))}function I(e){return`${e.platform}:${e.kind}:${e.id}`}async function Ne(e){return Fe(h(await N(e,[`status_bar`,e.id,`list`],{allowFailure:!0}),`Failed to read simulator status bar overrides`).stdout)}async function Pe(e){await N(e,[`status_bar`,e.id,`clear`])}async function L(e,t){t.length!==0&&await N(e,[`status_bar`,e.id,`override`,...t])}function Fe(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=Ee[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=De[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=Oe[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 Ie(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||Le(e.dataNetwork)||e.operatorName!==void 0)&&t.push(`--cellularBars`,e.cellularBars),e.operatorName!==void 0&&t.push(`--operatorName`,e.operatorName),t}function Le(e){return!!(e&&e!==`hide`&&e!==`wifi`)}function R(e,t,n){p({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...x(n)}})}function z(e,t,n){return ie(e,t,n)}const Re={ensureBooted:k,prepareStatusBarForScreenshot:ke,captureWithRetry:Ve,normalizeDensity:qe,captureWithRunner:H,shouldFallbackToRunner:G},B=new Map,V=new Map;async function ze(e,t,n={}){if(f(e)){await H(e,t,n.appBundleId,n.fullscreen,n.runnerOptions);return}if(e.kind===`simulator`){await Be(e,t,n);return}await S(e).captureScreenshot(e,t,{appBundleId:n.appBundleId,fullscreen:n.fullscreen,runnerOptions:n.runnerOptions,runRunnerCommand:D})}async function Be(e,n,r={}){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Simulator screenshot fallback flow supports only iOS simulators`);let i={...Re,...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&&Ke(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=>W(e,`restore_failed`,t))}}async function Ve(e,t){let n=g.fromTimeoutMs(de);await ee(async({deadline:n})=>{await z(e,[`io`,e.id,`screenshot`,t],{timeoutMs:Math.max(1e3,n?.remainingMs()??2e4)})},{maxAttempts:5,baseDelayMs:ue,maxDelayMs:pe,jitter:.2,shouldRetry:e=>G(e)},{deadline:n,phase:`ios_simulator_screenshot`})}async function H(e,n,r,i,a){if(e.kind===`device`&&!f(e)){await S(e).captureScreenshot(e,n,{appBundleId:r,fullscreen:i,runnerOptions:a,preferRunner:!0,runRunnerCommand:D});return}let o=(await D(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(f(e)){await M.copyFile(o,n);return}if(e.kind===`simulator`){await He(e,o,n);return}throw new t(`COMMAND_FAILED`,`Unsupported Apple screenshot target`)}async function He(e,n,r){let i=g.fromTimeoutMs(T),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 le){let o=await z(e,[`get_app_container`,e.id,t,`data`],{allowFailure:!0,timeoutMs:Ue(i,T,`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 Ge(e,t))try{return await M.copyFile(i,n),{copied:!0}}catch(e){r=e instanceof Error?e.message:String(e)}return{copied:!1,error:r}}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 r=x(n);p({level:`warn`,phase:`ios_screenshot_fallback`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,from:t,to:`runner`,...r}})}function W(e,t,n){p({level:`warn`,phase:`ios_screenshot_status_bar_${t}`,data:{platform:e.platform,deviceKind:e.kind,deviceId:e.id,...x(n)}})}function Ge(e,t){let n=j.resolve(e),r=t.trim();if(!r)return[];let i=[],a=new Set,o=e=>{let t=j.normalize(e);a.has(t)||(a.add(t),i.push(t))},s=r.replace(/^\/+/,``),c=s.replace(/\\/g,`/`);if(s&&o(j.join(n,s)),j.isAbsolute(r)&&o(j.normalize(r)),c.startsWith(`tmp/`))o(j.join(n,c));else{let e=c.lastIndexOf(`/tmp/`);if(e>=0){let t=c.slice(e+1);o(j.join(n,t))}}let l=j.basename(r);return l&&o(j.join(n,`tmp`,l)),i}function G(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=w(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 Ke(e){if(!(e instanceof t)||e.code!==`COMMAND_FAILED`)return!1;let n=w(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 qe(e,t,n){let r=await Je(e),i=ce(await se(t),r,n);i&&await oe(t,i.width,i.height)}async function Je(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:me}),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 Ye(e,t){let n=await v(re(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 y(`plutil`,[`-extract`,`CFBundleExecutable`,`raw`,`-o`,`-`,`${r}/Info.plist`],{allowFailure:!0});if(i.exitCode!==0||!i.stdout.trim())return{installed:!0};let a=await y(`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 Xe(e){return e.installed?e.simulatorCompatible===!1?`ARCH_MISMATCH`:`PERSISTENT_LAUNCH_FAIL`:`APP_NOT_INSTALLED`}function Ze(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 Qe(e,n,r){let i=r?.launchConsole?.trim(),a=r?.launchArgs;if(i&&(!d(e)||e.kind!==`simulator`))throw new t(`UNSUPPORTED_OPERATION`,u);if(f(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 Ce(e,n,r);return}let p=r?.url?.trim();if(p){if(i)throw new t(`INVALID_ARGS`,s);if(!o(p))throw new t(`INVALID_ARGS`,`open <app> <url> requires a valid URL target`);if(e.kind===`simulator`){let t=!!a||l(p);if(r?.terminateRunningApp||t){let i=r?.appBundleId??await A(e,n);t?await Z(e,i,{...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}}):await X(e,i)}await J(e,p,void 0);return}let u=c(r?.appBundleId??await A(e,n),p);if(!u)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,u,{payloadUrl:p,launchArgs:a,runnerOptions:r?.runnerOptions});return}let m=n.trim();if(o(m)){if(i)throw new t(`INVALID_ARGS`,s);if(e.kind===`simulator`){await J(e,m,a);return}let n=c(r?.appBundleId,m);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:m,launchArgs:a,runnerOptions:r?.runnerOptions});return}let h=r?.appBundleId??await A(e,n);if(e.kind===`simulator`){await Z(e,h,{...i?{launchConsole:i}:{},...a?{launchArgs:a}:{},...r?.terminateRunningApp?{terminateRunningApp:!0}:{}});return}await Q(e,h,{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 k(e),await b(e,[`openurl`,e.id,n])}async function $e(e){f(e)||e.kind===`simulator`&&await he(e)!==`Booted`&&await k(e)}async function Y(e,t,n){if(f(e)){await xe(e,t);return}let r=await A(e,t);if(e.kind===`simulator`){await X(e,r);return}await S(e).terminateApp(e,r,{runnerOptions:n,runRunnerCommand:D})}async function X(e,n){await k(e);let r=C(e,[`terminate`,e.id,n]),i=await v(r,{allowFailure:!0,timeoutMs:fe});if(i.exitCode!==0&&!i.stderr.toLowerCase().includes(`found nothing to terminate`))throw new t(`COMMAND_FAILED`,`xcrun exited with code ${i.exitCode}`,m(i,{cmd:`xcrun`,args:r}))}async function Z(e,n,r){await k(e);let i=0,a=g.fromTimeoutMs(E);try{await ee(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`App launch deadline exceeded`,{timeoutMs:E});let a=C(e,et(e.id,n,r)),o=r?.launchConsole?await tt(a,r.launchConsole):await v(a,{allowFailure:!0});if(o.exitCode!==0)throw new t(`COMMAND_FAILED`,`xcrun exited with code ${o.exitCode}`,m(o,{cmd:`xcrun`,args:a}))},{maxAttempts:10,baseDelayMs:1e3,maxDelayMs:5e3,jitter:.2,shouldRetry(e){return K(e)?(i+=1,i<3):!1}},{deadline:a})}catch(t){if(K(t)){let r=t,i=Xe(await Ye(e,n));r.details={...r.details,hint:Ze(i)}}throw t}}function et(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 tt(e,n){await M.mkdir(j.dirname(n),{recursive:!0});try{let t=await v(e,{allowFailure:!0,timeoutMs:q});return await nt(n,t.stdout,t.stderr),t}catch(e){let r=(e instanceof t?e:void 0)?.details;if(r?.timeoutMs===q){let e=typeof r.stdout==`string`?r.stdout:``,t=typeof r.stderr==`string`?r.stderr:``;return await nt(n,e,t),p({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 nt(e,t,n){await M.writeFile(e,rt(t,n),`utf8`)}function rt(e,t){return!e||!t||e.endsWith(`
3
+ `)||e.endsWith(`\r`)?`${e}${t}`:`${e}\n${t}`}async function Q(e,t,n){await S(e).launchApp(e,t,{...n,runRunnerCommand:D})}async function it(e){return f(e)?await ve():(O(e,`clipboard`),await k(e),h(await b(e,[`pbpaste`,e.id],{allowFailure:!0}),`Failed to read iOS simulator clipboard`).stdout.replace(/\r\n/g,`
4
+ `).replace(/\n$/,``))}async function at(e,t){if(f(e)){await we(t);return}O(e,`clipboard`),await k(e),h(await b(e,[`pbcopy`,e.id],{allowFailure:!0,stdin:t}),`Failed to write iOS simulator clipboard`)}let $=null,ot;async function st(e,r,o,s,c){if(f(e)){let e=r.toLowerCase();if(e===`appearance`){await ye(o);return}if(e===`permission`){let e=a(o);if(e===`deny`)throw new t(`INVALID_ARGS`,n(`permission`));return await ge(e,lt(c?.permissionTarget))}throw new t(`INVALID_ARGS`,n(r))}O(e,`settings`),await k(e);let l=r.toLowerCase();switch(l){case`clear-app-state`:{if(o.toLowerCase()!==`clear`)throw new t(`INVALID_ARGS`,`settings clear-app-state only supports clear.`);if(!s)throw new t(`INVALID_ARGS`,`settings clear-app-state requires an app id or an active app session.`);let n=await ct(e,s);return{bundleId:n.bundleId,containerPath:n.containerPath,cleared:!0}}case`wifi`:{let t=_(o)?`active`:`failed`;await b(e,[`status_bar`,e.id,`override`,`--wifiMode`,t]),F(e);return}case`airplane`:_(o)?(await b(e,[`status_bar`,e.id,`override`,`--dataNetwork`,`hide`,`--wifiMode`,`failed`,`--wifiBars`,`0`,`--cellularMode`,`failed`,`--cellularBars`,`0`,`--operatorName`,``]),F(e)):(await b(e,[`status_bar`,e.id,`clear`]),je(e));return;case`location`:{if(o.toLowerCase()===`set`){let{latitude:t,longitude:n}=i(c);return await b(e,[`location`,e.id,`set`,`${t},${n}`]),{latitude:t,longitude:n}}let n=_(o);if(!s)throw new t(`INVALID_ARGS`,`location setting requires an active app in session`);let r=n?`grant`:`revoke`;await b(e,[`privacy`,e.id,r,`location`,s]);return}case`faceid`:case`touchid`:{let t=l,n=ft[t];await bt(e,yt(o,t),{settingName:t,label:n.label,modalityAliases:n.modalityAliases});return}case`appearance`:{let t=await ut(e,o);await b(e,[`ui`,e.id,`appearance`,t]);return}case`permission`:if(!s)throw new t(`INVALID_ARGS`,`permission setting requires an active app in session`);await mt(e,pt(a(o)),vt(c?.permissionTarget,c?.permissionMode),s);return;default:throw new t(`INVALID_ARGS`,`Unsupported setting: ${r}`)}}async function ct(e,n){if(!d(e)||e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`Clearing app state is currently supported only on iOS simulators.`);let r=await A(e,n);await k(e),await Y(e,r);let i=h(await b(e,[`get_app_container`,e.id,r,`data`],{allowFailure:!0}),`simctl get_app_container failed for ${r}`).stdout.trim();if(!i)throw new t(`COMMAND_FAILED`,`simctl get_app_container returned an empty data container path for ${r}`);let a=await M.readdir(i);return await Promise.all(a.map(e=>M.rm(j.join(i,e),{recursive:!0,force:!0}))),{bundleId:r,containerPath:i}}function lt(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 ut(e,n){let r=ne(n);if(r!==`toggle`)return r;let i=h(await b(e,[`ui`,e.id,`appearance`],{allowFailure:!0}),`Failed to read current iOS appearance`),a=dt(i.stdout,i.stderr);if(!a)throw new t(`COMMAND_FAILED`,`Unable to determine current iOS appearance for toggle`,{stdout:i.stdout,stderr:i.stderr});return a===`dark`?`light`:`dark`}function dt(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 ft={faceid:{label:`Face ID`,modalityAliases:[`face`]},touchid:{label:`Touch ID`,modalityAliases:[`finger`,`touch`]}};function pt(e){return e===`deny`?`revoke`:e}async function mt(e,n,r,i){let a=await gt(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 b(e,o);return}catch(n){throw s&&ht(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 b(e,o);return}catch(e){if(!ht(e))throw e}try{await b(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 ht(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 gt(e){let n=ae(e.simulatorSetPath),r=`${process.env.PATH??``}::${n??``}`;if($&&ot===r)return $;let i=await b(e,[`privacy`,`help`],{allowFailure:!0}),a=_t(`${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,ot=r,a}function _t(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 vt(e,n){let i=r(e);if(i!==`photos`&&n?.trim())throw new t(`INVALID_ARGS`,`Permission mode is only supported for photos. Received: ${n}.`);if(i===`camera`)return`camera`;if(i===`microphone`)return`microphone`;if(i===`contacts`)return`contacts`;if(i===`contacts-limited`)return`contacts-limited`;if(i===`notifications`)return`notifications`;if(i===`calendar`)return`calendar`;if(i===`location`)return`location`;if(i===`location-always`)return`location-always`;if(i===`media-library`)return`media-library`;if(i===`motion`)return`motion`;if(i===`reminders`)return`reminders`;if(i===`siri`)return`siri`;if(i===`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 yt(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 bt(e,n,r){let i=xt(e.id,n,r.modalityAliases),a=[];for(let t of i){let n=C(e,t),r=await v(n,{allowFailure:!0});if(r.exitCode===0)return;a.push({args:n,stderr:r.stderr,stdout:r.stdout,exitCode:r.exitCode})}let o=te(a);throw a.length>0&&a.every(e=>St(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 xt(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 St(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 Ct=e({findIosSimulatorInstalledApp:()=>be,listIosApps:()=>Se,resolveIosApp:()=>A,resolveIosSimulatorDeepLinkBundleId:()=>_e});export{Y as a,H as c,at as i,ze as l,st as n,Qe as o,it as r,$e as s,Ct as t};
@@ -1 +1 @@
1
- import{c as e}from"./sdk-device.js";import{s as t}from"./helper.js";const n={platform:`host-system-audio`,source:`system-audio`,backend:`macos-screencapturekit`,sourceCount:1,start:t,notes:r};function r(t){return[`Audio probe samples host system audio through ScreenCaptureKit for this ${e(t)?`iOS simulator`:t.platform===`android`?`Android emulator`:`macOS session`}; it is not app-instrumented audio.`,`Screen Recording permission is required for host system audio capture.`,`Other audible host apps can contribute to the measured buckets.`]}export{n as macOsScreenCaptureKitAudioProbeBackend};
1
+ import{c as e}from"./sdk-device.js";import{o as t}from"./helper.js";const n={platform:`host-system-audio`,source:`system-audio`,backend:`macos-screencapturekit`,sourceCount:1,start:t,notes:r};function r(t){return[`Audio probe samples host system audio through ScreenCaptureKit for this ${e(t)?`iOS simulator`:t.platform===`android`?`Android emulator`:`macOS session`}; it is not app-instrumented audio.`,`Screen Recording permission is required for host system audio capture.`,`Other audible host apps can contribute to the measured buckets.`]}export{n as macOsScreenCaptureKitAudioProbeBackend};
@@ -1,2 +1,2 @@
1
- import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n}from"./sdk-contracts.js";import{A as r}from"./sdk-android-adb.js";var i=e({Deadline:()=>s,isEnvTruthy:()=>a,retryWithPolicy:()=>c});function a(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const o={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var s=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 c(e,n={},r={}){let i={maxAttempts:n.maxAttempts??o.maxAttempts,baseDelayMs:n.baseDelayMs??o.baseDelayMs,maxDelayMs:n.maxDelayMs??o.maxDelayMs,jitter:n.jitter??o.jitter,shouldRetry:n.shouldRetry},a;for(let n=1;n<=i.maxAttempts;n+=1){if(r.signal?.aborted)throw new t(`COMMAND_FAILED`,`request canceled`,{reason:`request_canceled`});if(r.deadline?.isExpired()&&n>1)break;try{let t=await e({attempt:n,maxAttempts:i.maxAttempts,deadline:r.deadline});return r.onEvent?.({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),d({phase:r.phase,event:`succeeded`,attempt:n,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs()}),t}catch(e){a=e;let t=r.classifyReason?.(e),o={phase:r.phase,event:`attempt_failed`,attempt:n,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};if(r.onEvent?.(o),d(o),n>=i.maxAttempts||i.shouldRetry&&!i.shouldRetry(e,n))break;let s=l(i.baseDelayMs,i.maxDelayMs,i.jitter,n),c=r.deadline?Math.min(s,r.deadline.remainingMs()):s;if(c<=0)break;let f={phase:r.phase,event:`retry_scheduled`,attempt:n,maxAttempts:i.maxAttempts,delayMs:c,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:t};r.onEvent?.(f),d(f),await u(c,r.signal)}}let s={phase:r.phase,event:`exhausted`,attempt:i.maxAttempts,maxAttempts:i.maxAttempts,elapsedMs:r.deadline?.elapsedMs(),remainingMs:r.deadline?.remainingMs(),reason:r.classifyReason?.(a)};throw r.onEvent?.(s),d(s),a||new t(`COMMAND_FAILED`,`retry failed`)}function l(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 u(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 d(e){r({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}const f=new Set([`IOS_BOOT_TIMEOUT`,`IOS_RUNNER_CONNECT_TIMEOUT`,`IOS_TOOL_MISSING`,`ANDROID_BOOT_TIMEOUT`,`ADB_TRANSPORT_UNAVAILABLE`,`CI_RESOURCE_STARVATION_SUSPECTED`]);function p(e){return f.has(e.toUpperCase())}function m(e){let t=e.error?n(e.error):null,r=e.context?.platform,i=e.context?.phase;if(t?.code===`TOOL_MISSING`)return r===`android`?`ADB_TRANSPORT_UNAVAILABLE`:`IOS_TOOL_MISSING`;let a=t?.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,t?.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(`0xe8008012`)?`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:r===`ios`&&(d.includes(`provisioning profile`)||d.includes(`embedded profile`))?`BOOT_COMMAND_FAILED`: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`:t?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function h(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`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:return`The XCTest runner cannot be installed on this device: its provisioning profile does not cover it. Register the device with the signing team (Xcode > Settings > Accounts, or add its UDID to the provisioning profile) and retry. Retrying without that will keep failing.`;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{a,s as i,m as n,c as o,p as r,i as s,h as t};
1
+ import{n as e}from"./rolldown-runtime.js";import{_ as t,v as n,y as r}from"./sdk-contracts.js";import{A as i}from"./sdk-android-adb.js";var a=e({Deadline:()=>c,isEnvTruthy:()=>o,retryWithPolicy:()=>l});function o(e){return[`1`,`true`,`yes`,`on`].includes((e??``).trim().toLowerCase())}const s={maxAttempts:3,baseDelayMs:200,maxDelayMs:2e3,jitter:.2};var c=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 l(e,n={},i={}){let a={maxAttempts:n.maxAttempts??s.maxAttempts,baseDelayMs:n.baseDelayMs??s.baseDelayMs,maxDelayMs:n.maxDelayMs??s.maxDelayMs,jitter:n.jitter??s.jitter,shouldRetry:n.shouldRetry},o;for(let t=1;t<=a.maxAttempts;t+=1){if(i.signal?.aborted)throw r();if(i.deadline?.isExpired()&&t>1)break;try{let n=await e({attempt:t,maxAttempts:a.maxAttempts,deadline:i.deadline});return i.onEvent?.({phase:i.phase,event:`succeeded`,attempt:t,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs()}),f({phase:i.phase,event:`succeeded`,attempt:t,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs()}),n}catch(e){o=e;let n=i.classifyReason?.(e),r={phase:i.phase,event:`attempt_failed`,attempt:t,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs(),reason:n};if(i.onEvent?.(r),f(r),t>=a.maxAttempts||a.shouldRetry&&!a.shouldRetry(e,t))break;let s=u(a.baseDelayMs,a.maxDelayMs,a.jitter,t),c=i.deadline?Math.min(s,i.deadline.remainingMs()):s;if(c<=0)break;let l={phase:i.phase,event:`retry_scheduled`,attempt:t,maxAttempts:a.maxAttempts,delayMs:c,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs(),reason:n};i.onEvent?.(l),f(l),await d(c,i.signal)}}let c={phase:i.phase,event:`exhausted`,attempt:a.maxAttempts,maxAttempts:a.maxAttempts,elapsedMs:i.deadline?.elapsedMs(),remainingMs:i.deadline?.remainingMs(),reason:i.classifyReason?.(o)};throw i.onEvent?.(c),f(c),o||new t(`COMMAND_FAILED`,`retry failed`)}function u(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 d(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 f(e){i({level:e.event===`attempt_failed`||e.event===`exhausted`?`warn`:`debug`,phase:`retry`,data:{...e}})}const p=new Set([`IOS_BOOT_TIMEOUT`,`IOS_RUNNER_CONNECT_TIMEOUT`,`IOS_TOOL_MISSING`,`ANDROID_BOOT_TIMEOUT`,`ADB_TRANSPORT_UNAVAILABLE`,`CI_RESOURCE_STARVATION_SUSPECTED`]);function m(e){return p.has(e.toUpperCase())}function h(e){let t=e.error?n(e.error):null,r=e.context?.platform,i=e.context?.phase;if(t?.code===`TOOL_MISSING`)return r===`android`?`ADB_TRANSPORT_UNAVAILABLE`:`IOS_TOOL_MISSING`;let a=t?.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,t?.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(`0xe8008012`)?`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:r===`ios`&&(d.includes(`provisioning profile`)||d.includes(`embedded profile`))?`BOOT_COMMAND_FAILED`: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`:t?.code===`COMMAND_FAILED`||d.length>0?`BOOT_COMMAND_FAILED`:`UNKNOWN`}function g(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`IOS_RUNNER_DEVICE_NOT_PROVISIONED`:return`The XCTest runner cannot be installed on this device: its provisioning profile does not cover it. Register the device with the signing team (Xcode > Settings > Accounts, or add its UDID to the provisioning profile) and retry. Retrying without that will keep failing.`;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{o as a,c as i,h as n,l as o,m as r,a as s,g as t};
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{_ as t}from"./location-coordinates.js";import{i as n}from"./command-catalog.js";import{S as r,d as i,l as a}from"./registry.js";import{D as o,T as s}from"./sdk-android-adb.js";import{n as c,t as l}from"./path-resolution.js";import{r as u}from"./command-schema.js";import d from"node:path";import f from"node:fs";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.configurable&&t.supportsCommand(e))}function b(e,t){return v(e)?.supportsCommand(t)??!1}function x(e,t,n,r){return o(T(e),t,n,r)}function S(){let e=new Map;for(let t of r()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of i)t.set(e,new Set([`*`]));for(let e of n()){let n=u(e);for(let r of[...n.allowedFlags??[],...n.supportedFlags??[]]){let n=t.get(r);n&&n.has(`*`)||(n?n.add(e):t.set(r,new Set([e])))}}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,configurable:!m.has(e),env:{names:h.has(e)?[]:[s(e)]},supportsCommand(n){let r=t.get(e);return r?r.has(`*`)?!0:n?r.has(n):!1:!1}})).sort((e,t)=>C(e.key,t.key))}function C(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===r?e<t?-1:+(e>t):n<r?-1:1}function w(e){let t=e.flagDefinitions[0];if(!t)throw Error(`Missing flag definition for option ${e.key}`);return t}function T(e){let t=e.flagDefinitions.find(e=>e.setValue===void 0);if(t)return t;let n=w(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}function E(e){let t=e.env??process.env;return p(p({},j(O(e.cwd,e.cliFlags.config,t))),F(t,e.command))}const D=new Set(`json.platform.target.device.udid.serial.session.sessionLock.activity.launchArgs.launchUrl.remote.deviceHub.testIme.appsFilter.clean.force.stale.relaunch.shutdown.surface.headless.restart.noRecord.record.recordAs.snapshotInteractiveOnly.snapshotDiff.snapshotDepth.snapshotScope.snapshotRaw.snapshotCustomActions.snapshotForceFull.screenshotPixelDensity.screenshotFullscreen.screenshotScale.screenshotNoStabilize.screenshotNormalizeStatusBar.overlayRefs.networkInclude.baseline.threshold.count.pointerCount.fps.quality.hideTouches.recordingScope.intervalMs.delayMs.durationMs.holdMs.jitterPx.pixels.doubleTap.verify.settle.settleQuietMs.clickButton.backMode.pauseMs.pattern.kind.perfTemplate.responseLevel.verbose.cost.timeoutMs.retries.failFast.recordVideo.replayUpdate.replayMaestro.replayFrom.replayPlanDigest.replayKeepSession.findFirst.findLast.batchOnError.batchMaxSteps.retainPaths.retentionMs.shardAll.shardSplit.noLogin`.split(`.`));function O(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:A(r,e,n),required:!0,source:`explicit`}]:[{path:k(n),required:!1,source:`user`},{path:d.resolve(e,`agent-device.json`),required:!1,source:`project`}]}function k(e){return d.join(l(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return c(e,{cwd:t,env:n})}function j(e){let t={};for(let n of e)p(t,M(n));return t}function M(t){let{path:n,required:r}=t;if(!f.existsSync(n)){if(r)throw new e(`INVALID_ARGS`,`Config file not found: ${n}`);return{}}let i;try{i=f.readFileSync(n,`utf8`)}catch(t){throw new e(`INVALID_ARGS`,`Failed to read config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}let a;try{a=JSON.parse(i)}catch(t){throw new e(`INVALID_ARGS`,`Invalid JSON in config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}if(!a||typeof a!=`object`||Array.isArray(a))throw new e(`INVALID_ARGS`,`Config file must contain a JSON object: ${n}`);return N(a,{source:t.source,label:`${t.source===`project`?`project `:``}config file ${n}`})}function N(n,r){let i={};for(let[o,s]of Object.entries(n)){let n=o,c=v(n);if(!c)throw o===t.flagKey?new e(`INVALID_ARGS`,`Config key "${o}" in ${r.label} was removed; use "screenshotScale" (0.01-1) to downscale screenshots. Recordings capture at native resolution.`):new e(`INVALID_ARGS`,`Unknown config key "${o}" in ${r.label}.`);if(!c.configurable)throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. This key is not supported in config files.`);if(r.source===`project`&&!D.has(n))throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. Move it to ~/.agent-device/config.json, pass it with --config or AGENT_DEVICE_CONFIG, or provide it through CLI flags/environment variables.`);if(n===`installSource`){i.installSource=a(s,r.label);continue}i[n]=x(c,s,r.label,o)}return i}const P=new Set([`screenshot`,`record`]);function F(n,r){let i=n[t.envVar];if(r!==null&&P.has(r)&&typeof i==`string`&&i.trim().length>0)throw new e(`INVALID_ARGS`,`${t.envVar} was removed. ${t.migration[r===`record`?`record`:`screenshot`]}`);let a={};for(let e of y(r)){if(e.key===`installSource`)continue;let t=e.env.names.map(e=>({name:e,value:n[e]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(a[e.key]=x(e,t.value,`environment variable ${t.name}`,t.name))}return a}export{b as n,p as r,E as t};
1
+ import{_ as e}from"./sdk-contracts.js";import{_ as t}from"./location-coordinates.js";import{i as n}from"./command-catalog.js";import{S as r,d as i,l as a}from"./registry.js";import{n as o,t as s}from"./path-resolution.js";import{D as c,T as l}from"./sdk-android-adb.js";import{r as u}from"./command-schema.js";import d from"node:path";import f from"node:fs";const p=new Set([`config`,`remoteConfig`,`help`,`version`,`batchSteps`,`githubActionsArtifact`]),m=new Set([`appsFilter`,`iosSimulatorDeviceSet`]),h=x(),g=new Map(h.map(e=>[e.key,e]));function _(e){return g.get(e)}function v(e){return h.filter(t=>t.configurable&&t.supportsCommand(e))}function y(e,t){return _(e)?.supportsCommand(t)??!1}function b(e,t,n,r){return c(w(e),t,n,r)}function x(){let e=new Map;for(let t of r()){let n=e.get(t.key);n?n.push(t):e.set(t.key,[t])}let t=new Map;for(let e of i)t.set(e,new Set([`*`]));for(let e of n()){let n=u(e);for(let r of[...n.allowedFlags??[],...n.supportedFlags??[]]){let n=t.get(r);n&&n.has(`*`)||(n?n.add(e):t.set(r,new Set([e])))}}return[...e.entries()].map(([e,n])=>({key:e,flagDefinitions:n,configurable:!p.has(e),env:{names:m.has(e)?[]:[l(e)]},supportsCommand(n){let r=t.get(e);return r?r.has(`*`)?!0:n?r.has(n):!1:!1}})).sort((e,t)=>S(e.key,t.key))}function S(e,t){let n=e.toLowerCase(),r=t.toLowerCase();return n===r?e<t?-1:+(e>t):n<r?-1:1}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}function T(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}function E(e){let t=e.env??process.env;return T(T({},j(O(e.cwd,e.cliFlags.config,t))),F(t,e.command))}const D=new Set(`json.platform.target.device.udid.serial.session.sessionLock.activity.launchArgs.launchUrl.remote.deviceHub.testIme.appsFilter.clean.force.stale.relaunch.shutdown.surface.headless.restart.noRecord.record.recordAs.snapshotInteractiveOnly.snapshotDiff.snapshotDepth.snapshotScope.snapshotRaw.snapshotCustomActions.snapshotForceFull.screenshotPixelDensity.screenshotFullscreen.screenshotScale.screenshotNoStabilize.screenshotNormalizeStatusBar.overlayRefs.networkInclude.baseline.threshold.count.pointerCount.fps.quality.hideTouches.recordingScope.intervalMs.delayMs.durationMs.holdMs.jitterPx.pixels.doubleTap.verify.settle.settleQuietMs.clickButton.backMode.pauseMs.pattern.kind.perfTemplate.responseLevel.verbose.cost.timeoutMs.retries.failFast.recordVideo.replayUpdate.replayMaestro.replayFrom.replayPlanDigest.replayKeepSession.findFirst.findLast.batchOnError.batchMaxSteps.retainPaths.retentionMs.shardAll.shardSplit.noLogin`.split(`.`));function O(e,t,n){let r=t??n.AGENT_DEVICE_CONFIG;return r?[{path:A(r,e,n),required:!0,source:`explicit`}]:[{path:k(n),required:!1,source:`user`},{path:d.resolve(e,`agent-device.json`),required:!1,source:`project`}]}function k(e){return d.join(s(`~`,{env:e}),`.agent-device`,`config.json`)}function A(e,t,n){return o(e,{cwd:t,env:n})}function j(e){let t={};for(let n of e)T(t,M(n));return t}function M(t){let{path:n,required:r}=t;if(!f.existsSync(n)){if(r)throw new e(`INVALID_ARGS`,`Config file not found: ${n}`);return{}}let i;try{i=f.readFileSync(n,`utf8`)}catch(t){throw new e(`INVALID_ARGS`,`Failed to read config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}let a;try{a=JSON.parse(i)}catch(t){throw new e(`INVALID_ARGS`,`Invalid JSON in config file: ${n}`,{cause:t instanceof Error?t.message:String(t)})}if(!a||typeof a!=`object`||Array.isArray(a))throw new e(`INVALID_ARGS`,`Config file must contain a JSON object: ${n}`);return N(a,{source:t.source,label:`${t.source===`project`?`project `:``}config file ${n}`})}function N(n,r){let i={};for(let[o,s]of Object.entries(n)){let n=o,c=_(n);if(!c)throw o===t.flagKey?new e(`INVALID_ARGS`,`Config key "${o}" in ${r.label} was removed; use "screenshotScale" (0.01-1) to downscale screenshots. Recordings capture at native resolution.`):new e(`INVALID_ARGS`,`Unknown config key "${o}" in ${r.label}.`);if(!c.configurable)throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. This key is not supported in config files.`);if(r.source===`project`&&!D.has(n))throw new e(`INVALID_ARGS`,`Config key "${o}" is not allowed in ${r.label}. Move it to ~/.agent-device/config.json, pass it with --config or AGENT_DEVICE_CONFIG, or provide it through CLI flags/environment variables.`);if(n===`installSource`){i.installSource=a(s,r.label);continue}i[n]=b(c,s,r.label,o)}return i}const P=new Set([`screenshot`,`record`]);function F(n,r){let i=n[t.envVar];if(r!==null&&P.has(r)&&typeof i==`string`&&i.trim().length>0)throw new e(`INVALID_ARGS`,`${t.envVar} was removed. ${t.migration[r===`record`?`record`:`screenshot`]}`);let a={};for(let e of v(r)){if(e.key===`installSource`)continue;let t=e.env.names.map(e=>({name:e,value:n[e]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);t&&(a[e.key]=b(e,t.value,`environment variable ${t.name}`,t.name))}return a}export{T as n,y as r,E as t};
@@ -1,8 +1,8 @@
1
- import{Yn as e}from"./sdk-batch-runner.js";import{i as t}from"./command-catalog.js";import{S as n,d as r,m as i}from"./registry.js";import{n as a}from"./version.js";import{i as o,r as s}from"./command-schema.js";const c=[`Flows: launchApp; runFlow file/inline with platform, visibility, and limited boolean conditions; onFlowStart/onFlowComplete; repeat.times and retry.`,`Interactions: tapOn, doubleTapOn, longPressOn, inputText, eraseText, openLink, hideKeyboard, basic pressKey, and back; targets support index, childOf, label, points, and optional.`,`Assertions and navigation: assertVisible, assertNotVisible, extendedWaitUntil, scroll, scrollUntilVisible, absolute/percentage/target swipe, takeScreenshot, waitForAnimationToEnd, and stopApp.`,`Scripts: ordered runScript file/env scripts with http.post, json, and output variables.`],l=[`Runtime: iOS and Android only; launchApp.clearState supports Android and iOS simulators, launch arguments are Apple-only, and standalone device utility/state commands are unsupported.`,`Expressions: when.true supports boolean literals and maestro.platform comparisons; repeat.while, evalScript, and broader JavaScript expressions are unsupported.`,`Environment: flow env is the default, AD_VAR_* overrides it, and CLI -e KEY=VALUE wins over both.`,`Failure diagnostics: resolved targets and runFlow paths are rendered, while inputText payloads remain hidden; do not place secrets in diagnostic identifiers.`,`Trust: runScript executes trusted scripts, may make http.post network requests, and is not a security sandbox; output keys cannot contain a dot.`,`Errors and tracking: unsupported commands and fields fail with source context when available; open a focused issue only when implementation work is planned.`];function u(){return[`Supported subset:`,...c.map(e=>` - ${e}`),``,`Boundaries:`,...l.map(e=>` - ${e}`)].join(`
2
- `)}function d(e){let t=e.endsWith(`?`),n=t?e.slice(0,-1):e;return t?`[${n}]`:`<${n}>`}function f(e){return n().filter(t=>t.key===e)}function p(e,t){if(t.usageOverride)return t.usageOverride;let n=(t.positionalArgs??[]).map(d),r=(t.allowedFlags??[]).flatMap(e=>f(e).map(e=>e.usageLabel??e.names[0])).map(e=>`[${e}]`);return[e,...n,...r].join(` `)}function m(){return`agent-device <command> [args] [--json]
1
+ import{n as e}from"./rolldown-runtime.js";import{rr as t}from"./sdk-batch-runner.js";import{i as n}from"./command-catalog.js";import{S as r,d as i,m as a}from"./registry.js";import{n as o}from"./version.js";import{i as s,r as c}from"./command-schema.js";const l=[`Flows: launchApp; runFlow file/inline with platform, visibility, and limited boolean conditions; onFlowStart/onFlowComplete; repeat.times and retry.`,`Interactions: tapOn, doubleTapOn, longPressOn, inputText, eraseText, openLink, hideKeyboard, basic pressKey, and back; targets support index, childOf, label, points, and optional.`,`Assertions and navigation: assertVisible, assertNotVisible, extendedWaitUntil, scroll, scrollUntilVisible, absolute/percentage/target swipe, takeScreenshot, waitForAnimationToEnd, and stopApp.`,`Scripts: ordered runScript file/env scripts with http.post, json, and output variables.`],u=[`Runtime: iOS and Android only; launchApp.clearState supports Android and iOS simulators, launch arguments are Apple-only, and standalone device utility/state commands are unsupported.`,`Expressions: when.true supports boolean literals and maestro.platform comparisons; repeat.while, evalScript, and broader JavaScript expressions are unsupported.`,`Environment: flow env is the default, AD_VAR_* overrides it, and CLI -e KEY=VALUE wins over both.`,`Failure diagnostics: resolved targets and runFlow paths are rendered, while inputText payloads remain hidden; do not place secrets in diagnostic identifiers.`,`Trust: runScript executes trusted scripts, may make http.post network requests, and is not a security sandbox; output keys cannot contain a dot.`,`Errors and tracking: unsupported commands and fields fail with source context when available; open a focused issue only when implementation work is planned.`];function d(){return[`Supported subset:`,...l.map(e=>` - ${e}`),``,`Boundaries:`,...u.map(e=>` - ${e}`)].join(`
2
+ `)}function f(e){let t=e.endsWith(`?`),n=t?e.slice(0,-1):e;return t?`[${n}]`:`<${n}>`}function p(e){return r().filter(t=>t.key===e)}function m(e,t){if(t.usageOverride)return t.usageOverride;let n=(t.positionalArgs??[]).map(f),r=(t.allowedFlags??[]).flatMap(e=>p(e).map(e=>e.usageLabel??e.names[0])).map(e=>`[${e}]`);return[e,...n,...r].join(` `)}function h(){return`agent-device <command> [args] [--json]
3
3
 
4
4
  Automates iOS, Android, macOS, TV, and web apps for AI agents.
5
- All ${t().length} commands: agent-device help commands
5
+ All ${n().length} commands: agent-device help commands
6
6
 
7
7
  Start:
8
8
  When starting a task with a known app, first run:
@@ -14,6 +14,7 @@ Start:
14
14
 
15
15
  Loop:
16
16
  press|click|fill|longpress <target> ... --settle
17
+ hover <target> --settle (web only; reveals hover-gated UI)
17
18
  scroll <direction|top|bottom> [amount] --settle; back --settle
18
19
  acts, waits for quiet, and prints the UI diff. Continue from that diff.
19
20
  Run snapshot -i only when the diff lacks the next target or did not settle.
@@ -24,13 +25,13 @@ Loop:
24
25
  Targets:
25
26
  Copy refs exactly: @e12, @e12~s4. Keep @ and any ~sN pin; refs go stale
26
27
  after mutations. A literal @handle is label="@handle", not a bare ref.
27
- Prefer refs, then id/label/role selectors. Selector keys: ${e.join(` `)}.
28
+ Prefer refs, then id/label/role selectors. Selector keys: ${t.join(` `)}.
28
29
  Coordinates are last resort: after snapshot -i shows no semantic target, or a
29
30
  sparse/AX-unavailable warning says its refs and selectors are invalid.
30
31
  Then screenshot, press <x> <y>, and re-snapshot on the changed screen.
31
32
 
32
33
  Rules:
33
- --settle is only for press/click/fill/longpress/scroll/back; never open,
34
+ --settle is only for press/click/fill/longpress/hover/scroll/back; never open,
34
35
  snapshot, or close. type never accepts --settle.
35
36
  fill <target> <text> --settle replaces; type <text> appends after focus.
36
37
  Late network/debounce result: wait text "Expected", not snapshot polling.
@@ -48,14 +49,14 @@ Guides (agent-device help <topic>):
48
49
  manual-qa / dogfood / validate / debugging / scripting / gestures
49
50
  react-native / react-devtools / cdp / tv / web / macos / remote
50
51
  physical-device / ios-system-ui / maestro
51
- `}const h=[`Default config files: ~/.agent-device/config.json, ./agent-device.json (project-safe defaults only).`,`Use --config <path> or AGENT_DEVICE_CONFIG for explicit connection/provider defaults; project config cannot select endpoints or credentials.`],g=[{label:`AGENT_DEVICE_SESSION`,description:`Explicit session name`},{label:`AGENT_DEVICE_PLATFORM`,description:`Default platform binding`},{label:`AGENT_DEVICE_SCREENSHOT_SCALE`,description:`Default screenshot scale factor`},{label:`AGENT_DEVICE_SESSION_LOCK`,description:`Bound-session conflict mode`},{label:`AGENT_DEVICE_DAEMON_BASE_URL`,description:`Connect to remote daemon`},{label:`AGENT_DEVICE_DAEMON_AUTH_TOKEN`,description:`Remote daemon service/API token`},{label:`AGENT_DEVICE_CLOUD_BASE_URL`,description:`Bridge/control-plane API origin for cloud auth and /api-keys`}],_=[`agent-device open Settings --platform ios`,`agent-device open https://example.com --platform web`,`agent-device snapshot -i`,`agent-device fill @e3 "test@example.com"`,`agent-device replay ./session.ad`,`agent-device test ./suite --platform android`],v=`Wait failure contract:
52
+ `}var g=e({buildCommandUsageText:()=>N,buildUsageText:()=>E,helpTopicIds:()=>P});const _=[`Default config files: ~/.agent-device/config.json, ./agent-device.json (project-safe defaults only).`,`Use --config <path> or AGENT_DEVICE_CONFIG for explicit connection/provider defaults; project config cannot select endpoints or credentials.`],v=[{label:`AGENT_DEVICE_SESSION`,description:`Explicit session name`},{label:`AGENT_DEVICE_PLATFORM`,description:`Default platform binding`},{label:`AGENT_DEVICE_SCREENSHOT_SCALE`,description:`Default screenshot scale factor`},{label:`AGENT_DEVICE_SESSION_LOCK`,description:`Bound-session conflict mode`},{label:`AGENT_DEVICE_DAEMON_BASE_URL`,description:`Connect to remote daemon`},{label:`AGENT_DEVICE_DAEMON_AUTH_TOKEN`,description:`Remote daemon service/API token`},{label:`AGENT_DEVICE_CLOUD_BASE_URL`,description:`Bridge/control-plane API origin for cloud auth and /api-keys`}],y=[`agent-device open Settings --platform ios`,`agent-device open https://example.com --platform web`,`agent-device snapshot -i`,`agent-device fill @e3 "test@example.com"`,`agent-device replay ./session.ad`,`agent-device test ./suite --platform android`],b=`Wait failure contract:
52
53
  Read the verdict from error.details.reason in --json, not the message text.
53
54
  wait_target_absent: a readable capture ran and found no match.
54
55
  wait_capture_stalled: no readable capture finished before the deadline -- retriable.
55
56
  wait_deadline_exceeded: a later capture used the remaining budget after an earlier readable one.
56
57
  wait_landmark_identity_mismatch: a replay destination guard found the selector but not the recorded identity.
57
58
  wait_stable_timeout: wait stable never saw a stable UI -- not an absence verdict.
58
- `,y={commands:{summary:`Full command catalog, global flags, configuration, and environment`,body:`agent-device help commands`},"manual-qa":{summary:`Follow manual test scripts with exact interactions and verification`,body:`agent-device help manual-qa
59
+ `,x={commands:{summary:`Full command catalog, global flags, configuration, and environment`,body:`agent-device help commands`},"manual-qa":{summary:`Follow manual test scripts with exact interactions and verification`,body:`agent-device help manual-qa
59
60
 
60
61
  Use this when asked to follow a manual QA script, test case, checklist, acceptance flow, or user-provided instructions.
61
62
 
@@ -95,11 +96,11 @@ Recovery:
95
96
  Sparse or recovered accessibility snapshot: use screenshot as visual truth, leave the bad screen if needed, then retry snapshot -i.
96
97
  Non-hittable success hint: verify with the settled diff or snapshot; retarget by a better ref/selector if the UI did not change.
97
98
 
98
- ${v}`},maestro:{summary:`Supported Maestro YAML commands, grammar, and runtime boundaries`,body:`agent-device help maestro
99
+ ${b}`},maestro:{summary:`Supported Maestro YAML commands, grammar, and runtime boundaries`,body:`agent-device help maestro
99
100
 
100
101
  Run Maestro compatibility flows with replay <flow.yaml> --maestro or test <path> --maestro. Bind an iOS or Android target with --platform or an existing session.
101
102
 
102
- ${u()}
103
+ ${d()}
103
104
 
104
105
  Unsupported syntax fails loudly rather than being skipped. Architecture, performance tradeoffs, and declared conformance divergences: https://github.com/callstack/agent-device/blob/main/docs/adr/0015-direct-maestro-engine.md
105
106
  Focused compatibility request: https://github.com/callstack/agent-device/issues/new`},workflow:{summary:`Normal agent-device bootstrap, exploration, and validation loop`,body:`agent-device help workflow
@@ -144,7 +145,7 @@ Session ordering:
144
145
  Stateful commands (open/press/fill/type/scroll/back/alert/replay/batch/close) run serially within one session. Parallelize only read-only commands, or separate sessions/devices.
145
146
 
146
147
  Read-only and waits:
147
- ${v}
148
+ ${b}
148
149
  snapshot/get/is/find answer read-only questions; snapshot -i only when refs are needed. --settle confirms local UI quieted; for results that arrive later (network/debounce), follow with wait text "Expected result" or wait <selector> instead of polling.
149
150
  wait stable [quietMs] [timeoutMs] (defaults 500/10000) is the fallback for open/relaunch/navigation, or an intentionally-unsettled mutation -- not after a --settle whose diff already shows the change. Ambiguous find: add --first or --last.
150
151
 
@@ -179,6 +180,9 @@ Escalate:
179
180
 
180
181
  Use this for reusable .ad script authoring (save-script), scripted destination guards, secret-safe fills, batch multi-step JSON, replay divergence/repair, and evidence recording.
181
182
 
183
+ Script paths are the caller's:
184
+ replay <path> and test <path-or-glob> resolve and read on the machine running the command, then send the script content (Maestro runFlow includes too) with the request. The same flows therefore run against a local daemon and against a remote one (AGENT_DEVICE_DAEMON_BASE_URL) with no copy step, and a missing script fails immediately, naming the path you typed. --save-script writes on the DAEMON host and is rejected against a remote daemon.
185
+
182
186
  Reusable open-to-destination scripts:
183
187
  Arm recording on the first open, perform the full journey, verify the destination with a selector-targeted wait, then publish without closing:
184
188
  agent-device open com.example.app --relaunch --save-script=screen-x.ad
@@ -356,6 +360,7 @@ Diagnostics and traces:
356
360
  Open output includes Session state; JSON also includes runnerLogPath and requestLogPath.
357
361
  For open timing under --debug, run open --debug --json and inspect requestLogPath for the open_timing event.
358
362
  Session requests/<request-id>.ndjson holds daemon request diagnostics; session runner.log holds Apple runner/xcodebuild output.
363
+ Against a remote daemon the Diagnostics Log path is always local: the failing request's record is fetched to <state-dir>/remote-diagnostics/, and if it cannot be fetched the line reads "unavailable" with the reason instead of a daemon-host path.
359
364
  daemon.log is global daemon lifecycle evidence, not the primary per-run log.
360
365
  Use trace for low-level session diagnostics around one repro:
361
366
  agent-device trace start ./traces/diagnostics.trace
@@ -818,6 +823,7 @@ First-slice loop:
818
823
  agent-device is visible 'label="Welcome"' --platform web
819
824
  agent-device find text "Welcome" exists --platform web
820
825
  agent-device click @e12 --platform web
826
+ agent-device hover @e14 --settle --platform web
821
827
  agent-device fill @e13 "qa@example.com" --platform web
822
828
  agent-device wait text "Welcome" 3000 --platform web
823
829
  agent-device record start ./artifacts/web-flow.webm --platform web
@@ -830,7 +836,8 @@ First-slice loop:
830
836
  agent-device close --platform web
831
837
 
832
838
  Supported in agent-device web sessions:
833
- open <url>, snapshot -i, get text/attrs, is visible/exists/text, find text/selector, click/press @ref or selector, fill/type @ref or selector, wait text/selector, network dump, audio probe, screenshot, record start/stop with WebM output, close, and replay scripts made from those commands.
839
+ open <url>, snapshot -i, get text/attrs, is visible/exists/text, find text/selector, click/press @ref or selector, hover @ref or selector, fill/type @ref or selector, wait text/selector, network dump, audio probe, screenshot, record start/stop with WebM output, close, and replay scripts made from those commands.
840
+ hover moves the pointer without pressing so hover-gated UI (row toolbars, menus) appears; use --settle to read what it revealed, then act on the fresh refs. hover @ref hovers the browser element handle directly; pair --settle with a selector or coordinates (web refs carry no geometry, as with click @ref --settle). Web only: touch platforms have no hover state, so hover-gated flows there need a different entry point.
834
841
 
835
842
  Out of scope for agent-device web support:
836
843
  Browser runtime debugging, tabs/windows/devtools control, network routing/interception/HAR, storage/cookie management, arbitrary page scripting, downloads/uploads, multi-page orchestration, and agent-browser-specific diagnostics. Use agent-browser directly for those browser-specific workflows.
@@ -931,31 +938,31 @@ Evidence:
931
938
 
932
939
  Report:
933
940
  Summarize what changed, exact validation commands, pass/fail observations, artifact paths, and residual risk.
934
- If live validation is blocked, state the blocker, device/session, and exact next command needed.`}};function b(e,t,n){let r=n.endsWith(`?`),i=r?n.slice(0,-1):n,a=/^[a-z-]+(?:\|[a-z-]+)+$/i.test(i),o=a||t.usageOverride!==void 0&&t.usageOverride.startsWith(`${e} ${i}`);return r?a?`[${i}]`:o?i:`[${i}]`:o?i:`<${i}>`}function x(e,t){return t.listUsageOverride?t.listUsageOverride:[e,...(t.positionalArgs??[]).map(n=>b(e,t,n))].join(` `)}function S(){return m()}function C(){return`agent-device help commands
941
+ If live validation is blocked, state the blocker, device/session, and exact next command needed.`}};function S(e,t,n){let r=n.endsWith(`?`),i=r?n.slice(0,-1):n,a=/^[a-z-]+(?:\|[a-z-]+)+$/i.test(i),o=a||t.usageOverride!==void 0&&t.usageOverride.startsWith(`${e} ${i}`);return r?a?`[${i}]`:o?i:`[${i}]`:o?i:`<${i}>`}function C(e,t){return t.listUsageOverride?t.listUsageOverride:[e,...(t.positionalArgs??[]).map(n=>S(e,t,n))].join(` `)}function w(){return h()}function T(){return`agent-device help commands
935
942
 
936
943
  Full command catalog. Use agent-device help <command> for exact flags and behavior.
937
944
 
938
- ${A(t().map(e=>{let t=s(e);return{name:e,schema:t,usage:x(e,t)}}))}
945
+ ${M(n().map(e=>{let t=c(e);return{name:e,schema:t,usage:C(e,t)}}))}
939
946
 
940
- ${D(`Global Flags:`,T(r))}
947
+ ${k(`Global Flags:`,D(i))}
941
948
 
942
- ${k(`Configuration:`,h)}
949
+ ${j(`Configuration:`,_)}
943
950
 
944
- ${O(`Environment:`,g)}
951
+ ${A(`Environment:`,v)}
945
952
 
946
- ${k(`Examples:`,_)}
947
- `}function w(){return S()}function T(e){return n().filter(t=>e.has(t.key)&&t.usageLabel!==void 0&&t.usageDescription!==void 0)}function E(e,t){return t?e.map(e=>{let n=t[e.key];return n===void 0?e:{...e,usageDescription:n}}):e}function D(e,t){return O(e,t.map(e=>({label:e.usageLabel??``,description:e.usageDescription??``})))}function O(e,t){if(t.length===0)return`${e}\n (none)`;let n=Math.max(...t.map(e=>Math.min(e.label.length,26)))+2,r=[e];for(let e of t){let t=e.label.length<=26?e.label.padEnd(n):`${e.label} `;r.push(` ${t}${e.description}`)}return r.join(`
948
- `)}function k(e,t){return t.length===0?`${e}\n (none)`:[e,...t.map(e=>` ${e}`)].join(`
949
- `)}function A(e){return O(`Commands:`,e.map(e=>({label:e.usage,description:e.schema.text.summary})))}function j(e){let t=M(e);if(t)return t;let n=o(e);if(!n)return null;let r=p(e,n),a=E(T(new Set(n.allowedFlags??[])),n.flagDescriptionOverrides),s=[];a.length>0&&s.push(D(`Command flags:`,a));let c=s.length>0?`\n\n${s.join(`
953
+ ${j(`Examples:`,y)}
954
+ `}function E(){return w()}function D(e){return r().filter(t=>e.has(t.key)&&t.usageLabel!==void 0&&t.usageDescription!==void 0)}function O(e,t){return t?e.map(e=>{let n=t[e.key];return n===void 0?e:{...e,usageDescription:n}}):e}function k(e,t){return A(e,t.map(e=>({label:e.usageLabel??``,description:e.usageDescription??``})))}function A(e,t){if(t.length===0)return`${e}\n (none)`;let n=Math.max(...t.map(e=>Math.min(e.label.length,26)))+2,r=[e];for(let e of t){let t=e.label.length<=26?e.label.padEnd(n):`${e.label} `;r.push(` ${t}${e.description}`)}return r.join(`
955
+ `)}function j(e,t){return t.length===0?`${e}\n (none)`:[e,...t.map(e=>` ${e}`)].join(`
956
+ `)}function M(e){return A(`Commands:`,e.map(e=>({label:e.usage,description:e.schema.text.summary})))}function N(e){let t=F(e);if(t)return t;let n=s(e);if(!n)return null;let r=m(e,n),i=O(D(new Set(n.allowedFlags??[])),n.flagDescriptionOverrides),o=[];i.length>0&&o.push(k(`Command flags:`,i));let c=o.length>0?`\n\n${o.join(`
950
957
 
951
958
  `)}`:``;return`Usage:
952
959
  agent-device ${r}
953
960
 
954
- ${i(n.text)}${c}
955
- `}function M(e){let t=y[e];return t?`${N(e,e===`commands`?C():t.body)}
961
+ ${a(n.text)}${c}
962
+ `}function P(){return Object.keys(x)}function F(e){let t=x[e];return t?`${I(e,e===`commands`?T():t.body)}
956
963
 
957
964
  Related:
958
965
  agent-device help <command> command-specific flags
959
966
  agent-device help manual-qa routine QA loop
960
967
  agent-device help workflow full automation reference
961
- `:null}function N(e,t){let n=`agent-device help ${e}`;return t.startsWith(n)?`agent-device ${a()} — ${e}${t.slice(n.length)}`:t}export{j as buildCommandUsageText,w as buildUsageText};
968
+ `:null}function I(e,t){let n=`agent-device help ${e}`;return t.startsWith(n)?`agent-device ${o()} — ${e}${t.slice(n.length)}`:t}export{P as i,E as n,g as r,N as t};
@@ -1 +1 @@
1
- import{t as e}from"./cli-grammar.js";import{t}from"./cli-output.js";import{n}from"./command-surface.js";async function r(e){return(await i(e)).result}async function i(r){let i=e(r.command,r.positionals,r.flags),a=await n(r.client,r.command,i);return{result:a,cliOutput:t({name:r.command,input:i,result:a})}}export{i as n,r as t};
1
+ import{t as e}from"./cli-output.js";import{t}from"./cli-grammar.js";import{n}from"./command-surface.js";async function r(e){return(await i(e)).result}async function i(r){let i=t(r.command,r.positionals,r.flags),a=await n(r.client,r.command,i);return{result:a,cliOutput:e({name:r.command,input:i,result:a})}}export{i as n,r as t};