agent-device 0.18.2 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.2.apk → agent-device-android-multitouch-helper-0.19.0.apk} +0 -0
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +1 -0
  3. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.2.manifest.json → agent-device-android-multitouch-helper-0.19.0.manifest.json} +4 -4
  4. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.2.apk → agent-device-android-snapshot-helper-0.19.0.apk} +0 -0
  5. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +1 -0
  6. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.2.manifest.json → agent-device-android-snapshot-helper-0.19.0.manifest.json} +6 -6
  7. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +28 -0
  8. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +9 -120
  9. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +132 -66
  10. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +155 -0
  11. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +67 -0
  12. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +20 -74
  13. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +64 -0
  14. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +0 -177
  15. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +81 -48
  16. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +102 -129
  17. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +208 -46
  18. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +82 -11
  19. package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +72 -0
  20. package/dist/src/agent-browser-tool.js +1 -0
  21. package/dist/src/android-adb.d.ts +64 -234
  22. package/dist/src/android-adb.js +1 -1
  23. package/dist/src/android.js +1 -5
  24. package/dist/src/app-lifecycle.js +7 -0
  25. package/dist/src/apple-runner-options.js +1 -0
  26. package/dist/src/apps.js +5 -11
  27. package/dist/src/artifacts.d.ts +4 -3
  28. package/dist/src/artifacts.js +1 -1
  29. package/dist/src/audio-probe.js +1 -1
  30. package/dist/src/batch.d.ts +2 -177
  31. package/dist/src/batch.js +1 -1
  32. package/dist/src/cli-help.js +64 -38
  33. package/dist/src/cli-output.js +1 -1
  34. package/dist/src/cli-runner.js +2 -0
  35. package/dist/src/cli.js +12 -41
  36. package/dist/src/client-metro-companion.js +1 -0
  37. package/dist/src/client.js +3 -0
  38. package/dist/src/command-metadata.js +1 -0
  39. package/dist/src/command-schema.js +22 -0
  40. package/dist/src/command-surface.js +1 -1
  41. package/dist/src/contracts.d.ts +2 -213
  42. package/dist/src/contracts.js +1 -1
  43. package/dist/src/debug-symbols.js +5 -3
  44. package/dist/src/device-input-state.js +2 -0
  45. package/dist/src/device-rotation.js +14 -0
  46. package/dist/src/devices.js +1 -1
  47. package/dist/src/devices2.js +1 -0
  48. package/dist/src/devices3.js +1 -0
  49. package/dist/src/find.js +1 -1
  50. package/dist/src/finders.d.ts +2 -81
  51. package/dist/src/finders.js +1 -1
  52. package/dist/src/generic.js +1 -1
  53. package/dist/src/handler-utils.js +1 -1
  54. package/dist/src/helper.js +2 -0
  55. package/dist/src/host-process.js +2 -0
  56. package/dist/src/index.d.ts +1265 -1768
  57. package/dist/src/index.js +1 -1
  58. package/dist/src/input-actions.js +3 -1
  59. package/dist/src/input-actions2.js +1 -0
  60. package/dist/src/install-source.d.ts +13 -14
  61. package/dist/src/install-source.js +1 -1
  62. package/dist/src/install-source2.js +1 -0
  63. package/dist/src/interaction-snapshot.js +1 -0
  64. package/dist/src/interaction.js +1 -1
  65. package/dist/src/interactor.js +2 -1
  66. package/dist/src/internal/bin.d.ts +1 -1
  67. package/dist/src/internal/bin.js +2 -5
  68. package/dist/src/internal/companion-tunnel.d.ts +1 -1
  69. package/dist/src/internal/companion-tunnel.js +1 -1
  70. package/dist/src/internal/daemon.d.ts +1 -1
  71. package/dist/src/internal/daemon.js +16 -1
  72. package/dist/src/internal/png-worker.d.ts +29 -26
  73. package/dist/src/internal/png-worker.js +1 -1
  74. package/dist/src/internal/update-check-entry.d.ts +1 -1
  75. package/dist/src/internal/update-check-entry.js +1 -1
  76. package/dist/src/io.d.ts +2 -85
  77. package/dist/src/io.js +1 -1
  78. package/dist/src/lease.js +1 -1
  79. package/dist/src/linux.js +1 -1
  80. package/dist/src/logcat.js +6 -0
  81. package/dist/src/manifest.js +1 -0
  82. package/dist/src/metro.d.ts +70 -113
  83. package/dist/src/metro.js +1 -1
  84. package/dist/src/metro2.js +1 -0
  85. package/dist/src/notifications.js +1 -1
  86. package/dist/src/output-path.js +1 -0
  87. package/dist/src/path-resolution.js +1 -0
  88. package/dist/src/png-worker-contract.js +1 -0
  89. package/dist/src/points.js +4 -0
  90. package/dist/src/project-runtime.js +1 -0
  91. package/dist/src/provider.js +1 -1
  92. package/dist/src/providers.js +1 -0
  93. package/dist/src/react-native.js +1 -1
  94. package/dist/src/record-trace-recording.js +2 -5
  95. package/dist/src/record-trace.js +1 -1
  96. package/dist/src/recording-provider.js +1 -1
  97. package/dist/src/registry.js +37 -0
  98. package/dist/src/remote-config.d.ts +2 -83
  99. package/dist/src/reporting.js +9 -0
  100. package/dist/src/rolldown-runtime.js +1 -0
  101. package/dist/src/runner-client.js +1 -0
  102. package/dist/src/runner-provider.js +1 -0
  103. package/dist/src/runner-sequence.js +1 -1
  104. package/dist/src/runtime-transport.js +1 -0
  105. package/dist/src/runtime.js +3 -0
  106. package/dist/src/scoped-provider.js +1 -0
  107. package/dist/src/sdk-android-adb.d.ts +144 -0
  108. package/dist/src/sdk-android-adb.js +4 -0
  109. package/dist/src/sdk-app-inventory.d.ts +4 -0
  110. package/dist/src/sdk-app-inventory.js +1 -0
  111. package/dist/src/sdk-batch-runner.d.ts +40 -0
  112. package/dist/src/sdk-batch-runner.js +2 -0
  113. package/dist/src/sdk-batch.js +2 -0
  114. package/dist/src/sdk-contracts.d.ts +386 -0
  115. package/dist/src/sdk-contracts.js +2 -0
  116. package/dist/src/sdk-finders.d.ts +61 -0
  117. package/dist/src/sdk-finders.js +1 -0
  118. package/dist/src/sdk-io.d.ts +79 -0
  119. package/dist/src/sdk-io.js +1 -0
  120. package/dist/src/sdk-remote-config.d.ts +140 -0
  121. package/dist/src/sdk-remote-config.js +1 -0
  122. package/dist/src/sdk-selectors.js +1 -0
  123. package/dist/src/selector-runtime.js +1 -1
  124. package/dist/src/selectors.d.ts +39 -137
  125. package/dist/src/selectors.js +1 -1
  126. package/dist/src/selectors2.js +1 -0
  127. package/dist/src/server.js +3 -2
  128. package/dist/src/session.js +10 -11
  129. package/dist/src/setting-state.js +1 -0
  130. package/dist/src/simctl.js +1 -0
  131. package/dist/src/simulator.js +1 -2
  132. package/dist/src/snapshot-diagnostics.js +3 -0
  133. package/dist/src/snapshot-helper.js +5 -0
  134. package/dist/src/snapshot-quality.js +1 -0
  135. package/dist/src/snapshot.js +1 -2
  136. package/dist/src/snapshot2.js +2 -0
  137. package/dist/src/{5560.js → timeouts.js} +1 -1
  138. package/dist/src/tool-provider.js +3 -0
  139. package/dist/src/tool-provider2.js +1 -0
  140. package/dist/src/ttl-memo.js +1 -0
  141. package/dist/src/update-check.js +1 -0
  142. package/dist/src/url.js +1 -0
  143. package/dist/src/version.js +1 -0
  144. package/dist/src/web.js +1 -1
  145. package/dist/src/xml.js +2 -0
  146. package/package.json +12 -19
  147. package/server.json +2 -2
  148. package/skills/agent-device/SKILL.md +2 -0
  149. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +0 -1
  150. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +0 -1
  151. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +0 -443
  152. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -169
  153. package/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +0 -220
  154. package/dist/src/1404.js +0 -1
  155. package/dist/src/1986.js +0 -1
  156. package/dist/src/2748.js +0 -1
  157. package/dist/src/2948.js +0 -30
  158. package/dist/src/3006.js +0 -1
  159. package/dist/src/314.js +0 -1
  160. package/dist/src/3340.js +0 -8
  161. package/dist/src/4418.js +0 -1
  162. package/dist/src/4428.js +0 -3
  163. package/dist/src/485.js +0 -1
  164. package/dist/src/4917.js +0 -1
  165. package/dist/src/495.js +0 -5
  166. package/dist/src/5448.js +0 -3
  167. package/dist/src/5484.js +0 -1
  168. package/dist/src/5643.js +0 -1
  169. package/dist/src/587.js +0 -1
  170. package/dist/src/5913.js +0 -4
  171. package/dist/src/6849.js +0 -1
  172. package/dist/src/6918.js +0 -1
  173. package/dist/src/6967.js +0 -1
  174. package/dist/src/760.js +0 -1
  175. package/dist/src/7871.js +0 -1
  176. package/dist/src/8184.js +0 -1
  177. package/dist/src/8225.js +0 -1
  178. package/dist/src/8391.js +0 -1
  179. package/dist/src/8404.js +0 -2
  180. package/dist/src/8414.js +0 -2
  181. package/dist/src/8875.js +0 -4
  182. package/dist/src/893.js +0 -1
  183. package/dist/src/8936.js +0 -1
  184. package/dist/src/9414.js +0 -1
  185. package/dist/src/9581.js +0 -22
  186. package/dist/src/9612.js +0 -1
  187. package/dist/src/9624.js +0 -1
  188. package/dist/src/9722.js +0 -38
  189. package/dist/src/devices~1.js +0 -1
  190. package/dist/src/devices~2.js +0 -1
  191. package/dist/src/input-actions~1.js +0 -1
  192. package/dist/src/rslib-runtime.js +0 -1
  193. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
  194. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
  195. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  196. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  197. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  198. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  199. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
  200. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
  201. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  202. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  203. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
  204. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
  205. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
  206. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  207. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  208. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
  209. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
  210. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  211. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
  212. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  213. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  214. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  215. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  216. /package/{apple-runner → dist/apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
@@ -0,0 +1 @@
1
+ import{F as e}from"./sdk-contracts.js";function t(e){return e.map(e=>({args:e.args.join(` `),exitCode:e.exitCode,stderr:e.stderr.slice(0,400)}))}const n=[`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`];function r(t){let n=t.trim().toLowerCase();if(n===`grant`)return`grant`;if(n===`deny`)return`deny`;if(n===`reset`)return`reset`;throw new e(`INVALID_ARGS`,`Invalid permission action: ${t}. Use grant|deny|reset.`)}function i(t){let r=t?.trim().toLowerCase();if(r===`camera`||r===`microphone`||r===`photos`||r===`contacts`||r===`contacts-limited`||r===`notifications`||r===`calendar`||r===`location`||r===`location-always`||r===`media-library`||r===`motion`||r===`reminders`||r===`siri`)return r;throw new e(`INVALID_ARGS`,`permission setting requires a target: ${n.join(`|`)}`)}function a(t){let n=t.trim().toLowerCase();if(n===`light`)return`light`;if(n===`dark`)return`dark`;if(n===`toggle`)return`toggle`;throw new e(`INVALID_ARGS`,`Invalid appearance state: ${t}. Use light|dark|toggle.`)}function o(t){let n=t.toLowerCase();if(n===`on`||n===`true`||n===`1`)return!0;if(n===`off`||n===`false`||n===`0`)return!1;throw new e(`INVALID_ARGS`,`Invalid setting state: ${t}`)}export{t as a,i,a as n,r,o as t};
@@ -0,0 +1 @@
1
+ import{p as e}from"./sdk-contracts.js";import{h as t}from"./logcat.js";import{o as n}from"./tool-provider.js";function r(e,n={}){let r=t(n.simulatorSetPath);return r?[`simctl`,`--set`,r,...e]:[`simctl`,...e]}function i(t,n){return!e(t)||t.kind!==`simulator`?[`simctl`,...n]:r(n,{simulatorSetPath:t.simulatorSetPath})}function a(e,t,r){return n(i(e,t),r)}export{i as n,a as r,r as t};
@@ -1,2 +1 @@
1
- import{AppError as t}from"./485.js";import{classifyBootFailure as e,retryWithPolicy as o,bootFailureHint as i,Deadline as r}from"./3340.js";import{runXcrun as s,buildSimctlArgs as d,buildSimctlArgsForDevice as a,runAppleToolCommand as u}from"./9722.js";let l=["Simulator"],n=["Device Hub","Simulator"],c=new Map;function m(t){return`${t.id}|${t.simulatorSetPath??""}`}function f(t){c.set(m(t),Date.now())}function S(e,o){if("simulator"!==e.kind)throw new t("UNSUPPORTED_OPERATION",`${o} is only supported on iOS simulators`)}async function w(t={}){let e=t.deviceHub?n:l,o=t.background?["-g","-a"]:["-a"];for(let t of e)if(0===(await u("open",[...o,t],{allowFailure:!0,timeoutMs:1e4})).exitCode)return}async function C(d,u={}){let l,n,S,M;if("simulator"!==d.kind)return;if("Booted"===((S=m(d),void 0!==(M=c.get(S))&&(!(Date.now()-M>5e3)||(c.delete(S),0)))?"Booted":await b(d))){f(d),u.focusExisting&&await w({background:u.deviceHub,deviceHub:u.deviceHub});return}u.onColdBootStart?.(d);let _=r.fromTimeoutMs(18e4);try{await o(async({deadline:e})=>{if(e?.isExpired())throw new t("COMMAND_FAILED","iOS simulator boot deadline exceeded",{timeoutMs:18e4});let o=Math.max(1e3,e?.remainingMs()??18e4),i=await s(a(d,["boot",d.id]),{allowFailure:!0,timeoutMs:o});l={stdout:String(i.stdout??""),stderr:String(i.stderr??""),exitCode:i.exitCode};let r=`${l.stdout}
2
- ${l.stderr}`.toLowerCase(),u=r.includes("already booted")||r.includes("current state: booted");if(0!==l.exitCode&&!u)throw new t("COMMAND_FAILED","simctl boot failed",{stdout:l.stdout,stderr:l.stderr,exitCode:l.exitCode});let c=await s(a(d,["bootstatus",d.id,"-b"]),{allowFailure:!0,timeoutMs:o});if(n={stdout:String(c.stdout??""),stderr:String(c.stderr??""),exitCode:c.exitCode},0!==n.exitCode)throw new t("COMMAND_FAILED","simctl bootstatus failed",{stdout:n.stdout,stderr:n.stderr,exitCode:n.exitCode});let m=await b(d);if("Booted"!==m)throw new t("COMMAND_FAILED","Simulator is still booting",{state:m})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:t=>{let o=e({error:t,stdout:n?.stdout??l?.stdout,stderr:n?.stderr??l?.stderr,context:{platform:"ios",phase:"boot"}});return"IOS_BOOT_TIMEOUT"!==o&&"CI_RESOURCE_STARVATION_SUSPECTED"!==o}},{deadline:_,phase:"boot",classifyReason:t=>e({error:t,stdout:n?.stdout??l?.stdout,stderr:n?.stderr??l?.stderr,context:{platform:"ios",phase:"boot"}})})}catch(r){let o=e({error:r,stdout:n?.stdout??l?.stdout,stderr:n?.stderr??l?.stderr,context:{platform:"ios",phase:"boot"}});throw new t("COMMAND_FAILED","iOS simulator failed to boot",{platform:"ios",deviceId:d.id,timeoutMs:18e4,elapsedMs:_.elapsedMs(),reason:o,hint:i(o),boot:l,bootstatus:n})}f(d),await w({deviceHub:u.deviceHub})}async function M(t){c.delete(m(t));let e=a(t,["shutdown",t.id]),o=await s(e,{allowFailure:!0,timeoutMs:15e3});return{success:0===o.exitCode,exitCode:o.exitCode,stdout:String(o.stdout??""),stderr:String(o.stderr??"")}}async function b(t){let e="string"==typeof t?t:t.id,o="string"==typeof t?d(["list","devices","-j"]):a(t,["list","devices","-j"]),i=await s(o,{allowFailure:!0,timeoutMs:6e4});if(0!==i.exitCode)return null;try{let t=JSON.parse(String(i.stdout??""));for(let o of Object.values(t.devices??{})){let t=o.find(t=>t.udid===e);if(t)return t.state}return null}catch{return null}}export{C as ensureBootedSimulator,b as getSimulatorState,f as markSimulatorBooted,S as requireSimulatorDevice,M as shutdownSimulator};
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{h as n,p as r}from"./sdk-android-adb.js";import{d as i,g as a,u as o,v as s}from"./logcat.js";import{a as c,o as l}from"./tool-provider.js";import{n as u,t as d}from"./simctl.js";import{t as f}from"./ttl-memo.js";import{X as p,q as m}from"./internal/daemon.js";var h=e({SIMULATOR_BOOTED_MEMO_TTL_MS:()=>v,ensureBootedSimulator:()=>E,getSimulatorState:()=>O,markSimulatorBooted:()=>S,openIosSimulatorApp:()=>T,requireSimulatorDevice:()=>w,shutdownSimulator:()=>D});const g=[`Simulator`],_=[`Device Hub`,`Simulator`],v=5e3,y=f({ttlMs:v});function b(e){return`${e.id}|${e.simulatorSetPath??``}`}function x(e){return y.get(b(e))===!0}function S(e){y.set(b(e),!0)}function C(e){y.delete(b(e))}function w(e,n){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`${n} is only supported on iOS simulators`)}async function T(e={}){let t=e.deviceHub?_:g,n=e.background?[`-g`,`-a`]:[`-a`];for(let e of t)if((await c(`open`,[...n,e],{allowFailure:!0,timeoutMs:1e4})).exitCode===0)return}async function E(e,c={}){if(e.kind!==`simulator`)return;if((x(e)?`Booted`:await O(e))===`Booted`){S(e),c.focusExisting&&await T({background:c.deviceHub,deviceHub:c.deviceHub});return}c.onColdBootStart?.(e);let d=a.fromTimeoutMs(m),f,p;try{await s(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`iOS simulator boot deadline exceeded`,{timeoutMs:m});let a=Math.max(1e3,i?.remainingMs()??18e4);f=await l(u(e,[`boot`,e.id]),{allowFailure:!0,timeoutMs:a});let o=`${f.stdout}\n${f.stderr}`.toLowerCase(),s=o.includes(`already booted`)||o.includes(`current state: booted`);if(f.exitCode!==0&&!s)throw new t(`COMMAND_FAILED`,`simctl boot failed`,r(f));p=await l(u(e,[`bootstatus`,e.id,`-b`]),{allowFailure:!0,timeoutMs:a}),n(p,`simctl bootstatus failed`);let c=await O(e);if(c!==`Booted`)throw new t(`COMMAND_FAILED`,`Simulator is still booting`,{state:c})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let t=i({error:e,stdout:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});return t!==`IOS_BOOT_TIMEOUT`&&t!==`CI_RESOURCE_STARVATION_SUSPECTED`}},{deadline:d,phase:`boot`,classifyReason:e=>i({error:e,stdout:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(n){let r=i({error:n,stdout:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});throw new t(`COMMAND_FAILED`,`iOS simulator failed to boot`,{platform:`ios`,deviceId:e.id,timeoutMs:m,elapsedMs:d.elapsedMs(),reason:r,hint:o(r),boot:f,bootstatus:p})}S(e),await T({deviceHub:c.deviceHub})}async function D(e){C(e);let t=await l(u(e,[`shutdown`,e.id]),{allowFailure:!0,timeoutMs:15e3});return{success:t.exitCode===0,exitCode:t.exitCode,stdout:t.stdout,stderr:t.stderr}}async function O(e){let t=typeof e==`string`?e:e.id,n=await l(typeof e==`string`?d([`list`,`devices`,`-j`]):u(e,[`list`,`devices`,`-j`]),{allowFailure:!0,timeoutMs:p});if(n.exitCode!==0)return null;try{let e=JSON.parse(n.stdout);for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}export{D as a,w as i,O as n,h as o,S as r,E as t};
@@ -0,0 +1,3 @@
1
+ import{F as e}from"./sdk-contracts.js";import{n as t,t as n}from"./version.js";import{n as r,t as i}from"./path-resolution.js";import{a,n as o,o as s,u as c}from"./host-process.js";import{d as l,l as u,u as d}from"./sdk-batch-runner.js";import f from"node:crypto";import p from"node:fs";import m from"node:path";function h(e){return new Promise((t,n)=>{let r=``;e.setEncoding(`utf8`),e.on(`data`,e=>{r+=e}),e.on(`end`,()=>t(r)),e.on(`error`,n)})}async function g(t,n,r){let i=[],a=0;for await(let o of t){let t=Buffer.isBuffer(o)?o:Buffer.from(o);if(a+=t.length,a>n)throw new e(`INVALID_ARGS`,r);i.push(t)}return Buffer.concat(i)}function _(e,t={}){let n=v(e,t);return{baseDir:n,infoPath:m.join(n,`daemon.json`),lockPath:m.join(n,`daemon.lock`),logPath:m.join(n,`daemon.log`),sessionsDir:m.join(n,`sessions`)}}function v(e,t){let n=(e??``).trim();return n?r(n,{env:t.env}):y(t)}function y(e={}){let t=m.join(i(`~`,{env:e.env}),`.agent-device`),r=e.projectRoot??n();return b(r)?m.join(t,`dev`,x(r)):t}function b(e){return p.existsSync(m.join(e,`package.json`))&&p.existsSync(m.join(e,`src`,`daemon.ts`))}function x(e){let t=ee(e),n=m.basename(t).replaceAll(/[^a-zA-Z0-9._-]+/g,`-`),r=f.createHash(`sha1`).update(t).digest(`hex`).slice(0,12);return`${n||`agent-device`}-${r}`}function ee(e){try{return p.realpathSync.native(e)}catch{return m.resolve(e)}}function te(e){let t=(e??``).trim().toLowerCase();return t===`http`?`http`:t===`dual`?`dual`:`socket`}function ne(e){let t=(e??``).trim().toLowerCase();return t===`auto`?`auto`:t===`socket`?`socket`:t===`http`?`http`:`auto`}function re(e){return(e??``).trim().toLowerCase()===`tenant`?`tenant`:`none`}function ie(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}const S=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,C=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,w=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`];function T(){let e=process.argv[1];return e?E(e):`unknown`}function E(e,t=n()){try{let n=m.resolve(t),r=[m.resolve(e)],i=new Set,a=[];for(;r.length>0;){let e=r.pop();if(!e||i.has(e))continue;i.add(e);let t=p.statSync(e);if(!t.isFile())continue;let o=m.relative(n,e)||e;a.push(`${o}:${t.size}:${Math.trunc(t.mtimeMs)}`);let s=p.readFileSync(e,`utf8`);for(let t of D(s)){let n=k(e,t);n&&r.push(n)}}let o=a.sort().join(`|`),s=f.createHash(`sha1`).update(o).digest(`hex`);return`graph:${a.length}:${s}`}catch{return`unknown`}}function D(e){let t=new Set;return O(e,S,t),O(e,C,t),[...t]}function O(e,t,n){t.lastIndex=0;let r=null;for(;(r=t.exec(e))!==null;){let e=r[1]?.trim();e?.startsWith(`.`)&&n.add(e)}}function k(e,t){let n=m.resolve(m.dirname(e),t),r=A(n);if(r)return r;for(let e of w){let t=A(`${n}${e}`);if(t)return t}for(let e of w){let t=A(m.join(n,`index${e}`));if(t)return t}return null}function A(e){try{return p.statSync(e).isFile()?e:null}catch{return null}}const j=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function M(e){let t=e.toLowerCase().replaceAll(`\\`,`/`);return t.includes(`agent-device`)?j.some(e=>e.test(t)):!1}function N(e,t){if(!o(e))return!1;if(t){let n=s(e);if(!n||n!==t)return!1}let n=a(e);return n?M(n):!1}function P(e,t){try{return process.kill(e,t),!0}catch(e){let t=e.code;if(t===`ESRCH`||t===`EPERM`)return!1;throw e}}async function F(e,t){N(e,t.expectedStartTime)&&P(e,`SIGTERM`)&&(await c(e,t.termTimeoutMs)||P(e,`SIGKILL`)&&await c(e,t.killTimeoutMs))}const I=/^[A-Za-z0-9_@%+=:,./-]+$/;function L(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function R(e){return I.test(e)?e:L(e)}function z(e,t){let n=[],r=e+t.toString(),i=r.indexOf(`
2
+ `);for(;i!==-1;){let e=r.slice(0,i).trim();r=r.slice(i+1),e&&n.push(e),i=r.indexOf(`
3
+ `)}return{lines:n,buffer:r}}function B(e){return e.meta?.requestProgress===`replay-test`||e.meta?.requestProgress===`command`}function V(e){return!!e&&typeof e==`object`&&e.type===`progress`&&!!e.event}function ae(e){return!!e&&typeof e==`object`&&e.type===`response`&&!!e.response}function H(e){return`${JSON.stringify({type:`progress`,event:e})}\n`}function U(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function W(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function G(e,n={}){return{ok:!0,service:e,version:t(),rpcProtocolVersion:1,...n.upstream===void 0?{}:{upstream:n.upstream}}}function K(e){if(!u(e))return;let t=typeof e.path==`string`?e.path:void 0,n=Array.isArray(e.overlayRefs)?e.overlayRefs.filter(se).flatMap(e=>{let t=q(e);return t?[t]:[]}):void 0;return{...t?{path:t}:{},...n?{overlayRefs:n}:{}}}function q(e){if(typeof e.ref!=`string`||e.ref.length===0)return;let t=J(e);if(t)return{ref:e.ref,...oe(e),...t}}function J(e){let t=l(e.rect);if(!t)return;let n=l(e.overlayRect);if(!n)return;let r=d(e.center);return r?{rect:t,overlayRect:n,center:r}:void 0}function oe(e){return typeof e.label==`string`&&e.label.length>0?{label:e.label}:{}}function se(e){return u(e)}const Y=1500;function ce(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function le(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return X(t)}function X(e){if(e.length===0)return;let t=Z(e);return{stats:t,...t.p95Ms>=Y?{warning:$(t)}:{}}}function ue(e){let t=e.flatMap(e=>ve(e?.stats));if(t.length===0)return;let n=Z(t);return{stats:n,...n.p95Ms>=Y?{warning:$(n)}:{}}}function de(e){if(!u(e))return;let t=me(e.stats);if(!t)return;let n=typeof e.warning==`string`?e.warning:void 0;return{stats:t,...n?{warning:n}:{}}}function Z(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:Q(t,50),p95Ms:Q(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:Y,...fe(e),...pe(e)}}function Q(e,t){if(e.length===0)return 0;let n=Math.max(0,Math.ceil(t/100*e.length)-1);return e[Math.min(n,e.length-1)]??0}function fe(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function pe(e){let t={};for(let n of e)n.backend&&(t[n.backend]=(t[n.backend]??0)+1);return Object.keys(t).length>0?{backends:t}:{}}function $(e){return`Warning: ${e.platform?`${e.platform} `:``}snapshots are slow in this run: p95 ${e.p95Ms}ms over ${e.count} captures. Possible causes: device load, app or dev server stuck, helper fallback, or stale daemon.`}function me(e){if(!u(e))return;let t=he(e);if(t)return{...t,..._e(e)}}function he(e){let t={count:e.count,p50Ms:e.p50Ms,p95Ms:e.p95Ms,maxMs:e.maxMs,slowThresholdMs:e.slowThresholdMs};if(!Object.values(t).some(e=>typeof e!=`number`))return t}function ge(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function _e(e){let t=typeof e.platform==`string`?e.platform:void 0,n=u(e.backends)?ge(e.backends):void 0;return{...t?{platform:t}:{},...n?{backends:n}:{}}}function ve(e){if(!e||e.count<=0)return[];let t=e.platform;return e.count===1?[{durationMs:e.maxMs,platform:t}]:e.count===2?[{durationMs:e.p50Ms,platform:t},{durationMs:e.maxMs,platform:t}]:[...Array.from({length:e.count-3},()=>({durationMs:e.p50Ms,platform:t})),{durationMs:e.p50Ms,platform:t},{durationMs:e.p95Ms,platform:t},{durationMs:e.maxMs,platform:t}]}export{te as C,h as D,g as E,_ as S,re as T,N as _,X as a,T as b,V as c,U as d,W as f,R as g,L as h,le as i,ae as l,z as m,de as n,K as o,B as p,ce as r,G as s,ue as t,H as u,F as v,ne as w,ie as x,E as y};
@@ -0,0 +1,5 @@
1
+ import{F as e}from"./sdk-contracts.js";import{j as t,n,o as r,p as i}from"./sdk-android-adb.js";import{N as a}from"./device-rotation.js";import{E as o}from"./sdk-selectors.js";import s from"node:crypto";import c from"node:fs";import"node:os";import"node:path";import"node:fs/promises";import l from"node:net";function u(e){if(!e)return;let t=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(e);if(!t)return;let n=Number(t[1]),r=Number(t[2]),i=Number(t[3]),a=Number(t[4]);return{x:n,y:r,width:Math.max(0,i-n),height:Math.max(0,a-r)}}function*d(e){let t=/<node\b[^>]*>/g,n=t.exec(e);for(;n;)yield f(n[0]),n=t.exec(e)}function f(e){let t=ne(e),n=u(t.bounds);return{...t,...n?{rect:n}:{}}}function ee(e,t,n){let{sourceNodes:r,...i}=p(_(e),t,n);return i}function p(e,t,n){let r={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:n.depth??1/0,options:n,analysis:Pe(e),interactiveDescendantMemo:new Map,truncated:!1},i=n.scope?Ne(e,n.scope):null,a=i?[i]:e.children;for(let e of a)if(m(r,e,0),r.truncated)break;let o={nodes:r.nodes,sourceNodes:r.sourceNodes,analysis:r.analysis};return r.truncated?{...o,truncated:!0}:o}function m(e,t,n,r,i=!1,a=!1){if(e.maxNodes!==void 0&&e.nodes.length>=e.maxNodes){e.truncated=!0;return}if(n>e.maxDepth)return;let o=e.options.raw||Te(t,e.options,i,h(e,t),a)?te(e,t,n,r):r,s=i||!!t.hittable,c=a||je(t.type);for(let r of t.children)if(m(e,r,n+1,o,s,c),e.truncated)return}function te(e,t,n,r){let i=e.nodes.length;return e.sourceNodes.push(t),e.nodes.push({index:i,type:t.type??void 0,label:t.label??void 0,value:t.value??void 0,identifier:t.identifier??void 0,bundleId:t.packageName??void 0,rect:t.rect,enabled:t.enabled,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:n,parentIndex:r,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{}}),i}function h(e,t){let n=e.interactiveDescendantMemo.get(t);if(n!==void 0)return n;for(let n of t.children)if(n.visibleToUser!==!1&&(n.hittable||h(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function ne(e){let t=re(e),n=e=>me(t,e),r=e=>{let t=n(e);if(t!==null)return t===`true`},i=e=>{let t=n(e);if(t===null||t.trim()===``)return;let r=Number(t);return Number.isFinite(r)?r:void 0},a=(e,t)=>{let n=i(t);return n===void 0?{}:{[e]:n}},o=(e,t)=>{let r=u(n(t));return r===void 0?{}:{[e]:r}},s=(e,t)=>{let n=r(t);return n===void 0?{}:{[e]:n}};return{text:n(`text`),desc:n(`content-desc`),resourceId:n(`resource-id`),packageName:n(`package`),className:n(`class`),bounds:n(`bounds`),clickable:r(`clickable`),enabled:r(`enabled`),focusable:r(`focusable`),focused:r(`focused`),password:r(`password`),...s(`visibleToUser`,`visible-to-user`),...a(`drawingOrder`,`drawing-order`),...s(`scrollable`,`scrollable`),...s(`canScrollForward`,`can-scroll-forward`),...s(`canScrollBackward`,`can-scroll-backward`),...a(`windowIndex`,`window-index`),...a(`windowType`,`window-type`),...a(`windowLayer`,`window-layer`),...s(`windowActive`,`window-active`),...s(`windowFocused`,`window-focused`),...o(`windowRect`,`window-bounds`)}}function re(e){let t=new Map,n=e.indexOf(` `),r=e.lastIndexOf(`>`);if(n<0||r<=n)return t;let i=n;for(;i<r;){let n=ie(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function ie(e,t,n){if(t=g(e,t,n),t>=n||oe(e[t]))return;let r=t;t=ae(e,t,n);let i=e.slice(r,t);if(t=g(e,t,n),!i||e[t]!==`=`)return;t=g(e,t+1,n);let a=e[t];if(!se(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:ue(e.slice(o,s)),nextCursor:s+1}}function ae(e,t,n){for(;t<n&&!le(e[t]??``);)t+=1;return t}function g(e,t,n){for(;t<n&&ce(e[t]??``);)t+=1;return t}function oe(e){return e===`/`||e===`>`}function se(e){return e===`"`||e===`'`}function ce(e){return e===` `||e===`
2
+ `||e===`\r`||e===` `}function le(e){return e===`=`||e===`/`||e===`>`||ce(e)}function ue(e){let t=``,n=0;for(;n<e.length;){let r=e.indexOf(`&`,n);if(r<0){t+=e.slice(n);break}t+=e.slice(n,r);let i=e.indexOf(`;`,r+1);if(i<0){t+=e.slice(r);break}let a=e.slice(r+1,i);t+=de(a)??e.slice(r,i+1),n=i+1}return t}function de(e){switch(e){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return fe(e)}}function fe(e){if(!e.startsWith(`#`))return;let t=e[1]?.toLowerCase()===`x`?16:10,n=t===16?e.slice(2):e.slice(1);if(!n||!pe(n,t))return;let r=Number.parseInt(n,t);if(Number.isFinite(r))try{return String.fromCodePoint(r)}catch{return}}function pe(e,t){for(let n of e){let e=n.charCodeAt(0),r=e>=48&&e<=57;if(t===10){if(!r)return!1;continue}if(!r&&!(e>=65&&e<=70)&&!(e>=97&&e<=102))return!1}return!0}function me(e,t){return e.get(t)??null}function _(e){let t={type:null,label:null,value:null,identifier:null,packageName:null,depth:-1,children:[]},n=[t],r=/<node\b[^>]*>|<\/node>/g,i=r.exec(e);for(;i;){let t=i[0];if(t.startsWith(`</node`)){n.length>1&&n.pop(),i=r.exec(e);continue}let a=f(t),o=n[n.length-1],s={type:a.className,label:a.text||a.desc,value:a.text,identifier:a.resourceId,packageName:a.packageName,rect:a.rect,enabled:a.enabled,visibleToUser:a.visibleToUser,drawingOrder:a.drawingOrder,hittable:a.clickable??a.focusable,scrollable:a.scrollable,canScrollForward:a.canScrollForward,canScrollBackward:a.canScrollBackward,windowIndex:a.windowIndex,windowType:a.windowType,windowLayer:a.windowLayer,windowActive:a.windowActive,windowFocused:a.windowFocused,windowRect:a.windowRect,depth:o.depth+1,parentIndex:void 0,children:[]};o.children.push(s),t.endsWith(`/>`)||n.push(s),i=r.exec(e)}return v(t),be(t),y(t,{actionableContentMemo:new WeakMap}),ye(t),t}function v(e){let t=0;for(let n of e.children)n.visibleToUser!==!1&&(v(n),e.children[t]=n,t+=1);t<e.children.length&&(e.children.length=t)}function y(e,t){for(let n of e.children)y(n,t);if(e.children.length<2)return;let n=e.children,r=n.filter(e=>ge(e,t));r.length!==0&&(e.children=n.filter(e=>!he(e,r)))}function he(e,t){if(e.visibleToUser===!1||e.drawingOrder===void 0||!x(e))return!1;for(let n of t)if(!(n===e||n.drawingOrder<=e.drawingOrder)&&ve(n.rect,e.rect)>=.9)return!0;return!1}function ge(e,t){return e.visibleToUser!==!1&&e.drawingOrder!==void 0&&x(e)&&(_e(e)||b(e,t))}function _e(e){if(e.visibleToUser===!1)return!1;if(e.hittable)return!0;let t=e.label?.trim()??``;if(t&&!T(t))return!0;let n=e.identifier?.trim()??``;return!!(n&&!T(n))}function b(e,t){let n=t.actionableContentMemo.get(e);if(n!==void 0)return n;let r=e.children.some(e=>e.visibleToUser!==!1&&(!!e.hittable||b(e,t)));return t.actionableContentMemo.set(e,r),r}function x(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function ve(e,t){let n=t.width*t.height;return n<=0?0:a(e,t)/n}function ye(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),Ce(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}function be(e){let t=e.children.filter(Se);if(t.length<2)return;let n=t.filter(e=>S(e)&&C(e));if(n.length===0)return;let r=xe(n);e.children=e.children.filter(e=>S(e)?C(e)?r===void 0||e.windowLayer===r:!1:!0)}function xe(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function Se(e){return e.windowIndex!==void 0||e.windowType!==void 0}function S(e){return e.windowType===1}function C(e){return e.windowActive===!0||e.windowFocused===!0}function Ce(e){if(!e.scrollable||!o(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let t=we(e);return!(t&&t.horizontal>t.vertical&&t.horizontal>16)}function we(e){if(!e.rect||e.children.length===0)return null;let t=e.children.map(e=>e.rect).filter(e=>e!==void 0);if(t.length===0)return null;let n=Math.min(...t.map(e=>e.x)),r=Math.max(...t.map(e=>e.x+e.width)),i=Math.min(...t.map(e=>e.y)),a=Math.max(...t.map(e=>e.y+e.height));return{horizontal:Math.max(0,r-n-e.rect.width),vertical:Math.max(0,a-i-e.rect.height)}}function Te(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=Ee(e);return t.interactiveOnly?De(e,a,n,r,i):a.isStructural||a.isVisual?Ae(e,a,r):!0}function Ee(e){let t=w(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!T(e.label??``),hasMeaningfulId:r&&!T(e.identifier??``),isStructural:Me(t),isVisual:t===`imageview`||t===`imagebutton`}}function De(e,t,n,r,i){return ke(e)?!1:e.hittable||o(t.type)&&r?!0:Oe(t,n,r,i)}function Oe(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r?!1:t||n||r}function ke(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function Ae(e,t,n){return e.hittable||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function je(e){if(!e)return!1;let t=w(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function w(e){return e?e.toLowerCase():``}function Me(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function T(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Ne(e,t){let n=t.toLowerCase(),r=[...e.children],i=0;for(;i<r.length;){let e=r[i++],t=e.label?.toLowerCase()??``,a=e.value?.toLowerCase()??``,o=e.identifier?.toLowerCase()??``;if(t.includes(n)||a.includes(n)||o.includes(n))return e;r.push(...e.children)}return null}function Pe(e){let t=0,n=0,r=[...e.children];for(;r.length>0;){let e=r.pop();t+=1,n=Math.max(n,e.depth),r.push(...e.children)}return{rawNodeCount:t,maxDepth:n}}function E(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))Fe(n,t);return Ie(t),{status:t.status,results:t.results}}function Fe(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},k(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){D(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},k(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&O(t)}function Ie(e){D(e),O(e)}function D(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function O(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function k(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function A(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function j(e){if(e===`true`)return!0;if(e===`false`)return!1}function M(t,n,r){if(typeof t!=`number`||!Number.isInteger(t))throw new e(`INVALID_ARGS`,`Android ${r} manifest ${n} must be an integer.`);return t}function N(t,n,r,i){if(t!==r)throw new e(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}const P=`android-snapshot-helper-v1`,F=`uiautomator-xml`,I={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};async function Le(t){let n=await He(t.apkPath);if(n!==t.manifest.sha256)throw new e(`COMMAND_FAILED`,`Android snapshot helper APK checksum mismatch`,{apkPath:t.apkPath,expectedSha256:t.manifest.sha256,actualSha256:n})}function Re(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest must be an object.`);let n=t;return{name:R(n.name,`name`,`android-snapshot-helper`),version:B(n.version,`version`),releaseTag:V(n.releaseTag),assetName:V(n.assetName),apkUrl:Ue(n.apkUrl,`apkUrl`),sha256:Ve(n.sha256),checksumName:V(n.checksumName),packageName:B(n.packageName,`packageName`),versionCode:L(n.versionCode,`versionCode`),instrumentationRunner:B(n.instrumentationRunner,`instrumentationRunner`),minSdk:L(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:L(n.targetSdk,`targetSdk`),outputFormat:R(n.outputFormat,`outputFormat`,F),statusProtocol:R(n.statusProtocol,`statusProtocol`,P),installArgs:z(n.installArgs)}}function L(e,t){return M(e,t,`snapshot helper`)}function R(e,t,n){return N(e,t,n,`snapshot helper`)}function ze(e){return Be(z(e.installArgs))}function z(t){let n=We(t,`installArgs`);if(n[0]!==`install`)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must start with "install".`);if(n.some(e=>e.includes(`\0`)))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs must not contain null bytes.`);let r=n.slice(1).find(e=>!Ge(e));if(r)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function Be(t){let n={};for(let r of t.slice(1)){let t=Ke(r);if(!t)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[t]=!0}return n}function Ve(t){let n=B(t,`sha256`).trim().toLowerCase();if(n.length!==64||!qe(n))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}async function He(e){return await new Promise((t,n)=>{let r=s.createHash(`sha256`),i=c.createReadStream(e);i.on(`error`,n),i.on(`data`,e=>r.update(e)),i.on(`end`,()=>t(r.digest(`hex`)))})}function B(t,n){if(typeof t!=`string`||t.trim().length===0)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest ${n} is required.`);return t}function V(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Ue(e,t){return e===null?null:B(e,t)}function We(t,n){if(!Array.isArray(t)||!t.every(e=>typeof e==`string`))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest ${n} must be a string array.`);return t}function Ge(e){return Ke(e)!==void 0}function Ke(e){if(Object.hasOwn(I,e))return I[e]}function qe(e){for(let t of e){let e=t.charCodeAt(0);if(!(e>=48&&e<=57)&&!(e>=97&&e<=102))return!1}return!0}async function Je(t){let n=H(t),r=await t.adb(W(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs}),{output:a,cleanupDone:o}=await Ye(t,n,r);if(n.outputPath&&!o&&await nt(t.adb,n.outputPath),r.exitCode!==0)throw new e(`COMMAND_FAILED`,`Android snapshot helper failed`,i(r,{helper:a.metadata}));return a}function H(e){let t=U(e.timeoutMs,8e3),n=U(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:U(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:U(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:U(e.commandTimeoutMs,t+5e3),maxDepth:U(e.maxDepth,128),maxNodes:U(e.maxNodes,5e3),packageName:n,runner:U(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function U(e,t){return e===void 0?t:e}function W(e){return[`shell`,`am`,`instrument`,`-w`,`-e`,`waitForIdleTimeoutMs`,String(e.waitForIdleTimeoutMs),`-e`,`waitForIdleQuietMs`,String(e.waitForIdleQuietMs),`-e`,`timeoutMs`,String(e.timeoutMs),`-e`,`maxDepth`,String(e.maxDepth),`-e`,`maxNodes`,String(e.maxNodes),...e.outputPath?[`-e`,`outputPath`,e.outputPath]:[],...e.emitChunks===void 0?[]:[`-e`,`emitChunks`,String(e.emitChunks)],e.runner]}async function Ye(e,t,n){try{return{output:rt(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Xe(e,t,n,r)}}async function Xe(t,n,r,i){if(i instanceof e&&r.exitCode!==0&&i.details?.helper)throw i;let a=await Ze(t,n,r);if(a)return{output:a,cleanupDone:!0};throw new e(`COMMAND_FAILED`,r.exitCode===0?`Android snapshot helper output could not be parsed`:`Android snapshot helper failed before returning parseable output`,{stdout:r.stdout,stderr:r.stderr,exitCode:r.exitCode},i)}async function Ze(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await $e(e.adb,t.outputPath,tt(`${n.stdout}\n${n.stderr}`)??Qe(t))}function Qe(e){return{outputFormat:F,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function $e(e,t,n){let r;try{r=await e(et(t),{allowFailure:!0,timeoutMs:5e3})}catch{return}if(r.exitCode!==0)return;let i=r.stdout.trim();if(!(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`)))return{xml:i,metadata:n}}function et(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function tt(e){try{return K(G(E(e).results))}catch{return null}}async function nt(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function rt(e){let t=E(e),n=G(t.results);return{xml:ot(it(t.status),n),metadata:{...K(n),transport:`instrumentation`}}}function it(e){let t=[];for(let n of e){if(n.agentDeviceProtocol!==`android-snapshot-helper-v1`||n.outputFormat!==`uiautomator-xml`)continue;let{payloadBase64:e}=n;e!==void 0&&t.push({index:q(n.chunkIndex),count:q(n.chunkCount),payloadBase64:e})}return t}function G(t){let n=t.find(e=>e.agentDeviceProtocol===P);if(!n)throw new e(`COMMAND_FAILED`,`Android snapshot helper did not return a final result`);if(n.ok!==`true`)throw new e(`COMMAND_FAILED`,at(n),{errorType:n.errorType,helper:n});return n}function at(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function ot(t,n){if(t.length===0)throw new e(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=st(t),i=Buffer.concat(lt(ct(t,r),r)).toString(`utf8`);if(!i.includes(`<hierarchy`)||!i.includes(`</hierarchy>`))throw new e(`COMMAND_FAILED`,`Android snapshot helper output did not contain XML`,{xml:i});return i}function st(t){let n=t[0]?.count??t.length;if(n<1||t.length!==n||t.some(e=>e.count!==n))throw new e(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{expectedChunks:n,actualChunks:t.length});return n}function ct(t,n){let r=new Map;for(let i of t){if(i.index===void 0||i.index<0||i.index>=n)throw new e(`COMMAND_FAILED`,`Android snapshot helper returned invalid chunk index`,{chunkIndex:i.index,expectedChunks:n});if(r.has(i.index))throw new e(`COMMAND_FAILED`,`Android snapshot helper returned duplicate XML chunks`,{chunkIndex:i.index});r.set(i.index,i.payloadBase64)}return r}function lt(t,n){let r=[];for(let i=0;i<n;i+=1){let a=t.get(i);if(a===void 0)throw new e(`COMMAND_FAILED`,`Android snapshot helper returned incomplete XML chunks`,{missingChunkIndex:i,expectedChunks:n});r.push(Buffer.from(a,`base64`))}return r}function K(e){return{helperApiVersion:e.helperApiVersion,outputFormat:F,waitForIdleTimeoutMs:q(e.waitForIdleTimeoutMs),waitForIdleQuietMs:q(e.waitForIdleQuietMs),timeoutMs:q(e.timeoutMs),maxDepth:q(e.maxDepth),maxNodes:q(e.maxNodes),rootPresent:J(e.rootPresent),captureMode:ut(e.captureMode),windowCount:q(e.windowCount),nodeCount:q(e.nodeCount),truncated:J(e.truncated),elapsedMs:q(e.elapsedMs)}}function ut(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const q=A,J=j,dt=2e3,ft=5e3,Y=new Map,pt=new Map;async function mt(e){if(!At()||!e.adbProvider?.spawn)return;let n=H(e),r=e.deviceKey??`android:default`,i=kt(r,n,e);if(pt.get(r)===i)return;let a=Y.get(r);if(a&&a.identity!==i&&(await X(r),a=void 0),!a)try{a=await _t({deviceKey:r,identity:i,options:e,resolved:n})}catch(e){pt.set(r,i),t({level:`warn`,phase:`android_snapshot_helper_session_disabled`,data:{deviceKey:r,reason:e instanceof Error?e.message:String(e)}});return}try{let e=a.capturedCount>0,t=await bt(a,n);return a.capturedCount+=1,{xml:t.xml,metadata:{...t.metadata,transport:`persistent-session`,sessionReused:e}}}catch(e){throw await X(r),e}}async function X(e){let n=Y.get(e);if(n){Y.delete(e);try{await Z(n,`quit ${Date.now()}`,1e3)}catch{}try{await n.process.kill(`SIGTERM`)}catch{}await vt(n.process,dt);try{await Dt(n)}catch{}t({phase:`android_snapshot_helper_session_stop`,data:{deviceKey:e,port:n.port,capturedCount:n.capturedCount,lifetimeMs:Date.now()-n.startedAtMs}})}}async function ht(e){await X(gt(e))}function gt(e){return`${e.platform}:${e.id}`}async function _t(n){let r=await jt();await n.options.adb([`forward`,`tcp:${r}`,`tcp:${r}`],{allowFailure:!1,timeoutMs:ft});let i=W({...n.resolved,outputPath:void 0,emitChunks:!1}),a=i[i.length-1];if(!a)throw new e(`INVALID_ARGS`,`Android snapshot helper runner was not resolved`);let o=[...i.slice(0,-1),`-e`,`sessionPort`,String(r),a],s=n.options.adbProvider.spawn(o,{allowFailure:!0,captureOutput:!1}),c={identity:n.identity,deviceKey:n.deviceKey,port:r,adb:n.options.adb,process:s,startedAtMs:Date.now(),capturedCount:0};try{return await yt(s,1e4),Y.set(n.deviceKey,c),t({phase:`android_snapshot_helper_session_ready`,data:{deviceKey:n.deviceKey,port:r,packageName:n.resolved.packageName,runner:n.resolved.runner}}),c}catch(e){await Dt(c);try{s.kill(`SIGTERM`)}catch{}throw await vt(s,dt),e}}function vt(e,t){return new Promise(n=>{let r=setTimeout(n,t);e.once(`close`,()=>{clearTimeout(r),n()}),e.once(`exit`,()=>{clearTimeout(r),n()})})}function yt(t,n){return new Promise((r,i)=>{let a=``,o=setTimeout(()=>{i(new e(`COMMAND_FAILED`,`Android snapshot helper session did not become ready`,{output:a,timeoutMs:n}))},n),s=e=>{a+=e.toString(),a.includes(`agentDeviceProtocol=android-snapshot-helper-v1`)&&a.includes(`sessionReady=true`)&&(clearTimeout(o),r())};t.stdout?.on(`data`,s),t.stderr?.on(`data`,s),t.once(`exit`,(t,n)=>{clearTimeout(o),i(new e(`COMMAND_FAILED`,`Android snapshot helper session exited before ready`,{output:a,exitCode:t,signal:n}))}),t.on(`error`,e=>{clearTimeout(o),i(e)})})}async function bt(e,t){let n=`snapshot-${Date.now()}-${Math.random().toString(16).slice(2)}`,r=Math.min(t.commandTimeoutMs,Math.max(t.timeoutMs+1e4,3e3));return xt(await Z(e,`snapshot ${n}`,r),n)}function Z(t,n,r){return new Promise((i,a)=>{let o=l.connect({host:`127.0.0.1`,port:t.port}),s=[],c=setTimeout(()=>{o.destroy(),a(new e(`COMMAND_FAILED`,`Android snapshot helper session request timed out`,{command:n,timeoutMs:r,port:t.port}))},r);o.on(`connect`,()=>{o.write(`${n}\n`)}),o.on(`data`,e=>{s.push(Buffer.from(e))}),o.on(`error`,e=>{clearTimeout(c),a(e)}),o.on(`close`,()=>{clearTimeout(c),i(Buffer.concat(s).toString(`utf8`))})})}function xt(e,t){let{headers:n,xml:r}=St(e);return Ct(n,t),wt(n,r),{xml:r,metadata:Et(n)}}function St(t){let n=t.indexOf(`
3
+
4
+ `);if(n<0)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:t});return{headers:Tt(t.slice(0,n)),xml:t.slice(n+2)}}function Ct(t,n){if(t.agentDeviceProtocol!==`android-snapshot-helper-v1`)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned wrong protocol`,{headers:t});if(t.outputFormat!==`uiautomator-xml`)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned wrong output format`,{headers:t});if(t.requestId!==n)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned stale output`,{headers:t,requestId:n});if(t.ok!==`true`)throw new e(`COMMAND_FAILED`,t.message||t.errorType||`Android snapshot helper session returned an error`,{helper:t})}function wt(t,n){let r=A(t.byteLength);if(r!==void 0&&Buffer.byteLength(n,`utf8`)!==r)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned truncated XML`,{headers:t,actualByteLength:Buffer.byteLength(n,`utf8`)});if(!n.includes(`<hierarchy`)||!n.includes(`</hierarchy>`))throw new e(`COMMAND_FAILED`,`Android snapshot helper session did not return XML`,{headers:t,xml:n})}function Tt(e){let t={};for(let n of e.split(/\r?\n/)){let e=n.indexOf(`=`);e<0||(t[n.slice(0,e)]=n.slice(e+1))}return t}function Et(e){return{helperApiVersion:e.helperApiVersion,outputFormat:F,waitForIdleTimeoutMs:A(e.waitForIdleTimeoutMs),waitForIdleQuietMs:A(e.waitForIdleQuietMs),timeoutMs:A(e.timeoutMs),maxDepth:A(e.maxDepth),maxNodes:A(e.maxNodes),rootPresent:j(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:A(e.windowCount),nodeCount:A(e.nodeCount),truncated:j(e.truncated),elapsedMs:A(e.elapsedMs)}}async function Dt(e){await e.process.stdin?.end(),await e.process.stdout?.destroy(),await e.process.stderr?.destroy(),await Ot(e)}async function Ot(e){await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:ft})}function kt(e,t,n){return JSON.stringify({deviceKey:e,packageName:t.packageName,runner:t.runner,helperVersion:n.helperVersion,helperVersionCode:n.helperVersionCode,waitForIdleTimeoutMs:t.waitForIdleTimeoutMs,waitForIdleQuietMs:t.waitForIdleQuietMs,timeoutMs:t.timeoutMs,maxDepth:t.maxDepth,maxNodes:t.maxNodes})}function At(){let e=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}function jt(){return new Promise((e,t)=>{let n=l.createServer();n.unref(),n.on(`error`,t),n.listen(0,`127.0.0.1`,()=>{let r=n.address();if(!r||typeof r==`string`){n.close(()=>t(Error(`Failed to allocate a local TCP port`)));return}let i=r.port;n.close(()=>e(i))})})}const Q=new Map;function Mt(e){$(Nt(e.deviceKey,e.packageName,e.versionCode))}function Nt(e,t,n){return e?`${e}\0${t}\0${n}`:void 0}function Pt(e,t){e&&Q.set(e,t)}function $(e){e&&Q.delete(e)}async function Ft(e){let{adb:t,artifact:r}=e,i=e.installPolicy??`missing-or-outdated`,a=r.manifest.packageName,o=r.manifest.versionCode;if(i===`never`)return{packageName:a,versionCode:o,installed:!1,reason:`skipped`};let s=Nt(e.deviceKey,a,o),c=s?Q.get(s):void 0;if(s&&i!==`always`&&c!==void 0)return{packageName:a,versionCode:o,installedVersionCode:c,installed:!1,reason:`current`};let l=await It(t,a,e.timeoutMs),u=Bt(i,l,o);if(u===`current`){if(l===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Pt(s,l),{packageName:a,versionCode:o,installedVersionCode:l,installed:!1,reason:u}}await Le(r);let d=await Lt(t,e.adbProvider??t,r.apkPath,ze(r.manifest),{packageName:a,timeoutMs:e.timeoutMs});if(d.exitCode!==0)throw $(s),n(`Failed to install Android snapshot helper`,d,{packageName:a,versionCode:o});return Pt(s,o),{packageName:a,versionCode:o,installedVersionCode:l,installed:!0,reason:u}}async function It(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n});if(r.exitCode===0)return Rt(`${r.stdout}\n${r.stderr}`,t)}async function Lt(e,t,n,i,a){let o=async()=>await r(n,{allowFailure:!0,provider:t,...i,timeoutMs:a.timeoutMs}),s=await o();if(s.exitCode===0||!zt(s))return s;let c=await e([`uninstall`,a.packageName],{allowFailure:!0,timeoutMs:a.timeoutMs}),l=await o();return l.exitCode===0?l:{...l,stderr:[l.stderr,c.stderr?`Previous uninstall stderr after INSTALL_FAILED_UPDATE_INCOMPATIBLE: ${c.stderr}`:``].filter(Boolean).join(`
5
+ `)}}function Rt(e,t){let n=`package:${t}`;for(let t of e.split(/\r?\n/)){if(!t.startsWith(n)||t.length>n.length&&!/\s/.test(t[n.length]??``))continue;let e=/(?:^|\s)versionCode:(\d+)(?:\s|$)/.exec(t);if(e)return Number(e[1])}}function zt(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Bt(e,t,n){return e===`never`?`skipped`:e===`always`?`forced`:t===void 0?`missing`:t<n?`outdated`:`current`}export{u as _,X as a,Re as c,N as d,A as f,_ as g,ee as h,gt as i,E as l,p as m,Mt as n,ht as o,d as p,mt as r,Je as s,Ft as t,M as u};
@@ -0,0 +1 @@
1
+ const e=new Set([`healthy`,`recovered`,`sparse`]),t=new Set([`tree`,`queries`,`private-ax`]),n=new Set([`ax-rejected`,`sparse-tree`,`budget`,`no-nodes`,`capture-failed`]);function r(r){if(!r||typeof r!=`object`)return;let i=r;if(!(typeof i.state!=`string`||!e.has(i.state))&&!(typeof i.backend!=`string`||!t.has(i.backend)))return{state:i.state,backend:i.backend,reason:typeof i.reason==`string`?i.reason:void 0,reasonCode:typeof i.reasonCode==`string`&&n.has(i.reasonCode)?i.reasonCode:void 0,effectiveDepth:typeof i.effectiveDepth==`number`?i.effectiveDepth:void 0,collapsedLeafIndexes:Array.isArray(i.collapsedLeafIndexes)?i.collapsedLeafIndexes.filter(e=>typeof e==`number`):void 0}}function i(e){return e?.state===`sparse`}function a(e,t){return[...o(e),...s(e),...c(e,t)]}function o(e){if(e.state===`recovered`){let t=e.reasonCode===`budget`?` The primary capture ran out of its time budget (busy app or simulator); the recovered tree is authoritative for this screen.`:` This usually means the app publishes an unhealthy accessibility tree — fixing the app's accessibility is the real cure. Treat screenshot as visual truth when this warning appears.`;return[`Recovered this snapshot with the ${e.backend} accessibility backend`+(e.reason?` after: ${e.reason}.`:`.`)+t]}return e.state===`sparse`?[`No snapshot backend could read this screen`+(e.reason?` (${e.reason})`:``)+`. Use screenshot as visual truth and coordinate taps; retry snapshot after navigating.`]:[]}function s(e){return e.effectiveDepth===void 0?[]:[`The accessibility server rejected deeper requests; this tree is capped at depth ${e.effectiveDepth} — re-run with --depth ${e.effectiveDepth} --scope <container> for deeper content.`]}function c(e,t){let n=[];for(let r of e.collapsedLeafIndexes??[]){let e=t.find(e=>e.index===r);if(!e)continue;let i=e.identifier?` (${e.identifier})`:``;n.push(`@${e.ref} [${e.type??`element`}]${i} merges many labels into a single accessibility element. The app likely marks a container as accessible, which hides every descendant from assistive tech and automation — the children cannot be addressed individually. Fix the app's accessibility (mark the rows, not the container); until then use screenshot as visual truth and coordinate taps.`)}return n}export{r as n,a as r,i as t};
@@ -1,2 +1 @@
1
- import{__webpack_require__ as e}from"./rslib-runtime.js";import{promises as t}from"node:fs";import a from"node:os";import n from"node:path";import{isMacOs as s,centerOfRect as o,isIosFamily as r,publicPlatformString as i}from"./6849.js";import{normalizeError as l,AppError as d}from"./485.js";import{withDiagnosticTimer as p,emitDiagnostic as u}from"./8875.js";import{pressAndroid as c,backAndroid as f}from"./input-actions.js";import{runAppleRunnerCommand as m,createDaemonRuntimeSessionStore as h,captureSnapshot as w,dispatchCommand as g,requireCommandSupported as y,runMacOsAlertAction as _,errorResponse as v,annotateScreenshotWithRefs as S,resolveSnapshotScope as b,snapshotAndroid as I,context_contextFromFlags as A}from"./9722.js";import{SETTINGS_INVALID_ARGS_MESSAGE as C,parseTimeout as R,getUnsupportedMacOsSettingMessage as N,successText as M,isMacOsSettingSupported as k,snapshotCaptureAnnotationsFrom as D}from"./2948.js";import{sleep as K}from"./5560.js";import{buildAppleRunnerRequestOptions as x}from"./8414.js";import{buildSnapshotSession as P,dispatchWaitViaRuntime as E,createDaemonRuntimePolicy as U,recordIfSession as L,resolveSessionDevice as O,withSessionlessRunnerCleanup as B}from"./selector-runtime.js";import{createAgentDevice as H}from"./7871.js";import{summarizeSnapshotDiagnostics as $}from"./5913.js";var q={};e.r(q),e.d(q,{handleSnapshotCommands:()=>ev});let F=new Set(["com.android.permissioncontroller","com.google.android.permissioncontroller","com.google.android.packageinstaller","com.android.packageinstaller"]),j=new Set(["android","com.android.systemui"]),T=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,z=/^android:id\/button[123]$/i,G=/(?:^|:)id\/permission_/i,V=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,W=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,J=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function Q(e,t){let a=t[0];if(!a)return;let n=X(e,a.index);for(let a of t.slice(1)){let t=new Set(X(e,a.index));for(let e=n.length-1;e>=0;e-=1)t.has(n[e])||n.splice(e,1)}return n[n.length-1]}function X(e,t){let a=new Map(e.map(e=>[e.index,e])),n=[],s=a.get(t);for(;s;)n.push(s.index),s=void 0===s.parentIndex?void 0:a.get(s.parentIndex);return n.reverse()}function Y(e,t){let a=new Map;for(let t of e){if(void 0===t.parentIndex)continue;let e=a.get(t.parentIndex)??[];e.push(t),a.set(t.parentIndex,e)}let n=new Set([t]),s=[t];for(let e of s)for(let t of a.get(e)??[])n.has(t.index)||(n.add(t.index),s.push(t.index));return e.filter(e=>n.has(e.index))}function Z(e){let t=e.type??"",a=e.identifier??"";return!!(e.hittable||/\bbutton\b/i.test(t)||z.test(a)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(a))}function ee(e){if(!e)return"";let t=[e.label,e.value].filter(e=>"string"==typeof e&&e.trim().length>0);return t[0]?.trim()??""}async function et(e,t,a={}){if("wait"===t)return await ea(e,a.timeoutMs??1e4);if("get"===t){var n;let t=await eo(e);return{kind:"alertStatus",platform:"android",action:"get",alert:n=t?.alert??null,...n?M("Alert visible"):M("No alert visible")}}return await en(e,t)}async function ea(e,t){let a=Date.now(),n=await es(e,t);if(!n)throw new d("COMMAND_FAILED","alert wait timed out");return{kind:"alertWait",platform:"android",action:"wait",alert:n.alert,waitedMs:Date.now()-a,...M("Alert visible")}}async function en(e,t){var a;let n,s,o=await es(e,2e3);if(!o)throw new d("COMMAND_FAILED","alert not found",{hint:"If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref."});let r=(a=o.buttons,n="accept"===t?"accept":"dismiss",(s=a.find(e=>e.role===n))||("dismiss"===t?a.find(e=>"neutral"===e.role)??null:1===a.length?a[0]??null:null));if(r)return await c(e,r.x,r.y),er(t,o.alert,r.label);if("dismiss"===t)return await f(e),er(t,o.alert,"Back");throw new d("COMMAND_FAILED","alert accept found an alert but no accept button",{alert:o.alert,hint:"Inspect alert get --json for visible buttons, then use press by visible label/ref if needed."})}async function es(e,t){let a=Date.now();for(;Date.now()-a<t;){let t=await eo(e);if(t)return t;await K(300)}return null}async function eo(e){return function(e){var t,a,n,s;let r,i=function(e){let t=e.filter(e=>{var t;let a;return a=(t=e).bundleId??"",F.has(a)||G.test(t.identifier??"")});if(t.length)return{nodes:t,source:"permission"};let a=function(e){let t=e.filter(e=>{var t;let a;return a=(t=e).bundleId??"",j.has(a)&&V.test(ee(t))});if(0===t.length)return[];let a=Q(e,t);return void 0===a?t:Y(e,a).filter(e=>e.bundleId&&j.has(e.bundleId))}(e);return a.length?{nodes:a,source:"system-dialog"}:{nodes:function(e){var t;let a,n,s=e.filter(e=>{var t;return t=e.type??"",/(?:^|[.$])[^.]*Dialog$/i.test(t)}),o=e.filter(e=>T.test(e.identifier??"")),r=s.length?[...s,...o]:(a=(t=o).some(e=>z.test(e.identifier??"")),n=t.some(e=>!z.test(e.identifier??"")),a&&n?t:[]);if(0===r.length)return[];let i=Q(e,r);return void 0===i?r:Y(e,i)}(e),source:"native-dialog"}}(e),l=i.nodes;if(0===l.length)return null;let d=function(e){let t=new Set,a=[];for(let n of e){let e=ee(n);if(!e||!n.rect||!Z(n))continue;let s=e.trim().toLowerCase();if(!s||t.has(s))continue;t.add(s);let r=o(n.rect);a.push({label:e,x:r.x,y:r.y,role:function(e,t){var a;let n=(a=e.identifier??"",/(?:^|:)id\/button1$/i.test(a)?"accept":/(?:^|:)id\/button2$/i.test(a)?"dismiss":/(?:^|:)id\/button3$/i.test(a)?"neutral":/(?:^|:)id\/permission_allow/i.test(a)?"accept":/(?:^|:)id\/permission_deny/i.test(a)?"dismiss":null);return n||(W.test(t.trim())?"accept":J.test(t.trim())?"dismiss":"neutral")}(n,e)})}return a}(l),p=l.filter(e=>ee(e)&&!Z(e)),u=ee((t=p).find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??"")))||ee(t[0]),c=(a=p,n=u,(r=a.map(e=>ee(e)).filter(e=>e&&e!==n)).length?[...new Set(r)].join("\n"):void 0),f=(s=l,s.find(e=>e.bundleId)?.bundleId);return{alert:{...u?{title:u}:{},...c?{message:c}:{},buttons:d.map(e=>e.label),platform:"android",source:i.source,...f?{packageName:f}:{}},buttons:d}}((await p("snapshot_capture",async()=>await I(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:"android",purpose:"alert"})).nodes)}function er(e,t,a){return{kind:"alertHandled",platform:"android",action:e,handled:!0,alert:t,button:a,...M(`Alert ${e}ed`)}}async function ei(e){var t;let{req:a,logPath:n,session:o,device:r}=e,i="accept"===(t=a.positionals?.[0])||"dismiss"===t||"wait"===t?t:"get",l=o?"frontmost-app"===o.surface?{surface:"frontmost-app"}:{bundleId:o.appBundleId,surface:o.surface}:{},d=y("alert",r);if(d)return d;if("android"===r.platform){let t=R(a.positionals?.[1])??1e4;return eu(e,await et(r,i,{timeoutMs:t}))}if(s(r)){let t=async e=>await _(e,l);return await el(e,i,t)}let p=x({req:a,logPath:n,traceLogPath:o?.trace?.outPath}),u=async e=>await m(r,{command:"alert",action:e,appBundleId:o?.appBundleId},p);return await el(e,i,u)}async function el(e,t,a){if("wait"===t)return await ed(e,a);let n="accept"===t||"dismiss"===t?t:"get";return"accept"===n||"dismiss"===n?await ep(e,n,a):eu(e,await a("get"))}async function ed(e,t){let a=R(e.req.positionals?.[1])??1e4,n=Date.now();for(;Date.now()-n<a;){try{return eu(e,await t("get"))}catch{}await K(300)}return v("COMMAND_FAILED","alert wait timed out")}async function ep(e,t,a){var n,s;let o,r,i=Date.now();for(;Date.now()-i<2e3;){try{return eu(e,await a(t))}catch(t){r=t;let e=String(t?.message??"").toLowerCase();if(!e.includes("alert not found")&&!e.includes("no alert"))break}await K(300)}throw(n=r)instanceof d&&(s=n,(o=String(s?.message??"").toLowerCase()).includes("alert not found")||o.includes("no alert"))?new d(n.code,n.message,{...n.details??{},hint:"If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref."}):n}function eu(e,t){return L(e.sessionStore,e.session,e.req,t),{ok:!0,data:t}}async function ec(e){let{req:t,logPath:a,sessionStore:n,session:o,device:r,parsed:i}=e,{setting:l,state:d,appBundleId:p,permissionTarget:u,latitude:c,longitude:f}=i,m=y("settings",r);if(m)return m;if(s(r)&&!k(l))return v("INVALID_ARGS",N(l));let h=p??o?.appBundleId;if("clear-app-state"===l&&!h)return v("INVALID_ARGS","settings clear-app-state requires an app id when no app is bound to the session");let w="clear-app-state"===l?[l,d,h??""]:"permission"===l?[l,d,u??"",t.positionals?.[3]??"",h??""]:"location"===l&&"set"===d?[l,d,c??"",f??"",h??""]:[l,d,h??""],_=await g(r,"settings",w,t.flags?.out,{...A(a,t.flags,h,o?.trace?.outPath)});return L(n,o,t,_??{setting:l,state:d}),{ok:!0,data:_??{setting:l,state:d}}}async function ef(e){var t,a;let n;if("snapshot"!==e.command||"android"!==e.device.platform)return;let s=l(e.error);if("COMMAND_FAILED"===(t=s).code&&(a=t,n=`${a.message}
2
- ${a.hint??""}`,/Android UI hierarchy dump timed out/i.test(n)||/Stock UIAutomator fallback was skipped/i.test(n)||/Android accessibility snapshots can be blocked/i.test(n)||function(e){if(!e||"object"!=typeof e)return!1;let t=String(e.errorType??""),a=String(e.message??"");return/TimeoutException/i.test(t)||/timed out/i.test(a)}(t.details?.helper)||function(e){var t;if(!e)return!1;let a=e?.timeoutMs,n=e?.cmd,s=Array.isArray(t=e?.args)?t.map(String):"string"==typeof t?t.split(/\s+/):[];return"number"==typeof a&&"adb"===n&&s.includes("uiautomator")&&s.includes("dump")}(t.details)))return{ok:!1,error:{...s,details:{...s.details??{},androidSnapshotTimeoutScreenshot:await em(e)}}}}async function em(e){try{var s,o,r;let i=await t.mkdtemp(n.join(a.tmpdir(),"agent-device-android-snapshot-timeout-")),l=n.join(i,"snapshot-timeout-overlay-refs.png"),d=(s=await g(e.device,"screenshot",[l],void 0,{...A(e.logPath,{screenshotNoStabilize:!0},e.session?.appBundleId,e.session?.trace?.outPath),surface:e.session?.surface}),o=l,(r=s,"object"==typeof r&&null!==r&&"path"in r&&"string"==typeof r.path)?s.path:o);await t.access(d);let p=await eh(d,e.session);return u({level:"warn",phase:"android_snapshot_timeout_screenshot_captured",data:{path:d,overlayRefCount:"overlayRefCount"in p?p.overlayRefCount:void 0,overlayRefsAnnotated:"overlayRefsAnnotated"in p?p.overlayRefsAnnotated:void 0}}),p}catch(t){let e=l(t);return u({level:"warn",phase:"android_snapshot_timeout_screenshot_failed",data:{error:e.message}}),{captureFailed:!0,error:e.message}}}async function eh(e,t){if(!t?.snapshot)return{path:e,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:"unavailable",overlayRefCount:0};try{let a=await S({screenshotPath:e,snapshot:t.snapshot});return{path:e,overlayRefsRequested:!0,overlayRefsAnnotated:a.length>0,overlayRefCount:a.length,overlayRefSource:"session-snapshot",overlayRefs:a}}catch(a){let t=l(a);return u({level:"warn",phase:"android_snapshot_timeout_screenshot_overlay_failed",data:{path:e,error:t.message}}),{path:e,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:"session-snapshot",overlayRefCount:0,overlayAnnotationError:t.message}}}async function ew(e){return await ey({...e,command:"snapshot",unsupportedMessage:"snapshot is not supported on this device",execute:async({runtime:e,sessionName:t,req:a,snapshotScope:n})=>{let s=await e.capture.snapshot({session:t,interactiveOnly:a.flags?.snapshotInteractiveOnly,depth:a.flags?.snapshotDepth,scope:n,raw:a.flags?.snapshotRaw,forceFull:a.flags?.snapshotForceFull});return{data:s,record:{kind:"snapshot",nodes:s.nodes.length,truncated:s.truncated}}}})}async function eg(e){return await ey({...e,command:"diff",unsupportedMessage:"diff is not supported on this device",execute:async({runtime:e,sessionName:t,req:a,snapshotScope:n})=>{let s=await e.capture.diffSnapshot({session:t,interactiveOnly:a.flags?.snapshotInteractiveOnly,depth:a.flags?.snapshotDepth,scope:n,raw:a.flags?.snapshotRaw});return{data:s,record:{kind:"diff",mode:"snapshot",baselineInitialized:s.baselineInitialized,summary:s.summary}}}})}async function ey(e){var t,a;let{req:n,sessionName:s,logPath:o,sessionStore:l}=e,{session:p,device:u}=await O(l,s,n.flags),c=y(e.command,u,{message:e.unsupportedMessage});if(c)return c;let f=b(n.flags?.snapshotScope,p);if(!f.ok)return f;let m=(t=e.command,a=p,!r(u)||a?.appBundleId?null:v("SESSION_NOT_FOUND",`iOS ${t} requires an active app session on the target device. Run open first (for example: open --session ${a?.name??"sim"} --platform ios --device "<name>" <app>).`));return m||await B(p,u,async()=>{var t,a;let r,c,m=function(e){let{req:t,sessionName:a,logPath:n,sessionStore:s,session:o,device:r,snapshotScope:l}=e;return H({backend:function(e){let{req:t,logPath:a,session:n,device:s,snapshotScope:o}=e;return{platform:i(s),captureSnapshot:async(e,r)=>{let i=await w({device:s,session:n,flags:t.flags,outPath:r?.outPath??t.flags?.out,logPath:a,snapshotScope:o}),l=$(n);return{snapshot:i.snapshot,...D(i),...l?{snapshotDiagnostics:l}:{},appName:n?.appBundleId?n.appName??n.appBundleId:void 0,appBundleId:n?.appBundleId}}}}({req:t,logPath:n,session:o,device:r,snapshotScope:l}),...U("snapshot"),sessions:h({sessionName:a,getSession:()=>s.get(a),recordOptions:{includeSnapshot:!0},setRecord:e=>{var n;let o=function(e){if(!e.snapshot)throw new d("UNKNOWN","snapshot runtime did not produce session state");return e}(e),i=s.get(a);s.set(a,function(e){var t,a;let{current:n,sessionName:s,device:o,record:r,refScopedSnapshot:i}=e,l=(t=n,a=r,i&&a.snapshot?.nodes.length===0&&t?.snapshot!==void 0),d=l?n.snapshot:r.snapshot,p=P({session:n,sessionName:s,device:o,snapshot:d,appBundleId:r.appBundleId});return p.snapshotScopeSource=function(e){let{current:t,keepCurrentSnapshot:a,refScopedSnapshot:n}=e;if(n)return a?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}({current:n,keepCurrentSnapshot:l,refScopedSnapshot:i}),r.appName&&(p.appName=r.appName),p}({current:i,sessionName:a,device:r,record:o,refScopedSnapshot:(n=t,n.flags?.snapshotScope?.trim().startsWith("@")===!0)}))}})})}({req:n,sessionName:s,logPath:o,sessionStore:l,session:p,device:u,snapshotScope:f.scope});try{c=await e.execute({runtime:m,sessionName:s,req:n,snapshotScope:f.scope})}catch(a){let t=await ef({error:a,command:e.command,logPath:o,session:p,device:u});if(!t)throw a;return t}return(r=(t={req:n,sessionName:s,sessionStore:l,result:c.record}).sessionStore.get(t.sessionName))&&t.sessionStore.recordAction(r,{command:t.req.command,positionals:t.req.positionals??[],flags:t.req.flags??{},result:"snapshot"===(a=t.result).kind?{nodes:a.nodes,truncated:a.truncated}:{mode:a.mode,baselineInitialized:a.baselineInitialized,summary:a.summary}}),{ok:!0,data:c.data}})}let e_={snapshot:async({req:e,sessionName:t,logPath:a,sessionStore:n})=>await ew({req:e,sessionName:t,logPath:a,sessionStore:n}),diff:async({req:e,sessionName:t,logPath:a,sessionStore:n})=>e.positionals?.[0]!=="snapshot"?v("INVALID_ARGS","diff currently supports only: diff snapshot"):await eg({req:e,sessionName:t,logPath:a,sessionStore:n}),wait:async({req:e,sessionName:t,logPath:a,sessionStore:n})=>await E({req:e,sessionName:t,logPath:a,sessionStore:n}),alert:async({req:e,sessionName:t,logPath:a,sessionStore:n})=>{let{session:s,device:o}=await O(n,t,e.flags);return await B(s,o,async()=>await ei({req:e,logPath:a,sessionStore:n,session:s,device:o}))},settings:async({req:e,sessionName:t,logPath:a,sessionStore:n})=>{let s,o,r,i=(s=e.positionals?.[0]?.toLowerCase(),o=e.positionals?.[1]?.toLowerCase(),r=e.positionals?.[2]?.toLowerCase(),"clear-app-state"===s?{ok:!0,parsed:{setting:s,state:"clear",appBundleId:"clear"===o?e.positionals?.[2]:e.positionals?.[1]}}:s&&o&&("permission"!==s||r)&&("location"!==s||"set"!==o||e.positionals?.[2]&&e.positionals?.[3])?{ok:!0,parsed:{setting:s,state:o,permissionTarget:r,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}:v("INVALID_ARGS",C));if(!i.ok)return i;let{session:l,device:d}=await O(n,t,e.flags);return await B(l,d,async()=>await ec({req:e,logPath:a,sessionStore:n,session:l,device:d,parsed:i.parsed}))}};async function ev(e){let t=e_[e.req.command];return t?await t(e):null}export{q as snapshot_namespaceObject};
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{j as n}from"./sdk-android-adb.js";import{n as r,t as i}from"./tool-provider2.js";import a from"node:fs";import o from"node:path";import{fileURLToPath as s}from"node:url";const c={"push button":`Button`,"toggle button":`Button`,"push button menu":`Button`,label:`StaticText`,static:`StaticText`,caption:`StaticText`,text:`TextField`,entry:`TextField`,"password text":`TextField`,"spin button":`TextField`,terminal:`TextArea`,"document text":`TextArea`,paragraph:`TextArea`,frame:`Window`,window:`Window`,dialog:`Dialog`,alert:`Alert`,"file chooser":`Dialog`,"color chooser":`Dialog`,"font chooser":`Dialog`,panel:`Group`,filler:`Group`,section:`Group`,form:`Group`,grouping:`Group`,"layered pane":`Group`,"glass pane":`Group`,"root pane":`Group`,"option pane":`Group`,"internal frame":`Group`,"desktop frame":`Group`,"block quote":`Group`,article:`Group`,comment:`Group`,landmark:`Group`,log:`Group`,marquee:`Group`,math:`Group`,notification:`Group`,"content deletion":`Group`,"content insertion":`Group`,mark:`Group`,suggestion:`Group`,"scroll pane":`ScrollArea`,"scroll bar":`ScrollBar`,"menu bar":`MenuBar`,menu:`Menu`,"popup menu":`Menu`,"menu item":`MenuItem`,"check menu item":`MenuItem`,"radio menu item":`MenuItem`,"tearoff menu item":`MenuItem`,"check box":`CheckBox`,"radio button":`RadioButton`,switch:`Switch`,"combo box":`ComboBox`,"page tab":`Tab`,"page tab list":`TabList`,table:`Table`,"tree table":`Table`,"table cell":`Cell`,"table row":`Row`,"table column header":`Cell`,"table row header":`Cell`,"column header":`Cell`,"row header":`Cell`,list:`List`,"list item":`ListItem`,"list box":`List`,tree:`Tree`,"tree item":`TreeItem`,"description list":`List`,"description term":`ListItem`,"description value":`ListItem`,"tool bar":`Toolbar`,"status bar":`StatusBar`,"info bar":`StatusBar`,slider:`Slider`,"progress bar":`ProgressBar`,"level bar":`ProgressBar`,image:`Image`,icon:`Image`,animation:`Image`,canvas:`Image`,"drawing area":`Image`,video:`Video`,audio:`Audio`,link:`Link`,hyperlink:`Link`,separator:`Separator`,application:`Application`,"tool tip":`Tooltip`,timer:`Timer`,heading:`Heading`,footnote:`Footnote`,"title bar":`TitleBar`,"date editor":`DateEditor`,rating:`Slider`};function l(e){let t=e.toLowerCase().trim();return c[t]||t.split(/[\s_-]+/).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)}const u=`atspi-dump.py`;let d=null;function f(){if(d)return d;let e=o.dirname(s(import.meta.url));for(let t=0;t<5;t++){let n=o.join(e,`src`,`platforms`,`linux`,u);if(a.existsSync(n))return d=n,n;if(t===0){let t=o.join(e,u);if(a.existsSync(t))return d=t,t}e=o.dirname(e)}throw new t(`TOOL_MISSING`,`Cannot find ${u}. Ensure the agent-device package is installed correctly.`)}async function p(e,n={}){let a=i().accessibility;if(a)return await a.captureTree(e,n);if(process.platform!==`linux`)throw new t(`UNSUPPORTED_PLATFORM`,`AT-SPI2 bridge is only available on Linux`);if(!await i().whichCommand(`python3`))throw new t(`TOOL_MISSING`,`python3 is required for AT-SPI2 accessibility snapshots on Linux.`);let o=n.maxNodes??1500,s=n.maxDepth??12,c=n.maxApps??24,u=await r(`python3`,[f(),`--surface`,e,`--max-nodes`,String(o),`--max-depth`,String(s),`--max-apps`,String(c)],{allowFailure:!0,timeoutMs:3e4});if(u.exitCode!==0){let e=u.stderr.trim();throw e.includes(`No module named`)||e.includes(`gi.require_version`)?new t(`TOOL_MISSING`,`AT-SPI2 Python bindings not found. Install python3-gi and gir1.2-atspi-2.0.`,{cause:e}):new t(`COMMAND_FAILED`,`AT-SPI2 snapshot failed (exit ${u.exitCode}): ${e||u.stdout}`)}let d;try{d=JSON.parse(u.stdout)}catch{throw new t(`COMMAND_FAILED`,`AT-SPI2 snapshot returned invalid JSON: ${u.stdout.slice(0,200)}`)}if(d.error)throw new t(`COMMAND_FAILED`,`AT-SPI2: ${d.error}`);return{nodes:(d.nodes??[]).map(e=>({index:e.index,type:l(e.role),role:e.role,label:e.label??void 0,value:e.value??void 0,rect:e.rect??void 0,enabled:e.enabled??void 0,selected:e.selected??void 0,hittable:e.hittable??void 0,depth:e.depth,parentIndex:e.parentIndex??void 0,pid:e.pid??void 0,appName:e.appName??void 0,windowTitle:e.windowTitle??void 0})),truncated:d.truncated,surface:e}}var m=e({readLinuxTextAtPoint:()=>_,snapshotLinux:()=>g});function h(e){return e===`desktop`?`desktop`:e===`frontmost-app`||e===`app`?`frontmost-app`:(e===`menubar`&&n({level:`warn`,phase:`linux_snapshot`,data:{message:`menubar surface is not supported on Linux, falling back to desktop`}}),`desktop`)}async function g(e){let t=await p(h(e));return{nodes:t.nodes,truncated:t.truncated}}async function _(e,t,n){let{nodes:r}=await g(n),i=r.filter(n=>{let r=n.rect;return r?e>=r.x&&t>=r.y&&e<=r.x+r.width&&t<=r.y+r.height:!1}).sort((e,t)=>{let n=e.depth??0,r=t.depth??0;return n===r?v(e.rect)-v(t.rect):r-n});for(let e of i){let t=y(e);if(t.trim())return t}return``}function v(e){return(e?.width??0)*(e?.height??0)}function y(e){for(let t of[e.value,e.label,e.identifier])if(typeof t==`string`&&t.length>0)return t;return``}export{m as n,g as t};
@@ -0,0 +1,2 @@
1
+ import{B as e,F as t,O as n,b as r,m as i,p as a}from"./sdk-contracts.js";import{F as o,j as s}from"./sdk-android-adb.js";import{b as c}from"./sdk-batch.js";import{i as l}from"./snapshot-diagnostics.js";import{t as u}from"./timeouts.js";import{Ct as ee,St as te,Tt as d,bt as f,gn as p,sn as m}from"./device-rotation.js";import{t as h}from"./runtime.js";import{i as g}from"./runner-client.js";import{i as ne}from"./helper.js";import{Dt as _,Ht as v,It as y,Mt as re,Qt as b,Tt as x,Xt as S,bt as C,jt as ie,wt as ae}from"./internal/daemon.js";import{l as oe,n as se}from"./input-actions.js";import{t as ce}from"./apple-runner-options.js";import{C as w,S as T,b as le,i as ue,o as de,x as E}from"./selector-runtime.js";import{promises as D}from"node:fs";import fe from"node:os";import O from"node:path";const k=new Set([`com.android.permissioncontroller`,`com.google.android.permissioncontroller`,`com.google.android.packageinstaller`,`com.android.packageinstaller`]),A=new Set([`android`,`com.android.systemui`]),j=/^android:id\/(?:alertTitle|message|button[123]|parentPanel|buttonPanel|contentPanel)$/i,M=/^android:id\/button[123]$/i,N=/(?:^|:)id\/permission_/i,P=/\b(?:is(?:n't| not) responding|keeps stopping|has stopped|close app|app info)\b/i,F=/^(?:ok|allow|allow all|while using the app|only this time|yes|continue|save|confirm|turn on|open settings)$/i,I=/^(?:cancel|deny|don.t allow|don’t allow|not now|no|dismiss|close|close app|later|skip)$/i;function L(e){let t=z(e),n=t.nodes;if(n.length===0)return null;let r=he(n),i=n.filter(e=>K(e)&&!G(e)),a=ve(i),o=ye(i,a),s=Se(n);return{alert:{...a?{title:a}:{},...o?{message:o}:{},buttons:r.map(e=>e.label),platform:`android`,source:t.source,...s?{packageName:s}:{}},buttons:r}}function R(e,t){let n=t===`accept`?`accept`:`dismiss`;return e.find(e=>e.role===n)||(t===`dismiss`?e.find(e=>e.role===`neutral`)??null:e.length===1?e[0]??null:null)}function z(e){let t=e.filter(e=>be(e));if(t.length)return{nodes:t,source:`permission`};let n=me(e);return n.length?{nodes:n,source:`system-dialog`}:{nodes:B(e),source:`native-dialog`}}function B(e){let t=e.filter(e=>V(e.type??``)),n=e.filter(e=>j.test(e.identifier??``)),r=t.length?[...t,...n]:pe(n);if(r.length===0)return[];let i=H(e,r);return i===void 0?r:W(e,i)}function V(e){return/(?:^|[.$])[^.]*Dialog$/i.test(e)}function pe(e){let t=e.some(e=>M.test(e.identifier??``)),n=e.some(e=>!M.test(e.identifier??``));return t&&n?e:[]}function me(e){let t=e.filter(e=>xe(e));if(t.length===0)return[];let n=H(e,t);return n===void 0?t:W(e,n).filter(e=>e.bundleId&&A.has(e.bundleId))}function he(e){let t=new Set,r=[];for(let i of e){let e=K(i);if(!e||!i.rect||!G(i))continue;let a=e.trim().toLowerCase();if(!a||t.has(a))continue;t.add(a);let o=n(i.rect);r.push({label:e,x:o.x,y:o.y,role:ge(i,e)})}return r}function ge(e,t){return _e(e.identifier??``)||(F.test(t.trim())?`accept`:I.test(t.trim())?`dismiss`:`neutral`)}function _e(e){return/(?:^|:)id\/button1$/i.test(e)?`accept`:/(?:^|:)id\/button2$/i.test(e)?`dismiss`:/(?:^|:)id\/button3$/i.test(e)?`neutral`:/(?:^|:)id\/permission_allow/i.test(e)?`accept`:/(?:^|:)id\/permission_deny/i.test(e)?`dismiss`:null}function ve(e){return K(e.find(e=>/(?:^|:)id\/(?:alertTitle|permission_message)$/i.test(e.identifier??``)))||K(e[0])}function ye(e,t){let n=e.map(e=>K(e)).filter(e=>e&&e!==t);return n.length?[...new Set(n)].join(`
2
+ `):void 0}function H(e,t){let n=t[0];if(!n)return;let r=U(e,n.index);for(let n of t.slice(1)){let t=new Set(U(e,n.index));for(let e=r.length-1;e>=0;--e)t.has(r[e])||r.splice(e,1)}return r[r.length-1]}function U(e,t){let n=new Map(e.map(e=>[e.index,e])),r=[],i=n.get(t);for(;i;)r.push(i.index),i=i.parentIndex===void 0?void 0:n.get(i.parentIndex);return r.reverse()}function W(e,t){let n=new Map;for(let t of e){if(t.parentIndex===void 0)continue;let e=n.get(t.parentIndex)??[];e.push(t),n.set(t.parentIndex,e)}let r=new Set([t]),i=[t];for(let e of i)for(let t of n.get(e)??[])r.has(t.index)||(r.add(t.index),i.push(t.index));return e.filter(e=>r.has(e.index))}function be(e){let t=e.bundleId??``;return k.has(t)||N.test(e.identifier??``)}function xe(e){let t=e.bundleId??``;return A.has(t)&&P.test(K(e))}function G(e){let t=e.type??``,n=e.identifier??``;return!!(e.hittable||/\bbutton\b/i.test(t)||M.test(n)||/(?:^|:)id\/permission_(?:allow|deny)/i.test(n))}function K(e){return e?[e.label,e.value].filter(e=>typeof e==`string`&&e.trim().length>0)[0]?.trim()??``:``}function Se(e){return e.find(e=>e.bundleId)?.bundleId}async function Ce(e,t,n={}){return t===`wait`?await we(e,n.timeoutMs??1e4):t===`get`?Ee((await J(e))?.alert??null):await Te(e,t)}async function we(e,n){let r=Date.now(),i=await q(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...p(`Alert visible`)}}async function Te(e,n){let r=await q(e,d);if(!r)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let i=R(r.buttons,n);if(i)return await oe(e,i.x,i.y),Y(n,r.alert,i.label);if(n===`dismiss`)return await se(e),Y(n,r.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function q(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await J(e);if(t)return t;await u(300)}return null}async function J(e){return L((await o(`snapshot_capture`,async()=>await ae(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function Ee(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...p(e?`Alert visible`:`No alert visible`)}}function Y(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...p(`Alert ${e}ed`)}}async function De(e){let{req:t,logPath:n,session:r,device:a}=e,o=Oe(t.positionals?.[0]),s=r?r.surface===`frontmost-app`?{surface:`frontmost-app`}:{bundleId:r.appBundleId,surface:r.surface}:{},l=b(`alert`,a);if(l)return l;if(a.platform===`android`)return Z(e,await Ce(a,o,{timeoutMs:c(t.positionals?.[1])??1e4}));if(i(a))return await X(e,o,async e=>await ne(e,s));let u=ce({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await X(e,o,async e=>await g(a,{command:`alert`,action:e,appBundleId:r?.appBundleId},u))}async function X(e,t,n){if(t===`wait`)return await ke(e,n);let r=t===`accept`||t===`dismiss`?t:`get`;return r===`accept`||r===`dismiss`?await Ae(e,r,n):Z(e,await n(`get`))}function Oe(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}async function ke(e,t){let n=c(e.req.positionals?.[1])??1e4,r=Date.now();for(;Date.now()-r<n;){try{return Z(e,await t(`get`))}catch{}await u(300)}return S(`COMMAND_FAILED`,`alert wait timed out`)}async function Ae(e,t,n){let r=Date.now(),i;for(;Date.now()-r<d;){try{return Z(e,await n(t))}catch(e){i=e;let t=String(e?.message??``).toLowerCase();if(!t.includes(`alert not found`)&&!t.includes(`no alert`))break}await u(300)}throw je(i)}function Z(e,t){let n=t;return E(e.sessionStore,e.session,e.req,n),{ok:!0,data:n}}function je(e){return!(e instanceof t)||!Me(e)?e:new t(e.code,e.message,{...e.details??{},hint:`If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref.`})}function Me(e){let t=String(e?.message??``).toLowerCase();return t.includes(`alert not found`)||t.includes(`no alert`)}function Ne(e){let t=e.positionals?.[0]?.toLowerCase(),n=e.positionals?.[1]?.toLowerCase(),r=e.positionals?.[2]?.toLowerCase();return t===`clear-app-state`?{ok:!0,parsed:{setting:t,state:`clear`,appBundleId:n===`clear`?e.positionals?.[2]:e.positionals?.[1]}}:!t||!n||t===`permission`&&!r||t===`location`&&n===`set`&&(!e.positionals?.[2]||!e.positionals?.[3])?S(`INVALID_ARGS`,f):{ok:!0,parsed:{setting:t,state:n,permissionTarget:r,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}}async function Pe(e){let{req:t,logPath:n,sessionStore:r,session:a,device:o,parsed:s}=e,{setting:c,state:l,appBundleId:u,permissionTarget:d,latitude:f,longitude:p}=s,m=b(`settings`,o);if(m)return m;if(i(o)&&!ee(c))return S(`INVALID_ARGS`,te(c));let h=u??a?.appBundleId;if(c===`clear-app-state`&&!h)return S(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let g=await v(o,`settings`,c===`clear-app-state`?[c,l,h??``]:c===`permission`?[c,l,d??``,t.positionals?.[3]??``,h??``]:c===`location`&&l===`set`?[c,l,f??``,p??``,h??``]:[c,l,h??``],t.flags?.out,{...y(n,t.flags,h,a?.trace?.outPath)});return E(r,a,t,g??{setting:c,state:l}),{ok:!0,data:g??{setting:c,state:l}}}async function Fe(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(Be(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await Ie(t)}}}}async function Ie(t){try{let e=await D.mkdtemp(O.join(fe.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=O.join(e,`snapshot-timeout-overlay-refs.png`),r=Re(await v(t.device,`screenshot`,[n],void 0,{...y(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await D.access(r);let i=await Le(r,t.session);return s({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:r,overlayRefCount:`overlayRefCount`in i?i.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in i?i.overlayRefsAnnotated:void 0}}),i}catch(t){let n=e(t);return s({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function Le(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await C({screenshotPath:t,snapshot:n.snapshot});return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:e.length>0,overlayRefCount:e.length,overlayRefSource:`session-snapshot`,overlayRefs:e}}catch(n){let r=e(n);return s({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:r.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:r.message}}}function Re(e,t){return ze(e)?e.path:t}function ze(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function Be(e){return e.code===`COMMAND_FAILED`?Ve(e)||He(e.details?.helper)||Ue(e.details):!1}function Ve(e){let t=`${e.message}\n${e.hint??``}`;return/Android UI hierarchy dump timed out/i.test(t)||/Stock UIAutomator fallback was skipped/i.test(t)?!0:/Android accessibility snapshots can be blocked/i.test(t)}function He(e){if(!e||typeof e!=`object`)return!1;let t=e,n=String(t.errorType??``),r=String(t.message??``);return/TimeoutException/i.test(n)||/timed out/i.test(r)}function Ue(e){if(!e)return!1;let t=e?.timeoutMs,n=e?.cmd,r=We(e?.args);return typeof t==`number`&&n===`adb`&&r.includes(`uiautomator`)&&r.includes(`dump`)}function We(e){return Array.isArray(e)?e.map(String):typeof e==`string`?e.split(/\s+/):[]}async function Ge(e){return await Q({...e,command:`snapshot`,unsupportedMessage:`snapshot is not supported on this device`,execute:async({runtime:t,sessionName:n,req:r,snapshotScope:i})=>{let a=await t.capture.snapshot({session:n,interactiveOnly:r.flags?.snapshotInteractiveOnly,depth:r.flags?.snapshotDepth,scope:i,raw:r.flags?.snapshotRaw,forceFull:r.flags?.snapshotForceFull}),o=e.sessionStore.get(n)?.snapshotGeneration;return{data:o===void 0?a:{...a,refsGeneration:o},record:{kind:`snapshot`,nodes:a.nodes.length,truncated:a.truncated}}}})}async function Ke(e){return await Q({...e,command:`diff`,unsupportedMessage:`diff is not supported on this device`,execute:async({runtime:e,sessionName:t,req:n,snapshotScope:r})=>{let i=await e.capture.diffSnapshot({session:t,interactiveOnly:n.flags?.snapshotInteractiveOnly,depth:n.flags?.snapshotDepth,scope:r,raw:n.flags?.snapshotRaw});return{data:i,record:{kind:`diff`,mode:`snapshot`,baselineInitialized:i.baselineInitialized,summary:i.summary}}}})}async function Q(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,{session:a,device:o}=await T(i,n,t.flags),s=b(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=re(t.flags?.snapshotScope,a);return c.ok?qe(e.command,a,o)||await w(a,o,async()=>{let s=Je({req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:c.scope}),l;try{l=await e.execute({runtime:s,sessionName:n,req:t,snapshotScope:c.scope})}catch(t){let n=await Fe({error:t,command:e.command,logPath:r,session:a,device:o});if(!n)throw t;return n}return $e({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function qe(e,t,n){return!a(n)||t?.appBundleId?null:S(`SESSION_NOT_FOUND`,`iOS ${e} requires an active app session on the target device. Run open first (for example: open --session ${t?.name??`sim`} --platform ios --device "<name>" <app>).`)}function Je(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return h({backend:Qe({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...de(`snapshot`),sessions:x({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=et(e),a=i.get(n);i.set(n,$({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:Ye(t),issuesRefsToClient:t.command===`snapshot`}))}})})}function $(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=Xe(t,i,a),s=le({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return s.snapshotScopeSource=Ze({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),s.snapshotRefsStale=o?t?.snapshotRefsStale:!e.issuesRefsToClient,s.snapshotGeneration=o?t?.snapshotGeneration:_(t?.snapshotGeneration),i.appName&&(s.appName=i.appName),s}function Ye(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function Xe(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function Ze(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function Qe(e){let{req:t,logPath:n,session:i,device:a,snapshotScope:o}=e;return{platform:r(a),captureSnapshot:async(e,r)=>{let s=await ie({device:a,session:i,flags:t.flags,outPath:r?.outPath??t.flags?.out,logPath:n,snapshotScope:o}),c=l(i);return{snapshot:s.snapshot,...m(s),...c?{snapshotDiagnostics:c}:{},appName:i?.appBundleId?i.appName??i.appBundleId:void 0,appBundleId:i?.appBundleId}}}}function $e(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:tt(e.result)})}function et(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function tt(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const nt={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await Ge({req:e,sessionName:t,logPath:n,sessionStore:r}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>e.positionals?.[0]===`snapshot`?await Ke({req:e,sessionName:t,logPath:n,sessionStore:r}):S(`INVALID_ARGS`,`diff currently supports only: diff snapshot`),wait:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await ue({req:e,sessionName:t,logPath:n,sessionStore:r}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let{session:i,device:a}=await T(r,t,e.flags);return await w(i,a,async()=>await De({req:e,logPath:n,sessionStore:r,session:i,device:a}))},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let i=Ne(e);if(!i.ok)return i;let{session:a,device:o}=await T(r,t,e.flags);return await w(a,o,async()=>await Pe({req:e,logPath:n,sessionStore:r,session:a,device:o,parsed:i.parsed}))}};async function rt(e){let t=e.req.command,n=nt[t];return n?await n(e):null}export{rt as handleSnapshotCommands};
@@ -1 +1 @@
1
- function e(e){return new Promise(t=>setTimeout(t,e))}export{e as sleep};
1
+ function e(e){return new Promise(t=>setTimeout(t,e))}export{e as t};
@@ -0,0 +1,3 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{f as n,h as r,v as i,w as a}from"./sdk-android-adb.js";import{t as o}from"./scoped-provider.js";import{promises as s}from"node:fs";import c from"node:os";import l from"node:path";function u(e,t){return t===`user-installed`?e.filter(e=>!e.bundleId.startsWith(`com.apple.`)):e}function d(e,n){return{openBundle:async(t,n)=>{await e(`open`,f(t,n))},openTarget:async t=>{await e(`open`,[t])},readClipboard:async()=>r(await e(`pbpaste`,[],{allowFailure:!0}),`Failed to read macOS clipboard`).stdout.replace(/\r\n/g,`
2
+ `).replace(/\n$/,``),writeClipboard:async t=>{r(await e(`pbcopy`,[],{allowFailure:!0,stdin:t}),`Failed to write macOS clipboard`)},readDarkMode:async()=>{let n=r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to get dark mode`],{allowFailure:!0}),`Failed to read macOS appearance`),i=n.stdout.trim().toLowerCase();if(i===`true`)return!0;if(i===`false`)return!1;throw new t(`COMMAND_FAILED`,`Unable to determine current macOS appearance from osascript output: ${n.stdout.trim()}`)},setDarkMode:async t=>{r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to set dark mode to ${t?`true`:`false`}`],{allowFailure:!0}),`Failed to set macOS appearance`)},listApps:async t=>await p(e,n,t)}}function f(e,t){let n=[`-b`,e];return t&&n.push(t),n}async function p(e,t,n){let r=[`/Applications`,`/System/Applications`,l.join(c.homedir(),`Applications`)],i=new Set;for(let t of r){if(!(await s.stat(t).catch(()=>null))?.isDirectory())continue;let n=await e(`find`,[t,`-maxdepth`,`4`,`-type`,`d`,`-name`,`*.app`],{allowFailure:!0});if(n.exitCode===0)for(let e of n.stdout.split(`
3
+ `)){let t=e.trim();t&&i.add(t)}}return u((await Promise.all(Array.from(i).map(async e=>{let n=await m(e,t).catch(()=>({})),r=n.bundleId;return r?{bundleId:r,name:n.appName??l.basename(e,`.app`)}:null}))).filter(e=>e!==null).sort((e,t)=>e.name.localeCompare(t.name)),n)}async function m(e,t){for(let n of[l.join(e,`Contents`,`Info.plist`),l.join(e,`Info.plist`)]){let e=await t(n),r=h(e,`CFBundleIdentifier`),i=h(e,`CFBundleDisplayName`),a=h(e,`CFBundleName`);if(r||i||a)return{bundleId:r,appName:i??a}}return{}}function h(e,t){let n=e?.[t];return typeof n==`string`&&n.trim()?n.trim():void 0}var g=e({createLocalAppleToolProvider:()=>y,hasScopedAppleToolProvider:()=>S,readApplePlistJson:()=>T,resolveAppleToolProvider:()=>b,runAppleToolCommand:()=>C,runXcrun:()=>w,withAppleToolProvider:()=>x});const _={runCommand:i,simctl:{run:async(e,t)=>await i(`xcrun`,[`simctl`,...e],t)},devicectl:{run:async(e,t)=>await i(`xcrun`,[`devicectl`,...e],t)},plist:{readJson:async e=>await k(i,e)},macosHost:d(i,async e=>await k(i,e)),whichCommand:a},v=o(_,E);function y(e={}){let t={..._,...e},n=e.plist??{readJson:async e=>await k(t.runCommand,e)};return{...t,simctl:e.simctl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`simctl`,...e],n)},devicectl:e.devicectl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`devicectl`,...e],n)},plist:n,macosHost:e.macosHost??d(t.runCommand,async e=>await n.readJson(e))}}function b(e){return v.resolve(e)}async function x(e,t){return await v.run(e,t)}function S(){return v.hasScope()}async function C(e,t,n){return await b().runCommand(e,t,n)}async function w(e,t){let n=b(),[r,...i]=e;return r===`simctl`?await(n.simctl?.run(i,t)??n.runCommand(`xcrun`,e,t)):r===`devicectl`?await(n.devicectl?.run(i,t)??n.runCommand(`xcrun`,e,t)):await C(`xcrun`,e,t)}async function T(e){return await b().plist?.readJson(e)??null}function E(e){return y(typeof e==`function`?{runCommand:D(e)}:{...e,runCommand:D(e.runCommand),...e.simctl?{simctl:{run:O(e.simctl.run)}}:{},...e.devicectl?{devicectl:{run:O(e.devicectl.run)}}:{},...e.macosHelper?{macosHelper:{run:O(e.macosHelper.run)}}:{}})}function D(e){return async(t,r,i)=>n(await e(t,r,i))}function O(e){return async(t,r)=>n(await e(t,r))}async function k(e,t){try{let n=await e(`plutil`,[`-convert`,`json`,`-o`,`-`,t],{allowFailure:!0});return n.exitCode!==0||!n.stdout.trim()?null:JSON.parse(n.stdout)}catch{return null}}export{C as a,x as c,b as i,u as l,S as n,w as o,T as r,g as s,y as t};
@@ -0,0 +1 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{F as t}from"./sdk-contracts.js";import{j as n,v as r,w as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{t as o}from"./scoped-provider.js";var s=e({createLocalLinuxToolProvider:()=>u,resolveLinuxToolProvider:()=>d,runLinuxToolCommand:()=>p,withLinuxToolProvider:()=>f});const c={runCommand:r,whichCommand:i,desktop:m(r,i),clipboard:h(r,i),screenshot:g(r,i)},l=o(c,u);function u(e={}){let t={...c,...e};return{...t,desktop:e.desktop??m(t.runCommand,t.whichCommand),clipboard:e.clipboard??h(t.runCommand,t.whichCommand),screenshot:e.screenshot??g(t.runCommand,t.whichCommand)}}function d(e){return l.resolve(e)}async function f(e,t){return await l.run(e,t)}async function p(e,t,n){return await d().runCommand(e,t,n)}function m(e,t){return{async openTarget(r){if(r.includes(`://`)||r.startsWith(`/`)){await e(`xdg-open`,[r]);return}if(await t(r)){e(r,[],{allowFailure:!0}).catch(e=>{n({level:`warn`,phase:`linux_app_launch`,data:{app:r,error:String(e)}})}),await a(500);return}await e(`xdg-open`,[r],{allowFailure:!0})},async closeApp(n){if(await t(`wmctrl`)){await e(`wmctrl`,[`-c`,n],{allowFailure:!0});return}await e(`pkill`,[`-x`,n],{allowFailure:!0})}}}function h(e,t){return{async readText(){let n=await C(t,v),r=b[n];return(await e(r.cmd,r.args,r.options)).stdout},async writeText(n){let r=await C(t,v),i=x[r](n);await e(i.cmd,i.args,i.options)}}}function g(e,t){return{async capture(n){let r=await C(t,y),i=S[r](n);await e(i.cmd,i.args,i.options)}}}const _=5e3,v={wayland:[{tool:`wl-clipboard`,command:`wl-paste`}],x11:[{tool:`xclip`,command:`xclip`},{tool:`xsel`,command:`xsel`}],waylandError:`wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.`,x11Error:`xclip or xsel is required for clipboard access on X11. Install via your package manager.`},y={wayland:[{tool:`grim`,command:`grim`},{tool:`gnome-screenshot`,command:`gnome-screenshot`}],x11:[{tool:`scrot`,command:`scrot`},{tool:`import`,command:`import`},{tool:`gnome-screenshot`,command:`gnome-screenshot`}],waylandError:`grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.`,x11Error:`scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager.`},b={"wl-clipboard":{cmd:`wl-paste`,args:[`--no-newline`],options:{allowFailure:!0,timeoutMs:_}},xclip:{cmd:`xclip`,args:[`-selection`,`clipboard`,`-o`],options:{allowFailure:!0,timeoutMs:_}},xsel:{cmd:`xsel`,args:[`--clipboard`,`--output`],options:{allowFailure:!0,timeoutMs:_}}},x={"wl-clipboard":e=>({cmd:`wl-copy`,args:[`--`,e],options:{allowFailure:!1,timeoutMs:_}}),xclip:e=>({cmd:`xclip`,args:[`-selection`,`clipboard`],options:{allowFailure:!1,timeoutMs:_,stdin:e}}),xsel:e=>({cmd:`xsel`,args:[`--clipboard`,`--input`],options:{allowFailure:!1,timeoutMs:_,stdin:e}})},S={grim:e=>({cmd:`grim`,args:[e]}),scrot:e=>({cmd:`scrot`,args:[e]}),import:e=>({cmd:`import`,args:[`-window`,`root`,e]}),"gnome-screenshot":e=>({cmd:`gnome-screenshot`,args:[`-f`,e]})};async function C(e,n){let r=w()?`wayland`:`x11`;for(let t of n[r])if(await e(t.command))return t.tool;throw new t(`TOOL_MISSING`,r===`wayland`?n.waylandError:n.x11Error)}function w(){return!!process.env.WAYLAND_DISPLAY||process.env.XDG_SESSION_TYPE===`wayland`}export{p as n,s as r,d as t};
@@ -0,0 +1 @@
1
+ const e=new Set;function t(t={}){let r=new Map,i=t.now??(()=>Date.now()),a=e=>{e?.timer&&clearTimeout(e.timer)},o={get(e){let t=r.get(e);if(t){if(t.expiresAt!==void 0&&t.expiresAt<=i()){o.delete(e);return}return t.value}},set(e,o){a(r.get(e));let s=n(t.ttlMs,i),c={value:o,expiresAt:s};t.scheduleExpiry&&s!==void 0&&(c.timer=setTimeout(()=>{r.delete(e)},Math.max(0,s-i())),c.timer.unref?.()),r.set(e,c)},delete(e){let t=r.get(e);return t?(a(t),r.delete(e)):!1},clear(){for(let e of r.values())a(e);r.clear()}};return e.add(o.clear),o}function n(e,t){if(!(e===void 0||!Number.isFinite(e)))return t()+Math.max(0,e)}export{t};
@@ -0,0 +1 @@
1
+ import{b as e}from"./sdk-android-adb.js";import t from"node:fs";import n from"node:path";import{fileURLToPath as r}from"node:url";const i=`agent-device`,a=`--agent-device-run-update-check`;function o(e){if(!c(e))return;let t=Date.now(),r=n.join(e.stateDir,`update-check.json`),a=d(r);l(a,e.currentVersion)&&(process.stderr.write(`Update available: ${i} ${e.currentVersion} -> ${a.latestVersion}. Run \`npm install -g ${i}@latest\` to upgrade the CLI and bundled skills.\n`),f(r,{...a,prompted:!0})),u(a,t)&&m(r,e.currentVersion)}async function s(e){let t=Date.now(),n=d(e.cachePath);try{let r=await h()??void 0;if(!r||_(r,e.currentVersion)<=0){f(e.cachePath,{checkedAt:new Date(t).toISOString()});return}f(e.cachePath,{checkedAt:new Date(t).toISOString(),latestVersion:r,prompted:n.latestVersion===r?n.prompted===!0:!1})}catch{f(e.cachePath,{...n,checkedAt:new Date(t).toISOString()})}}function c(e){return!e.command||e.command===`help`||e.command===`test`||e.flags.help||e.flags.version||e.flags.json||process.env.CI?.trim()||process.env.NODE_ENV===`test`||process.env.AGENT_DEVICE_NO_UPDATE_NOTIFIER?.trim()?!1:!!process.stderr.isTTY}function l(e,t){return!e.latestVersion||_(e.latestVersion,t)<=0?!1:e.prompted!==!0}function u(e,t){let n=g(e.checkedAt);return n===void 0||t-n>=12096e5}function d(e){try{let n=JSON.parse(t.readFileSync(e,`utf8`));return{checkedAt:typeof n.checkedAt==`string`?n.checkedAt:void 0,latestVersion:typeof n.latestVersion==`string`?n.latestVersion:void 0,prompted:n.prompted===!0}}catch{return{}}}function f(e,r){try{t.mkdirSync(n.dirname(e),{recursive:!0}),t.writeFileSync(e,`${JSON.stringify(r,null,2)}\n`,`utf8`)}catch{}}function p(){let e=r(import.meta.url),i=n.extname(e)||`.js`,a=[n.join(n.dirname(e),`update-check-entry${i}`),n.join(n.dirname(e),`internal`,`update-check-entry${i}`)].find(e=>t.existsSync(e));if(!a)throw Error(`Update check entrypoint not found. Rebuild the package to include the update-check worker entry.`);return a}function m(t,n){let r=p(),i=r.endsWith(`.ts`)?[`--experimental-strip-types`]:[];e(process.execPath,[...i,r,a,t,n])}async function h(){let e=await fetch(`https://registry.npmjs.org/${i}/latest`,{signal:AbortSignal.timeout(3500),headers:{accept:`application/json`}});if(!e.ok)return;let t=await e.json();return typeof t.version==`string`&&t.version.trim().length>0?t.version.trim():void 0}function g(e){if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:t}function _(e,t){return e.localeCompare(t,void 0,{numeric:!0})}function v(e){if(e[0]!==a)return null;let t=e[1]?.trim(),n=e[2]?.trim();return!t||!n?null:{cachePath:t,currentVersion:n}}export{v as n,s as r,o as t};
@@ -0,0 +1 @@
1
+ const e=`--agent-device-run-metro-companion`,t=`--agent-device-run-react-devtools-companion`,n=1e3,r=`AGENT_DEVICE_COMPANION_TUNNEL_SERVER_BASE_URL`,i=`AGENT_DEVICE_COMPANION_TUNNEL_BEARER_TOKEN`,a=`AGENT_DEVICE_COMPANION_TUNNEL_LOCAL_BASE_URL`,o=`AGENT_DEVICE_COMPANION_TUNNEL_LAUNCH_URL`,s=`AGENT_DEVICE_COMPANION_TUNNEL_STATE_PATH`,c=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_TENANT_ID`,l=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_RUN_ID`,u=`AGENT_DEVICE_COMPANION_TUNNEL_SCOPE_LEASE_ID`,d=`AGENT_DEVICE_COMPANION_TUNNEL_REGISTER_PATH`,f=`AGENT_DEVICE_COMPANION_TUNNEL_UNREGISTER_PATH`,p=`AGENT_DEVICE_COMPANION_TUNNEL_DEVICE_PORT`,m=`AGENT_DEVICE_COMPANION_TUNNEL_SESSION`;var h=class extends Error{name=`MissingCompanionEnvError`};function g(e){let t=e.length;for(;t>0&&e.charCodeAt(t-1)===47;)--t;return t===e.length?e:e.slice(0,t)}function _(e,t){let n=new URL(`${g(e)}/index.bundle`);return n.searchParams.set(`platform`,t),n.searchParams.set(`dev`,`true`),n.searchParams.set(`minify`,`false`),n.toString()}export{h as _,p as a,d as c,c as d,r as f,e as g,f as h,i,u as l,s as m,g as n,o,m as p,n as r,a as s,_ as t,l as u,t as v};
@@ -0,0 +1 @@
1
+ import e from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";function r(){try{let n=i();return JSON.parse(e.readFileSync(t.join(n,`package.json`),`utf8`)).version??`0.0.0`}catch{return`0.0.0`}}function i(){let r=t.dirname(n(import.meta.url)),i=r;for(let n=0;n<6;n+=1){let n=t.join(i,`package.json`);if(e.existsSync(n))return i;i=t.dirname(i)}return r}export{r as n,i as t};
package/dist/src/web.js CHANGED
@@ -1 +1 @@
1
- import{AppError as e}from"./485.js";import{withDiagnosticTimer as t}from"./8875.js";import{resolveWebProvider as r}from"./provider.js";function o(){return{open:(e,t)=>r().open(t?.url??e,{url:t?.url}),openDevice:()=>r().open("about:blank"),close:e=>r().close(e),tap:(e,t)=>r().click(e,t),doubleTap:()=>n("doubleTap"),swipe:()=>n("swipe"),pan:()=>n("pan"),fling:()=>n("fling"),longPress:()=>n("longPress"),focus:(e,t)=>r().click(e,t),type:(e,t)=>r().typeText(e,{delayMs:t}),fill:(e,t,o,n)=>r().fill(e,t,o,{delayMs:n}),scroll:(e,t)=>r().scroll(e,t),pinch:()=>n("pinch"),screenshot:(e,t)=>r().screenshot(e,t),setViewport:(e,t)=>r().setViewport(e,t),snapshot:async e=>{let o=await t("snapshot_capture",async()=>await r().snapshot(e),{backend:"web"});return{nodes:o.nodes,truncated:o.truncated??!1,backend:"web"}},back:()=>n("back"),home:()=>n("home"),rotate:()=>n("rotate"),rotateGesture:()=>n("rotateGesture"),transformGesture:()=>n("transformGesture"),appSwitcher:()=>n("appSwitcher"),readClipboard:()=>n("readClipboard"),writeClipboard:()=>n("writeClipboard"),setSetting:()=>n("setSetting")}}async function n(t){throw new e("UNSUPPORTED_OPERATION",`${t} is not supported on web`)}export{o as createWebInteractor};
1
+ import{F as e}from"./sdk-contracts.js";import{F as t}from"./sdk-android-adb.js";import{n}from"./provider.js";function r(){let e=()=>n();return{open:(t,n)=>e().open(n?.url??t,{url:n?.url}),openDevice:()=>e().open(`about:blank`),close:t=>e().close(t),tap:(t,n)=>e().click(t,n),doubleTap:()=>i(`doubleTap`),swipe:()=>i(`swipe`),pan:()=>i(`pan`),fling:()=>i(`fling`),longPress:()=>i(`longPress`),focus:(t,n)=>e().click(t,n),type:(t,n)=>e().typeText(t,{delayMs:n}),fill:(t,n,r,i)=>e().fill(t,n,r,{delayMs:i}),scroll:(t,n)=>e().scroll(t,n),pinch:()=>i(`pinch`),screenshot:(t,n)=>e().screenshot(t,n),setViewport:(t,n)=>e().setViewport(t,n),snapshot:async n=>{let r=await t(`snapshot_capture`,async()=>await e().snapshot(n),{backend:`web`});return{nodes:r.nodes,truncated:r.truncated??!1,backend:`web`}},back:()=>i(`back`),home:()=>i(`home`),rotate:()=>i(`rotate`),rotateGesture:()=>i(`rotateGesture`),transformGesture:()=>i(`transformGesture`),appSwitcher:()=>i(`appSwitcher`),readClipboard:()=>i(`readClipboard`),writeClipboard:()=>i(`writeClipboard`),setSetting:()=>i(`setSetting`)}}async function i(t){throw new e(`UNSUPPORTED_OPERATION`,`${t} is not supported on web`)}export{r as createWebInteractor};
@@ -0,0 +1,2 @@
1
+ const e=new Set(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.:-`),t=new Set([` `,` `,`
2
+ `,`\r`]),n=new Set([`__defineGetter__`,`__defineSetter__`,`__proto__`,`constructor`,`prototype`]);function r(e,t={}){let n=t.maxDocumentChars??134217728;if(e.length>n)throw Error(`XML document exceeds maximum supported size of ${n} characters.`);return new a(e).parse()}function i(e,t){for(let n of e){if(n.name===`dict`)for(let e=0;e<n.children.length-1;e+=1){let r=n.children[e],i=n.children[e+1];r?.name===`key`&&r.text&&i&&t(r.text,i)}i(n.children,t)}}var a=class{roots=[];stack=[];index=0;xml;constructor(e){this.xml=e}parse(){for(this.skipByteOrderMark();this.index<this.xml.length;)this.readNextToken();return this.assertFullyClosed(),this.roots}readNextToken(){if(this.xml[this.index]!==`<`){this.readText();return}this.resolveMarkupReader()()}resolveMarkupReader(){return this.startsWith(`<!--`)?()=>this.skipUntil(`-->`,`Comment is not closed.`):this.startsWith(`<?`)?()=>this.skipUntil(`?>`,`Processing instruction is not closed.`):this.startsWith(`<![CDATA[`)?()=>this.readCdata():this.startsWith(`<!`)?()=>this.skipDeclaration():this.startsWith(`</`)?()=>this.readClosingTag():()=>this.readOpeningTag()}assertFullyClosed(){if(this.stack.length>0){let e=this.stack[this.stack.length-1];throw Error(`Unclosed XML tag <${e?.name??`unknown`}>.`)}}skipByteOrderMark(){this.xml.charCodeAt(0)===65279&&(this.index=1)}readOpeningTag(){this.index+=1,this.skipWhitespace();let e=this.readRequiredName(`Missing XML tag name at offset ${this.index}.`),{attributes:t,selfClosing:n}=this.readOpeningTagBody(),r={name:e,attributes:t,text:null,children:[]};this.addNode(r),n||this.pushOpenNode(r)}readOpeningTagBody(){let e={};for(;;){this.skipWhitespace();let t=this.readOpeningTagEnd();if(t)return{attributes:e,selfClosing:t===`self-closing`};let n=this.readAttribute();e[n.name]=n.value}}readOpeningTagEnd(){if(this.index>=this.xml.length)throw Error(`Opening XML tag is not closed.`);return this.xml[this.index]===`>`?(this.index+=1,`open`):this.xml[this.index]===`/`&&this.xml[this.index+1]===`>`?(this.index+=2,`self-closing`):null}readAttribute(){let e=this.readRequiredName(`Invalid XML attribute at offset ${this.index}.`);if(f(e),this.skipWhitespace(),this.xml[this.index]!==`=`)throw Error(`Missing value for XML attribute "${e}".`);return this.index+=1,this.skipWhitespace(),{name:e,value:this.readAttributeValue(e)}}pushOpenNode(e){if(this.stack.length>=256)throw Error(`Maximum XML nesting depth of 256 exceeded.`);this.stack.push(e)}readClosingTag(){this.index+=2,this.skipWhitespace();let e=this.readName();if(this.skipWhitespace(),this.xml[this.index]!==`>`)throw Error(`Closing XML tag </${e}> is not closed.`);this.index+=1;let t=this.stack.pop();if(!t)throw Error(`Unexpected closing XML tag </${e}>.`);if(t.name!==e)throw Error(`Expected </${t.name}> before </${e}>.`)}readText(){let e=this.xml.indexOf(`<`,this.index),t=e===-1?this.xml.length:e;this.appendText(this.xml.slice(this.index,t),!0),this.index=t}readCdata(){let e=this.index+9,t=this.xml.indexOf(`]]>`,e);if(t===-1)throw Error(`CDATA section is not closed.`);this.appendText(this.xml.slice(e,t),!1),this.index=t+3}appendText(e,t){let n=e.trim();if(!n)return;let r=this.stack[this.stack.length-1];r&&(r.text=`${r.text??``}${t?p(n):n}`)}addNode(e){let t=this.stack[this.stack.length-1];t?t.children.push(e):this.roots.push(e)}readName(){let e=this.index;for(;this.index<this.xml.length&&o(this.xml[this.index]);)this.index+=1;return this.xml.slice(e,this.index)}readRequiredName(e){let t=this.readName();if(!t)throw Error(e);return t}readAttributeValue(e){let t=this.xml[this.index];if(t!==`"`&&t!==`'`)throw Error(`XML attribute "${e}" must use a quoted value.`);this.index+=1;let n=this.index,r=this.xml.indexOf(t,n);if(r===-1)throw Error(`XML attribute "${e}" is not closed.`);return this.index=r+1,p(this.xml.slice(n,r).trim())}skipDeclaration(){let e={quote:null,bracketDepth:0};for(let t=this.index+2;t<this.xml.length;t+=1)if(c(e,this.xml[t])){this.index=t+1;return}throw Error(`XML declaration is not closed.`)}skipUntil(e,t){let n=this.xml.indexOf(e,this.index+e.length);if(n===-1)throw Error(t);this.index=n+e.length}skipWhitespace(){for(;this.index<this.xml.length&&s(this.xml[this.index]);)this.index+=1}startsWith(e){return this.xml.startsWith(e,this.index)}};function o(t){return t!==void 0&&e.has(t)}function s(e){return e!==void 0&&t.has(e)}function c(e,t){return t===void 0||l(e,t)?!1:(u(e,t),d(e,t))}function l(e,t){return e.quote?(t===e.quote&&(e.quote=null),!0):t===`"`||t===`'`?(e.quote=t,!0):!1}function u(e,t){if(t===`[`){e.bracketDepth+=1;return}t===`]`&&e.bracketDepth>0&&--e.bracketDepth}function d(e,t){return t===`>`&&e.bracketDepth===0}function f(e){if(n.has(e))throw Error(`Unsupported XML attribute name "${e}".`)}function p(e){return e.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|amp|lt|gt|quot|apos);/g,(e,t)=>{switch(t){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return m(e,t)}})}function m(e,t){let n=t.startsWith(`#x`)?Number.parseInt(t.slice(2),16):Number(t.slice(1));if(!Number.isInteger(n)||n<0||n>1114111)return e;try{return String.fromCodePoint(n)}catch{return e}}export{i as n,r as t};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.18.2",
3
+ "version": "0.19.0",
4
4
  "description": "Agent-native CLI for AI app automation across iOS, Android, tvOS, Android TV, macOS, Linux, and web.",
5
5
  "mcpName": "io.github.callstackincubator/agent-device",
6
6
  "license": "MIT",
@@ -64,13 +64,13 @@
64
64
  }
65
65
  },
66
66
  "engines": {
67
- "node": ">=22.19"
67
+ "node": ">=22.12"
68
68
  },
69
69
  "bin": {
70
70
  "agent-device": "bin/agent-device.mjs"
71
71
  },
72
72
  "scripts": {
73
- "build": "rslib build",
73
+ "build": "tsdown",
74
74
  "clean:daemon": "node --experimental-strip-types scripts/clean-daemon.ts",
75
75
  "daemon:state-dir": "node --experimental-strip-types scripts/print-daemon-state-dir.ts",
76
76
  "clean:xcuitest": "node scripts/clean-xcuitest-derived.mjs",
@@ -90,6 +90,7 @@
90
90
  "build:android-snapshot-helper": "sh ./scripts/build-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
91
91
  "package:android-snapshot-helper": "sh ./scripts/package-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") v$(node -p \"require('./package.json').version\") .tmp/android-snapshot-helper",
92
92
  "package:android-snapshot-helper:npm": "rm -rf android-snapshot-helper/dist && sh ./scripts/package-android-snapshot-helper.sh $(node -p \"require('./package.json').version\") v$(node -p \"require('./package.json').version\") android-snapshot-helper/dist",
93
+ "package:apple-runner:npm": "node scripts/package-apple-runner-source.mjs",
93
94
  "build:android-multitouch-helper": "sh ./scripts/build-android-multitouch-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-multitouch-helper",
94
95
  "package:android-multitouch-helper": "sh ./scripts/package-android-multitouch-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-multitouch-helper",
95
96
  "package:android-multitouch-helper:npm": "rm -rf android-multitouch-helper/dist && sh ./scripts/package-android-multitouch-helper.sh $(node -p \"require('./package.json').version\") android-multitouch-helper/dist",
@@ -102,8 +103,8 @@
102
103
  "perf:ios": "node --experimental-strip-types scripts/perf/run.ts --platform ios",
103
104
  "perf:android": "node --experimental-strip-types scripts/perf/run.ts --platform android",
104
105
  "lint": "oxlint . --deny-warnings",
105
- "format": "node ./node_modules/oxfmt/bin/oxfmt --write src test skills package.json tsconfig.json tsconfig.lib.json rslib.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
106
- "format:check": "node ./node_modules/oxfmt/bin/oxfmt --check src test skills package.json tsconfig.json tsconfig.lib.json rslib.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
106
+ "format": "node ./node_modules/oxfmt/bin/oxfmt --write src test skills package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
107
+ "format:check": "node ./node_modules/oxfmt/bin/oxfmt --check src test skills package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
107
108
  "fallow": "fallow audit --base origin/main",
108
109
  "fallow:all": "fallow --summary",
109
110
  "fallow:baseline": "(fallow dead-code --save-baseline fallow-baselines/dead-code.json --summary || true) && (fallow health --save-baseline fallow-baselines/health.json --summary || true)",
@@ -116,8 +117,8 @@
116
117
  "check:tooling": "pnpm lint && pnpm typecheck && pnpm check:layering && pnpm check:mcp-metadata && pnpm build",
117
118
  "check:unit": "pnpm test:unit && pnpm test:smoke",
118
119
  "check": "pnpm check:tooling && pnpm check:fallow && pnpm check:unit",
119
- "prepack": "pnpm check:mcp-metadata && pnpm build:all && pnpm package:android-snapshot-helper:npm && pnpm package:android-multitouch-helper:npm",
120
- "typecheck": "tsc -p tsconfig.json",
120
+ "prepack": "pnpm check:mcp-metadata && pnpm build:all && pnpm package:apple-runner:npm && pnpm package:android-snapshot-helper:npm && pnpm package:android-multitouch-helper:npm",
121
+ "typecheck": "tsgo -p tsconfig.json",
121
122
  "test-app:install": "pnpm install --dir examples/test-app --ignore-workspace",
122
123
  "test-app:start": "pnpm --dir examples/test-app start",
123
124
  "test-app:ios": "pnpm --dir examples/test-app ios",
@@ -128,8 +129,8 @@
128
129
  "test-app:maestro": "node scripts/run-test-app-maestro-suite.mjs",
129
130
  "test-app:maestro:ios": "node scripts/run-test-app-maestro-suite.mjs --platform ios",
130
131
  "test-app:maestro:android": "node scripts/run-test-app-maestro-suite.mjs --platform android",
131
- "test": "vitest run --project unit",
132
- "test:unit": "vitest run --project unit",
132
+ "test": "vitest run --project unit-core --project android-adb",
133
+ "test:unit": "vitest run --project unit-core --project android-adb",
133
134
  "test:coverage": "vitest run --coverage",
134
135
  "test:integration:provider": "vitest run --project provider-integration",
135
136
  "test:integration:progress": "node --experimental-strip-types scripts/integration-progress.ts",
@@ -149,13 +150,6 @@
149
150
  "files": [
150
151
  "bin",
151
152
  "dist",
152
- "apple-runner",
153
- "!apple-runner/**/.build",
154
- "!apple-runner/**/.swiftpm",
155
- "!apple-runner/**/xcuserdata",
156
- "!apple-runner/**/*.xcuserstate",
157
- "!apple-runner/README.md",
158
- "!apple-runner/RUNNER_PROTOCOL.md",
159
153
  "macos-helper",
160
154
  "!macos-helper/**/.build",
161
155
  "android-snapshot-helper/dist",
@@ -218,16 +212,15 @@
218
212
  "yaml": "^2.9.0"
219
213
  },
220
214
  "devDependencies": {
221
- "@microsoft/api-extractor": "^7.58.8",
222
- "@rslib/core": "0.22.1",
223
215
  "@types/node": "^22.19.21",
224
216
  "@typescript/native-preview": "7.0.0-dev.20260613.1",
225
217
  "@vitest/coverage-v8": "4.1.8",
226
218
  "fallow": "^2.95.0",
219
+ "oxc-parser": "^0.138.0",
227
220
  "oxfmt": "^0.42.0",
228
221
  "oxlint": "^1.69.0",
229
222
  "skillgym": "^0.9.1",
230
- "typescript": "^6.0.3",
223
+ "tsdown": "^0.22.3",
231
224
  "vite": "^8.0.16",
232
225
  "vitest": "^4.1.8"
233
226
  }
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/callstack/agent-device",
8
8
  "source": "github"
9
9
  },
10
- "version": "0.18.2",
10
+ "version": "0.19.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "agent-device",
15
- "version": "0.18.2",
15
+ "version": "0.19.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }
@@ -35,6 +35,8 @@ agent-device help dogfood
35
35
 
36
36
  Default loop: `open -> snapshot/-i -> get/is/find or press/fill/scroll/wait -> verify -> close`.
37
37
 
38
+ On a fresh machine (first iOS run), start with `agent-device doctor --platform ios`: it preflights the environment and warms the iOS runner build cache in the background so the first `open` is fast.
39
+
38
40
  Use this skill only to route into version-matched CLI help. Let `help workflow` provide exact command shapes, platform limits, and current workflow guidance.
39
41
 
40
42
  For precise location workflows, read the installed `settings` help before planning so coordinate support and platform limits come from the active CLI version.
@@ -1 +0,0 @@
1
- 1c8e6f04f5453ecea2e26281896faf7d940237c0011ba8d50b436c0b7ba82c4e agent-device-android-multitouch-helper-0.18.2.apk
@@ -1 +0,0 @@
1
- a91e0b0b4d8b5b1dc6d1e25abe1491efefa8b8d89cc5c406f1fd84a302e56ebf agent-device-android-snapshot-helper-0.18.2.apk