agent-device 0.19.0 → 0.19.2

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 (86) hide show
  1. package/README.md +5 -1
  2. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.2.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.19.0.manifest.json → agent-device-android-multitouch-helper-0.19.2.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.apk → agent-device-android-snapshot-helper-0.19.2.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.2.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.19.0.manifest.json → agent-device-android-snapshot-helper-0.19.2.manifest.json} +6 -6
  8. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +24 -7
  9. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +506 -119
  10. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +153 -48
  11. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +172 -0
  12. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +76 -5
  13. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +60 -52
  14. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +159 -56
  15. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +142 -0
  16. package/dist/apple-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +16 -14
  17. package/dist/src/android-adb.d.ts +1 -2
  18. package/dist/src/android-adb.js +1 -1
  19. package/dist/src/android-input-ownership.js +6 -0
  20. package/dist/src/android.js +1 -1
  21. package/dist/src/app-lifecycle.js +3 -3
  22. package/dist/src/apple-runner-options.js +1 -1
  23. package/dist/src/apps.js +5 -5
  24. package/dist/src/cli-help.js +149 -37
  25. package/dist/src/cli-runner.js +1 -1
  26. package/dist/src/cli.js +11 -11
  27. package/dist/src/client.js +2 -2
  28. package/dist/src/command-metadata.js +1 -1
  29. package/dist/src/command-schema.js +3 -3
  30. package/dist/src/device-input-state.js +2 -2
  31. package/dist/src/devices2.js +1 -1
  32. package/dist/src/find.js +1 -1
  33. package/dist/src/generic.js +1 -1
  34. package/dist/src/index.d.ts +224 -20
  35. package/dist/src/input-actions.js +3 -3
  36. package/dist/src/interaction-snapshot.js +1 -1
  37. package/dist/src/interaction.js +1 -1
  38. package/dist/src/interactor.js +2 -2
  39. package/dist/src/internal/bin.js +1 -1
  40. package/dist/src/internal/daemon.js +17 -15
  41. package/dist/src/lease.js +1 -1
  42. package/dist/src/linux.js +1 -1
  43. package/dist/src/metro.d.ts +0 -1
  44. package/dist/src/notifications.js +1 -1
  45. package/dist/src/points.js +1 -1
  46. package/dist/src/project-runtime.js +1 -1
  47. package/dist/src/providers.js +1 -1
  48. package/dist/src/react-native.js +1 -1
  49. package/dist/src/record-trace-recording.js +2 -2
  50. package/dist/src/record-trace.js +1 -1
  51. package/dist/src/registry.js +24 -23
  52. package/dist/src/reporting.js +3 -3
  53. package/dist/src/runner-client.js +1 -1
  54. package/dist/src/runtime.js +2 -2
  55. package/dist/src/sdk-android-adb.d.ts +2 -2
  56. package/dist/src/sdk-batch-runner.d.ts +0 -1
  57. package/dist/src/sdk-batch.js +2 -2
  58. package/dist/src/sdk-finders.d.ts +1 -2
  59. package/dist/src/sdk-finders.js +1 -1
  60. package/dist/src/sdk-io.d.ts +0 -1
  61. package/dist/src/sdk-remote-config.d.ts +1 -2
  62. package/dist/src/sdk-remote-config.js +1 -1
  63. package/dist/src/sdk-selectors.js +1 -1
  64. package/dist/src/selector-runtime.js +1 -1
  65. package/dist/src/selectors.d.ts +0 -1
  66. package/dist/src/selectors.js +1 -1
  67. package/dist/src/selectors2.js +1 -1
  68. package/dist/src/server.js +3 -3
  69. package/dist/src/session.js +10 -10
  70. package/dist/src/simctl.js +1 -1
  71. package/dist/src/simulator.js +1 -1
  72. package/dist/src/snapshot-diagnostics.js +2 -2
  73. package/dist/src/snapshot-helper.js +4 -4
  74. package/dist/src/snapshot-quality.js +1 -1
  75. package/dist/src/snapshot2.js +2 -2
  76. package/dist/src/tv-remote.js +14 -0
  77. package/dist/src/version.js +1 -1
  78. package/dist/src/web.js +1 -1
  79. package/package.json +5 -4
  80. package/server.json +2 -2
  81. package/skills/agent-device/SKILL.md +8 -7
  82. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk +0 -0
  83. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.0.apk.sha256 +0 -1
  84. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.0.apk.sha256 +0 -1
  85. package/dist/src/device-rotation.js +0 -14
  86. package/dist/src/logcat.js +0 -6
@@ -1 +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
+ import{p as e}from"./sdk-contracts.js";import{x as t}from"./android-input-ownership.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 +1 @@
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};
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{S as i,_ as a,g as o,w as s}from"./android-input-ownership.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=i.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=a({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=>a({error:e,stdout:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(n){let r=a({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};
@@ -1,3 +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(`
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 ae=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,S=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,C=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`];function w(){let e=process.argv[1];return e?T(e):`unknown`}function T(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 E(s)){let n=O(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 E(e){let t=new Set;return D(e,ae,t),D(e,S,t),[...t]}function D(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 O(e,t){let n=m.resolve(m.dirname(e),t),r=k(n);if(r)return r;for(let e of C){let t=k(`${n}${e}`);if(t)return t}for(let e of C){let t=k(m.join(n,`index${e}`));if(t)return t}return null}function k(e){try{return p.statSync(e).isFile()?e:null}catch{return null}}const A=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function j(e){let t=e.toLowerCase().replaceAll(`\\`,`/`);return t.includes(`agent-device`)?A.some(e=>e.test(t)):!1}function M(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?j(n):!1}function N(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 P(e,t){M(e,t.expectedStartTime)&&N(e,`SIGTERM`)&&(await c(e,t.termTimeoutMs)||N(e,`SIGKILL`)&&await c(e,t.killTimeoutMs))}const F=/^[A-Za-z0-9_@%+=:,./-]+$/;function I(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function L(e){return F.test(e)?e:I(e)}function R(e,t){let n=[],r=e+t.toString(),i=r.indexOf(`
2
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};
3
+ `)}return{lines:n,buffer:r}}function z(e){return e.meta?.requestProgress===`replay-test`||e.meta?.requestProgress===`command`}function B(e){return!!e&&typeof e==`object`&&e.type===`progress`&&!!e.event}function V(e){return!!e&&typeof e==`object`&&e.type===`response`&&!!e.response}function oe(e){return`${JSON.stringify({type:`progress`,event:e})}\n`}function H(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function U(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function W(e,n={}){return{ok:!0,service:e,version:t(),rpcProtocolVersion:1,...n.upstream===void 0?{}:{upstream:n.upstream}}}function G(e){return{...typeof e.path==`string`?{path:e.path}:{},...typeof e.width==`number`?{width:e.width}:{},...typeof e.height==`number`?{height:e.height}:{},...typeof e.logicalWidth==`number`?{logicalWidth:e.logicalWidth}:{},...typeof e.logicalHeight==`number`?{logicalHeight:e.logicalHeight}:{},...typeof e.pixelDensity==`number`?{pixelDensity:e.pixelDensity}:{},...e.overlayRefs?{overlayRefs:e.overlayRefs}:{}}}function K(e){if(u(e))return G({path:typeof e.path==`string`?e.path:void 0,width:typeof e.width==`number`?e.width:void 0,height:typeof e.height==`number`?e.height:void 0,logicalWidth:typeof e.logicalWidth==`number`?e.logicalWidth:void 0,logicalHeight:typeof e.logicalHeight==`number`?e.logicalHeight:void 0,pixelDensity:typeof e.pixelDensity==`number`?e.pixelDensity:void 0,overlayRefs:Array.isArray(e.overlayRefs)?e.overlayRefs.filter(le).flatMap(e=>{let t=q(e);return t?[t]:[]}):void 0})}function q(e){if(typeof e.ref!=`string`||e.ref.length===0)return;let t=se(e);if(t)return{ref:e.ref,...ce(e),...t}}function se(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 ce(e){return typeof e.label==`string`&&e.label.length>0?{label:e.label}:{}}function le(e){return u(e)}const J=1500;function ue(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function de(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return Y(t)}function Y(e){if(e.length===0)return;let t=X(e);return{stats:t,...t.p95Ms>=J?{warning:$(t)}:{}}}function fe(e){let t=e.flatMap(e=>ye(e?.stats));if(t.length===0)return;let n=X(t);return{stats:n,...n.p95Ms>=J?{warning:$(n)}:{}}}function pe(e){if(!u(e))return;let t=he(e.stats);if(!t)return;let n=typeof e.warning==`string`?e.warning:void 0;return{stats:t,...n?{warning:n}:{}}}function X(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:Z(t,50),p95Ms:Z(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:J,...me(e),...Q(e)}}function Z(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 me(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function Q(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 he(e){if(!u(e))return;let t=ge(e);if(t)return{...t,...ve(e)}}function ge(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 _e(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function ve(e){let t=typeof e.platform==`string`?e.platform:void 0,n=u(e.backends)?_e(e.backends):void 0;return{...t?{platform:t}:{},...n?{backends:n}:{}}}function ye(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{_ as C,g as D,re as E,h as O,ie as S,ne as T,L as _,Y as a,T as b,W as c,oe as d,H as f,I as g,R as h,de as i,B as l,z as m,pe as n,G as o,U as p,ue as r,K as s,fe as t,V as u,M as v,te as w,w as x,P as y};
@@ -1,5 +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(`
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{z as a}from"./tv-remote.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=ie(e),n=u(t.bounds);return{...t,...n?{rect:n}:{}}}function ee(e,t,n){let{sourceNodes:r,...i}=te(g(e),t,n);return i}function te(e,t,n){let r={nodes:[],sourceNodes:[],...t===void 0?{}:{maxNodes:t},maxDepth:n.depth??1/0,options:n,analysis:Ie(e),interactiveDescendantMemo:new Map,truncated:!1},i=n.scope?Fe(e,n.scope):null,a=i?[i]:e.children;for(let e of a)if(ne(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 ne(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||De(t,e.options,i,p(e,t),a)?re(e,t,n,r):r,s=i||!!t.hittable,c=a||Ne(t.type);for(let r of t.children)if(ne(e,r,n+1,o,s,c),e.truncated)return}function re(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,focused:t.focused,visibleToUser:t.visibleToUser,hittable:t.hittable,depth:n,parentIndex:r,...t.hiddenContentAbove?{hiddenContentAbove:!0}:{},...t.hiddenContentBelow?{hiddenContentBelow:!0}:{}}),i}function p(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||p(e,n)))return e.interactiveDescendantMemo.set(t,!0),!0;return e.interactiveDescendantMemo.set(t,!1),!1}function ie(e){let t=ae(e),n=e=>he(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 ae(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=oe(e,i,r);if(!n)break;t.set(n.name,n.value),i=n.nextCursor}return t}function oe(e,t,n){if(t=m(e,t,n),t>=n||ce(e[t]))return;let r=t;t=se(e,t,n);let i=e.slice(r,t);if(t=m(e,t,n),!i||e[t]!==`=`)return;t=m(e,t+1,n);let a=e[t];if(!le(a))return;let o=t+1,s=e.indexOf(a,o);if(!(s<0||s>=n))return{name:i,value:de(e.slice(o,s)),nextCursor:s+1}}function se(e,t,n){for(;t<n&&!ue(e[t]??``);)t+=1;return t}function m(e,t,n){for(;t<n&&h(e[t]??``);)t+=1;return t}function ce(e){return e===`/`||e===`>`}function le(e){return e===`"`||e===`'`}function h(e){return e===` `||e===`
2
+ `||e===`\r`||e===` `}function ue(e){return e===`=`||e===`/`||e===`>`||h(e)}function de(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+=fe(a)??e.slice(r,i+1),n=i+1}return t}function fe(e){switch(e){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return pe(e)}}function pe(e){if(!e.startsWith(`#`))return;let t=e[1]?.toLowerCase()===`x`?16:10,n=t===16?e.slice(2):e.slice(1);if(!n||!me(n,t))return;let r=Number.parseInt(n,t);if(Number.isFinite(r))try{return String.fromCodePoint(r)}catch{return}}function me(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 he(e,t){return e.get(t)??null}function g(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,focused:a.focused,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 _(t),Se(t),v(t,{actionableContentMemo:new WeakMap}),xe(t),t}function _(e){let t=0;for(let n of e.children)n.visibleToUser!==!1&&(_(n),e.children[t]=n,t+=1);t<e.children.length&&(e.children.length=t)}function v(e,t){for(let n of e.children)v(n,t);if(e.children.length<2)return;let n=e.children,r=n.filter(e=>_e(e,t));r.length!==0&&(e.children=n.filter(e=>!ge(e,r)))}function ge(e,t){if(e.visibleToUser===!1||e.drawingOrder===void 0||!ye(e))return!1;for(let n of t)if(!(n===e||n.drawingOrder<=e.drawingOrder)&&be(n.rect,e.rect)>=.9)return!0;return!1}function _e(e,t){return e.visibleToUser!==!1&&e.drawingOrder!==void 0&&ye(e)&&(ve(e)||y(e,t))}function ve(e){if(e.visibleToUser===!1)return!1;if(e.hittable)return!0;let t=e.label?.trim()??``;if(t&&!C(t))return!0;let n=e.identifier?.trim()??``;return!!(n&&!C(n))}function y(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||y(e,t)));return t.actionableContentMemo.set(e,r),r}function ye(e){return!!(e.rect&&e.rect.width>0&&e.rect.height>0)}function be(e,t){let n=t.width*t.height;return n<=0?0:a(e,t)/n}function xe(e){let t=[...e.children];for(;t.length>0;){let e=t.pop();t.push(...e.children),Te(e)&&(e.canScrollBackward&&(e.hiddenContentAbove=!0),e.canScrollForward&&(e.hiddenContentBelow=!0))}}function Se(e){let t=e.children.filter(we);if(t.length<2)return;let n=t.filter(e=>b(e)&&x(e));if(n.length===0)return;let r=Ce(n);e.children=e.children.filter(e=>b(e)?x(e)?r===void 0||e.windowLayer===r:!1:!0)}function Ce(e){let t=e.map(e=>e.windowLayer).filter(e=>e!==void 0);return t.length>0?Math.max(...t):void 0}function we(e){return e.windowIndex!==void 0||e.windowType!==void 0}function b(e){return e.windowType===1}function x(e){return e.windowActive===!0||e.windowFocused===!0}function Te(e){if(!e.scrollable||!o(e.type)||`${e.type??``}`.toLowerCase().includes(`horizontalscrollview`))return!1;let t=Ee(e);return!(t&&t.horizontal>t.vertical&&t.horizontal>16)}function Ee(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 De(e,t,n,r,i){if(e.visibleToUser===!1)return!1;let a=Oe(e);return t.interactiveOnly?ke(e,a,n,r,i):a.isStructural||a.isVisual?Me(e,a,r):!0}function Oe(e){let t=S(e.type),n=!!(e.label&&e.label.trim().length>0),r=!!(e.identifier&&e.identifier.trim().length>0);return{type:t,hasMeaningfulText:n&&!C(e.label??``),hasMeaningfulId:r&&!C(e.identifier??``),isStructural:Pe(t),isVisual:t===`imageview`||t===`imagebutton`}}function ke(e,t,n,r,i){return je(e)?!1:e.focused||e.hittable||o(t.type)&&r?!0:Ae(t,n,r,i)}function Ae(e,t,n,r){return!e.hasMeaningfulText&&!e.hasMeaningfulId||e.isVisual||e.isStructural&&!r?!1:t||n||r}function je(e){return!!(e.rect&&(e.rect.width<=0||e.rect.height<=0))}function Me(e,t,n){return e.hittable||t.hasMeaningfulText||t.hasMeaningfulId?!0:n}function Ne(e){if(!e)return!1;let t=S(e);return t.includes(`recyclerview`)||t.includes(`listview`)||t.includes(`gridview`)}function S(e){return e?e.toLowerCase():``}function Pe(e){let t=e.split(`.`).pop()??e;return t.includes(`layout`)||t===`viewgroup`||t===`view`}function C(e){let t=e.trim();return t?/^[\w.]+:id\/[\w.-]+$/i.test(t):!1}function Fe(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 Ie(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 w(e){let t={status:[],results:[],currentStatus:null,currentResult:null};for(let n of e.split(/\r?\n/))Le(n,t);return Re(t),{status:t.status,results:t.results}}function Le(e,t){if(e.startsWith(`INSTRUMENTATION_STATUS: `)){t.currentStatus??={},E(e.slice(24),t.currentStatus);return}if(e.startsWith(`INSTRUMENTATION_STATUS_CODE: `)){ze(t);return}if(e.startsWith(`INSTRUMENTATION_RESULT: `)){t.currentResult??={},E(e.slice(24),t.currentResult);return}e.startsWith(`INSTRUMENTATION_CODE: `)&&T(t)}function Re(e){ze(e),T(e)}function ze(e){e.currentStatus&&=(e.status.push(e.currentStatus),null)}function T(e){e.currentResult&&=(e.results.push(e.currentResult),null)}function E(e,t){let n=e.indexOf(`=`);n<0||(t[e.slice(0,n)]=e.slice(n+1))}function D(e){if(e===void 0)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function O(e){if(e===`true`)return!0;if(e===`false`)return!1}function k(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 A(t,n,r,i){if(t!==r)throw new e(`INVALID_ARGS`,`Android ${i} manifest ${n} must be "${r}".`);return r}const j=`android-snapshot-helper-v1`,M=`uiautomator-xml`,N={"-r":`replace`,"-t":`allowTestPackages`,"-d":`allowDowngrade`,"-g":`grantPermissions`};async function Be(t){let n=await Ge(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 Ve(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:F(n.name,`name`,`android-snapshot-helper`),version:L(n.version,`version`),releaseTag:R(n.releaseTag),assetName:R(n.assetName),apkUrl:Ke(n.apkUrl,`apkUrl`),sha256:We(n.sha256),checksumName:R(n.checksumName),packageName:L(n.packageName,`packageName`),versionCode:P(n.versionCode,`versionCode`),instrumentationRunner:L(n.instrumentationRunner,`instrumentationRunner`),minSdk:P(n.minSdk,`minSdk`),targetSdk:n.targetSdk===void 0?void 0:P(n.targetSdk,`targetSdk`),outputFormat:F(n.outputFormat,`outputFormat`,M),statusProtocol:F(n.statusProtocol,`statusProtocol`,j),installArgs:I(n.installArgs)}}function P(e,t){return k(e,t,`snapshot helper`)}function F(e,t,n){return A(e,t,n,`snapshot helper`)}function He(e){return Ue(I(e.installArgs))}function I(t){let n=qe(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=>!Je(e));if(r)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);return n}function Ue(t){let n={};for(let r of t.slice(1)){let t=z(r);if(!t)throw new e(`INVALID_ARGS`,`Android snapshot helper manifest installArgs contains unsupported install flag "${r}".`);n[t]=!0}return n}function We(t){let n=L(t,`sha256`).trim().toLowerCase();if(n.length!==64||!Ye(n))throw new e(`INVALID_ARGS`,`Android snapshot helper manifest sha256 must be a 64-character hex string.`);return n}async function Ge(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 L(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 R(e){return typeof e==`string`&&e.trim().length>0?e:void 0}function Ke(e,t){return e===null?null:L(e,t)}function qe(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 Je(e){return z(e)!==void 0}function z(e){if(Object.hasOwn(N,e))return N[e]}function Ye(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 Xe(t){let n=B(t),r=await t.adb(H(n),{allowFailure:!0,timeoutMs:n.commandTimeoutMs}),{output:a,cleanupDone:o}=await Ze(t,n,r);if(n.outputPath&&!o&&await it(t.adb,n.outputPath),r.exitCode!==0)throw new e(`COMMAND_FAILED`,`Android snapshot helper failed`,i(r,{helper:a.metadata}));return a}function B(e){let t=V(e.timeoutMs,8e3),n=V(e.packageName,`com.callstack.agentdevice.snapshothelper`);return{waitForIdleTimeoutMs:V(e.waitForIdleTimeoutMs,500),waitForIdleQuietMs:V(e.waitForIdleQuietMs,100),timeoutMs:t,commandTimeoutMs:V(e.commandTimeoutMs,t+5e3),maxDepth:V(e.maxDepth,128),maxNodes:V(e.maxNodes,5e3),packageName:n,runner:V(e.instrumentationRunner,`${n}/.SnapshotInstrumentation`),...e.outputPath?{outputPath:e.outputPath}:{},...e.emitChunks===void 0?{}:{emitChunks:e.emitChunks}}}function V(e,t){return e===void 0?t:e}function H(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 Ze(e,t,n){try{return{output:at(`${n.stdout}\n${n.stderr}`),cleanupDone:!1}}catch(r){return await Qe(e,t,n,r)}}async function Qe(t,n,r,i){if(i instanceof e&&r.exitCode!==0&&i.details?.helper)throw i;let a=await $e(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 $e(e,t,n){if(!(n.exitCode!==0||!t.outputPath))return await tt(e.adb,t.outputPath,rt(`${n.stdout}\n${n.stderr}`)??et(t))}function et(e){return{outputFormat:M,waitForIdleTimeoutMs:e.waitForIdleTimeoutMs,waitForIdleQuietMs:e.waitForIdleQuietMs,timeoutMs:e.timeoutMs,maxDepth:e.maxDepth,maxNodes:e.maxNodes,transport:`instrumentation`}}async function tt(e,t,n){let r;try{r=await e(nt(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 nt(e){return[`shell`,`sh`,`-c`,`cat "$1"; status=$?; rm -f "$1"; exit "$status"`,`agent-device-snapshot-helper-output`,e]}function rt(e){try{return W(U(w(e).results))}catch{return null}}async function it(e,t){try{await e([`shell`,`rm`,`-f`,t],{allowFailure:!0,timeoutMs:5e3})}catch{}}function at(e){let t=w(e),n=U(t.results);return{xml:ct(ot(t.status),n),metadata:{...W(n),transport:`instrumentation`}}}function ot(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:G(n.chunkIndex),count:G(n.chunkCount),payloadBase64:e})}return t}function U(t){let n=t.find(e=>e.agentDeviceProtocol===j);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`,st(n),{errorType:n.errorType,helper:n});return n}function st(e){return e.message&&e.message!==`null`?e.message:e.errorType||`Android snapshot helper returned an error`}function ct(t,n){if(t.length===0)throw new e(`COMMAND_FAILED`,`Android snapshot helper did not return XML chunks`,{helper:n});let r=lt(t),i=Buffer.concat(dt(ut(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 lt(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 ut(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 dt(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 W(e){return{helperApiVersion:e.helperApiVersion,outputFormat:M,waitForIdleTimeoutMs:G(e.waitForIdleTimeoutMs),waitForIdleQuietMs:G(e.waitForIdleQuietMs),timeoutMs:G(e.timeoutMs),maxDepth:G(e.maxDepth),maxNodes:G(e.maxNodes),rootPresent:K(e.rootPresent),captureMode:ft(e.captureMode),windowCount:G(e.windowCount),nodeCount:G(e.nodeCount),truncated:K(e.truncated),elapsedMs:G(e.elapsedMs)}}function ft(e){return e===`interactive-windows`||e===`active-window`?e:void 0}const G=D,K=O,q=2e3,J=5e3,Y=new Map,X=new Map;async function pt(e){if(!jt()||!e.adbProvider?.spawn)return;let n=B(e),r=e.deviceKey??`android:default`,i=At(r,n,e);if(X.get(r)===i)return;let a=Y.get(r);if(a&&a.identity!==i&&(await Z(r),a=void 0),!a)try{a=await _t({deviceKey:r,identity:i,options:e,resolved:n})}catch(e){X.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 Z(r),e}}async function Z(e){let n=Y.get(e);if(n){Y.delete(e);try{await xt(n,`quit ${Date.now()}`,1e3)}catch{}try{await n.process.kill(`SIGTERM`)}catch{}await vt(n.process,q);try{await Ot(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 mt(e){await Z(ht(e))}function ht(e){return`${e.platform}:${e.id}`}function gt(e){return Math.min(e.commandTimeoutMs,Math.max(e.timeoutMs+1e4,3e3))}async function _t(n){let r=await Mt();await n.options.adb([`forward`,`tcp:${r}`,`tcp:${r}`],{allowFailure:!1,timeoutMs:J});let i=H({...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 Ot(c);try{s.kill(`SIGTERM`)}catch{}throw await vt(s,q),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=gt(t);return St(await xt(e,`snapshot ${n}`,r),n)}function xt(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 St(e,t){let{headers:n,xml:r}=Ct(e);return wt(n,t),Tt(n,r),{xml:r,metadata:Dt(n)}}function Ct(t){let n=t.indexOf(`
3
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};
4
+ `);if(n<0)throw new e(`COMMAND_FAILED`,`Android snapshot helper session returned malformed output`,{response:t});return{headers:Et(t.slice(0,n)),xml:t.slice(n+2)}}function wt(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 Tt(t,n){let r=D(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 Et(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 Dt(e){return{helperApiVersion:e.helperApiVersion,outputFormat:M,waitForIdleTimeoutMs:D(e.waitForIdleTimeoutMs),waitForIdleQuietMs:D(e.waitForIdleQuietMs),timeoutMs:D(e.timeoutMs),maxDepth:D(e.maxDepth),maxNodes:D(e.maxNodes),rootPresent:O(e.rootPresent),captureMode:e.captureMode===`interactive-windows`||e.captureMode===`active-window`?e.captureMode:void 0,windowCount:D(e.windowCount),nodeCount:D(e.nodeCount),truncated:O(e.truncated),elapsedMs:D(e.elapsedMs)}}async function Ot(e){await e.process.stdin?.end(),await e.process.stdout?.destroy(),await e.process.stderr?.destroy(),await kt(e)}async function kt(e){await e.adb([`forward`,`--remove`,`tcp:${e.port}`],{allowFailure:!0,timeoutMs:J})}function At(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 jt(){let e=process.env.AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION;return e===void 0||!/^(0|false|no|off)$/i.test(e)}function Mt(){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 Nt(e){$(Pt(e.deviceKey,e.packageName,e.versionCode))}function Pt(e,t,n){return e?`${e}\0${t}\0${n}`:void 0}function Ft(e,t){e&&Q.set(e,t)}function $(e){e&&Q.delete(e)}async function It(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=Pt(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 Lt(t,a,e.timeoutMs),u=Vt(i,l,o);if(u===`current`){if(l===void 0)throw Error(`Expected installed versionCode for current Android snapshot helper`);return Ft(s,l),{packageName:a,versionCode:o,installedVersionCode:l,installed:!1,reason:u}}await Be(r);let d=await Rt(t,e.adbProvider??t,r.apkPath,He(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 Ft(s,o),{packageName:a,versionCode:o,installedVersionCode:l,installed:!0,reason:u}}async function Lt(e,t,n){let r=await e([`shell`,`cmd`,`package`,`list`,`packages`,`--show-versioncode`,t],{allowFailure:!0,timeoutMs:n});if(r.exitCode===0)return zt(`${r.stdout}\n${r.stderr}`,t)}async function Rt(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||!Bt(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 zt(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 Bt(e){return`${e.stdout}\n${e.stderr}`.includes(`INSTALL_FAILED_UPDATE_INCOMPATIBLE`)}function Vt(e,t,n){return e===`never`?`skipped`:e===`always`?`forced`:t===void 0?`missing`:t<n?`outdated`:`current`}export{u as _,Z as a,Ve as c,A as d,D as f,g,ee as h,ht as i,w as l,te as m,Nt as n,mt as o,d as p,pt as r,Xe as s,It as t,k as u};
@@ -1 +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
+ 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){return e.state===`recovered`?[`Detected an overly complex or slow accessibility tree. Fell back to the ${e.backend} snapshot backend. It is OK to continue; use --json to inspect snapshotQuality.reason if you need recovery details.`]: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?[]:[`Some deeper accessibility nodes were omitted; this tree is capped at depth ${e.effectiveDepth}. Re-run with --depth ${e.effectiveDepth} --scope <container> only if you need 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,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
+ 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{E as c}from"./sdk-batch.js";import{Et as l,Ot as u,hn as d,jt as f,kt as p,wn as m}from"./tv-remote.js";import{i as h}from"./snapshot-diagnostics.js";import{t as g}from"./timeouts.js";import{t as _}from"./runtime.js";import{i as v}from"./runner-client.js";import{i as ee}from"./helper.js";import{$t as y,At as te,Ct as ne,Dt as re,Ft as ie,Gt as b,Ot as ae,Pt as x,tn as S,zt as C}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,...m(`Alert visible`)}}async function Te(e,n){let r=await q(e,f);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 g(300)}return null}async function J(e){return L((await o(`snapshot_capture`,async()=>await re(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function Ee(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...m(e?`Alert visible`:`No alert visible`)}}function Y(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...m(`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=S(`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 ee(e,s));let u=ce({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await X(e,o,async e=>await v(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 g(300)}return y(`COMMAND_FAILED`,`alert wait timed out`)}async function Ae(e,t,n){let r=Date.now(),i;for(;Date.now()-r<f;){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 g(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])?y(`INVALID_ARGS`,l):{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:d,permissionTarget:f,latitude:m,longitude:h}=s,g=S(`settings`,o);if(g)return g;if(i(o)&&!p(c))return y(`INVALID_ARGS`,u(c));let _=d??a?.appBundleId;if(c===`clear-app-state`&&!_)return y(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let v=await b(o,`settings`,c===`clear-app-state`?[c,l,_??``]:c===`permission`?[c,l,f??``,t.positionals?.[3]??``,_??``]:c===`location`&&l===`set`?[c,l,m??``,h??``,_??``]:[c,l,_??``],t.flags?.out,{...C(n,t.flags,_,a?.trace?.outPath)});return E(r,a,t,v??{setting:c,state:l}),{ok:!0,data:v??{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 b(t.device,`screenshot`,[n],void 0,{...C(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 ne({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=S(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=ie(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:y(`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 _({backend:Qe({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...de(`snapshot`),sessions:ae({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:te(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 x({device:a,session:i,flags:t.flags,outPath:r?.outPath??t.flags?.out,logPath:n,snapshotScope:o}),c=h(i);return{snapshot:s.snapshot,...d(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}):y(`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};
@@ -0,0 +1,14 @@
1
+ import{A as e,B as t,F as n,O as r,P as i,j as a,k as o}from"./sdk-contracts.js";import{C as s,S as c,b as l,p as u,w as d,x as f,y as p}from"./sdk-batch.js";import{A as m,C as h,D as g,F as ee,L as te,M as ne,N as re,O as ie,S as ae,T as oe,b as se,j as ce,k as le,m as ue,p as de,w as fe,x as pe,y as me,z as he}from"./sdk-selectors.js";import{b as _}from"./sdk-batch-runner.js";import{n as ge,t as _e}from"./snapshot-quality.js";import{a as ve,i as ye,n as be,o as xe,t as Se}from"./selectors2.js";import{createHash as Ce}from"node:crypto";import we from"node:path";import{styleText as Te}from"node:util";const Ee=Pe(`public`),De=Pe(`internal`),Oe=Pe(`local-cli`),ke={help:`help`},Ae=[`pan`,`fling`,`swipe`,`pinch`,`rotate`,`transform`],je=`gesture requires one of: ${Ae.join(`, `)}`;function Me(){return[...Object.values(Ee),...Object.values(Oe)].sort()}function Ne(e){return Object.values(ke).includes(e)||Object.values(De).includes(e)?!0:Me().includes(e)}function Pe(e){let t={};for(let[n,r]of u(e))t[n]=r;return t}function v(e){return e.width>0&&e.height>0}function Fe(e,t){return!e||!t?!1:e.x>=t.x-2&&e.y>=t.y-2&&e.x+e.width<=t.x+t.width+2&&e.y+e.height<=t.y+t.height+2}function Ie(e,t){if(!e||!t)return!0;let n=e.y+e.height/2,r=t.y+t.height/2;return Math.abs(n-r)<=Math.max(e.height,t.height,1)}function Le(e){return typeof e.parentIndex!=`number`}function y(e){let t=(e.type??``).toLowerCase(),n=(e.identifier??``).trim().toLowerCase();return t.includes(`edittext`)||t.includes(`textfield`)||n===`composer`}function Re(e){let t=(e.type??``).toLowerCase();return t.includes(`scroll`)||t.includes(`list`)||t.includes(`recyclerview`)}function b(e){let t=he(e);if(!t||t!==e.identifier?.trim()||!ze(t))return t;let n=(e.type??``).toLowerCase();return n.includes(`view`)||n.includes(`layout`)||n.includes(`image`)||n.includes(`list`)||n.includes(`recyclerview`)||n.includes(`collection`)?``:t}function x(e){let t=e.trim().replace(/\s+/g,` `).toLowerCase();return!t||/^(true|false|\d+)$/.test(t)?null:t}function ze(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function Be(e,t,n){let r=e;for(;typeof r.parentIndex==`number`;){let e=t.get(r.parentIndex);if(!e)return null;if(n(e))return e;r=e}return null}function Ve(e,t){let n=[],r=[t];for(;r.length>0;){let t=r.pop();for(let i of e)i.parentIndex===t&&(n.push(i),r.push(i.index))}return n}function S(e,t,n){let r=[t];for(;r.length>0;){let t=r.pop();if(!n.has(t)){n.add(t);for(let i of e)i.parentIndex!==t||n.has(i.index)||r.push(i.index)}}}const He=[`button`,`switch`,`checkbox`,`radio`],Ue=[`button`,`image`,`textview`,`view`];function We(e,t,n){for(let r of e){if(t.has(r.index)||!qe(r))continue;let i=Je(Ve(e,r.index),r,t);if(i.label){n.set(r.index,{...r,...n.get(r.index),label:i.label});for(let n of i.removableIndexes)S(e,n,t)}}}function Ge(e,t,n){let r=new Map;for(let i of e){if(t.has(i.index)||!tt(i))continue;let a=x(b(i));if(!a)continue;let o=r.get(a);if(o&&Qe(o,i,t)){let s=$e(e,o,i,t,n);r.set(a,s);continue}r.set(a,i)}}function Ke(e,t){for(let n of e){if(t.has(n.index)||!Xe(n))continue;let r=x(b(n));if(!r)continue;let i=Ve(e,n.index).filter(e=>!t.has(e.index)&&Ze(n,e,r));for(let n of i.filter(Ye))S(e,n.index,t);let a=i.filter(e=>!Ye(e)),o=new Set(a.map(e=>x(b(e))).filter(e=>!!e));if(!(a.length<2||o.size<2))for(let n of a)S(e,n.index,t)}}function qe(e){return e.hittable===!0&&!y(e)&&!!(e.rect&&v(e.rect))&&b(e).trim().length===0}function Je(e,t,n){let r=[],i=[],a=new Set;for(let o of e){if(n.has(o.index)||!Ye(o)||!Fe(o.rect,t.rect))continue;let e=b(o).trim().replace(/\s+/g,` `),s=x(e);i.push(o.index),!(!e||!s||a.has(s))&&(a.add(s),r.push(e))}return{label:r.join(`, `),removableIndexes:i}}function Ye(e){if(e.hittable===!0||y(e))return!1;let t=(e.type??``).toLowerCase();return t.includes(`text`)||t.includes(`image`)||t.includes(`icon`)}function Xe(e){return e.hittable===!0&&!y(e)&&!!(e.rect&&v(e.rect))&&!!x(b(e))}function Ze(e,t,n){if(!tt(t)||!Fe(t.rect,e.rect))return!1;let r=x(b(t));return!!(r&&n!==r&&n.includes(r))}function Qe(e,t,n){return!n.has(e.index)&&Ie(e.rect,t.rect)&&(ot(e,t)||at(e,t))}function $e(e,t,n,r,i){let a=nt(t,n),o=a.index===t.index?n:t,s=(o.type??``).toLowerCase().includes(`image`)?`has image`:null,c=i.get(a.index)??a,l=i.get(o.index)?.presentationHints??o.presentationHints;return i.set(a.index,{...c,presentationHints:et(c.presentationHints,l,s)}),S(e,o.index,r),i.get(a.index)??a}function et(e,t,n){return[...new Set([...Array.isArray(e)?e:[],...Array.isArray(t)?t:[],...n?[n]:[]])]}function tt(e){if(!e.rect||!v(e.rect)||Le(e)||y(e))return!1;let t=(e.type??``).toLowerCase();return t===`text`||it(t,Ue)}function nt(e,t){let n=rt(e);return rt(t)>n?t:e}function rt(e){let t=(e.type??``).toLowerCase(),n=0;return it(t,He)?n+=100:t.includes(`image`)?n+=30:t.includes(`textview`)||t===`text`?n+=20:t.includes(`view`)&&(n+=10),e.hittable===!0&&(n+=20),e.enabled!==!1&&(n+=5),n}function it(e,t){return t.some(t=>e.includes(t))}function at(e,t){let n=e.parentIndex===t.index?t:t.parentIndex===e.index?e:null,r=n?.index===e.index?t:n?.index===t.index?e:null;return!n||!r?!1:nt(n,r).index===n.index}function ot(e,t){return e.parentIndex===t.parentIndex?Math.abs(e.index-t.index)<=3:e.parentIndex===t.index||t.parentIndex===e.index?!1:Math.abs((e.depth??0)-(t.depth??0))<=1&&Math.abs(e.index-t.index)<=2}function st(e,t,n){if(n.raw||!ct(e))return{nodes:t,filteredCount:0};let r=lt(t);return{nodes:r,filteredCount:t.length-r.length}}function ct(e){let t=e.androidSnapshot;return!t||typeof t!=`object`?!1:t.backend===`android-helper`}function lt(e){if(e.length===0)return e;let t=new Set,n=new Map,r=new Map(e.map(e=>[e.index,e]));return ut(e,t),dt(e,r,t,n),We(e,t,n),Ke(e,t),Ge(e,t,n),e.filter(e=>!t.has(e.index)).map(e=>n.get(e.index)??e)}function ut(e,t){for(let n of e)!n.rect||v(n.rect)||Le(n)||S(e,n.index,t)}function dt(e,t,n,r){for(let i of e){if(n.has(i.index)||i.rect||Le(i))continue;let a=Be(i,t,Re);a&&pt(r,a,ft(i,e)),S(e,i.index,n)}}function ft(e,t){let n=t.filter(t=>t.parentIndex===e.parentIndex&&t.rect&&v(t.rect)).map(e=>e.index);return n.length===0?null:e.index<Math.min(...n)?`above`:e.index>Math.max(...n)?`below`:null}function pt(e,t,n){if(!n)return;let r=e.get(t.index)??t;e.set(t.index,{...r,hiddenContentAbove:r.hiddenContentAbove===!0||n===`above`?!0:void 0,hiddenContentBelow:r.hiddenContentBelow===!0||n===`below`?!0:void 0})}function mt(e){let t=e.trim().replace(/\s+/g,` `).toLowerCase();return!t||ht(t)?null:t}function ht(e){return/\S+@\S+\.\S+/.test(e)}function gt(e){if(e.length<20)return!1;let t=new Map;for(let n of e){let e=(n.type??``).toLowerCase(),r=mt(he(n));if(!r)continue;let i=`${e}|${r}`,a=t.get(i)??[];a.push(n),t.set(i,a)}let n=0;for(let e of t.values())e.length<=1||!_t(e)||(n+=e.length);return n>=8}function _t(e){for(let t=0;t<e.length;t+=1)for(let n=t+1;n<e.length;n+=1)if(vt(e[t]?.rect,e[n]?.rect))return!0;return!1}function vt(e,t){if(!e||!t)return!0;let n=.5;return!(e.x+e.width<=t.x+n||t.x+t.width<=e.x+n||e.y+e.height<=t.y+n||t.y+t.height<=e.y+n)}const yt={application:`application`,navigationbar:`navigation-bar`,tabbar:`tab-bar`,button:`button`,imagebutton:`button`,link:`link`,cell:`cell`,statictext:`text`,checkedtextview:`text`,textbox:`text-field`,textfield:`text-field`,edittext:`text-field`,textarea:`text-view`,switch:`switch`,slider:`slider`,image:`image`,imageview:`image`,webview:`webview`,framelayout:`group`,linearlayout:`group`,relativelayout:`group`,constraintlayout:`group`,viewgroup:`group`,view:`group`,listview:`list`,recyclerview:`list`,collectionview:`collection`,searchfield:`search`,segmentedcontrol:`segmented-control`,group:`group`,window:`window`,checkbox:`checkbox`,radio:`radio`,menuitem:`menu-item`,toolbar:`toolbar`,scrollarea:`scroll-area`,scrollview:`scroll-area`,nestedscrollview:`scroll-area`,table:`table`};function C(e,t={}){let n=[],r=[];for(let i of e){let e=i.depth??0,a=i.label?.trim()||i.value?.trim()||i.identifier?.trim()||``,o=T(i.type??`Element`),s=i.inheritsLabel===!0||i.inheritsIdentifier===!0;if(o===`group`&&!a&&!s)continue;for(;n.length>0&&e<=n[n.length-1];)n.pop();let c=n.length;n.push(e),r.push({node:i,depth:c,type:o,text:bt(i,c,!1,o,t)})}return r}function bt(e,t,n,r,i={}){let a=r??T(e.type??`Element`),o=ce(e,a),s=Tt(e,a,i,o),c=` `.repeat(t),l=e.ref?`@${e.ref}`:``,u=Et(e,a,i,o);!s&&(e.inheritsLabel===!0||e.inheritsIdentifier===!0)&&u.push(`same label as parent`);let d=u.map(e=>` [${e}]`).join(``),f=s?` "${s}"`:``;return n?`${c}${l} [${a}]${d}`.trimEnd():`${c}${l} [${a}]${f}${d}`.trimEnd()}function w(e,t){let n=e.label?.trim();if(n&&Ct(t,n))return``;let r=e.value?.trim();if(St(t)){if(r)return r;if(n)return n}else if(n)return n;if(r)return r;let i=e.identifier?.trim();return!i||wt(i)&&(t===`group`||t===`image`||t===`list`||t===`collection`)?``:i}function T(e){let t=e,n=e.replace(/XCUIElementType/gi,``).toLowerCase(),r=t.includes(`.`)&&(t.startsWith(`android.`)||t.startsWith(`androidx.`)||t.startsWith(`com.`));return n.includes(`.`)&&(n=n.replace(/^android\.widget\./,``).replace(/^android\.view\./,``).replace(/^android\.webkit\./,``).replace(/^androidx\./,``).replace(/^com\.google\.android\./,``).replace(/^com\.android\./,``),r&&n.includes(`.`)&&(n=n.slice(n.lastIndexOf(`.`)+1))),n===`textview`?r?`text`:`text-view`:xt(n)||n||`element`}function xt(e){return Object.prototype.hasOwnProperty.call(yt,e)?yt[e]:void 0}function St(e){return e===`text-field`||e===`text-view`||e===`search`}function Ct(e,t){return e!==`scroll-area`&&e!==`list`&&e!==`collection`&&e!==`table`?!1:te(t)}function wt(e){return/^[\w.]+:id\/[\w.-]+$/i.test(e)}function Tt(e,t,n,r){return!n.summarizeTextSurfaces||!r.shouldSummarize?w(e,t):Dt(e,t,r.text)||w(e,t)}function Et(e,t,n,r){let i=[];return e.enabled===!1&&i.push(`disabled`),i.push(...e.presentationHints??[]),!n.summarizeTextSurfaces||(e.selected===!0&&i.push(`selected`),e.focused===!0&&i.push(`focused`),St(t)&&i.push(`editable`),Ot(e,t)&&i.push(`scrollable`),!r.shouldSummarize)?At(i):(i.push(`preview:"${kt(m(r.text))}"`),i.push(`truncated`),At(i))}function Dt(e,t,n){let r=ee(e.label);if(r&&r!==n)return r;let i=ee(e.identifier);if(i&&!wt(i)&&i!==n)return i;switch(t){case`text`:case`text-view`:return`Text view`;case`text-field`:return`Text field`;case`search`:return`Search field`;default:return``}}function Ot(e,t){if(t===`scroll-area`)return!0;let n=(e.type??``).toLowerCase(),r=`${e.role??``} ${e.subrole??``}`.toLowerCase();return n.includes(`scroll`)||r.includes(`scroll`)}function kt(e){return e.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}function At(e){return[...new Set(e)]}function jt(e){process.stdout.write(`${JSON.stringify(e,null,2)}\n`)}function Mt(e,r={}){let i=e instanceof n?t(e):e;process.stderr.write(`Error (${i.code}): ${i.message}\n`),i.hint&&process.stderr.write(`Hint: ${i.hint}\n`),i.diagnosticId&&process.stderr.write(`Diagnostic ID: ${i.diagnosticId}\n`),i.logPath&&process.stderr.write(`Diagnostics Log: ${i.logPath}\n`),r.showDetails&&i.details&&process.stderr.write(`${JSON.stringify(i.details,null,2)}\n`)}function Nt(t,n={}){let r=t.nodes,a=Array.isArray(r)?r:[],o=i(e(t.backend)?t.backend:void 0),s=st(t,a,n),c=Lt(t),l=dn(t,a,n,s),u=l.length>0?`${l.join(`
2
+ `)}\n`:``,d=n.raw?null:Pt(t);if(d)return`${c}${u}${Ft(d)}\n`;let f=n.raw||!o?null:se(s.nodes),p=!!t.truncated,m=f?.nodes??a,h=n.raw||!o?null:Ut(t,f,m.length,a.length,s.filteredCount),g=Rt(a.length,h,p);return a.length===0?`${c}${g}\n${u}`:n.raw?`${c}${g}\n${u}${zt(a)}\n`:n.flatten?`${c}${g}\n${u}${Bt(m)}${Ht(f)}\n`:`${c}${g}\n${u}${Vt(m)}${Ht(f)}\n`}function Pt(e){let t=e.unchanged;if(!t||typeof t!=`object`)return null;let n=t;return typeof n.ageMs!=`number`||typeof n.nodeCount!=`number`?null:{ageMs:n.ageMs,nodeCount:n.nodeCount,interactiveOnly:n.interactiveOnly===!0?!0:void 0,scope:typeof n.scope==`string`?n.scope:void 0}}function Ft(e){let t=It(e.ageMs);return e.scope?[`Scoped snapshot unchanged for scope "${e.scope}" since previous read ${t} ago.`,`Previous refs in this scope remain valid. Use find/get/is for a targeted query, or --force-full to re-emit.`].join(`
3
+ `):e.interactiveOnly?[`Interactive snapshot unchanged since previous read ${t} ago.`,`${e.nodeCount} visible nodes are unchanged. Previous @e refs are still valid. Use find/get/is for a targeted query, or --force-full to re-emit.`].join(`
4
+ `):[`Snapshot unchanged since previous read ${t} ago.`,`Refs from the previous snapshot are still valid. Use --force-full to re-emit the tree, or use find/get/is for a targeted query.`].join(`
5
+ `)}function It(e){if(e<1e3)return`${Math.round(e)}ms`;if(e<6e4)return`${(Math.round(e/100)/10).toFixed(1)}s`;let t=e/6e4;if(t<60)return`${(Math.round(t*10)/10).toFixed(1)}m`;let n=t/60;return`${(Math.round(n*10)/10).toFixed(1)}h`}function Lt(e){let t=typeof e.appName==`string`?e.appName:void 0,n=typeof e.appBundleId==`string`?e.appBundleId:void 0,r=[];return t&&r.push(`Page: ${t}`),n&&r.push(`App: ${n}`),r.length>0?`${r.join(`
6
+ `)}\n`:``}function Rt(e,t,n){let r=n?` (truncated)`:``;return t?.partial?t.totalNodeCount>t.visibleNodeCount?`Snapshot: ${t.visibleNodeCount} visible nodes (${t.totalNodeCount} total)${r}`:`Snapshot: ${t.visibleNodeCount} visible nodes${r}`:`Snapshot: ${e} nodes${r}`}function zt(e){return e.map(e=>JSON.stringify(e)).join(`
7
+ `)}function Bt(e){return yn(e).join(`
8
+ `)}function Vt(e){return gn(C(e,{summarizeTextSurfaces:!0})).join(`
9
+ `)}function Ht(e){return e&&e.summaryLines.length>0?`\n${e.summaryLines.join(`
10
+ `)}`:``}function Ut(e,t,n,r,i=0){let a=Wt(e);if(i===0&&a)return a;let o=(t?.hiddenCount??0)+i,s=t?t.nodes.some(e=>e.hiddenContentAbove||e.hiddenContentBelow):!1;return o>0?{partial:!0,visibleNodeCount:n,totalNodeCount:Math.max(r,a?.totalNodeCount??r),reasons:Gt([...a?.reasons??[],`offscreen-nodes`])}:a||(s?{partial:!0,visibleNodeCount:n,totalNodeCount:n,reasons:[]}:null)}function Wt(e){let t=e.visibility;if(!t||typeof t!=`object`)return null;let n=t;return typeof n.partial!=`boolean`||typeof n.visibleNodeCount!=`number`||typeof n.totalNodeCount!=`number`||!Array.isArray(n.reasons)?null:{partial:n.partial,visibleNodeCount:n.visibleNodeCount,totalNodeCount:n.totalNodeCount,reasons:n.reasons.filter(e=>typeof e==`string`)}}function Gt(e){return[...new Set(e)]}function Kt(e){let t=e.baselineInitialized===!0,n=e.summary??{},r=D(n.additions),i=D(n.removals),a=D(n.unchanged),o=O(),s=hn(e),c=s.length>0?`${s.join(`
11
+ `)}\n`:``;if(t)return`${c}Baseline initialized (${a} lines).\n`;let l=un(Array.isArray(e.lines)?e.lines:[],1).map(e=>{let t=typeof e.text==`string`?e.text:``;if(e.kind===`added`){let e=t.startsWith(` `)?`+${t}`:`+ ${t}`;return o?k(e,`green`):e}if(e.kind===`removed`){let e=t.startsWith(` `)?`-${t}`:`- ${t}`;return o?k(e,`red`):e}return o?k(t,`dim`):t}),u=l.length>0?`${l.join(`
12
+ `)}\n`:``;return o?`${c}${u}${[`${k(String(r),`green`)} additions`,`${k(String(i),`red`)} removals`,`${k(String(a),`dim`)} unchanged`].join(`, `)}\n`:`${c}${u}${r} additions, ${i} removals, ${a} unchanged\n`}function qt(e){let t=O(),n=e.match===!0,r=e.dimensionMismatch,i=[];return i.push(...Jt(e,t)),i.push(...Yt(e,n,t)),!n&&!r&&(i.push(...Xt(e,t)),i.push(...Zt(e,t)),i.push(...Qt(e,t)),i.push(...en(e,t)),i.push(...tn(e,t))),`${i.join(`
13
+ `)}\n`}function Jt(e,t){if(e.match===!0)return[`${t?k(`✓`,`green`):`✓`} Screenshots match.`];let n=e.dimensionMismatch,r=t?k(`✗`,`red`):`✗`;if(n){let e=n.expected,t=n.actual;return[`${r} Screenshots have different dimensions: expected ${e?.width}x${e?.height}, got ${t?.width}x${t?.height}`]}let i=D(e.differentPixels),a=D(e.mismatchPercentage),o=`${a===0&&i>0?`<0.01`:String(a)}% pixels differ`;return[`${r} ${t?k(o,`red`):o}`]}function Yt(e,t,n){if(t)return[];let r=[];if(e.diffPath){let t=ln(e.diffPath),i=n?k(`Diff image:`,`dim`):`Diff image:`,a=n?k(t,`green`):t;r.push(` ${i} ${a}`)}if(e.currentOverlayPath){let t=ln(e.currentOverlayPath),i=n?k(`Current overlay:`,`dim`):`Current overlay:`,a=n?k(t,`green`):t,o=D(e.currentOverlayRefCount),s=o>0?` (${o} refs)`:``;r.push(` ${i} ${a}${s}`)}return r}function Xt(e,t){let n=D(e.differentPixels),r=D(e.totalPixels);return[` ${t?k(String(n),`red`):String(n)} different / ${r} total pixels`]}function Zt(e,t){let n=rn(e);return n.length===0?[]:[` ${A(`Hints:`,t)}`,...n.map(e=>` - ${e}`)]}function Qt(e,t){let n=Array.isArray(e.regions)?e.regions:[];if(n.length===0)return[];let r=[` ${A(`Changed regions:`,t)}`];for(let e of n.slice(0,5))r.push(...$t(e));return r}function $t(e){let t=e.shareOfDiffPercentage===0&&e.differentPixels>0?`<0.01`:String(e.shareOfDiffPercentage),n=e.rect,r=[` ${e.index}. ${e.location} x=${n.x} y=${n.y} ${n.width}x${n.height}, ${t}% of diff, change=${e.dominantChange}`],i=cn(e);i&&r.push(` ${i}`);let a=e.currentOverlayMatches?.[0];if(a){let e=a.label?` "${a.label}"`:``;r.push(` overlaps @${a.ref}${e}, ${a.regionCoveragePercentage}% of region`)}return r}function en(e,t){let n=e.ocr?.matches??[];if(n.length===0)return[];let r=n.slice(0,8),i=[` ${A(`OCR text deltas (${e.ocr?.provider}; baselineBlocks=${e.ocr?.baselineBlocks} currentBlocks=${e.ocr?.currentBlocks}; showing ${r.length}/${n.length}; px):`,t)}`,` ${A(`item | text | movePx | sizeDeltaPx | bboxBaseline | bboxCurrent | confidence | issueHint`,t)}`];for(let[e,t]of r.entries()){let n=t.delta;i.push(` ${e+1} | ${JSON.stringify(t.text)} | ${E(n.x)},${E(n.y)} | ${E(n.width)},${E(n.height)} | ${nn(t.baselineRect)} | ${nn(t.currentRect)} | ${t.confidence} | ${t.possibleTextMetricMismatch?`ocr-bbox-size-change`:`-`}`)}return i}function tn(e,t){let n=e.nonTextDeltas??[];if(n.length===0)return[];let r=n.slice(0,8),i=[` ${A(`Non-text visual deltas (showing ${r.length}/${n.length}; px):`,t)}`,` ${A(`item | region | slot | kind | bboxCurrent | nearestText`,t)}`];for(let e of r)i.push(` ${e.index} | ${e.regionIndex?`r${e.regionIndex}`:`-`} | ${e.slot} | ${e.likelyKind} | ${nn(e.rect)} | ${e.nearestText?JSON.stringify(e.nearestText):`-`}`);return i}function nn(e){return`x=${e.x},y=${e.y},w=${e.width},h=${e.height}`}function E(e){return e>0?`+${e}`:String(e)}function rn(e){let t=[],n=e.ocr?.movementClusters??[];for(let e of n.slice(0,2))t.push(`text movement cluster: ${sn(e.texts)} dx=${on(e.xRange)}px dy=${on(e.yRange)}px`);let r=(e.nonTextDeltas??[]).filter(e=>[`icon`,`toggle`,`chevron`].includes(e.likelyKind)).slice(0,3);r.length>0&&t.push(`non-text controls: ${r.map(an).join(`; `)}`);let i=(e.nonTextDeltas??[]).filter(e=>e.likelyKind===`separator`).slice(0,2);return i.length>0&&t.push(`non-text boundaries: ${i.map(an).join(`; `)}`),t.slice(0,6)}function an(e){let t=e.nearestText?` near ${JSON.stringify(e.nearestText)}`:``,n=e.regionIndex?` r${e.regionIndex}`:``;return`${e.likelyKind}${t}${n}`}function on(e){return e.min===e.max?E(e.min):`${E(e.min)}..${E(e.max)}`}function sn(e){let t=e.slice(0,4).map(e=>JSON.stringify(e)),n=e.length>t.length?` +${e.length-t.length} more`:``;return`${t.join(`, `)}${n}`}function cn(e){let t=[e.size?`size=${e.size}`:null,e.shape?`shape=${e.shape}`:null,typeof e.densityPercentage==`number`?`density=${e.densityPercentage}%`:null,e.averageBaselineColorHex&&e.averageCurrentColorHex?`avgColor=${e.averageBaselineColorHex}->${e.averageCurrentColorHex}`:null,typeof e.baselineLuminance==`number`&&typeof e.currentLuminance==`number`?`luminance=${e.baselineLuminance}->${e.currentLuminance}`:null].filter(e=>e!==null);return t.length>0?t.join(` `):null}function ln(e){let t=process.cwd(),n=we.relative(t,e);return n===``||!n.startsWith(`..`)&&!we.isAbsolute(n)?n===``?`.`:`.${we.sep}${n}`:e}function D(e){return typeof e==`number`&&Number.isFinite(e)?e:0}function un(e,t){if(e.length===0)return e;let n=e.map((e,t)=>({index:t,kind:e.kind})).filter(e=>e.kind===`added`||e.kind===`removed`).map(e=>e.index);if(n.length===0)return e;let r=Array(e.length).fill(!1);for(let i of n){let n=Math.max(0,i-t),a=Math.min(e.length-1,i+t);for(let e=n;e<=a;e+=1)r[e]=!0}return e.filter((e,t)=>r[t])}function O(e=process.stdout){let t=process.env.FORCE_COLOR;return typeof t==`string`?t!==`0`:typeof process.env.NO_COLOR==`string`?!1:!!e.isTTY}function k(e,t,n){return Te(t,e,n)}function A(e,t){return t?k(e,`dim`):e}function dn(e,t,n,r={nodes:t,filteredCount:0}){let i=hn(e);if(fn(e)){let e=mn(t,n);e&&i.push(e)}!n.raw&&r.filteredCount>0&&i.push(`Collapsed ${r.filteredCount} Android helper node${r.filteredCount===1?``:`s`} from the agent-facing text snapshot; use --raw or --json for the full hierarchy.`);let a=r.filteredCount>0?r.nodes:t;return!n.raw&&gt(a)&&i.push(`Warning: possible repeated nav subtree detected.`),i}function fn(e){return!e.snapshotQuality&&!pn(e)}function pn(e){let t=e.snapshotDiagnostics;if(!t||typeof t!=`object`)return!1;let n=t.stats;return!!(n&&typeof n==`object`&&n.platform===`web`)}function mn(e,t){if(t.scoped===!0||t.depthLimited===!0||e.length>3)return null;let n=e.length===1?`node`:`nodes`;return`Hint: sparse accessibility snapshot returned ${e.length} ${n}; snapshot state is invalid or unavailable for this screen. Use plain screenshot, not screenshot --overlay-refs, as visual truth. If screenshot shows the Home Screen or another app, run open for this app again first. Then navigate away with coordinates if needed and retry snapshot -i on the next screen.`}function hn(e){let t=e.warnings;return Array.isArray(t)?t.filter(e=>typeof e==`string`&&e.length>0):[]}function gn(e){let t=[],n=[],r=new Map(e.map(e=>[e.node.index,e.node])),i=e=>{for(;n.length>0&&(!e||_n(e,n[n.length-1],r));)t.push(...bn(n.pop(),`below`))};for(let r of e)i(r),t.push(r.text),t.push(...bn(r,`above`)),r.node.hiddenContentBelow&&n.push(r);return i(),t}function _n(e,t,n){return vn(e.node,t.node,n)?!1:e.depth<=t.depth}function vn(e,t,n){let r=e;for(;typeof r.parentIndex==`number`;){if(r.parentIndex===t.index)return!0;let e=n.get(r.parentIndex);if(!e)return!1;r=e}return!1}function yn(e){return C(e,{summarizeTextSurfaces:!0}).flatMap(e=>[bt(e.node,0,!1,e.type,{summarizeTextSurfaces:!0}),...bn({...e,depth:0})])}function bn(e,t){let n=xn(e.type);if(!n)return[];let r=[];if(e.node.hiddenContentAbove&&t!==`below`&&r.push(`[content above ${n} hidden]`),e.node.hiddenContentBelow&&t!==`above`&&r.push(`[content below ${n} hidden]`),r.length===0)return[];let i=` `.repeat(e.depth+1);return r.map(e=>`${i}${e}`)}function xn(e){return e===`scroll-area`||e===`list`||e===`collection`||e===`table`?e:null}function Sn(e,t={}){let n=O(process.stderr);if(e===`pass`){let e=t.passFormat??`green`;return n?j(`✓`,e):`✓`}return e===`fail`?n?j(`⨯`,`red`):`⨯`:e===`warn`?n?j(`!`,`yellow`):`!`:n?j(`-`,`dim`):`-`}function j(e,t){return k(e,t,{validateStream:!1})}function Cn(e){return`${Sn(Tn(e.status))} ${En(e)}`}function wn(e){return e.status!==`fail`&&e.status!==`warn`?[]:typeof e.command==`string`?[` run: ${e.command}`]:typeof e.hint==`string`?[` hint: ${e.hint}`]:[]}function Tn(e){return e===`pass`?`pass`:e===`fail`?`fail`:e===`warn`?`warn`:`skip`}function En(e){let t=typeof e.id==`string`&&e.id.length>0?e.id:`check`,n=typeof e.summary==`string`&&e.summary.length>0?e.summary:t;return n===t?t:`${t}: ${n}`}const Dn=3e5,On=[`leaseId`,`tenantId`,`runId`,`clientId`,`deviceKey`];function kn(e){return _({tenantId:e.meta?.tenantId??M(e.flags,`tenant`),runId:e.meta?.runId??M(e.flags,`runId`),leaseId:e.meta?.leaseId??M(e.flags,`leaseId`),leaseTtlMs:e.meta?.leaseTtlMs,leaseBackend:e.meta?.leaseBackend,leaseProvider:e.meta?.leaseProvider??M(e.flags,`leaseProvider`)??M(e.flags,`provider`),deviceKey:e.meta?.deviceKey??M(e.flags,`deviceKey`),clientId:e.meta?.clientId??M(e.flags,`clientId`)})}function An(e){return _({tenantId:e.tenant,runId:e.runId,leaseId:e.leaseId,leaseTtlMs:e.leaseTtlMs??e.ttlMs,leaseBackend:e.leaseBackend,leaseProvider:e.leaseProvider??e.provider,deviceKey:e.deviceKey,clientId:e.clientId})}function jn(e){return _({tenantId:e.tenantId,runId:e.runId,leaseId:e.leaseId,leaseTtlMs:e.leaseTtlMs,leaseBackend:e.leaseBackend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId})}function Mn(e){return _({tenant:e.tenantId,runId:e.runId,leaseId:e.leaseId,leaseBackend:e.leaseBackend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId})}function Nn(e){return _({tenantId:e.tenantId??``,runId:e.runId??``,leaseBackend:e.leaseBackend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId,ttlMs:e.leaseTtlMs})}function Pn(e){return Bn(e)}function Fn(e){let{ttlMs:t,...n}=Bn(e);return n}function In(e,t,n){let r=_({...n.includeTokenParam?{token:n.token}:{},session:n.session,tenantId:e.tenantId,runId:e.runId,leaseProvider:e.leaseProvider,clientId:e.clientId,deviceKey:e.deviceKey});switch(t){case`lease_allocate`:return{...r,..._({ttlMs:e.leaseTtlMs,backend:e.leaseBackend})};case`lease_heartbeat`:return{...r,..._({leaseId:e.leaseId,ttlMs:e.leaseTtlMs})};case`lease_release`:return{...r,..._({leaseId:e.leaseId})}}}function Ln(e){let t=_({leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId});return Object.keys(t).length>0?t:void 0}function Rn(e){return e.leaseProvider===`proxy`}function zn(e){return Rn(e)?On.filter(t=>!e[t]):[]}function Bn(e){return _({leaseId:e.leaseId??``,tenantId:e.tenantId,runId:e.runId,leaseBackend:e.leaseBackend,leaseProvider:e.leaseProvider,deviceKey:e.deviceKey,clientId:e.clientId,ttlMs:e.leaseTtlMs})}function M(e,t){let n=e?.[t];return typeof n==`string`?n:void 0}function N(e){return e?{message:e}:{}}function P(e,t){return t?{...e,message:t}:e}function Vn(e){return typeof e?.message==`string`&&e.message.length>0?e.message:null}const Hn=[`out`,`overlayRefs`,`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotMaxSize`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],Un=[`screenshotPixelDensity`,`screenshotFullscreen`,`screenshotMaxSize`,`screenshotNoStabilize`,`screenshotNormalizeStatusBar`],Wn=[{key:`screenshotPixelDensity`,names:[`--pixel-density`],type:`int`,min:1,usageLabel:`--pixel-density <n>`,usageDescription:`Screenshot: output PNG pixel density in pixels per logical point (currently supported on iOS simulators)`},{key:`screenshotFullscreen`,names:[`--fullscreen`,`--full`,`-f`],type:`boolean`,usageLabel:`--fullscreen, --full, -f`,usageDescription:`Screenshot: on web capture the full page; on macOS app sessions capture the full desktop instead of the app window`},{key:`screenshotMaxSize`,names:[`--max-size`],type:`int`,min:1,usageLabel:`--max-size <px>`,usageDescription:`Screenshot/record: downscale so the longest edge is at most <px>`},{key:`screenshotNoStabilize`,names:[`--no-stabilize`],type:`boolean`,usageLabel:`--no-stabilize`,usageDescription:`Screenshot: skip Android demo-mode/status-bar stabilization and settle delay for low-latency capture loops`},{key:`screenshotNormalizeStatusBar`,names:[`--normalize-status-bar`],type:`boolean`,usageLabel:`--normalize-status-bar`,usageDescription:`Screenshot: on iOS simulators temporarily normalize status-bar chrome for deterministic screenshot diffs`}],Gn=[{tokens:[`--fullscreen`,`--full`,`-f`],key:`screenshotFullscreen`},{tokens:[`--no-stabilize`],key:`screenshotNoStabilize`},{tokens:[`--normalize-status-bar`],key:`screenshotNormalizeStatusBar`}],Kn=[{token:`--pixel-density`,key:`screenshotPixelDensity`,label:`screenshot --pixel-density`},{token:`--max-size`,key:`screenshotMaxSize`,label:`screenshot --max-size`}];function qn(e){return Zn({overlayRefs:e?.overlayRefs,pixelDensity:e?.screenshotPixelDensity,fullscreen:e?.screenshotFullscreen,maxSize:e?.screenshotMaxSize,stabilize:e?.screenshotNoStabilize?!1:void 0,normalizeStatusBar:e?.screenshotNormalizeStatusBar})}function Jn(e={}){return Zn({overlayRefs:e.overlayRefs,screenshotPixelDensity:e.screenshotPixelDensity??e.pixelDensity,screenshotFullscreen:e.screenshotFullscreen??e.fullscreen,screenshotMaxSize:e.screenshotMaxSize??e.maxSize,screenshotNoStabilize:e.screenshotNoStabilize??(e.stabilize===!1?!0:void 0),screenshotNormalizeStatusBar:e.screenshotNormalizeStatusBar??e.normalizeStatusBar})}function Yn(e,t){typeof t?.screenshotPixelDensity==`number`&&e.push(`--pixel-density`,String(t.screenshotPixelDensity)),t?.screenshotFullscreen&&e.push(`--fullscreen`),typeof t?.screenshotMaxSize==`number`&&e.push(`--max-size`,String(t.screenshotMaxSize)),t?.screenshotNoStabilize&&e.push(`--no-stabilize`),t?.screenshotNormalizeStatusBar&&e.push(`--normalize-status-bar`)}function Xn(e){let{args:t,flags:n,index:r}=e,i=t[r];return Qn(i,n,r)??$n({args:t,index:r,flags:n,token:i})??{handled:!1}}function Zn(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}function Qn(e,t,n){let r=Gn.find(t=>t.tokens.some(t=>t===e));if(r)return t[r.key]=!0,{handled:!0,nextIndex:n}}function $n(e){let t=Kn.find(t=>t.token===e.token);if(!t)return;let r=e.args[e.index+1],i=r===void 0?NaN:Number(r);if(!Number.isInteger(i)||i<1)throw new n(`INVALID_ARGS`,`${t.label} requires a positive integer`);return e.flags[t.key]=i,{handled:!0,nextIndex:e.index+1}}function er(e){let t=ge(e.quality);return{...e.analysis?{analysis:e.analysis}:{},...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.freshness?{freshness:e.freshness}:{},...t?{quality:t}:{},...e.warnings?{warnings:e.warnings}:{}}}function tr(e){return{...e.androidSnapshot?{androidSnapshot:e.androidSnapshot}:{},...e.quality?{snapshotQuality:e.quality}:{},...e.warnings&&e.warnings.length>0?{warnings:e.warnings}:{}}}function nr(e){let t=rr(e.androidSnapshot),n=Array.isArray(e.warnings)?e.warnings.filter(e=>typeof e==`string`):void 0,r=ge(e.snapshotQuality);return tr({...t?{androidSnapshot:t}:{},...r?{quality:r}:{},...n?{warnings:n}:{}})}function rr(e){return typeof e==`object`&&e?e:void 0}function ir(e){let t=e.appId??e.bundleId??e.packageName;return{session:e.session,appId:t,appBundleId:e.bundleId,package:e.packageName}}function ar(e,t,n){return{deviceId:t,deviceName:n,...e===`android`?{serial:t}:e===`ios`?{udid:t}:{}}}function or(e,t={}){let n=t.includeAndroidSerial??!0;return{platform:e.platform,target:e.target,device:e.name,id:e.id,...e.platform===`ios`?{device_udid:e.ios?.udid??e.id,ios_simulator_device_set:e.ios?.simulatorSetPath??null}:{},...e.platform===`android`&&n?{serial:e.android?.serial??e.id}:{}}}function sr(e){return{name:e.name,...e.sessionStateDir?{sessionStateDir:e.sessionStateDir}:{},...e.runnerLogPath?{runnerLogPath:e.runnerLogPath}:{},...or(e.device,{includeAndroidSerial:!1}),createdAt:e.createdAt}}function cr(e){return{platform:e.platform,...e.appleOs?{appleOs:e.appleOs}:{},id:e.id,name:e.name,kind:e.kind,target:e.target,...typeof e.booted==`boolean`?{booted:e.booted}:{}}}function lr(e){return e.bundleId??e.package??e.app}function ur(e){return P({app:e.app,appPath:e.appPath,platform:e.platform,...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.package?{package:e.package}:{}},`Installed: ${lr(e)}`)}function dr(e){return e.appName??e.bundleId??e.packageName??e.launchTarget}function fr(e){return P({launchTarget:e.launchTarget,...e.appName?{appName:e.appName}:{},...e.appId?{appId:e.appId}:{},...e.bundleId?{bundleId:e.bundleId}:{},...e.packageName?{package:e.packageName}:{},...e.installablePath?{installablePath:e.installablePath}:{},...e.archivePath?{archivePath:e.archivePath}:{},...e.materializationId?{materializationId:e.materializationId}:{},...e.materializationExpiresAt?{materializationExpiresAt:e.materializationExpiresAt}:{}},`Installed: ${dr(e)}`)}function pr(e){let t=e.appName??e.appBundleId??e.session;return P({session:e.session,...e.sessionStateDir?{sessionStateDir:e.sessionStateDir}:{},...e.runnerLogPath?{runnerLogPath:e.runnerLogPath}:{},...e.requestLogPath?{requestLogPath:e.requestLogPath}:{},...e.eventLogPath?{eventLogPath:e.eventLogPath}:{},...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.startup?{startup:e.startup}:{},...e.runtime?{runtime:e.runtime}:{},...e.device?or(e.device):{}},t?`Opened: ${t}`:`Opened`)}function mr(e){return{session:e.session,...e.shutdown?{shutdown:e.shutdown}:{},...`provider`in e&&e.provider?{provider:e.provider}:{},...N(e.session?`Closed: ${e.session}`:`Closed`)}}function hr(e){return{nodes:e.nodes,truncated:e.truncated,...e.appName?{appName:e.appName}:{},...e.appBundleId?{appBundleId:e.appBundleId}:{},...e.visibility?{visibility:e.visibility}:{},...tr(gr(e)),...e.unchanged?{unchanged:e.unchanged}:{},...e.snapshotDiagnostics?{snapshotDiagnostics:e.snapshotDiagnostics}:{}}}function gr(e){return{...e,...e.snapshotQuality?{quality:e.snapshotQuality}:{}}}function _r(e,t){return e.includes(t)}function vr(e,t,r={}){let i=t===void 0?void 0:r.normalize?.(t)??t;if(i!==void 0&&_r(e,i))return i;throw new n(`INVALID_ARGS`,(typeof r.message==`function`?r.message(t):r.message)??`Invalid value: ${t}. Use ${e.join(`|`)}.`)}function F(e,t={}){return{values:e,is:t=>_r(e,t),parse:n=>vr(e,n,t)}}const yr=[`app`,`frontmost-app`,`desktop`,`menubar`],br=F(yr,{normalize:e=>e.trim().toLowerCase(),message:e=>`Invalid surface: ${e}. Use ${yr.join(`|`)}.`});function xr(e){return br.parse(e)}const Sr=[`app`,`device`,`system`];function Cr(e){return e===`device`||e===`system`}const wr=[`metrics`,`frames`,`memory`,`cpu`,`trace`],Tr=[`sample`,`snapshot`,`start`,`stop`,`report`],Er=[`profile`],Dr=[`xctrace`,`simpleperf`,`perfetto`,`android-hprof`,`memgraph`],Or=[`android-hprof`,`memgraph`],kr=F(wr),Ar=F(Tr),jr=F(Er),Mr=F(Dr),Nr=F(Or),Pr=`perf area must be metrics, frames, memory, cpu, or trace`,Fr=`perf action must be sample, snapshot, start, stop, or report`,Ir=`perf cpu requires profile`,Lr=`perf --kind must be xctrace, simpleperf, perfetto, android-hprof, or memgraph`,Rr=`perf memory snapshot --kind must be android-hprof or memgraph`,zr=kr.is,Br=Ar.is,Vr=jr.is,Hr=Mr.is,Ur=Nr.is,Wr=[`app launch with Apple-platform launch arguments and Android/iOS simulator clearState`,`runFlow file/inline with when.platform, when.visible, when.notVisible, and limited when.true boolean/platform expressions`,`onFlowStart and onFlowComplete hooks`,`deterministic repeat.times`,`tapOn including optional, index, childOf, label, and absolute/percentage point taps`,`doubleTapOn and longPressOn`,`inputText, focused-field eraseText, and pasteText`,`openLink`,`visibility assertions and extendedWaitUntil`,`scroll and scrollUntilVisible`,`absolute/percentage swipe and swipe.label`,`screenshots`,`keyboard dismiss`,`basic pressKey, back, animation waits, and stopApp`,`ordered trusted runScript file/env scripts with http.post, json, and output variables`],Gr=`https://github.com/callstack/agent-device/issues/558`,Kr=`https://github.com/callstack/agent-device/issues/new`;function qr(){return`Supported subset: ${Jr(Wr)}.`}function Jr(e){return e.length>1?`${e.slice(0,-1).join(`, `)}, and ${e.at(-1)}`:e[0]??``}const Yr=1e4,Xr=2e3,Zr=[`get`,`accept`,`dismiss`,`wait`],Qr=`<wifi|airplane|location> <on|off>`,$r=`location set <lat> <lon>`,ei=`animations <on|off>`,ti=`appearance <light|dark|toggle>`,ni=`faceid <match|nonmatch|enroll|unenroll>`,ri=`touchid <match|nonmatch|enroll|unenroll>`,ii=`fingerprint <match|nonmatch>`,ai=`clear-app-state [app-id]`,oi=`permission <grant|deny|reset> <camera|microphone|photos|contacts|contacts-limited|notifications|calendar|location|location-always|media-library|motion|reminders|siri> [full|limited]`,si=`permission <grant|reset> <accessibility|screen-recording|input-monitoring>`,ci=`macOS supports only settings ${ti} and settings ${si}. wifi|airplane|location|animations remain unsupported on macOS.`,li=[`settings ${Qr}`,`settings ${$r}`,`settings ${ei}`,`settings ${ti}`,`settings ${ni}`,`settings ${ri}`,`settings ${ii}`,`settings ${ai}`,`settings ${oi}`,`settings ${si}`].join(` | `),ui=`settings requires ${Qr}, ${$r}, ${ei}, ${ti}, ${ni}, ${ri}, ${ii}, ${ai}, ${oi}, or ${si}`;function di(e){let t=e.trim().toLowerCase();return t===`appearance`||t===`permission`}function fi(e){return`Unsupported macOS setting: ${e}. ${ci}`}function pi(e,t){if(e===void 0||e.trim()===``)throw new n(`INVALID_ARGS`,`settings location set requires ${t}`);return hi(Number(e),t)}function mi(e){return{latitude:hi(e?.latitude,`latitude`),longitude:hi(e?.longitude,`longitude`)}}function hi(e,t){let r=t===`latitude`?-90:-180,i=t===`latitude`?90:180;if(typeof e!=`number`||!Number.isFinite(e)||e<r||e>i)throw new n(`INVALID_ARGS`,`${t} must be a number from ${r} to ${i}`);return e}const gi=[`primary`,`secondary`,`middle`];function _i(e){return e?.clickButton??`primary`}function vi(e){return e.button===`primary`?null:e.commandLabel===`click`?e.platform!==`macos`&&e.platform!==`linux`?new n(`UNSUPPORTED_OPERATION`,`click --button ${e.button} is supported only on macOS and Linux`):e.platform===`macos`&&e.button===`middle`?new n(`UNSUPPORTED_OPERATION`,`click --button middle is not supported by the macOS runner yet`):typeof e.count==`number`||typeof e.intervalMs==`number`||typeof e.holdMs==`number`||typeof e.jitterPx==`number`||e.doubleTap===!0?new n(`INVALID_ARGS`,`click --button ${e.button} does not support repeat or gesture modifier flags`):null:new n(`INVALID_ARGS`,`--button is supported only for click`)}function yi(e){return e===`primary`?{}:{button:e}}const bi=1e4;function xi(e,t=`scroll accepts either a relative amount or --pixels, not both`){if(e.amount!==void 0&&e.pixels!==void 0)throw new n(`INVALID_ARGS`,t)}function Si(e,t={}){if(e===void 0)return;let r=t.field??`scroll durationMs`,i=t.max??1e4,a=t.invalidMessage??`${r} must be a non-negative integer`;if(!Number.isFinite(e)||!Number.isInteger(e)||e<0)throw new n(`INVALID_ARGS`,a);if(e>i)throw new n(`INVALID_ARGS`,`${r} must be a non-negative integer at most ${i}`);return e}function Ci(e){return typeof e?.durationMs==`number`?e.durationMs:void 0}const wi=[`up`,`down`,`left`,`right`],Ti=[`left`,`right`,`left-edge`,`right-edge`],Ei=[`one-way`,`ping-pong`],Di=F(Ti,{message:`gesture swipe requires left, right, left-edge, or right-edge`}),Oi=F(wi,{message:e=>`Unknown direction: ${e}`});function ki(e){let t=e.direction,n=t===`up`||t===`down`?e.referenceHeight:e.referenceWidth,r=Hi(e.amount),i=e.pixels===void 0?Math.round(n*r):Ui(e.pixels),a=Math.max(1,Math.round(n*.05)),o=Math.max(1,n-a*2),s=Math.max(1,Math.min(i,o)),c=Math.round(s/2),l=Math.round(e.referenceWidth/2),u=Math.round(e.referenceHeight/2),d=(n,r,i,a)=>({direction:t,x1:n,y1:r,x2:i,y2:a,referenceWidth:e.referenceWidth,referenceHeight:e.referenceHeight,amount:e.amount,pixels:s});switch(t){case`up`:return d(l,u-c,l,u+c);case`down`:return d(l,u+c,l,u-c);case`left`:return d(l-c,u,l+c,u);case`right`:return d(l+c,u,l-c,u)}}function Ai(e){Hi(e.amount),e.pixels!==void 0&&Ui(e.pixels)}function ji(e){return{...ki({...e,direction:Ri(e.direction)}),direction:e.direction}}function Mi(e,t,n={}){let r=n.marginPx??8,[i,a,o]=e===`left`?[85,15,50]:e===`right`?[15,85,50]:e===`left-edge`?[99,15,50]:[1,85,50],s=Fi(t,i,o,{marginPx:r}),c=Fi(t,a,o,{marginPx:r});return{preset:e,x1:s.x,y1:s.y,x2:c.x,y2:c.y,referenceWidth:t.referenceWidth,referenceHeight:t.referenceHeight}}function Ni(e){return Di.parse(e)}function Pi(e){let t=zi(e);if(t)return{referenceWidth:t.width,referenceHeight:t.height}}function Fi(e,t,n,r={}){let i={x:Math.round(e.referenceWidth*t/100),y:Math.round(e.referenceHeight*n/100)};return r.marginPx===void 0?i:Ii(i,e,r.marginPx)}function Ii(e,t,n){return{x:Wi(e.x,n,t.referenceWidth),y:Wi(e.y,n,t.referenceHeight)}}function Li(e){return Oi.parse(e)}function Ri(e){switch(e){case`up`:return`down`;case`down`:return`up`;case`left`:return`right`;case`right`:return`left`}}function zi(e){let t=e.filter(e=>Bi(e.type)&&Vi(e.rect)).map(e=>e.rect).sort((e,t)=>(t?.width??0)*(t?.height??0)-(e?.width??0)*(e?.height??0))[0];if(t)return t;let n=e.map(e=>e.rect).filter(Vi);if(n.length===0)return;let r=Math.max(...n.map(e=>e.x+e.width)),i=Math.max(...n.map(e=>e.y+e.height));if(!(r<=0||i<=0))return{x:0,y:0,width:r,height:i}}function Bi(e){if(!e)return!1;let t=e.toLowerCase();return t.includes(`application`)||t.includes(`window`)}function Vi(e){return!!e&&e.width>0&&e.height>0}function Hi(e){if(e===void 0)return .6;if(!Number.isFinite(e)||e<=0)throw new n(`INVALID_ARGS`,`scroll amount must be a positive number`);return e}function Ui(e){if(!Number.isFinite(e)||e<=0)throw new n(`INVALID_ARGS`,`scroll pixels must be a positive integer`);return Math.max(1,Math.round(e))}function Wi(e,t,n){let r=t;return Gi(e,r,Math.max(r,n-t))}function Gi(e,t,n){return Math.min(Math.round(n),Math.max(Math.round(t),Math.round(e)))}function I(e,t,r,i){if(!Number.isFinite(e)||!Number.isInteger(e)||e<r||e>i)throw new n(`INVALID_ARGS`,`${t} must be an integer between ${r} and ${i}`);return e}function Ki(e,t,n={}){let r=Zi(e??[]);if(r.length===0)return{canScroll:!1,emptySnapshot:!0,signature:``};let i=pe(r),a=Qi(r,i,t,n),o=aa(a?ea(r,a.index):r);return a?{canScroll:na(a,i.get(a.index),t),emptySnapshot:!1,signature:o,scope:ra(a)}:{canScroll:!1,emptySnapshot:!1,signature:o}}async function qi(e){let{edge:t,target:n={},scope:r,captureNodes:i}=e;try{let e=Ki(await i(r),t,n);return r&&e.emptySnapshot?await qi({edge:t,target:n,captureNodes:i}):e}catch(e){throw Xi(t,r,e)}}async function Ji(e){let{edge:t,captureState:r,scroll:i}=e,a=await r();a.scope&&(a=await r(a.scope));let o=0,s;for(;a.canScroll;){if(o>=40)throw new n(`COMMAND_FAILED`,`scroll ${t} reached the safety limit before the snapshot showed the edge`,{hint:`The scoped scroll container still reports hidden content. Use a smaller manual scroll + snapshot loop to inspect the current state.`});s=await i(),o+=1,a=await r(a.scope)}return{passes:o,result:s}}function Yi(e,t,n,r,i){return t&&n===0?`Already at ${t}; no hidden content ${t===`bottom`?`below`:`above`} detected`:t?`Scrolled to ${t} with ${n} ${e} passes`:i===void 0?r===void 0?`Scrolled ${e}`:`Scrolled ${e} by ${r}`:`Scrolled ${e} by ${i}px`}function Xi(e,t,r){return t?new n(`COMMAND_FAILED`,`Failed to verify scroll ${e} state for scoped container`,{scope:t,hint:`scroll ${e} could not verify the scoped scroll container. Run snapshot -i for the current screen and retry with a visible scroll target.`},r):new n(`COMMAND_FAILED`,`Failed to verify scroll ${e} state`,{hint:`scroll ${e} needs a snapshot showing hidden content ${e===`bottom`?`below`:`above`} before it will move.`},r)}function Zi(e){return e.map((e,t)=>({...e,ref:`ref`in e&&e.ref?e.ref:`e${t+1}`}))}function Qi(e,t,n,r){let i=new Map(e.map(e=>[e.index,e])),a=e.filter(e=>oe(e)&&la(e.rect));if(a.length===0)return null;let o=$i(r.nodeIndex,i);if(o)return o;let s=r.point;if(s){let e=a.filter(e=>e.rect&&ca(e.rect,s)).sort(oa);if(e.length>0)return e.find(e=>na(e,t.get(e.index),n))??e[0]??null}let c=a.filter(e=>na(e,t.get(e.index),n)).sort(sa);return c.length>0?c[0]??null:a.filter(t=>ae(t,e)).sort(sa)[0]??a.sort(sa)[0]??null}function $i(e,t){if(e===void 0)return null;let n=t.get(e);for(;n;){if(oe(n)&&la(n.rect))return n;n=n.parentIndex===void 0?void 0:t.get(n.parentIndex)}return null}function ea(e,t){let n=new Map(e.map(e=>[e.index,e]));return e.filter(e=>e.index===t||ta(e,t,n))}function ta(e,t,n){let r=e.parentIndex===void 0?void 0:n.get(e.parentIndex);for(;r;){if(r.index===t)return!0;r=r.parentIndex===void 0?void 0:n.get(r.parentIndex)}return!1}function na(e,t,n){return n===`bottom`?e.hiddenContentBelow===!0||t?.hiddenContentBelow===!0:e.hiddenContentAbove===!0||t?.hiddenContentAbove===!0}function ra(e){return[e.identifier,e.label,e.value].map(e=>typeof e==`string`?e.trim():``).find(ia)}function ia(e){return e.length>0&&e.length<=80&&!/^(true|false)$/i.test(e)&&!/^\d+$/.test(e)&&!/^\d+%$/.test(e)}function aa(e){return e.map(e=>{let t=e.rect?[`x`,`y`,`width`,`height`].map(t=>ua(e.rect?.[t])).join(`,`):``;return[String(e.index??``),String(e.parentIndex??``),String(e.type??``),String(e.label??``),String(e.value??``),t].join(`|`)}).join(`
14
+ `)}function oa(e,t){return L(e.rect)-L(t.rect)}function sa(e,t){return L(t.rect)-L(e.rect)}function L(e){return e?e.width*e.height:0}function ca(e,t){return t.x>=e.x&&t.x<=e.x+e.width&&t.y>=e.y&&t.y<=e.y+e.height}function la(e){return!!(e&&e.width>0&&e.height>0)}function ua(e){return typeof e==`number`&&Number.isFinite(e)?e.toFixed(1):``}function R(e,t){return{session:t.session,requestId:t.requestId,signal:t.signal??e.signal,metadata:t.metadata}}function z(e){return e.clock?.now()??Date.now()}async function da(e,t){e.clock?await e.clock.sleep(t):await new Promise(e=>setTimeout(e,t))}function B(e){return e&&typeof e==`object`?e:void 0}const fa=[`x`,`y`,`width`,`height`];function V(e){let t=H(e);if(!t)return null;let n=r(t);return!Number.isFinite(n.x)||!Number.isFinite(n.y)?null:n}function H(e){if(!e)return null;let t=Number(e.x),n=Number(e.y),r=Number(e.width),i=Number(e.height);return!Number.isFinite(t)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(i)||r<0||i<0?null:{x:t,y:n,width:r,height:i}}function U(e,t){return!e||!t?!1:fa.every(n=>Math.abs(e[n]-t[n])<=.5)}function pa(e){return{x:ma(e.x,e.width),y:ma(e.y,e.height)}}function ma(e,t){if(t<=1)return Math.floor(e);let n=Math.ceil(e),r=Math.floor(e+t-1);return Math.round(Math.min(r,Math.max(n,e+t/2)))}const ha=[`tabbar`,`toolbar`,`navigationbar`,`bottomnavigation`,`bottomnavigationview`,`sheet`,`dialog`,`alert`,`popover`,`menu`],ga=[`button`,`link`,`menuitem`,`tabitem`,`textfield`,`searchfield`,`edittext`,`checkbox`,`radio`,`switch`,`cell`];function _a(e,t={}){if(e.length<2)return e;let n=[...e],r=new Map(n.map(e=>[e.index,e])),i={nodes:n,byIndex:r,overlayPositions:n.flatMap((e,n)=>Sa(e,r,t)?[n]:[])},a=!1;for(let[e,r]of n.entries()){if(!xa(r)||!va(i,e,r,t))continue;a=!0;let o={...r,hittable:!1,interactionBlocked:`covered`,presentationHints:Ma(r.presentationHints)};n[e]=o,i.byIndex.set(o.index,o)}return a?n:e}function W(e){return e.interactionBlocked!==void 0}function va(e,t,n,i){let a=G(n.rect);if(!a)return null;let o=r(a);for(let r of e.overlayPositions){if(r<=t)continue;let s=e.nodes[r];if(s&&ya(e,r,n,a,o,i))return s}return null}function ya(e,t,n,r,i,a){if(!e.nodes[t])return!1;let o=ba(e,t,n,r,a);return!!(o&&g(o,i.x,i.y))}function ba(e,t,n,r,i){let a=e.nodes[t];if(!a||!Sa(a,e.byIndex,i)||Aa(n,a,e.byIndex))return null;let o=G(a.rect);return!o||U(r,o)||va(e,t,a,i)?null:o}function xa(e){return G(e.rect)?e.hittable===!0||Ea(e)?!0:!!(e.label?.trim()||e.value?.trim()||e.identifier?.trim()):!1}function Sa(e,t,n){return!G(e.rect)||ka(e)?!1:Da(e,ha)||Ca(e,t,n)}function Ca(e,t,n){return n.isAdditionalOverlayNode?.(e)===!0?!wa(e,t,n):!1}function wa(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0,i=new Set;for(;r&&!i.has(r.index);){if(Ta(r,n))return!0;i.add(r.index),r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}return!1}function Ta(e,t){return t.isAdditionalOverlayNode?.(e)===!0&&G(e.rect)!==null&&!ka(e)}function Ea(e){return Da(e,ga)}function Da(e,t){let n=Oa(e);return t.some(e=>n.includes(e))}function Oa(e){return[e.type,e.role,e.subrole].map(e=>re(e??``)).join(` `)}function ka(e){let t=Oa(e);return t.includes(`application`)||t.includes(`window`)}function Aa(e,t,n){return ja(e,t,n)||ja(t,e,n)}function ja(e,t,n){let r=typeof t.parentIndex==`number`?n.get(t.parentIndex):void 0,i=new Set;for(;r&&!i.has(r.index);){if(r.index===e.index)return!0;i.add(r.index),r=typeof r.parentIndex==`number`?n.get(r.parentIndex):void 0}return!1}function G(e){let t=H(e);return t&&t.width>0&&t.height>0?t:null}function Ma(e){return Array.from(new Set([...e??[],`covered`]))}function Na(e){return e}function Pa(e){let t=1/0,n=1/0,r=-1/0,i=-1/0;for(let a of e)t=Math.min(t,a.x),n=Math.min(n,a.y),r=Math.max(r,a.x+a.width),i=Math.max(i,a.y+a.height);return{x:t,y:n,width:r-t,height:i-n}}function Fa(e,t){return{x:e.x-t,y:e.y-t,width:e.width+t*2,height:e.height+t*2}}function Ia(e,t){let n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),i=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return i<=n||a<=r?0:(i-n)*(a-r)}function La(e){return{x:e.x+e.width/2,y:e.y+e.height/2}}function Ra(e,t){return(e.x-t.x)**2+(e.y-t.y)**2}function za(e,t,n){return Math.min(Math.max(e,t),n)}const Ba=[`button`,`link`,`menuitem`,`tabitem`,`textfield`,`searchfield`,`securetextfield`,`checkbox`,`radio`,`switch`,`cell`];function Va(e,t){return Ha(e,t).node}function Ha(e,t){if(W(t))return{node:t,reason:`covered`};let n=Ua(e,t);if(n?.rect&&V(n.rect))return{node:n,reason:`same-rect-descendant`};if(Wa(t)&&t.rect&&V(t.rect))return{node:t,reason:`semantic-target`};let r=de(e,t);return r?.rect&&!W(r)&&V(r.rect)?Ka(t,r,e)?{node:t,reason:`overly-broad-ancestor`}:{node:r,reason:`hittable-ancestor`}:{node:t,reason:`original`}}function Ua(e,t){let n=H(t.rect);if(!n)return null;let r=t,i=new Set;for(;!i.has(r.ref);){i.add(r.ref);let t=e.filter(e=>{if(e.parentIndex!==r.index||!e.hittable||W(e))return!1;let t=H(e.rect);return t?U(t,n):!1});if(t.length!==1)break;r=t[0]}return r===t?null:r}function Wa(e){return[e.type,e.role,e.subrole].map(e=>re(e??``)).some(Ga)}function Ga(e){return e===`tab`||Ba.some(t=>e.includes(t))}function Ka(e,t,n){let r=H(e.rect),i=H(t.rect);if(!r||!i)return!1;let a=qa(n,r);return!a||!Ja(i,a)?!1:!U(r,i)}function qa(e,t){let n=r(t),i=e.filter(e=>{let t=(e.type??``).toLowerCase();return t.includes(`application`)||t.includes(`window`)}).map(e=>H(e.rect)).filter(e=>e!==null);if(i.length===0)return null;let a=i.filter(e=>g(e,n.x,n.y));return ie(a.length>0?a:i)}function Ja(e,t){let n=Ia(e,t),r=e.width*e.height,i=t.width*t.height;if(n<=0||r<=0||i<=0)return!1;let a=n/i,o=n/r;return a>=.9&&o>=.8}async function K(e,t,n){return await J(e,t,n.action),t.target.kind===`point`?await Xa(e,t,t.target,n):t.target.kind===`ref`?await Qa(e,t,t.target,n):await $a(e,t,t.target,n)}async function Ya(e,t,n){let r=t.session??`default`,i=await e.sessions.get(r);if(!i?.snapshot)return;let a={x:n.x,y:n.y,width:0,height:0},o=le(i.snapshot.nodes,a);if(!o)return;let s={x:n.x,y:n.y};if(!g(o,s.x,s.y))return`Coordinates (${s.x}, ${s.y}) are outside the last-known viewport (${o.width}x${o.height}). The tap will be forwarded anyway; take a fresh snapshot if the screen changed.`}async function Xa(e,t,n,r){let i=await Ya(e,t,n);if(!r.captureEvidenceBaseline)return{kind:`point`,point:{x:n.x,y:n.y},...i?{warning:i}:{}};let a=await Za(e,t);return{kind:`point`,point:{x:n.x,y:n.y},...a?{preActionNodes:a}:{},...i?{warning:i}:{}}}async function Za(e,t){try{return(await q(e,t,!0)).snapshot.nodes}catch{return}}async function Qa(e,t,n,r){let i=await co(e,t,n),a=i.resolved,o=r.promoteToHittableAncestor?ro(i.snapshot.nodes,a.node,{action:r.action,label:`Ref ${n.ref}`}):a.node;return io(o,`Ref ${n.ref}`,r.action),mo(o,i.snapshot.nodes,n.ref,r.action),{kind:`ref`,point:uo(o,`Ref ${n.ref} not found or has invalid bounds`),target:{kind:`ref`,ref:`@${a.ref}`},...eo(e,o,i.snapshot.nodes,r.action)}}async function $a(e,t,r,i){let a=s(r.selector),o=await q(e,t,i.requireInteractive),c=ve(no(o.snapshot.nodes),a,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0});if((!c||!c.node.rect)&&i.requireInteractive&&(o=await q(e,t,!1),c=ve(no(o.snapshot.nodes),a,{platform:e.backend.platform,requireRect:!0,requireUnique:!0,disambiguateAmbiguous:!0})),!c||!c.node.rect){let t=ve(o.snapshot.nodes,a,{platform:e.backend.platform,requireRect:!0,requireUnique:!1});throw t?.node&&W(t.node)?ao({label:`Selector ${t.selector.raw}`,node:t.node,action:i.action,selector:t.selector.raw}):new n(`COMMAND_FAILED`,ye(a,c?.diagnostics??[],{unique:!0}),{hint:xe(c?.diagnostics??[])})}let l=i.promoteToHittableAncestor?ro(o.snapshot.nodes,c.node,{action:i.action,label:`Selector ${c.selector.raw}`}):c.node;return io(l,`Selector ${c.selector.raw}`,i.action),po(l,o.snapshot.nodes,c.selector.raw,i.action),{kind:`selector`,point:uo(l,`Selector ${c.selector.raw} resolved to invalid bounds`),target:{kind:`selector`,selector:c.selector.raw},...eo(e,l,o.snapshot.nodes,i.action)}}function eo(e,t,n,r){return{node:t,selectorChain:Se(t,e.backend.platform,{action:r===`fill`?`fill`:`click`}),refLabel:me(t,n),...to(t,r),preActionNodes:n}}function to(e,t){return e.hittable===!1?{targetHittable:!1,hint:`The resolved element reports hittable: false, so this ${t} may have had no visible effect. Verify with a snapshot, or prefer a @ref or a longer/more specific selector to target the intended element.`}:{}}function no(e){return e.filter(e=>!W(e))}function ro(e,t,n){let r=Ha(e,t);if(r.reason===`covered`)throw ao({label:n.label,node:t,action:n.action});return r.node}function io(e,t,n){if(W(e))throw ao({label:t,node:e,action:n})}function ao(e){return new n(`COMMAND_FAILED`,`${e.label} is covered by another visible element and cannot ${oo(e.action)} safely`,{hint:`Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying.`,...e.selector?{selector:e.selector}:{},ref:`@${e.node.ref}`,interactionBlocked:e.node.interactionBlocked})}function oo(e){switch(e){case`fill`:return`be filled`;case`focus`:return`be focused`;case`longPress`:return`be long-pressed`;default:return`be tapped`}}async function q(e,t,r){if(!e.backend.captureSnapshot)throw new n(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let i=t.session??`default`,a=await e.sessions.get(i);if(!a)throw new n(`SESSION_NOT_FOUND`,`No active session. Run open first.`);let o=await e.backend.captureSnapshot(R(e,t),{interactiveOnly:r,includeRects:!0}),s=o.snapshot??{nodes:o.nodes??[],truncated:o.truncated,backend:o.backend,createdAt:z(e)};return await e.sessions.set({...a,snapshot:s}),{snapshot:s}}async function J(e,t,r){if(e.backend.platform!==`macos`)return;let i=await so(e,t);if(!(i!==`desktop`&&i!==`menubar`)&&!(i===`menubar`&&(r===`click`||r===`press`)))throw new n(`UNSUPPORTED_OPERATION`,`${r} is not supported on macOS ${i} sessions yet. Open an app session to act, or use the ${i} surface to inspect.`)}async function so(e,t){return(await e.sessions.get(t.session??`default`))?.metadata?.surface}async function co(e,t,r){let i=t.session??`default`,a=await e.sessions.get(i);if(!a)throw new n(`SESSION_NOT_FOUND`,`No active session. Run open first.`);if(!a.snapshot)throw new n(`INVALID_ARGS`,`No snapshot in session. Run snapshot first.`);let o=r.fallbackLabel??``,s=lo(a.snapshot.nodes,r.ref,{fallbackLabel:o});if(s)return{snapshot:a.snapshot,resolved:s};let c=await q(e,t,!0),l=lo(c.snapshot.nodes,r.ref,{fallbackLabel:o});if(!l)throw new n(`COMMAND_FAILED`,`Ref ${r.ref} not found or has no bounds`,{hint:be});return{...c,resolved:l}}function lo(e,t,r){let i=a(t);if(!i)throw new n(`INVALID_ARGS`,`Invalid ref: ${t}`);let s=o(e,i);if(fo(s))return{ref:i,node:s};let c=r.fallbackLabel.length>0?ue(e,r.fallbackLabel):null;return fo(c)?{ref:i,node:c}:null}function uo(e,t){let r=V(e.rect);if(!r)throw new n(`COMMAND_FAILED`,t);return r}function fo(e){return e?V(e.rect)!==null:!1}function po(e,t,n,r){go(e,t,{message:`Selector ${n} resolved to an off-screen element and is not safe to ${r}`,details:{reason:`offscreen_selector`,selector:n},hint:`The element is outside the visible viewport — likely inside a closed drawer, another tab, or scrolled content. Scroll toward it or open its container, take a fresh snapshot, then retry ${r}.`})}function mo(e,t,n,r){go(e,t,{message:`Ref ${n} is off-screen and not safe to ${r}`,details:{reason:`offscreen_ref`,ref:a(n)},hint:`Use scroll with the direction from the off-screen summary, take a fresh snapshot, then retry ${r} with the new ref or a selector.`})}async function ho(e,t,n,r){let i=(await e.sessions.get(t.session??`default`))?.snapshot?.nodes;if(!i||a(n.ref)===null)return{};let o=lo(i,n.ref,{fallbackLabel:n.fallbackLabel??``});return o?(io(o.node,`Ref ${n.ref}`,r),mo(o.node,i,n.ref,r),to(o.node,r)):{}}function go(e,t,r){let i=e.rect?fe(e,t):null;if(!(!e.rect||!i||h(e,t)))throw new n(`COMMAND_FAILED`,r.message,{...r.details,rect:e.rect,viewport:i,hint:r.hint})}function _o(e){let t=Buffer.alloc(16);for(let n of e)yo(t,vo(n));return{digest:`ax1:${Ce(`sha256`).update(t).update(`\0`).update(String(e.length)).digest(`hex`).slice(0,16)}`,nodeCount:e.length}}function vo(e){return Ce(`sha256`).update(e.type??``).update(`\0`).update(e.label??``).update(`\0`).update(e.identifier??``).digest().subarray(0,16)}function yo(e,t){for(let n=0;n<e.length;n+=1)e[n]=(e[n]??0)^(t[n]??0)}function Y(e){let{digest:t,nodeCount:n}=_o(e),r=e.reduce((e,t)=>t.hittable===!1?e:e+1,0),i=bo(e);return{digest:t,nodeCount:n,interactiveNodeCount:r,...i?{foregroundApp:i}:{}}}function bo(e){for(let t of e)if(t.bundleId)return t.bundleId;for(let t of e)if(t.appName)return t.appName}function xo(e,t){let n=T(e.type??`Element`),r=w(e,n),i=e.enabled===!1?`disabled`:`enabled`,a=e.selected===!0?`selected`:`unselected`,o=e.hittable===!0?`hittable`:`not-hittable`;return[String(t??e.depth??0),n,r,i,a,o].join(`|`)}function So(e,t,n={}){let r=To(wo(e,n),wo(t,n)),i={additions:0,removals:0,unchanged:0};for(let e of r)e.kind===`added`&&(i.additions+=1),e.kind===`removed`&&(i.removals+=1),e.kind===`unchanged`&&(i.unchanged+=1);return{summary:i,lines:r}}function Co(e,t={}){return wo(e,t).length}function wo(e,t){return t.flatten?e.map(e=>({text:bt(e,0,!1),comparable:xo(e,0),...t.withRefs&&e.ref?{ref:e.ref}:{}})):C(e).map(e=>({text:e.text,comparable:xo(e.node,e.depth),...t.withRefs&&e.node.ref?{ref:e.node.ref}:{}}))}function To(e,t){let n=e.length,r=t.length,i=n+r,a=new Map,o=[];a.set(1,0);for(let s=0;s<=i;s+=1){o.push(new Map(a));for(let i=-s;i<=s;i+=2){let c=Do(a,i,s)?X(a,i+1):X(a,i-1)+1,l=c-i;for(;c<n&&l<r&&e[c].comparable===t[l].comparable;)c+=1,l+=1;if(a.set(i,c),c>=n&&l>=r)return Eo(o,e,t,n,r)}}return[]}function Eo(e,t,n,r,i){let a=[],o=r,s=i;for(let r=e.length-1;r>=0;--r){let i=e[r],c=o-s,l=Do(i,c,r)?c+1:c-1,u=X(i,l),d=u-l;for(;o>u&&s>d;)a.push({kind:`unchanged`,text:n[s-1].text}),--o,--s;if(r===0)break;if(o===u){let e=n[d];a.push({kind:`added`,text:e.text,...e.ref?{ref:e.ref}:{}}),s=d}else a.push({kind:`removed`,text:t[u].text}),o=u}return a.reverse(),a}function Do(e,t,n){return t===-n||t!==n&&X(e,t-1)<X(e,t+1)}function X(e,t){return e.get(t)??0}function Oo(e){return e===`text`||e===`label`||e===`any`}async function ko(e,t){let r=t??`default`,i=await e.sessions.get(r);if(!i)throw new n(`SESSION_NOT_FOUND`,`No active session. Run open first.`);if(!i.snapshot)throw new n(`INVALID_ARGS`,`No snapshot in session. Run snapshot first.`);return{sessionName:r,session:i,snapshot:i.snapshot}}async function Ao(e,t,r={updateSession:!0}){let i=e.backend.captureSnapshot;if(!i)throw new n(`UNSUPPORTED_OPERATION`,`snapshot is not supported by this backend`);let a=t.session??`default`,o=await e.sessions.get(a),s=await i(R(e,t),{interactiveOnly:r.interactiveOnly??!1,depth:t.depth,scope:r.scope??t.scope,raw:t.raw,includeRects:r.includeRects}),c=s.snapshot??{nodes:s.nodes??[],truncated:s.truncated,backend:s.backend,...s.quality?{snapshotQuality:s.quality}:{},createdAt:z(e)};return r.updateSession&&o&&!_e(c.snapshotQuality)&&await e.sessions.set({...o,snapshot:c}),{sessionName:a,session:o,snapshot:c}}async function jo(e,t,n){if(e.backend.readText){let r=await e.backend.readText(R(e,{session:t.sessionName}),n);if(r.text.trim())return r.text}return ne(n)}function Mo(e,t,r){let i=a(t);if(!i)throw new n(`INVALID_ARGS`,r.invalidRefMessage);let s=o(e,i)??(r.fallbackLabel.length>0?ue(e,r.fallbackLabel):null);if(!s)throw new n(`COMMAND_FAILED`,r.notFoundMessage);return{ref:i,node:s}}const No=`Settled on a nearly-empty tree — the app may still be loading. Wait for specific content (wait text ...) before interacting.`;async function Po(e,t,n){let{quietMs:r,timeoutMs:i}=n,a=z(e),o=a+i,s=!1,c=Math.min(300,Math.max(25,r)),l=0,u,d=0,f,p=a;for(;z(e)<o;){let m=await Io(e,t,o-z(e));if(!m)return{settled:!1,stalled:!0,waitedMs:z(e)-a,captures:l,nodeCount:d,lastCapture:f};l+=1,f=m;let h=Lo(m.snapshot.nodes),g=z(e);if(n.resetBudgetOnPrivateAxRecovery===!0&&!s&&Fo(m.snapshot.snapshotQuality)){s=!0,o=Math.max(o,g+i),p=g,u=h,d=m.snapshot.nodes.length,await da(e,c);continue}if(h!==u)u=h,d=m.snapshot.nodes.length,p=g;else if(l>=2&&g-p>=r)return{settled:!0,stalled:!1,waitedMs:g-a,captures:l,nodeCount:d,lastCapture:f};await da(e,c)}return{settled:!1,stalled:!1,waitedMs:z(e)-a,captures:l,nodeCount:d,lastCapture:f}}function Fo(e){return e?.state===`recovered`&&e.backend===`private-ax`}async function Io(e,t,n){let r=Ao(e,t,{updateSession:!1,interactiveOnly:!0}),i;try{let e=await Promise.race([r,new Promise(e=>{i=setTimeout(()=>e(void 0),n)})]);return e===void 0&&r.catch(()=>{}),e}finally{i!==void 0&&clearTimeout(i)}}function Lo(e){return e.map(Ro).join(`|`)}function Ro(e){let t=e.rect?`${Math.round(e.rect.x)},${Math.round(e.rect.y)},${Math.round(e.rect.width)},${Math.round(e.rect.height)}`:``;return`${e.type??``}#${e.label??``}#${e.identifier??``}#${t}`}const zo=`The UI kept changing for the whole settle budget (animation, carousel, or ticker?), so no settled diff is shown. Raise --timeout, wait for specific content, or take a fresh snapshot.`,Bo=`A snapshot capture stalled past the settle budget, so no settled diff is shown. The action itself succeeded; observe with wait stable or snapshot.`;async function Vo(e,t,n){let r=n.quietMs??500,i=n.timeoutMs??1e4,a={settled:!1,waitedMs:0,captures:0,quietMs:r,timeoutMs:i};try{let o=await Po(e,t,{quietMs:r,timeoutMs:i,resetBudgetOnPrivateAxRecovery:!0}),s={...a,settled:o.settled,waitedMs:o.waitedMs,captures:o.captures};if(!o.lastCapture)return{observation:{...s,hint:o.stalled?Bo:zo}};let c=await Zo(e,t,o.lastCapture),l=o.lastCapture.snapshot.nodes;return{observation:{...s,...o.settled&&c?Go(Uo(n.resolved),l):{},...Xo(o,c,l.length)},settledNodes:l}}catch(e){return{observation:{...a,hint:`Settle observation unavailable (${e instanceof Error?e.message:String(e)}). The action itself succeeded; take a snapshot to observe the result.`}}}}function Ho(e,t){if(!e)return;let n=Y(e),r=t!==void 0&&n.digest!==Y(t).digest;return{...n,changedFromBefore:r}}function Uo(e){return`preActionNodes`in e&&e.preActionNodes?e.preActionNodes:[]}function Wo(e,t){let n=So(Jo(e),Jo(t),{flatten:!0,withRefs:!0}),r=n.lines.filter(e=>e.kind!==`unchanged`),i=Yo(r).map(e=>({kind:e.kind,text:e.text,...e.ref?{ref:e.ref}:{}}));return{summary:n.summary,lines:i,...r.length>i.length?{truncated:!0}:{}}}function Go(e,t){let n=Wo(e,t);return{diff:n,...Ko(n,t)}}function Ko(e,t){let n=new Set(e.lines.filter(e=>e.kind===`added`&&e.ref).map(e=>e.ref));return n.size>0?{}:qo(t,n)}function qo(e,t){let n=e.filter(e=>e.ref&&e.hittable===!0&&e.interactionBlocked!==`covered`&&!t.has(e.ref));if(n.length===0)return{};let r=n.slice(0,20).map(e=>{let t=T(e.type??`Element`),n=w(e,t);return{ref:e.ref,role:t,...n?{label:n}:{}}});return{tail:r,...n.length>r.length?{tailTruncated:!0}:{}}}function Jo(e){return e.filter(e=>e.type!==`Key`)}function Yo(e){if(e.length<=80)return e;let t=e.filter(e=>e.kind===`added`),n=new Set(t.slice(0,80)),r=80-n.size,i=[];for(let t of e)n.has(t)?i.push(t):t.kind===`removed`&&r>0&&(i.push(t),--r);return i}function Xo(e,t,n){return e.stalled?{hint:Bo}:e.settled?t?n<5?{hint:No}:{}:{hint:`Settled on a sparse, unreadable tree — the diff is omitted. Use screenshot as visual truth before interacting further.`}:{hint:zo}}async function Zo(e,t,n){if(_e(n.snapshot.snapshotQuality))return!1;let r=await e.sessions.get(t.session??`default`);return r?(await e.sessions.set({...r,snapshot:n.snapshot}),!0):!1}function Qo(e){let t=e.verify===!0;return{verify:t,needsPreActionBaseline:t||e.settle!==void 0,...e.settle===void 0?{}:{settle:e.settle}}}async function $o(e,t,n,r,i){let a=await es(e,t,n,i);return ns({...r,...a})}async function es(e,t,n,r){if(r.settle!==void 0){let i=await Vo(e,t,{...r.settle,resolved:n}),a=r.verify?Ho(i.settledNodes,`preActionNodes`in n?n.preActionNodes:void 0):void 0;return{settle:i.observation,...a?{evidence:a}:{}}}if(!r.verify)return{};let i=await ts(e,t,n);return i?{evidence:i}:{}}async function ts(e,t,n){let r=`preActionNodes`in n?n.preActionNodes:void 0;try{let n=Y((await q(e,t,!0)).snapshot.nodes),i=r!==void 0&&n.digest!==Y(r).digest;return{...n,changedFromBefore:i}}catch{return}}function ns(e){let t=e;if(t.targetHittable!==!1||!rs(t)||t.hint===void 0)return e;let{hint:n,...r}=t;return r}function rs(e){if(e.evidence?.changedFromBefore===!0)return!0;let t=e.settle?.diff?.summary;return!!t&&(t.additions>0||t.removals>0)}const is=[`up`,`down`,`left`,`right`,`top`,`bottom`],as=async(e,t)=>{let r=await K(e,t,{action:`focus`,requireInteractive:!0,promoteToHittableAncestor:!1});if(!e.backend.focus)throw new n(`UNSUPPORTED_OPERATION`,`focus is not supported by this backend`);let i=Z(r),a=B(await e.backend.focus(R(e,t),i));return{...r,...a?{backendResult:a}:{},...N(`Focused (${i.x}, ${i.y})`)}},os=async(e,t)=>{let r=Qo(t),i=await K(e,t,{action:`longPress`,requireInteractive:!0,promoteToHittableAncestor:!0,captureEvidenceBaseline:r.needsPreActionBaseline});if(!e.backend.longPress)throw new n(`UNSUPPORTED_OPERATION`,`longPress is not supported by this backend`);let a=t.durationMs===void 0?void 0:I(t.durationMs,`durationMs`,0,12e4),o=Z(i),s=B(await e.backend.longPress(R(e,t),o,{durationMs:a}));return await $o(e,t,i,{...i,...a===void 0?{}:{durationMs:a},...s?{backendResult:s}:{},...N(`Long pressed (${o.x}, ${o.y})`)},r)},ss=async(e,t)=>{if(!e.backend.scroll)throw new n(`UNSUPPORTED_OPERATION`,`scroll is not supported by this backend`);let r=ms(t.direction),i=bs(t.amount,`scroll amount`),a=Ss(t.pixels,`scroll pixels`),o=Si(t.durationMs);xi({amount:i,pixels:a},`scroll accepts either amount or pixels, not both`);let s=await ds(e,t),c=s.kind===`viewport`?{kind:`viewport`}:{kind:`point`,point:Z(s)},l=e.backend.scroll,u=async()=>await l(R(e,t),c,{direction:r.direction,...i===void 0?{}:{amount:i},...a===void 0?{}:{pixels:a},...o===void 0?{}:{durationMs:o}}),d,f=0;if(r.edge){let n=r.edge,i=hs(s),a=await Ji({edge:n,captureState:async r=>await gs(e,t,n,i,r),scroll:u});d=a.result,f=a.passes}else d=await u(),f=1;let p=B(d),m=Ci(p);return{...s,direction:r.direction,...r.edge?{edge:r.edge,passes:f}:{},...i===void 0?{}:{amount:i},...a===void 0?{}:{pixels:a},...m===void 0?{}:{durationMs:m},...p?{backendResult:p}:{},...N(Yi(r.direction,r.edge,f,i,a))}},cs=async(e,t)=>{if(!e.backend.swipe)throw new n(`UNSUPPORTED_OPERATION`,`swipe is not supported by this backend`);if(t.preset)return await ls(e,t,e.backend.swipe);let r=await fs(e,t),i=ps(r.point,t),a=t.durationMs===void 0?void 0:I(t.durationMs,`durationMs`,16,1e4),o=B(await e.backend.swipe(R(e,t),r.point,i.point,{durationMs:a}));return{kind:`swipe`,from:r.point,to:i.point,...i.direction?{direction:i.direction}:{},...i.distance===void 0?{}:{distance:i.distance},...a===void 0?{}:{durationMs:a},...r.target?{fromTarget:r.target}:{},...o?{backendResult:o}:{},...N(`Swiped`)}};async function ls(e,t,r){if(t.from||t.to||t.direction||t.distance!==void 0)throw new n(`INVALID_ARGS`,`gesture swipe preset cannot be combined with from, to, direction, or distance`);let i=Ni(t.preset);await J(e,t,`swipe`);let a=Mi(i,ws((await q(e,t,!1)).snapshot.nodes),{platform:e.backend.platform}),o=t.durationMs===void 0?void 0:I(t.durationMs,`durationMs`,16,1e4),s={x:a.x1,y:a.y1},c={x:a.x2,y:a.y2},l=B(await r(R(e,t),s,c,{durationMs:o}));return{kind:`swipe`,from:s,to:c,preset:i,...o===void 0?{}:{durationMs:o},fromTarget:{kind:`viewport`},...l?{backendResult:l}:{},...N(`Swiped ${i}`)}}const us=async(e,t)=>{if(!e.backend.pinch)throw new n(`UNSUPPORTED_OPERATION`,`pinch is not supported by this backend`);await J(e,t,`pinch`);let r=xs(t.scale,`pinch scale`),i=t.center?await K(e,{...t,target:t.center},{action:`pinch`,requireInteractive:!1,promoteToHittableAncestor:!1}):void 0,a=B(await e.backend.pinch(R(e,t),{scale:r,...i?{center:i.point}:{}}));return{kind:`pinch`,scale:r,...i?{center:i.point,centerTarget:i}:{},...a?{backendResult:a}:{},...N(`Pinched to scale ${r}`)}};async function ds(e,t){let n=t.target??{kind:`viewport`};return n.kind===`viewport`?(await J(e,t,`scroll`),{kind:`viewport`}):await K(e,{...t,target:n},{action:`scroll`,requireInteractive:!1,promoteToHittableAncestor:!1})}async function fs(e,t){if(t.from){if(ys(t.from))return await J(e,t,`swipe`),{point:vs(t.from,`from`)};let n=await K(e,{...t,target:t.from},{action:`swipe`,requireInteractive:!1,promoteToHittableAncestor:!1});return{point:Z(n),target:n}}if(!t.direction)throw new n(`INVALID_ARGS`,`swipe requires from+to or a direction`);return await J(e,t,`swipe`),{point:r(Cs((await q(e,t,!1)).snapshot.nodes)),target:{kind:`viewport`}}}function ps(e,t){if(t.to)return{point:vs(t.to,`to`)};let n=_s(t.direction,`swipe direction`),r=xs(t.distance??200,`swipe distance`);switch(n){case`up`:return{point:{x:e.x,y:e.y-r},direction:n,distance:r};case`down`:return{point:{x:e.x,y:e.y+r},direction:n,distance:r};case`left`:return{point:{x:e.x-r,y:e.y},direction:n,distance:r};case`right`:return{point:{x:e.x+r,y:e.y},direction:n,distance:r}}}function ms(e){return e===`bottom`?{direction:`down`,edge:`bottom`}:e===`top`?{direction:`up`,edge:`top`}:{direction:_s(e,`scroll direction`)}}function hs(e){return e.kind===`viewport`?{}:{point:e.point,nodeIndex:`node`in e?e.node?.index:void 0}}function Z(e){if(!e.point)throw new n(`COMMAND_FAILED`,`Interaction target resolved without coordinates`);return e.point}async function gs(e,t,r,i,a){if(!e.backend.captureSnapshot)throw new n(`UNSUPPORTED_OPERATION`,`scroll ${r} requires snapshot support to verify hidden content before scrolling`);let{captureSnapshot:o}=e.backend;return await qi({edge:r,target:i,scope:a,captureNodes:async n=>{let r=await o(R(e,t),{scope:n});return r.snapshot?.nodes??r.nodes??[]}})}function _s(e,t){switch(e){case`up`:case`down`:case`left`:case`right`:return e;default:throw new n(`INVALID_ARGS`,`${t} must be up, down, left, or right`)}}function vs(e,t){let r=Number(e.x),i=Number(e.y);if(!Number.isFinite(r)||!Number.isFinite(i))throw new n(`INVALID_ARGS`,`${t} point requires finite x and y`);return{x:r,y:i}}function ys(e){return`x`in e&&`y`in e}function bs(e,t){return e===void 0?void 0:xs(e,t)}function xs(e,t){if(!Number.isFinite(e)||e<=0)throw new n(`INVALID_ARGS`,`${t} must be a positive number`);return e}function Ss(e,t){if(e!==void 0){if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new n(`INVALID_ARGS`,`${t} must be a positive integer`);return e}}function Cs(e){let t=e.filter(t=>ae(t,e)).map(e=>e.rect).filter(Ts),r=t.length>0?t:e.map(e=>e.rect).filter(Ts);if(r.length===0)throw new n(`COMMAND_FAILED`,`Cannot infer viewport for directional swipe`);let i=Math.min(...r.map(e=>e.x)),a=Math.min(...r.map(e=>e.y)),o=Math.max(...r.map(e=>e.x+e.width)),s=Math.max(...r.map(e=>e.y+e.height));return{x:i,y:a,width:o-i,height:s-a}}function ws(e){let t=Cs(e);return{referenceWidth:t.width,referenceHeight:t.height}}function Ts(e){return!!(e&&e.width>0&&e.height>0)}const Es=/^e\d+$/;function Ds(e){if(e[0]?.startsWith(`@`)){let t=Fs(e.slice(1));return{ref:e[0],...t===void 0?{}:{label:t}}}if(Es.test(e[0]??``))throw new n(`INVALID_ARGS`,`Did you mean "@${e[0]}"? Snapshot refs need the @ prefix.`);let t=d(e);if(t){if(t.rest.length>0)throw new n(`INVALID_ARGS`,Ns(e,t));return{selector:t.selectorExpression}}return ks(e)}function Os(e){let t=e[0];if(t?.startsWith(`@`)){let n=e.length>=3?e.slice(2).join(` `):e.slice(1).join(` `);return{kind:`ref`,target:{ref:t,label:e.length>=3?Fs(e.slice(1,2)):void 0},text:n}}if(Es.test(t??``))throw new n(`INVALID_ARGS`,`Did you mean "@${t}"? Snapshot refs need the @ prefix.`);let r=d(e,{preferTrailingValue:!0});return r?{kind:`selector`,target:{selector:r.selectorExpression},text:r.rest.join(` `)}:{kind:`point`,target:ks(e.slice(0,2)),text:e.slice(2).join(` `)}}function ks(e){let t=e[0]??``,r=l(t);if(r){let i=As(t)?r.value:[r.value,...e.slice(1)].join(` `).trim();throw new n(`INVALID_ARGS`,js({key:r.key,value:i}))}let i=Number(e[0]),a=Number(e[1]);if(Number.isFinite(i)&&Number.isFinite(a))return{x:i,y:a};throw new n(`INVALID_ARGS`,Ms(e))}function As(e){let t=e.slice(e.indexOf(`=`)+1).trim();if(t.length<2)return!1;let n=t[0];return(n===`"`||n===`'`)&&t.endsWith(n)}function js(e){let{key:t,value:n}=e;return`Unknown selector key "${t}". Supported: ${p.join(`, `)}. ${f(t)?`Did you mean role=${t} label=${Q(n)}?`:`Did you mean label=${Q(n)}?`}`}function Ms(e){let t=e.filter(e=>e!==void 0).join(` `);if(!t.trim())return`Missing target. Pass an @ref from snapshot, a selector like text="Sign in", or "x y" coordinates.`;let n=`Target "${t}" is not a @ref, selector, or "x y" point.`;return e.some(e=>c(e??``))?`${n} Selector values with spaces need quotes, e.g. text="Sign in".`:`${n} To match by visible text, use text=${Q(t)} (or label=/id=/role=), or pass an @ref from snapshot.`}function Ns(e,t){return`${`Selector ${t.selectorExpression} is followed by unexpected extra arguments: "${t.rest.join(` `)}".`} Selector values with spaces need quotes, e.g. ${Ps(e,t)??`text="Sign in"`}.`}function Ps(e,t){let n=e.length-t.rest.length,r=e[n-1];if(r===void 0)return;let i=r.indexOf(`=`);if(i<=0)return;let a=[r.slice(i+1),...t.rest].join(` `),o=`${r.slice(0,i+1)}${Q(a)}`;return[...e.slice(0,n-1),o].join(` `)}function Q(e){return`"${e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}"`}function Fs(e){return e.join(` `).trim()||void 0}function Is(e,t){let r=e===void 0?NaN:Number(e);if(!Number.isInteger(r)||r<1)throw new n(`INVALID_ARGS`,`viewport ${t} must be a positive integer`);return r}const Ls=[`path`,`start`,`stop`,`doctor`,`mark`,`clear`],Rs=[`medium`,`high`],zs=`medium`;function Bs(e){return Rs.includes(e)}function Vs(e){let t=typeof e==`number`?e:Hs(e);return t!==void 0&&Number.isInteger(t)&&t>=5&&t<=10?t:void 0}function Hs(e){return typeof e==`string`&&/^\d+$/.test(e)?Number(e):void 0}function Us(e){if(Bs(e))return e;let t=Vs(e);if(t!==void 0)return t<=7?`medium`:`high`}const Ws=[`portrait`,`portrait-upside-down`,`landscape-left`,`landscape-right`];function Gs(e){if(e===void 0)throw new n(`INVALID_ARGS`,`rotate requires an orientation argument. Use portrait|portrait-upside-down|landscape-left|landscape-right.`);switch(e?.trim().toLowerCase()){case`portrait`:return`portrait`;case`portrait-upside-down`:case`upside-down`:return`portrait-upside-down`;case`landscape-left`:case`left`:return`landscape-left`;case`landscape-right`:case`right`:return`landscape-right`;default:throw new n(`INVALID_ARGS`,`Invalid rotation: ${e}. Use portrait|portrait-upside-down|landscape-left|landscape-right.`)}}const Ks={android:`longpress`,apple:`exact`},qs={up:{aliases:[],androidKeyevent:`KEYCODE_DPAD_UP`,appleRemoteButton:`up`},down:{aliases:[],androidKeyevent:`KEYCODE_DPAD_DOWN`,appleRemoteButton:`down`},left:{aliases:[],androidKeyevent:`KEYCODE_DPAD_LEFT`,appleRemoteButton:`left`},right:{aliases:[],androidKeyevent:`KEYCODE_DPAD_RIGHT`,appleRemoteButton:`right`},select:{aliases:[`ok`,`center`,`enter`],androidKeyevent:`KEYCODE_DPAD_CENTER`,appleRemoteButton:`select`},menu:{aliases:[],androidKeyevent:`KEYCODE_MENU`,appleRemoteButton:`menu`},home:{aliases:[],androidKeyevent:`KEYCODE_HOME`,appleRemoteButton:`home`},back:{aliases:[],androidKeyevent:`KEYCODE_BACK`,appleRemoteButton:`menu`}},$=Object.keys(qs),Js=`<${$.join(`|`)}>`;function Ys(e){let t=e?.toLowerCase();if(Xs(t))return t;let r=t?ec.get(t):void 0;if(r)return r;throw new n(`INVALID_ARGS`,`tv-remote button must be one of: ${$.join(`, `)}.`)}function Xs(e){return typeof e==`string`&&$.includes(e)}function Zs(e){return qs[e].appleRemoteButton}function Qs(e){return qs[e].androidKeyevent}function $s(e){return Ks[e]}const ec=new Map($.flatMap(e=>qs[e].aliases.map(t=>[t,e])));export{qi as $,Ne as $n,xr as $t,Oo as A,kn as An,Zr as At,Na as B,Sn as Bn,Lr as Bt,Qo as C,Vn as Cn,_i as Ct,jo as D,zn as Dn,li as Dt,Ao as E,Dn as En,ui as Et,Va as F,In as Fn,qr as Ft,W as G,Mt as Gn,Br as Gt,Ra as H,qt as Hn,Rr as Ht,Ha as I,Fn as In,Fr as It,V as J,C as Jn,Ur as Jt,U as K,jt as Kn,zr as Kt,za as L,jn as Ln,Tr as Lt,Co as M,Mn,Yr as Mt,ho as N,Ln as Nn,Gr as Nt,ko as O,Rn as On,fi as Ot,K as P,Pn,Kr as Pt,R as Q,Ee as Qn,yr as Qt,Fa as R,wn as Rn,Pr as Rt,$o as S,qn as Sn,vi as St,Po as T,P as Tn,mi as Tt,Pa as U,Kt as Un,Ir as Ut,La as V,k as Vn,Dr as Vt,_a as W,Nt as Wn,Er as Wt,z as X,je as Xn,Sr as Xt,B as Y,Ae as Yn,Vr as Yt,da as Z,De as Zn,Cr as Zt,as as _,Hn as _n,xi as _t,Zs as a,dr as an,Ti as at,ss as b,Xn as bn,gi as bt,Gs as c,cr as cn,ji as ct,Us as d,sr as dn,Gi as dt,_r as en,Me as er,Yi as et,Ls as f,hr as fn,Pi as ft,is as g,Un as gn,bi as gt,Ds as h,er as hn,Fi as ht,Qs as i,lr as in,Ei as it,So as j,Nn as jn,Xr as jt,Mo as k,An as kn,di as kt,zs as l,fr as ln,Mi as lt,Os as m,nr as mn,Ni as mt,Js as n,ir as nn,I as nt,$s as o,mr as on,Ai as ot,Is as p,tr as pn,Li as pt,pa as q,O as qn,Hr as qt,Ys as r,ar as rn,wi as rt,Ws as s,ur as sn,ki as st,$ as t,vr as tn,Ji as tt,Rs as u,pr as un,Ii as ut,os as v,Wn as vn,Ci as vt,No as w,N as wn,pi as wt,cs as x,Jn as xn,yi as xt,us as y,Yn as yn,Si as yt,Ia as z,Cn as zn,wr as zt};
@@ -1 +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};
1
+ import e from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";function r(n=i()){try{let r=JSON.parse(e.readFileSync(t.join(n,`package.json`),`utf8`));return typeof r.version==`string`?r.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{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};
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`),tvRemote:()=>i(`tvRemote`),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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.19.0",
3
+ "version": "0.19.2",
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",
@@ -97,6 +97,7 @@
97
97
  "build:macos-helper": "swift build -c release --package-path macos-helper",
98
98
  "build:all": "pnpm build:node && pnpm build:xcuitest",
99
99
  "ad": "node bin/agent-device.mjs",
100
+ "bench:help-conformance": "node scripts/help-conformance-bench.mjs",
100
101
  "size": "node scripts/size-report.mjs",
101
102
  "size:markdown": "node scripts/size-report.mjs --json .tmp/size-report.json --markdown .tmp/size-report.md",
102
103
  "perf": "node --experimental-strip-types scripts/perf/run.ts",
@@ -118,7 +119,7 @@
118
119
  "check:unit": "pnpm test:unit && pnpm test:smoke",
119
120
  "check": "pnpm check:tooling && pnpm check:fallow && pnpm check:unit",
120
121
  "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",
122
+ "typecheck": "tsc -p tsconfig.json",
122
123
  "test-app:install": "pnpm install --dir examples/test-app --ignore-workspace",
123
124
  "test-app:start": "pnpm --dir examples/test-app start",
124
125
  "test-app:ios": "pnpm --dir examples/test-app ios",
@@ -213,14 +214,14 @@
213
214
  },
214
215
  "devDependencies": {
215
216
  "@types/node": "^22.19.21",
216
- "@typescript/native-preview": "7.0.0-dev.20260613.1",
217
+ "typescript": "^7.0.2",
217
218
  "@vitest/coverage-v8": "4.1.8",
218
219
  "fallow": "^2.95.0",
219
220
  "oxc-parser": "^0.138.0",
220
221
  "oxfmt": "^0.42.0",
221
222
  "oxlint": "^1.69.0",
222
223
  "skillgym": "^0.9.1",
223
- "tsdown": "^0.22.3",
224
+ "tsdown": "^0.22.4",
224
225
  "vite": "^8.0.16",
225
226
  "vitest": "^4.1.8"
226
227
  }
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.19.0",
10
+ "version": "0.19.2",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "agent-device",
15
- "version": "0.19.0",
15
+ "version": "0.19.2",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }