agent-device 0.20.0 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +3 -2
  2. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.apk → agent-device-android-ime-helper-0.20.1.apk} +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.manifest.json → agent-device-android-ime-helper-0.20.1.manifest.json} +4 -4
  5. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.apk → agent-device-android-snapshot-helper-0.20.1.apk} +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.apk.sha256 +1 -0
  7. package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.manifest.json → agent-device-android-snapshot-helper-0.20.1.manifest.json} +6 -6
  8. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +54 -6
  9. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
  10. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +15 -4
  11. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +8 -3
  12. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +4 -2
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
  14. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
  15. package/dist/src/agent-device-client.js +2 -2
  16. package/dist/src/android-input-method-overlays.js +1 -1
  17. package/dist/src/android-system-chrome.js +1 -1
  18. package/dist/src/android.js +1 -1
  19. package/dist/src/app-log-request-scope.js +1 -1
  20. package/dist/src/app-resolution.js +1 -1
  21. package/dist/src/apple-multitouch-support.js +1 -1
  22. package/dist/src/apps.js +5 -5
  23. package/dist/src/boot-diagnostics.js +2 -2
  24. package/dist/src/cli-config.js +1 -1
  25. package/dist/src/cli-help.js +76 -19
  26. package/dist/src/cli-runner.js +1 -1
  27. package/dist/src/cli.js +14 -14
  28. package/dist/src/command-metadata.js +1 -1
  29. package/dist/src/command-schema.js +1 -1
  30. package/dist/src/compatibility-policy.js +1 -0
  31. package/dist/src/context.js +1 -1
  32. package/dist/src/contracts.d.ts +2 -2
  33. package/dist/src/debug-symbols.js +1 -1
  34. package/dist/src/devices2.js +1 -1
  35. package/dist/src/devices4.js +1 -0
  36. package/dist/src/find.js +1 -1
  37. package/dist/src/finders.js +1 -1
  38. package/dist/src/generic.js +1 -1
  39. package/dist/src/index.d.ts +144 -9
  40. package/dist/src/input-actions.js +2 -2
  41. package/dist/src/interaction-snapshot.js +1 -1
  42. package/dist/src/interaction.d.ts +2 -2
  43. package/dist/src/interaction.js +1 -1
  44. package/dist/src/interactor.js +2 -2
  45. package/dist/src/interactor2.js +1 -0
  46. package/dist/src/internal/bin.js +1 -1
  47. package/dist/src/internal/daemon.js +20 -20
  48. package/dist/src/lease-context.js +1 -1
  49. package/dist/src/lease.js +1 -1
  50. package/dist/src/linux.js +1 -1
  51. package/dist/src/method-scope.js +1 -0
  52. package/dist/src/metro-types.d.ts +52 -0
  53. package/dist/src/metro.d.ts +2 -2
  54. package/dist/src/react-native.js +1 -1
  55. package/dist/src/recording-export-quality.js +15 -0
  56. package/dist/src/register-builtins.js +1 -1
  57. package/dist/src/registry.js +24 -24
  58. package/dist/src/remote-config.d.ts +1 -1
  59. package/dist/src/reporting.js +4 -4
  60. package/dist/src/runner-client.js +1 -1
  61. package/dist/src/runner-disposal.js +2 -2
  62. package/dist/src/runner-lease.js +1 -1
  63. package/dist/src/runner-provider.js +1 -1
  64. package/dist/src/runtime.js +3 -3
  65. package/dist/src/runtime2.js +1 -1
  66. package/dist/src/sdk-android-adb.d.ts +2 -24
  67. package/dist/src/sdk-android-adb.js +4 -4
  68. package/dist/src/sdk-batch-runner.js +3 -2
  69. package/dist/src/sdk-contracts.d.ts +4 -90
  70. package/dist/src/sdk-device.js +1 -1
  71. package/dist/src/sdk-finders.d.ts +3 -2
  72. package/dist/src/sdk-finders.js +1 -1
  73. package/dist/src/sdk-remote-config.d.ts +18 -103
  74. package/dist/src/sdk-selectors.js +1 -1
  75. package/dist/src/selector-runtime.js +1 -1
  76. package/dist/src/selector-vocabulary.js +1 -1
  77. package/dist/src/selectors.d.ts +1 -1
  78. package/dist/src/selectors.js +1 -1
  79. package/dist/src/server.js +2 -2
  80. package/dist/src/session-target-evidence.js +1 -1
  81. package/dist/src/session.js +8 -8
  82. package/dist/src/simctl.js +1 -0
  83. package/dist/src/simulator.js +1 -1
  84. package/dist/src/snapshot-diagnostics.js +4 -4
  85. package/dist/src/snapshot-quality.js +1 -1
  86. package/dist/src/snapshot2.js +1 -1
  87. package/dist/src/tool-provider3.js +1 -0
  88. package/dist/src/unsupported-interactor.js +1 -0
  89. package/dist/src/web.js +1 -1
  90. package/package.json +8 -6
  91. package/server.json +2 -2
  92. package/skills/agent-device/SKILL.md +5 -3
  93. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +0 -1
  94. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +0 -1
  95. package/dist/src/config.js +0 -1
  96. package/dist/src/daemon-shutdown-report.js +0 -1
  97. package/dist/src/sdk-batch.js +0 -2
  98. package/dist/src/tv-remote.js +0 -15
@@ -0,0 +1 @@
1
+ import{s as e}from"./sdk-device.js";import{o as t}from"./boot-diagnostics.js";import{a 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{_ as t}from"./sdk-contracts.js";import{h as n,p as r}from"./sdk-android-adb.js";import{l as i,n as a,s as o,t as s}from"./boot-diagnostics.js";import{M as c,j as l,k as u}from"./runner-disposal.js";import{a as d,i as f}from"./tool-provider.js";import{n as p,o as m}from"./config.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=u({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 f(`open`,[...n,e],{allowFailure:!0,timeoutMs:1e4})).exitCode===0)return}async function E(e,l={}){if(e.kind!==`simulator`)return;if((x(e)?`Booted`:await O(e))===`Booted`){S(e),l.focusExisting&&await T({background:l.deviceHub,deviceHub:l.deviceHub});return}l.onColdBootStart?.(e);let u=o.fromTimeoutMs(p),f,m;try{await i(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`iOS simulator boot deadline exceeded`,{timeoutMs:p});let a=Math.max(1e3,i?.remainingMs()??18e4);f=await d(c(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));m=await d(c(e,[`bootstatus`,e.id,`-b`]),{allowFailure:!0,timeoutMs:a}),n(m,`simctl bootstatus failed`);let l=await O(e);if(l!==`Booted`)throw new t(`COMMAND_FAILED`,`Simulator is still booting`,{state:l})},{maxAttempts:3,baseDelayMs:500,maxDelayMs:2e3,jitter:.2,shouldRetry:e=>{let t=a({error:e,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});return t!==`IOS_BOOT_TIMEOUT`&&t!==`CI_RESOURCE_STARVATION_SUSPECTED`}},{deadline:u,phase:`boot`,classifyReason:e=>a({error:e,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(n){let r=a({error:n,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});throw new t(`COMMAND_FAILED`,`iOS simulator failed to boot`,{platform:`ios`,deviceId:e.id,timeoutMs:p,elapsedMs:u.elapsedMs(),reason:r,hint:s(r),boot:f,bootstatus:m})}S(e),await T({deviceHub:l.deviceHub})}async function D(e){C(e);let t=await d(c(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 d(typeof e==`string`?l([`list`,`devices`,`-j`]):c(e,[`list`,`devices`,`-j`]),{allowFailure:!0,timeoutMs:m});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{_ as t}from"./sdk-contracts.js";import{h as n,p as r}from"./sdk-android-adb.js";import{l as i,n as a,s as o,t as s}from"./boot-diagnostics.js";import{F as c,N as l,q as u}from"./runner-disposal.js";import{a as d,i as f}from"./tool-provider.js";import{n as p,t as m}from"./simctl.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=u({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 f(`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 u=o.fromTimeoutMs(l),f,m;try{await i(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`iOS simulator boot deadline exceeded`,{timeoutMs:l});let a=Math.max(1e3,i?.remainingMs()??18e4);f=await d(p(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));m=await d(p(e,[`bootstatus`,e.id,`-b`]),{allowFailure:!0,timeoutMs:a}),n(m,`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:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});return t!==`IOS_BOOT_TIMEOUT`&&t!==`CI_RESOURCE_STARVATION_SUSPECTED`}},{deadline:u,phase:`boot`,classifyReason:e=>a({error:e,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(n){let r=a({error:n,stdout:m?.stdout??f?.stdout,stderr:m?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});throw new t(`COMMAND_FAILED`,`iOS simulator failed to boot`,{platform:`ios`,deviceId:e.id,timeoutMs:l,elapsedMs:u.elapsedMs(),reason:r,hint:s(r),boot:f,bootstatus:m})}S(e),await T({deviceHub:c.deviceHub})}async function D(e){C(e);let t=await d(p(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 d(typeof e==`string`?m([`list`,`devices`,`-j`]):p(e,[`list`,`devices`,`-j`]),{allowFailure:!0,timeoutMs:c});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,6 +1,6 @@
1
- import{T as e,_ as t,h as n}from"./sdk-contracts.js";import{N as r,j as i}from"./sdk-android-adb.js";import{P as a,b as o,h as s}from"./sdk-batch.js";import{Qn as c,Yn as ee,nr as te,qn as ne,rr as l}from"./tv-remote.js";import{n as re,t as u}from"./version.js";import{n as d,t as ie}from"./path-resolution.js";import{m as ae}from"./sdk-device.js";import{st as oe}from"./sdk-selectors.js";import{d as se,f,u as p}from"./sdk-batch-runner.js";import{a as ce,n as le,o as ue,u as m}from"./host-process.js";import h from"node:crypto";import g from"node:fs";import _ from"node:path";import{StringDecoder as de}from"node:string_decoder";const v=`/agent-device`,fe=`x-agent-device-tenant`;function pe(e){return me(e,v)}function me(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function he(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}function ge(e){let t=e?.trim();return t?{[fe]:t}:{}}const _e=`.webm`;function ve(e){return e===`web`?_e:`.mp4`}function ye(e,t){return _.extname(e)?e:`${e}${t}`}function be(e){return`./recording-${Date.now()}${ve(e)}`}function xe(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 Se(e,n,r){let i=[],a=0;for await(let o of e){let e=Buffer.isBuffer(o)?o:Buffer.from(o);if(a+=e.length,a>n)throw new t(`INVALID_ARGS`,r);i.push(e)}return Buffer.concat(i)}function y(e){return e.replace(/[^a-zA-Z0-9._-]/g,`_`)}function b(e,t){return d(e,{cwd:t})}function x(e,t,n){e.saveScriptPath!==void 0&&e.saveScriptPath!==t&&!n&&(e.saveScriptForce=void 0),e.saveScriptPath=t}function Ce(e,t){if(t.flags?.noRecord||Ee(e,t))return;t.flags?.saveScript&&(e.recordSession=!0,typeof t.flags.saveScript==`string`&&(x(e,b(t.flags.saveScript),t.flags.force),e.saveScriptDefaultedHealedPath=!1),t.flags.force&&(e.saveScriptForce=!0));let n={ts:Date.now(),command:t.command,positionals:t.positionals,runtime:t.runtime,flags:Oe(t.flags),result:t.result,...t.targetEvidence?{targetEvidence:t.targetEvidence}:{}};return e.actions.push(n),i({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),n}const we=new Set([`snapshot`,`get`,`is`,`find`]);function Te(e){return e.internal?.replayPlanStep===!0?!1:we.has(e.command)}function Ee(e,t){return!t.interactiveObservation||e.saveScriptBoundary===void 0?!1:t.flags?.record!==!0}const De=[`platform`,`device`,`udid`,`serial`,`out`,`verbose`,`metroHost`,`metroPort`,`bundleUrl`,`launchUrl`,`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`,...ee,`relaunch`,`saveScript`,`force`,`noRecord`,`record`,`fps`,`quality`,`hideTouches`,`count`,`pointerCount`,`intervalMs`,`delayMs`,`holdMs`,`jitterPx`,`doubleTap`,`clickButton`,`pauseMs`,`pattern`];function Oe(e){if(!e)return{};let t={};for(let n of De)e[n]!==void 0&&(t[n]=e[n]);return t}function ke(e){let t=e.result?.text;if(typeof t==`string`&&t.trim().length>0)return t;let n=e.positionals??[];return n.length===0?``:n[0]?.startsWith(`@`)?n.length>=3?n.slice(2).join(` `).trim():n.slice(1).join(` `).trim():n.length>=3&&!Number.isNaN(Number(n[0]))&&!Number.isNaN(Number(n[1]))?n.slice(2).join(` `).trim():n.slice(1).join(` `).trim()}function S(e){return e.startsWith(`@`)?n(e)?.base??e:e}const C=/^-?\d+(\.\d+)?$/,Ae=/^[^\s"\\]+$/,je=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),Me=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),Ne=new Map([[`--pointer-count`,`pointerCount`]]),Pe=new Map([[`--delay-ms`,`delayMs`]]);function w(e){return e===`click`||e===`press`}function T(e){return w(e)||e===`longpress`}function E(e){return e===`type`||e===`fill`}function D(e){return A(e,Fe)}function O(e){return JSON.stringify(e)}function k(e){return A(e,j)}function A(e,t){return t(e)?e:O(e)}function Fe(e){return j(e)&&e.startsWith(`@`)||C.test(e)}function j(e){return Ae.test(e)}const Ie=new Set([`fill`,`type`]);function Le(e){if(!Ie.has(e.command)){let t=(e.positionals??[]).map(e=>D(e));return[e.command,...t].join(` `)}let t=Re(e).map(e=>D(e)).join(` `);return[e.command,t,`<text>`].filter(e=>e.length>0).join(` `)}function Re(e){if(e.command===`type`)return[];let t=e.positionals??[],n=t[0];return n===void 0?[]:n.startsWith(`@`)?[n]:t.length>=3&&C.test(n)&&C.test(t[1]??``)?[n,t[1]]:[n]}function M(e,t){let n=t.flags??{};if(w(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}if(t.command===`gesture`){typeof n.pointerCount==`number`&&e.push(`--pointer-count`,String(n.pointerCount));return}E(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function N(e,t){t&&((t.platform===`ios`||t.platform===`android`)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,k(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,k(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,k(t.launchUrl)))}function ze(e,t){let[n,...r]=t.positionals??[];n&&e.push(k(n));for(let t of r)e.push(D(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),typeof t.flags?.screenshotMaxSize==`number`&&e.push(`--max-size`,String(t.flags.screenshotMaxSize)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function Be(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,D(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function Ve(e,t){for(let n of t.positionals??[])e.push(D(n));c(e,t.flags)}function He(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(k(t));N(e,t.flags)}function Ue(e,t){for(let n of t.positionals??[])e.push(D(t.command===`wait`?S(n):n));M(e,t)}function We(e,t){let n=[],r={},i=w(e)?je:e===`swipe`?Me:e===`gesture`?Ne:E(e)?Pe:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(w(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(w(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=F(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function P(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;(e===`ios`||e===`android`)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=F(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function F(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function Ge(e,t){for(let n of t.positionals??[])e.push(D(n));t.flags?.relaunch&&e.push(`--relaunch`),N(e,t.runtime)}function Ke(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}t.push(r)}let r=P(t);return{positionals:r.positionals,flags:n,runtime:qe(r.flags)?r.flags:void 0}}function qe(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}function Je(e,t={}){let n=[e.command];return e.command===`snapshot`?Be(n,e):e.command===`open`?Ge(n,e):e.command===`runtime`?He(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?ze(n,e):e.command===`screenshot`?Ve(n,e):Ue(n,e),n.join(` `)}function Ye(e){return e.targetEvidence?[oe(e.targetEvidence)]:[]}function Xe(e){let n=e.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new t(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(e.some(e=>e.command===`close`))throw new t(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[t,n]of e.entries())s({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=t);if(!e.slice(r+1).some($e))throw new t(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selective selector-targeted wait, for example wait 'role="heading" label="Screen X"', then retry session save-script.`})}function Ze(e){for(let n of e){let e=et(n),r=e??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&s(n)===`mutates-app`)throw new t(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=e;if(!(!i||!a(i)||n.targetEvidence))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Qe(e,n){if(e instanceof t){if(e.details?.reason===`script_target_exists`)return new t(e.code,`A file already exists at ${String(e.details.path)}.`,{...e.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=e.details?.retriable===!0;return new t(e.code,e.message,{...e.details,retriable:n,hint:e.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function $e(e){if(e.command!==`wait`)return!1;let t=o(e.positionals);return t?.kind===`selector`&&a(t.selectorExpression)!==null}function et(e){if(e.command===`get`)return e.positionals[1];if(T(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&I(t)&&I(n)?void 0:t}}function I(e){return e.trim().length>0&&Number.isFinite(Number(e))}function tt(e){return e.saveScriptBoundary===void 0?!1:e.saveScriptCommitted?!0:!e.saveScriptComplete}var nt=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=e.saveScriptBoundary!==void 0,r=t?.publication===`active`,i;try{if(!e.recordSession||tt(e))return{written:!1};let a=rt(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=_.dirname(i);return g.existsSync(o)||g.mkdirSync(o,{recursive:!0}),ot({scriptPath:i,script:a.script,force:t?.force}),n&&(e.saveScriptCommitted=!0),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return it({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){if(e.saveScriptPath)return b(e.saveScriptPath);let t=y(e.name),n=new Date(e.createdAt).toISOString().replace(/[:.]/g,`-`);return _.join(this.sessionsDir,`${t}-${n}.ad`)}};function rt(e,t){let n=st(e,{strictPortableRefs:t.activePublication});return t.activePublication&&Xe(n),{script:gt(e,n,t.appendCompleteSentinel),actionCount:n.length}}function it(e){let{session:n,error:r,scriptPath:a,repairArmed:o,activePublication:s}=e;if(i({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:a,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:at(r,a)};if(s)return{written:!1,error:Qe(r,a)};if(r instanceof t)throw r;return{written:!1}}function at(e,n){if(e instanceof t)return e;let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function ot(e){let{scriptPath:n,script:r,force:i}=e,a=_.dirname(n),o=_.join(a,`.${_.basename(n)}.${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);g.writeFileSync(o,r);try{if(i){g.renameSync(o,n);return}g.linkSync(o,n)}catch(e){throw e.code===`EEXIST`?new t(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):e}finally{g.rmSync(o,{force:!0})}}function st(e,t={}){let n=e.saveScriptBoundary!==void 0,r=e.actions.slice(e.saveScriptBoundary??0),i=[];for(let a of r){if(a.command===`snapshot`)continue;let r=lt(a);if(r){i.push(r);continue}(n||t.strictPortableRefs)&&ct(a);let o=ht(e,a);o&&i.push(o),i.push(a)}return t.strictPortableRefs&&Ze(i),i}function ct(e){if(!L(e.command))return;let n=e.command===`get`?e.positionals?.[1]:e.positionals?.[0];if(n?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot write recorded step "${e.command} ${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function lt(e){let t=ut(e);if(!(!t||!L(e.command)))return w(e.command)?{...e,positionals:[t]}:e.command===`longpress`?ft(e,t):e.command===`fill`?dt(e,t):pt(e,t)}function ut(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function L(e){return T(e)||e===`fill`||e===`get`}function dt(e,t){let n=ke(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function ft(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):mt(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function pt(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function mt(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function ht(e,t){if(!L(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function gt(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${ae(e.device)} device=${O(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...Ye(e)),r.push(_t(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
2
- `)}\n`}function _t(e){return vt([e.command],e)||Je(e)}function vt(e,t){if(w(t.command))return yt(e,t);if(t.command===`fill`)return bt(e,t);if(t.command===`get`)return xt(e,t)}function yt(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(D(S(n))),R(e,t),M(e,t),e.join(` `);if(t.positionals.length===1)return e.push(D(n)),M(e,t),e.join(` `)}}function bt(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(D(S(n))),R(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(D(r)),M(e,t),e.join(` `)}function xt(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(D(n)),e.push(D(S(r))),r.startsWith(`@`)&&R(e,t),e.join(` `)}function R(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(D(n))}function St(e){switch(e.command){case l.open:return`Opened ${B(e)??`session`}`;case l.close:return`Closed ${K(e.result?.session)??`session`}`;case l.click:case l.press:return`Tapped ${B(e)??`target`}`;case l.longPress:return`Long pressed ${B(e)??`target`}`;case l.fill:return`Filled ${B(e)??`target`}`;case l.type:return`Typed ${G(`text`,H(e))}`;case l.install:case l.reinstall:case te.installSource:return`Installed ${B(e)??`app`}`;default:return z(e)??`Ran ${e.command}`}}function Ct(e){let t=e.result??{};return{command:e.command,positionals:V(e),flags:e.flags,action:t.action,message:z(e),ref:t.ref,targetLabel:B(e),selectorChainLength:Vt(t.selectorChain)?.length,x:t.x,y:t.y,x2:t.x2,y2:t.y2,durationMs:t.durationMs,waitedMs:t.waitedMs,found:t.found,path:t.path,outPath:t.outPath,telemetryPath:t.telemetryPath,sessionStateDir:t.sessionStateDir,requestLogPath:t.requestLogPath,runnerLogPath:t.runnerLogPath,platform:t.platform,target:t.target,device:t.device,appName:t.appName,appBundleId:t.appBundleId,bundleId:t.bundleId,packageName:t.packageName,launchTarget:t.launchTarget,textLength:typeof t.text==`string`?Array.from(t.text).length:void 0,nodeCount:Array.isArray(t.nodes)?t.nodes.length:void 0}}function z(e){let t=K(e.result?.message);if(t&&!(wt(e)||Tt(e.result??{})))return t}function wt(e){return Et(e).length>0}function Tt(e){return K(e.refLabel)!==void 0||K(e.selector)!==void 0||Vt(e.selectorChain)!==void 0}function Et(e){return kt(Dt(e).sort((e,t)=>t.raw.length-e.raw.length))}function Dt(e){let t=V(e)??[],n=e.positionals.flatMap((e,n)=>{let r=Ot(e,t[n]);return r?[r]:[]}),r=e.result?.text;return typeof r==`string`&&r.length>0?[{raw:r,display:W(`text`,r)},...n]:n}function Ot(e,t){if(!e)return;let n=t??U(e);return n===e?void 0:{raw:e,display:n}}function kt(e){let t=new Set,n=[];for(let{raw:r,display:i}of e)t.has(r)||(t.add(r),n.push({raw:r,display:i}));return n}function B(e){let t=e.result??{};return At(t)??jt(t)??Mt(t)??zt(e.positionals[0])}function At(e){let t=K(e.ref);if(t)return t.startsWith(`@`)?t:`@${t}`}function jt(e){let t=q(e.x),n=q(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function Mt(e){return K(e.appName)??K(e.appBundleId)??K(e.bundleId)??K(e.packageName)}function V(e){if(e.positionals.length!==0)return e.command===l.type?[G(`text`,H(e))]:e.command===l.fill?Nt(e):e.command===l.find?Pt(e):e.command===l.clipboard?Ft(e):e.command===l.push||e.command===l.triggerAppEvent?It(e,`payload`):e.positionals.map(U)}function Nt(e){let t=G(`text`,H(e)),n=e.result??{},r=K(n.ref);if(r)return[r.startsWith(`@`)?r:`@${r}`,t];let i=K(n.selector);if(i)return[W(`target`,i),t];let a=q(n.x),o=q(n.y);return a!==void 0&&o!==void 0?[String(a),String(o),t]:[t]}function Pt(e){let t=+!!Bt(e.positionals[0]),n=e.positionals[t];if(n===void 0)return;let r=t+1,i=[...t===1?[String(e.positionals[0])]:[],W(`query`,n)],a=e.positionals[r];return a?a===`fill`||a===`type`?[...i,a,G(`text`,H(e))]:[...i,...e.positionals.slice(r).map(Lt)]:i}function Ft(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,G(`text`,Rt(e))]:e.positionals.map(U)}function It(e,t){let[n,r,...i]=e.positionals;return[...n?[n]:[],...r?[W(t,r)]:[],...i.map(U)]}function Lt(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:U(e)}function H(e){let t=e.result?.text;return typeof t==`string`?Array.from(t).length:e.command===l.type?Array.from(e.positionals.join(` `)).length:0}function Rt(e){let t=e.result?.textLength;return typeof t==`number`&&Number.isFinite(t)?t:Array.from(e.positionals.slice(1).join(` `)).length}function U(e){return zt(e)??W(`arg`,e)}function zt(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function W(e,t){return G(e,Array.from(t).length)}function G(e,t){return`<${e}:${t} chars>`}function Bt(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function K(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function q(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function Vt(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const J=new Map,Ht=new Set;function Ut(e){return _.join(e,`events.ndjson`)}function Wt(e){return e.command!==l.events}function Gt(t,n,r){let i=e({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});qt(t,`${JSON.stringify(i)}\n`)}async function Kt(e){await(e?J.get(e):Promise.all(J.values()))}function qt(e,t){let n=(J.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await Jt(e),await g.promises.appendFile(e,t,`utf8`)}).catch(t=>{i({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{J.get(e)===n&&J.delete(e)});J.set(e,n)}async function Jt(e){let t=_.dirname(e);if(!Ht.has(t))try{await g.promises.mkdir(t,{recursive:!0}),Ht.add(t)}catch(t){throw i({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function Yt(e,t,n){Gt(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:St(n),details:Ct(n)})}function Xt(e){let{req:t,sessionName:n,requestLogPath:i,runnerLogPath:a}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`,details:{publicSession:t.session,effectiveSession:n,tenant:t.meta?.tenantId,isolation:t.meta?.sessionIsolation,requestLogPath:i,runnerLogPath:a}}}function Zt(e){let{req:t,response:n,durationMs:i}=e;return n.ok?{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:`Finished ${t.command}`,details:{durationMs:i}}:{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId,logPath:n.error.logPath}}}function Qt(e,t={}){let n=rn(t.cursor),r=an(t.limit);if(!g.existsSync(e))return{path:e,cursor:String(n),limit:r,events:[]};let i=$t(e,n,r),a=i.lines.flatMap(e=>{let t=on(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:a,...i.nextCursor===void 0?{}:{nextCursor:String(i.nextCursor)}}}function $t(e,t,n){let r=g.openSync(e,`r`);try{let e=new de(`utf8`),i=Buffer.allocUnsafe(65536),a=en(t,n),o=``,s=0;do{s=g.readSync(r,i,0,i.length,null);let t=e.write(i.subarray(0,s));o=tn(`${o}${t}`,a)}while(s>0&&a.nextCursor===void 0);let c=`${o}${e.end()}`;return a.nextCursor===void 0&&c.length>0&&nn(c,a),{lines:a.lines,nextCursor:a.nextCursor}}finally{g.closeSync(r)}}function en(e,t){return{cursor:e,limit:t,lineIndex:0,lines:[]}}function tn(e,t){let n=0;for(let r=e.indexOf(`
1
+ import{T as e,_ as t,h as n}from"./sdk-contracts.js";import{N as r,j as i}from"./sdk-android-adb.js";import{M as a,R as o,et as s,g as c,h as l,m as u}from"./sdk-batch-runner.js";import{Dn as ee,Gn as te,Jn as ne,Pn as re,Qn as ie,Xn as d,bn as ae,cr as f,er as oe,kn as se,rr as ce,sr as le}from"./recording-export-quality.js";import{n as ue,t as de}from"./version.js";import{n as fe,t as pe}from"./path-resolution.js";import{h as me,n as he,r as ge,t as _e}from"./sdk-device.js";import{mt as ve}from"./sdk-selectors.js";import{a as ye,n as be,o as xe,u as p}from"./host-process.js";import Se from"node:crypto";import m from"node:fs";import h from"node:path";import{StringDecoder as Ce}from"node:string_decoder";const we=`/agent-device`,Te=`x-agent-device-tenant`;function Ee(e){return De(e,we)}function De(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function Oe(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}function ke(e){let t=e?.trim();return t?{[Te]:t}:{}}const Ae=`.webm`;function je(e){return e===`web`?Ae:`.mp4`}function Me(e,t){return h.extname(e)?e:`${e}${t}`}function Ne(e){return`./recording-${Date.now()}${je(e)}`}function Pe(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 Fe(e,n,r){let i=[],a=0;for await(let o of e){let e=Buffer.isBuffer(o)?o:Buffer.from(o);if(a+=e.length,a>n)throw new t(`INVALID_ARGS`,r);i.push(e)}return Buffer.concat(i)}function g(e){return e.replace(/[^a-zA-Z0-9._-]/g,`_`)}function _(e,t){return fe(e,{cwd:t})}function v(e){let t=e.result?.text;if(typeof t==`string`)return t;let n=e.positionals??[];return n.length===0?``:n[0]?.startsWith(`@`)?n.length>=3?n.slice(2).join(` `):n.slice(1).join(` `):n.length>=3&&!Number.isNaN(Number(n[0]))&&!Number.isNaN(Number(n[1]))?n.slice(2).join(` `):n.slice(1).join(` `)}const y=/^[A-Z_][A-Z0-9_]*$/,Ie=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g;function b(e){return e.startsWith(`AD_`)}function Le(e){return new t(`INVALID_ARGS`,`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function Re(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;let n=[e.fileEnv,e.shellEnv,e.cliEnv];for(let e of n)if(e)for(let[n,r]of Object.entries(e)){if(b(n))throw Le(n);t[n]=r}return{values:t,expandedBuiltinNames:new Set}}function ze(e){let t={};for(let[n,r]of Object.entries(e)){if(typeof r!=`string`||!n.startsWith(`AD_VAR_`))continue;let e=n.slice(7);e.length!==0&&y.test(e)&&(b(e)||(t[e]=r))}return t}function Be(e){let n={};for(let r of e){let e=r.indexOf(`=`);if(e<=0)throw new t(`INVALID_ARGS`,`Invalid -e entry "${r}": expected KEY=VALUE.`);let i=r.slice(0,e);if(!y.test(i))throw new t(`INVALID_ARGS`,`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(b(i))throw Le(i);n[i]=r.slice(e+1)}return n}function Ve(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function He(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}return process.env}function Ue(e,n,r){return e.replace(Ie,(e,i,a,o)=>{if(i)return"${";if(!a)return e;if(Object.prototype.hasOwnProperty.call(n.values,a))return b(a)&&(n.expandedBuiltinNames??=new Set).add(a),String(n.values[a]);if(o!==void 0)return o.replace(/\\(.)/g,`$1`);throw new t(`INVALID_ARGS`,`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function We(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>Ue(e,t,n)),flags:Ge(e.flags,t,n)??{},runtime:Ge(e.runtime,t,n)}}function Ge(e,t,n){return e&&x(e,t,n)}function x(e,t,n){return typeof e==`string`?Ue(e,t,n):Array.isArray(e)?e.map(e=>x(e,t,n)):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,r])=>[e,x(r,t,n)])):e}function Ke(e){return Object.entries(e.values).filter(([t,n])=>n.length>0&&(!b(t)||e.expandedBuiltinNames?.has(t))).map(([e,t])=>({name:e,value:t})).sort((e,t)=>t.value.length-e.value.length)}const qe=/^\$\{([A-Z_][A-Z0-9_]*)\}$/;function Je(e){if(e!==e.trim()||!y.test(e))throw new t(`INVALID_ARGS`,`Invalid --record-as variable "${e}": use uppercase letters, digits, and underscores (for example PASSWORD).`);if(e.startsWith(`AD_`))throw new t(`INVALID_ARGS`,`Invalid --record-as variable "${e}": the AD_* namespace is reserved for built-in replay variables.`);return e}function Ye(e){return`\${${e}}`}function Xe(e){let t=qe.exec(e);if(!(!t?.[1]||t[1].startsWith(`AD_`)))return t[1]}const Ze=new Set([`text`,`label`,`value`]),Qe=new Set(`action.backend.cost.delayMs.evidence.gesture.hint.kind.maestroFallbackReason.maestroNonHittableCoordinateFallbackAllowed.maestroNonHittableCoordinateFallbackUsed.message.platform.ref.referenceHeight.referenceWidth.refLabel.resolution.selector.selectorChain.settle.targetHittable.targetKind.text.warning.x.y`.split(`.`)),$e=new Set([`action`,`backend`,`gesture`,`kind`,`platform`,`ref`,`selector`,`targetKind`]),et=new Set([`cost`,`evidence`,`resolution`,`settle`]),tt=new Map([[`cost`,new Set([`nodeCount`,`runnerRoundTrips`,`wallClockMs`])],[`evidence`,new Set([`changedFromBefore`,`digest`,`foregroundApp`,`interactiveNodeCount`,`nodeCount`])],[`resolution`,new Set([`alternatives`,`kind`,`matchCount`,`phase`,`source`,`tiebreak`,`winnerDiagnostic`])],[`resolution.alternatives`,new Set([`diagnosticRef`,`label`,`role`])],[`resolution.winnerDiagnostic`,new Set([`diagnosticRef`,`label`,`role`])],[`settle`,new Set([`captures`,`diff`,`hint`,`quietMs`,`refs`,`refsGeneration`,`settled`,`tail`,`tailTruncated`,`timeoutMs`,`waitedMs`])],[`settle.diff`,new Set([`lines`,`summary`,`truncated`])],[`settle.diff.lines`,new Set([`kind`,`ref`,`text`])],[`settle.diff.summary`,new Set([`additions`,`removals`,`unchanged`])],[`settle.refs`,new Set([`ref`])],[`settle.tail`,new Set([`label`,`ref`,`role`])]]),nt=new Set([`evidence.digest`,`evidence.foregroundApp`,`resolution.alternatives.diagnosticRef`,`resolution.alternatives.role`,`resolution.kind`,`resolution.phase`,`resolution.source`,`resolution.tiebreak`,`resolution.winnerDiagnostic.diagnosticRef`,`resolution.winnerDiagnostic.role`,`settle.diff.lines.kind`,`settle.diff.lines.ref`,`settle.refs.ref`,`settle.tail.ref`,`settle.tail.role`]);function rt(e,t,n){if(!e)return e;let r=ut(e.selectorChain);return{...ot(e,t,n),...typeof e.text==`string`?{text:n}:{},...r?{selectorChain:r.filter(e=>!at(e,t))}:{}}}function it(e,t,n){return e&&{...e,...e.label===t?{label:n}:{},ancestry:e.ancestry.map(e=>({...e,...e.label===t?{label:n}:{}})),...e.scrollRegion?{scrollRegion:{...e.scrollRegion,...e.scrollRegion.label===t?{label:n}:{}}}:{}}}function at(e,t){return s(e)?.selectors.some(e=>e.terms.some(e=>Ze.has(e.key)&&typeof e.value==`string`&&C(e.value,t,``)!==e.value))??!1}function ot(e,t,n){return Object.fromEntries(Object.entries(e).map(([e,r])=>[Qe.has(e)?e:C(e,t,n),st(r,e,t,n)]))}function st(e,t,n,r){return typeof e==`string`&&$e.has(t)?e:t===`selectorChain`&&lt(e)?ct(e,n):S(e,n,r,et.has(t)?t:void 0)}function S(e,t,n,r){if(typeof e==`string`)return r&&nt.has(r)?e:C(e,t,n);if(Array.isArray(e))return e.map(e=>S(e,t,n,r));if(!e||typeof e!=`object`)return e;let i=r?tt.get(r):void 0;return Object.fromEntries(Object.entries(e).map(([e,a])=>{let o=i?.has(e)===!0;return[o?e:C(e,t,n),S(a,t,n,o?`${r}.${e}`:void 0)]}))}function ct(e,t){return e.filter(e=>!at(e,t))}function C(e,t,n){if(!t)return e===t?n:e;let r=n?e.split(n):[e];return r.every(e=>!e.includes(t))?e:t.trim()?r.map(e=>e.replaceAll(t,n)).join(n):n}function lt(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function ut(e){return lt(e)?e:void 0}function dt(e,t,n){e.saveScriptPath!==void 0&&e.saveScriptPath!==t&&!n&&(e.saveScriptForce=void 0),e.saveScriptPath=t}function ft(e,t){if(t.flags?.noRecord||_t(e,t))return;t.flags?.saveScript&&(e.recordSession=!0,typeof t.flags.saveScript==`string`&&(dt(e,_(t.flags.saveScript),t.flags.force),e.saveScriptDefaultedHealedPath=!1),t.flags.force&&(e.saveScriptForce=!0));let n=pt(t),r={ts:Date.now(),command:n.command,positionals:n.positionals,runtime:n.runtime,flags:yt(n.flags),result:n.result,...n.targetEvidence?{targetEvidence:n.targetEvidence}:{}};return e.actions.push(r),i({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),r}function pt(e){if(e.command!==`fill`||typeof e.flags.recordAs!=`string`)return e;let t=Ye(Je(e.flags.recordAs)),n=v({ts:0,command:e.command,positionals:e.positionals,flags:e.flags});return{...e,positionals:mt(e.positionals,t),result:rt(e.result,n,t),targetEvidence:it(e.targetEvidence,n,t)}}function mt(e,t){let n=e[0];return n?.startsWith(`@`)?e.length>=3?[n,e[1],t]:[n,t]:e.length>=3&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))?[e[0],e[1],t]:n===void 0?[t]:[n,t]}const ht=new Set([`snapshot`,`get`,`is`,`find`]);function gt(e){return e.internal?.replayPlanStep===!0?!1:ht.has(e.command)}function _t(e,t){return!t.interactiveObservation||e.saveScriptBoundary===void 0?!1:t.flags?.record!==!0}const vt=[`platform`,`device`,`udid`,`serial`,`out`,`verbose`,`metroHost`,`metroPort`,`bundleUrl`,`launchUrl`,`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`,...oe,`relaunch`,`saveScript`,`force`,`noRecord`,`record`,`fps`,`quality`,`hideTouches`,`count`,`pointerCount`,`intervalMs`,`delayMs`,`holdMs`,`jitterPx`,`doubleTap`,`clickButton`,`pauseMs`,`pattern`];function yt(e){if(!e)return{};let t={};for(let n of vt)e[n]!==void 0&&(t[n]=e[n]);return t}function w(e){return e.startsWith(`@`)?n(e)?.base??e:e}const T=/^-?\d+(\.\d+)?$/,bt=/^[^\s"\\]+$/,xt=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),St=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),Ct=new Map([[`--pointer-count`,`pointerCount`]]),wt=new Map([[`--delay-ms`,`delayMs`]]);function E(e){return e===`click`||e===`press`}function D(e){return E(e)||e===`longpress`}function Tt(e){return e===`type`||e===`fill`}function O(e){return Dt(e,Ot)}function Et(e){return JSON.stringify(e)}function k(e){return Dt(e,kt)}function Dt(e,t){return t(e)?e:Et(e)}function Ot(e){return kt(e)&&e.startsWith(`@`)||T.test(e)}function kt(e){return bt.test(e)}const At=new Set([`fill`,`type`]);function jt(e){if(!At.has(e.command)){let t=(e.positionals??[]).map(e=>O(e));return[e.command,...t].join(` `)}let t=Mt(e).map(e=>O(e)).join(` `);return[e.command,t,`<text>`].filter(e=>e.length>0).join(` `)}function Mt(e){if(e.command===`type`)return[];let t=e.positionals??[],n=t[0];return n===void 0?[]:n.startsWith(`@`)?[n]:t.length>=3&&T.test(n)&&T.test(t[1]??``)?[n,t[1]]:[n]}function A(e,t){let n=t.flags??{};if(E(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}if(t.command===`gesture`){typeof n.pointerCount==`number`&&e.push(`--pointer-count`,String(n.pointerCount));return}Tt(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function Nt(e,t){t&&((t.platform===`ios`||t.platform===`android`)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,k(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,k(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,k(t.launchUrl)))}function Pt(e,t){let[n,...r]=t.positionals??[];n&&e.push(k(n));for(let t of r)e.push(O(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),typeof t.flags?.screenshotMaxSize==`number`&&e.push(`--max-size`,String(t.flags.screenshotMaxSize)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function Ft(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,O(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function It(e,t){for(let n of t.positionals??[])e.push(O(n));ce(e,t.flags)}function Lt(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(k(t));Nt(e,t.flags)}function Rt(e,t){for(let n of t.positionals??[])e.push(O(t.command===`wait`?w(n):n));A(e,t)}function zt(e,t){let n=[],r={},i=E(e)?xt:e===`swipe`?St:e===`gesture`?Ct:Tt(e)?wt:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(E(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(E(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=Vt(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function Bt(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;(e===`ios`||e===`android`)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=Vt(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function Vt(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function Ht(e,t){for(let n of t.positionals??[])e.push(O(n));t.flags?.relaunch&&e.push(`--relaunch`),Nt(e,t.runtime)}function Ut(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}t.push(r)}let r=Bt(t);return{positionals:r.positionals,flags:n,runtime:Wt(r.flags)?r.flags:void 0}}function Wt(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}function Gt(e,t={}){let n=[e.command];return e.command===`snapshot`?Ft(n,e):e.command===`open`?Ht(n,e):e.command===`runtime`?Lt(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?Pt(n,e):e.command===`screenshot`?It(n,e):Rt(n,e),n.join(` `)}function Kt(e){return e.targetEvidence?[ve(e.targetEvidence)]:[]}function qt(e){let n=e.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new t(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(e.some(e=>e.command===`close`))throw new t(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[t,n]of e.entries())a({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=t);if(!e.slice(r+1).some(Xt))throw new t(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selector-targeted wait on a labeled or id-bearing landmark, for example wait 'role="heading" label="Screen X"', so its recorded identity is captured, then retry session save-script.`})}function Jt(e){for(let n of e){let e=Zt(n),r=e??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&a(n)===`mutates-app`)throw new t(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=e;if(!(!i||!s(i)||n.targetEvidence))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Yt(e,n){if(e instanceof t){if(e.details?.reason===`script_target_exists`)return new t(e.code,`A file already exists at ${String(e.details.path)}.`,{...e.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=e.details?.retriable===!0;return new t(e.code,e.message,{...e.details,retriable:n,hint:e.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function Xt(e){if(e.command!==`wait`)return!1;let t=o(e.positionals);return t?.kind!==`selector`||s(t.selectorExpression)===null?!1:e.targetEvidence?.verification===`verified`}function Zt(e){if(e.command===`get`)return e.positionals[1];if(D(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&Qt(t)&&Qt(n)?void 0:t}}function Qt(e){return e.trim().length>0&&Number.isFinite(Number(e))}function $t(e){return e.saveScriptBoundary===void 0?!1:e.saveScriptCommitted?!0:!e.saveScriptComplete}var en=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=e.saveScriptBoundary!==void 0,r=t?.publication===`active`,i;try{if(!e.recordSession||$t(e))return{written:!1};let a=tn(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=h.dirname(i);return m.existsSync(o)||m.mkdirSync(o,{recursive:!0}),an({scriptPath:i,script:a.script,force:t?.force}),n&&(e.saveScriptCommitted=!0),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return nn({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){if(e.saveScriptPath)return _(e.saveScriptPath);let t=g(e.name),n=new Date(e.createdAt).toISOString().replace(/[:.]/g,`-`);return h.join(this.sessionsDir,`${t}-${n}.ad`)}};function tn(e,t){let n=on(e,{strictPortableRefs:t.activePublication});return t.activePublication&&qt(n),{script:hn(e,n,t.appendCompleteSentinel),actionCount:n.length}}function nn(e){let{session:n,error:r,scriptPath:a,repairArmed:o,activePublication:s}=e;if(i({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:a,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:rn(r,a)};if(s)return{written:!1,error:Yt(r,a)};if(r instanceof t)throw r;return{written:!1}}function rn(e,n){if(e instanceof t)return e;let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function an(e){let{scriptPath:n,script:r,force:i}=e,a=h.dirname(n),o=h.join(a,`.${h.basename(n)}.${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);m.writeFileSync(o,r);try{if(i){m.renameSync(o,n);return}m.linkSync(o,n)}catch(e){throw e.code===`EEXIST`?new t(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):e}finally{m.rmSync(o,{force:!0})}}function on(e,t={}){let n=e.saveScriptBoundary!==void 0,r=e.actions.slice(e.saveScriptBoundary??0),i=[];for(let a of r){if(a.command===`snapshot`)continue;let r=cn(a);if(r){i.push(r);continue}(n||t.strictPortableRefs)&&sn(a);let o=mn(e,a);o&&i.push(o),i.push(a)}return t.strictPortableRefs&&Jt(i),i}function sn(e){if(!j(e.command))return;let n=e.command===`get`?e.positionals?.[1]:e.positionals?.[0];if(n?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot write recorded step "${e.command} ${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function cn(e){let t=ln(e);if(!(!t||!j(e.command)))return E(e.command)?{...e,positionals:[t]}:e.command===`longpress`?dn(e,t):e.command===`fill`?un(e,t):fn(e,t)}function ln(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function j(e){return D(e)||e===`fill`||e===`get`}function un(e,t){let n=v(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function dn(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):pn(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function fn(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function pn(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function mn(e,t){if(!j(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function hn(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${me(e.device)} device=${Et(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...Kt(e)),r.push(gn(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
2
+ `)}\n`}function gn(e){return _n([e.command],e)||Gt(e)}function _n(e,t){if(E(t.command))return vn(e,t);if(t.command===`fill`)return yn(e,t);if(t.command===`get`)return bn(e,t)}function vn(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(O(w(n))),M(e,t),A(e,t),e.join(` `);if(t.positionals.length===1)return e.push(O(n)),A(e,t),e.join(` `)}}function yn(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(O(w(n))),M(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(O(r)),A(e,t),e.join(` `)}function bn(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(O(n)),e.push(O(w(r))),r.startsWith(`@`)&&M(e,t),e.join(` `)}function M(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(O(n))}const xn=[`status`,`get`,`dismiss`,`enter`,`return`];function N(e){return xn.includes(e)}const Sn=[`id`,`deviceId`,`device_id`,`serial`,`udid`,`device_udid`,`identifier`],Cn={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`,apple:`Apple`,android:`Android`,linux:`Linux`,web:`Web`};function wn(e,t){let n=t??{};switch(e.command){case f.devices:return Tn(n.devices);case f.apps:return En(n.apps,e.flags?.appsFilter);case f.boot:return Dn(`Booted`,n,!0);case f.shutdown:return Dn(`Shut down`,n,!1);case f.install:return On(`Installed`,n);case f.reinstall:return On(`Reinstalled`,n);case f.screenshot:return kn(e,n);default:return{}}}function Tn(e){if(!Array.isArray(e))return{};let t=e.flatMap(e=>{let t=jn(e);return t?[t]:[]}),n=t.slice(0,5),r=Math.max(0,t.length-n.length),i=t.slice(0,3);return{summary:Bn(`Found ${t.length} ${Vn(`device`,t.length)}`,i.map(e=>Rn(e,!0)),Math.max(0,t.length-i.length)),details:{deviceCount:t.length,devices:n,...r>0?{omittedDeviceCount:r}:{}}}}function En(e,t){if(!Array.isArray(e))return{};let n=e.flatMap(e=>{let t=I(e);return t?[t]:[]}),r=n.slice(0,5),i=Math.max(0,n.length-r.length),a=n.slice(0,3);return{summary:Bn(`Found ${n.length} ${Vn(`app`,n.length)}`,a,Math.max(0,n.length-a.length)),details:{appCount:n.length,apps:r,...i>0?{omittedAppCount:i}:{},...t===`all`||t===`user-installed`?{filter:t}:{}}}}function Dn(e,t,n){let r=Mn(t);if(!r)return{};let i={device:r,...Ln(t),booted:n};return{summary:`${e} ${Rn(i,!1)}`,details:i}}function On(e,t){let n=I(t.appName),r=I(t.bundleId),i=P(t,[`packageName`,`package`]),a=I(t.platform),o=I(t.launchTarget),s=P(t,[`bundleId`,`packageName`,`package`,`appId`,`launchTarget`]),c=zn(n,s);if(!c)return{};let l={};return F(l,`appName`,n),F(l,`bundleId`,r),F(l,`packageName`,i),F(l,`platform`,a),o!==s&&F(l,`launchTarget`,o),{summary:`${e} ${c}`,details:l}}function kn(e,t){let n=An(e,t);return n?{details:{requestedFileName:n}}:{}}function An(e,t){let n=H(e.meta?.clientArtifactPaths?.path)??H(t.path);if(n)return V(n)}function jn(e){if(!u(e))return;let t=Mn(e);if(t)return{name:t,...Ln(e)}}function Mn(e){let t=P(e,[`name`,`deviceName`,`device`]);return!t||!Nn(e,t)?t:Fn(e)}function Nn(e,t){let n=Pn(t);return Sn.some(t=>{let r=I(e[t]);return r!==void 0&&Pn(r)===n})}function Pn(e){return e.toLowerCase()}function Fn(e){let t=I(e.appleOs),n=I(e.platform),r=I(e.kind),i=In(t,n);return i&&(r===`simulator`||r===`emulator`)?`${i} ${r}`:i?`${i} device`:r===`simulator`?`Simulator`:r===`emulator`?`Emulator`:`Unnamed device`}function In(e,t){let n=e??t;if(!(!n||!Object.hasOwn(Cn,n)))return Cn[n]}function Ln(e){let t=I(e.platform),n=I(e.appleOs),r=I(e.kind),i=I(e.target);return{...t?{platform:t}:{},...n?{appleOs:n}:{},...r?{kind:r}:{},...i?{target:i}:{},...typeof e.booted==`boolean`?{booted:e.booted}:{}}}function Rn(e,t){let n=I(e.name)??I(e.device)??`device`,r=I(e.platform),i=I(e.appleOs),a=[r,i===r?void 0:i,I(e.kind),I(e.target),t&&typeof e.booted==`boolean`?e.booted?`booted`:`stopped`:void 0].filter(e=>!!e);return a.length>0?`${n} (${a.join(`, `)})`:n}function zn(e,t){return e&&t&&e!==t?`${e} (${t})`:e??t}function P(e,t){for(let n of t){let t=I(e[n]);if(t)return t}}function F(e,t,n){n&&(e[t]=n)}function Bn(e,t,n){let r=[...t,...n>0?[`+${n} more`]:[]];return r.length>0?`${e}: ${r.join(`, `)}`:e}function Vn(e,t){return t===1?e:`${e}s`}function I(e){let t=H(e);if(!t)return;let n=t.trim(),r=Array.from(n);return r.length<=120?n:`${r.slice(0,119).join(``)}…`}function L(e){return I(e)}function R(e){return typeof e==`boolean`?e:void 0}function z(e,t){let n=L(e);return n&&t.includes(n)?n:void 0}function B(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function V(e){let t=H(e);return t?I(t.split(/[\\/]/).at(-1)):void 0}function H(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function U(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}const Hn=[`up`,`down`,`left`,`right`],Un=[`top`,`bottom`];function Wn(e){return`${e.command===f.reinstall?`Reinstalled`:`Installed`} ${Jn(e.result??{})??`app`}`}function Gn(e){let t=e.result??{};switch(e.command){case f.scroll:return Xn(t);case f.screenshot:return $n(t);case f.home:return`Went home`;case f.back:return tr(t);case f.appSwitcher:return`Opened app switcher`;case f.orientation:return nr(t);case f.viewport:return rr(t);case f.clipboard:return ir(t);case f.keyboard:return ar(t);case f.tvRemote:return sr(t);case f.gesture:return cr(t);case f.swipe:return lr(t);case f.trace:return dr(`trace`,e);case f.record:return dr(`recording`,e);default:return}}function Kn(e){let t=e.result??{};switch(e.command){case f.scroll:return B({direction:z(t.direction,Hn),edge:z(t.edge,Un),passes:U(t.passes),amount:U(t.amount),pixels:U(t.pixels),durationMs:U(t.durationMs),x1:U(t.x1),y1:U(t.y1),x2:U(t.x2),y2:U(t.y2)});case f.screenshot:return B({requestedFileName:er(t)});case f.back:return B({mode:z(t.mode,d)});case f.orientation:return B({orientation:z(t.orientation,ee)});case f.viewport:return B({width:U(t.width),height:U(t.height)});case f.clipboard:return B({action:z(t.action,[`read`,`write`])});case f.keyboard:return or(t);case f.tvRemote:return B({button:z(t.button,ae),durationMs:U(t.durationMs)});case f.gesture:case f.swipe:return ur(t);case f.trace:case f.record:return B({action:z(t.action,[`start`,`stop`]),fileName:pr(e),showTouches:R(t.showTouches)});default:return{}}}function qn(e,t){if(e.command!==f.screenshot)return t;let n=An(e,t);return n?{...t,requestedFileName:n}:t}function Jn(e){let t=L(e.appName),n=mr(e,[`bundleId`,`packageName`,`appBundleId`,`launchTarget`]);return t&&n&&t!==n?`${t} (${n})`:t??n??Yn(e)}function Yn(e){let t=L(e.app);return t&&!t.includes(`/`)&&!t.includes(`\\`)?t:void 0}function Xn(e){let t=z(e.direction,Hn),n=z(e.edge,Un),r=U(e.passes);return n?Zn(n,r):t?Qn(t,e):`Scrolled`}function Zn(e,t){return t===0?`Already at ${e}`:t===void 0?`Scrolled to ${e}`:`Scrolled to ${e} in ${t} ${t===1?`pass`:`passes`}`}function Qn(e,t){let n=U(t.pixels);if(n!==void 0)return`Scrolled ${e} by ${n}px`;let r=U(t.amount);return r===void 0?`Scrolled ${e}`:`Scrolled ${e} by ${r}`}function $n(e){let t=er(e);return t?`Captured screenshot ${t}`:`Captured screenshot`}function er(e){return V(e.requestedFileName)??V(e.path)}function tr(e){return z(e.mode,d)===`system`?`Went back using system navigation`:`Went back`}function nr(e){let t=z(e.orientation,ee);return t?`Rotated to ${t}`:`Changed orientation`}function rr(e){let t=U(e.width),n=U(e.height);return t!==void 0&&n!==void 0?`Set viewport to ${t}×${n}`:`Changed viewport`}function ir(e){let t=z(e.action,[`read`,`write`]);return t===`read`?`Read clipboard`:t===`write`?`Updated clipboard`:`Used clipboard`}function ar(e){let t=H(e.action);if(!t||!N(t))return`Used keyboard`;if(t===`dismiss`)return R(e.dismissed)===!1?`Keyboard was already hidden`:`Dismissed keyboard`;if(t===`enter`||t===`return`)return`Pressed keyboard return`;let n=R(e.visible);return n===void 0?`Inspected keyboard`:n?`Keyboard is visible`:`Keyboard is hidden`}function or(e){let t=H(e.action);return B({action:t&&N(t)?t:void 0,platform:z(e.platform,[`ios`,`android`]),visible:R(e.visible),wasVisible:R(e.wasVisible),dismissed:R(e.dismissed),attempts:U(e.attempts)})}function sr(e){let t=z(e.button,ae);return t?`Pressed TV remote ${t}`:`Used TV remote`}function cr(e){let t=z(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]);return t?`Ran ${t} gesture`:`Ran gesture`}function lr(e){let t=U(e.count);return t!==void 0&&t>1?`Swiped ${t} times`:`Swiped`}function ur(e){return B({kind:z(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]),durationMs:U(e.durationMs),pointerCount:U(e.pointerCount),x1:U(e.x1),y1:U(e.y1),x2:U(e.x2),y2:U(e.y2),count:U(e.count),pauseMs:U(e.pauseMs),pattern:z(e.pattern,[`one-way`,`ping-pong`]),scale:U(e.scale)})}function dr(e,t){let n=fr(e,z(t.result?.action,[`start`,`stop`])),r=pr(t);return r?`${n} ${r}`:n}function fr(e,t){return t===`start`?e===`trace`?`Started trace`:`Started recording`:t===`stop`?e===`trace`?`Stopped trace`:`Stopped recording`:e===`trace`?`Updated trace`:`Updated recording`}function pr(e){let t=e.result??{};return V(t.requestedFileName)??V(t.outPath)??V(t.path)??V(e.positionals[1])}function mr(e,t){for(let n of t){let t=L(e[n]);if(t)return t}}function hr(e){switch(e.command){case f.open:return`Opened ${W(e)??`session`}`;case f.close:return`Closed ${L(e.result?.session)??`session`}`;case f.click:case f.press:return`Tapped ${W(e)??`target`}`;case f.longPress:return`Long pressed ${W(e)??`target`}`;case f.fill:return`Filled ${W(e)??`target`}`;case f.type:return`Typed text`;case f.install:case f.reinstall:case le.installSource:return Wn(e);default:return Gn(e)??`Ran ${e.command}`}}function gr(e){return B({command:e.command,positionals:Tr(e),flags:Ir(e),..._r(e),...vr(e),...yr(e),...Kn(e)})}function _r(e){if(!br(e.command))return{};let t=e.result??{};return B({ref:J(t),targetLabel:W(e),selectorChainLength:Nr(t.selectorChain)?.length,x:U(t.x),y:U(t.y),x2:U(t.x2),y2:U(t.y2),durationMs:U(t.durationMs)})}function vr(e){if(!xr(e.command))return{};let t=e.result??{};return B({platform:z(t.platform,ge),target:z(t.target,_e),appName:L(t.appName),appBundleId:L(t.appBundleId),bundleId:L(t.bundleId),packageName:L(t.packageName),launchTarget:L(t.launchTarget)})}function yr(e){let t=e.result??{};return e.command===f.snapshot?{...Array.isArray(t.nodes)?{nodeCount:t.nodes.length}:{}}:e.command!==f.wait&&e.command!==f.find&&e.command!==f.get&&e.command!==f.is?{}:B({waitedMs:U(t.waitedMs),found:R(t.found)})}function br(e){return e===f.click||e===f.press||e===f.longPress||e===f.focus||e===f.fill}function xr(e){return e===f.open||e===f.install||e===f.reinstall||e===le.installSource}function W(e){let t=e.result??{};return Sr(t)??Cr(t)??wr(t)??jr(e.positionals[0])}function Sr(e){let t=J(e);if(t)return t.startsWith(`@`)?t:`@${t}`}function Cr(e){let t=U(e.x),n=U(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function wr(e){return L(e.appName)??L(e.appBundleId)??L(e.bundleId)??L(e.packageName)}function Tr(e){if(e.positionals.length!==0)return e.command===f.type?[K(`text`)]:e.command===f.fill?Er(e):e.command===f.find?Dr(e):e.command===f.clipboard?Or(e):e.command===f.push?kr(e,`app`,`payload`):e.command===f.triggerAppEvent?kr(e,`event`,`payload`):e.positionals.map(G)}function Er(e){let t=K(`text`),n=e.result??{},r=J(n);if(r)return[`@${r}`,t];if(L(n.selector))return[K(`target`),t];let i=U(n.x),a=U(n.y);return i!==void 0&&a!==void 0?[String(i),String(a),t]:[t]}function Dr(e){let t=+!!Mr(e.positionals[0]);if(e.positionals[t]===void 0)return;let n=t+1,r=[...t===1?[String(e.positionals[0])]:[],K(`query`)],i=e.positionals[n];return i?i===`fill`||i===`type`?[...r,i,K(`text`)]:[...r,...e.positionals.slice(n).map(Ar)]:r}function Or(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,K(`text`)]:e.positionals.map(G)}function kr(e,t,n){let[r,i,...a]=e.positionals;return[...r?[K(t)]:[],...i?[K(n)]:[],...a.map(G)]}function Ar(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:G(e)}function G(e){return jr(e)??K(`arg`)}function jr(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function K(e){return`<${e}>`}function Mr(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function Nr(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const Pr={enums:[{source:`platform`,values:he},{source:`target`,values:_e}]},Fr={[f.open]:{booleans:[{source:`relaunch`},{source:`testIme`}],enums:[{source:`surface`,values:te}]},[f.click]:q(),[f.press]:q(),[f.longPress]:q(),[f.fill]:Lr(),[f.type]:Lr(),[f.scroll]:{numbers:[{source:`pixels`},{source:`durationMs`}]},[f.gesture]:Rr(),[f.swipe]:Rr(),[f.screenshot]:{booleans:[{source:`overlayRefs`},{source:`screenshotFullscreen`,output:`fullscreen`},{source:`screenshotNoStabilize`,output:`noStabilize`},{source:`screenshotNormalizeStatusBar`,output:`normalizeStatusBar`}],numbers:[{source:`screenshotPixelDensity`,output:`pixelDensity`},{source:`screenshotMaxSize`,output:`maxSize`}]},[f.snapshot]:{booleans:[{source:`snapshotInteractiveOnly`,output:`interactiveOnly`},{source:`snapshotDiff`,output:`diff`},{source:`snapshotRaw`,output:`raw`},{source:`snapshotForceFull`,output:`forceFull`}],numbers:[{source:`snapshotDepth`,output:`depth`}]},[f.back]:{enums:[{source:`backMode`,output:`mode`,values:d}]},[f.record]:{booleans:[{source:`hideTouches`}],numbers:[{source:`fps`},{source:`screenshotMaxSize`,output:`maxSize`}],enums:[{source:`recordingScope`,output:`scope`,values:ne}]},[f.apps]:{enums:[{source:`appsFilter`,output:`filter`,values:[`user-installed`,`all`]}]},[f.boot]:{booleans:[{source:`headless`}]},[f.close]:{booleans:[{source:`shutdown`}]}};function Ir(e){let t=e.flags??{},n={},r=Object.hasOwn(Fr,e.command)?Fr[e.command]:void 0;return zr(n,t,Pr),zr(n,t,r),Object.keys(n).length>0?n:void 0}function q(){return{booleans:[{source:`doubleTap`},{source:`settle`}],numbers:[{source:`count`},{source:`intervalMs`},{source:`holdMs`},{source:`jitterPx`},{source:`settleQuietMs`}],enums:[{source:`clickButton`,values:se}]}}function Lr(){return{booleans:[{source:`settle`}],numbers:[{source:`delayMs`},{source:`settleQuietMs`}]}}function Rr(){return{numbers:[{source:`pointerCount`},{source:`count`},{source:`pauseMs`}],enums:[{source:`pattern`,values:re}]}}function zr(e,t,n){n&&(Br(e,t,n.booleans??[]),Vr(e,t,n.numbers??[]),Hr(e,t,n.enums??[]))}function Br(e,t,n){for(let r of n)Ur(e,r.output??r.source,t[r.source])}function Vr(e,t,n){for(let r of n)Wr(e,r.output??r.source,t[r.source])}function Hr(e,t,n){for(let r of n)Gr(e,r.output??r.source,t[r.source],r.values)}function J(e){let t=L(e.ref);if(!t)return;let n=t.startsWith(`@`)?t.slice(1):t;return/^[a-zA-Z0-9:_-]+$/.test(n)?n:void 0}function Ur(e,t,n){typeof n==`boolean`&&(e[t]=n)}function Wr(e,t,n){let r=U(n);r!==void 0&&(e[t]=r)}function Gr(e,t,n,r){let i=z(n,r);i!==void 0&&(e[t]=i)}const Y=new Map,Kr=new Set;function qr(e){return h.join(e,`events.ndjson`)}function Jr(e){return e.command!==f.events}function Yr(t,n,r){let i=e({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});Zr(t,`${JSON.stringify(i)}\n`)}async function Xr(e){await(e?Y.get(e):Promise.all(Y.values()))}function Zr(e,t){let n=(Y.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await Qr(e),await m.promises.appendFile(e,t,`utf8`)}).catch(t=>{i({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{Y.get(e)===n&&Y.delete(e)});Y.set(e,n)}async function Qr(e){let t=h.dirname(e);if(!Kr.has(t))try{await m.promises.mkdir(t,{recursive:!0}),Kr.add(t)}catch(t){throw i({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function $r(e,t,n){Yr(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:hr(n),details:gr(n)})}function ei(e){let{req:t}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`}}function ti(e){let{req:t,response:n,durationMs:i}=e;if(n.ok){let e=wn(t,n.data);return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:e.summary??`Finished ${t.command}`,details:{durationMs:i,...e.details}}}return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId}}}function ni(e,t={}){let n=si(t.cursor),r=ci(t.limit);if(!m.existsSync(e))return{path:e,cursor:String(n),limit:r,events:[]};let i=ri(e,n,r),a=i.lines.flatMap(e=>{let t=li(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:a,...i.nextCursor===void 0?{}:{nextCursor:String(i.nextCursor)}}}function ri(e,t,n){let r=m.openSync(e,`r`);try{let e=new Ce(`utf8`),i=Buffer.allocUnsafe(65536),a=ii(t,n),o=``,s=0;do{s=m.readSync(r,i,0,i.length,null);let t=e.write(i.subarray(0,s));o=ai(`${o}${t}`,a)}while(s>0&&a.nextCursor===void 0);let c=`${o}${e.end()}`;return a.nextCursor===void 0&&c.length>0&&oi(c,a),{lines:a.lines,nextCursor:a.nextCursor}}finally{m.closeSync(r)}}function ii(e,t){return{cursor:e,limit:t,lineIndex:0,lines:[]}}function ai(e,t){let n=0;for(let r=e.indexOf(`
3
3
  `);r!==-1;r=e.indexOf(`
4
- `,n))if(nn(e.slice(n,r),t),n=r+1,t.nextCursor!==void 0)return``;return e.slice(n)}function nn(e,t){let n=e.endsWith(`\r`)?e.slice(0,-1):e;if(n.trim().length!==0){if(t.lineIndex>=t.cursor+t.limit){t.nextCursor=t.cursor+t.limit;return}t.lineIndex>=t.cursor&&t.lines.push(n),t.lineIndex+=1}}function rn(e){if(e===void 0||e.trim()===``)return 0;let n=Number(e);if(Number.isInteger(n)&&n>=0)return n;throw new t(`INVALID_ARGS`,`events cursor must be a non-negative integer string.`)}function an(e){if(e===void 0||typeof e==`string`&&e.trim()===``)return 100;let n=typeof e==`string`?Number(e):e;if(Number.isInteger(n)&&n>=1&&n<=500)return n;throw new t(`INVALID_ARGS`,`events limit must be between 1 and 500.`)}function on(e){try{let t=sn(JSON.parse(e));return t?cn(t):void 0}catch{return}}function sn(e){if(p(e)&&e.version===1&&!(typeof e.ts!=`string`||typeof e.session!=`string`)&&ln(e.kind))return e}function cn(e){let t=p(e.details)?e.details:void 0;return{version:1,ts:e.ts,session:e.session,kind:e.kind,...typeof e.requestId==`string`?{requestId:e.requestId}:{},...typeof e.command==`string`?{command:e.command}:{},...un(e.status)?{status:e.status}:{},...typeof e.summary==`string`?{summary:e.summary}:{},...t?{details:t}:{}}}function ln(e){return e===`request.started`||e===`request.finished`||e===`action.recorded`}function un(e){return e===`ok`||e===`error`}const dn=60*6e4;var fn=class{sessions=new Map;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new nt(e)}get(e){return this.sessions.get(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){let n=Ce(e,t);if(n){let t=this.resolveStoredSessionName(e);Yt(this.resolveEventLogPath(t),t,n)}}recordEvent(e,t){Gt(this.resolveEventLogPath(e),e,t)}readEvents(e,t={}){return Qt(this.resolveEventLogPath(e),t)}async flushEvents(e){await Kt(e?this.resolveEventLogPath(e):void 0)}writeSessionLog(e,t){let n=this.scriptWriter.write(e,t);return n.written&&i({level:`info`,phase:`session_script_written`,data:{session:e.name,path:n.path}}),n}finalizeRepairTeardown(e){this.recordRepairFinalizeCloseIfCommitting(e);let t=this.writeSessionLog(e,{force:e.saveScriptForce});e.saveScriptBoundary!==void 0&&e.saveScriptCommitted!==!0&&(!t.written&&t.error?this.writeRepairTombstone(e,dn,{code:String(t.error.code),message:t.error.message}):this.writeRepairTombstone(e))}recordRepairFinalizeCloseIfCommitting(e){e.saveScriptBoundary!==void 0&&e.saveScriptComplete===!0&&e.saveScriptCommitted!==!0&&this.recordAction(e,{command:`close`,positionals:[],flags:{},result:{session:e.name,...ne(`Closed: ${e.name}`)}})}writeRepairTombstone(e,t=dn,n){try{let r=this.resolveSessionDir(e.name);g.mkdirSync(r,{recursive:!0});let i={owner:e.name,reapedAt:Date.now(),expiresAt:Date.now()+t,...e.repairSourcePath?{sourcePath:e.repairSourcePath}:{},...n?{commitFailure:n}:{}};g.writeFileSync(this.repairTombstonePath(e.name),`${JSON.stringify(i)}\n`)}catch(t){i({level:`warn`,phase:`repair_tombstone_write_failed`,data:{session:e.name,error:t instanceof Error?t.message:String(t)}})}}readRepairTombstone(e){return pn(this.repairTombstonePath(e))}clearRepairTombstone(e){try{g.rmSync(this.repairTombstonePath(e),{force:!0})}catch{}}repairTombstonePath(e){return _.join(this.resolveSessionDir(e),`repair-tombstone.json`)}defaultTracePath(e){let t=y(e.name),n=new Date().toISOString().replace(/[:.]/g,`-`);return _.join(this.sessionsDir,`${t}-${n}.trace.log`)}resolveSessionDir(e){return _.join(this.sessionsDir,y(e))}resolveDaemonStateDir(){return _.dirname(this.sessionsDir)}ensureSessionDir(e){let t=this.resolveSessionDir(e);return g.mkdirSync(t,{recursive:!0}),t}resolveAppLogPath(e){return _.join(this.resolveSessionDir(e),`app.log`)}resolveAppLogPidPath(e){return _.join(this.resolveSessionDir(e),`app-log.pid`)}resolveEventLogPath(e){return Ut(this.resolveSessionDir(e))}static expandHome(e,t){return b(e,t)}resolveStoredSessionName(e){for(let[t,n]of this.sessions)if(n===e)return t;return e.name}};function pn(e){let t;try{t=g.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||n.expiresAt<=Date.now()))return n}function mn(e){let t;try{t=g.readdirSync(e,{withFileTypes:!0})}catch{return}for(let n of t){if(!n.isDirectory())continue;let t=pn(_.join(e,n.name,`repair-tombstone.json`));if(t?.commitFailure)return{sessionName:n.name,tombstone:{...t,commitFailure:t.commitFailure}}}}function hn(e){return _.join(e,`runner.log`)}function gn(e,t){let n=y(t&&t.length>0?t:`unknown`);return _.join(e,`requests`,`${n}.ndjson`)}function _n(e,t={}){let n=vn(e,t);return{baseDir:n,infoPath:_.join(n,`daemon.json`),lockPath:_.join(n,`daemon.lock`),logPath:_.join(n,`daemon.log`),sessionsDir:_.join(n,`sessions`)}}function vn(e,t){let n=(e??``).trim();return n?d(n,{env:t.env}):yn(t)}function yn(e={}){let t=_.join(ie(`~`,{env:e.env}),`.agent-device`),n=e.projectRoot??u();return bn(n)?_.join(t,`dev`,xn(n)):t}function bn(e){return g.existsSync(_.join(e,`package.json`))&&g.existsSync(_.join(e,`src`,`daemon.ts`))}function xn(e){let t=Sn(e),n=_.basename(t).replaceAll(/[^a-zA-Z0-9._-]+/g,`-`),r=h.createHash(`sha1`).update(t).digest(`hex`).slice(0,12);return`${n||`agent-device`}-${r}`}function Sn(e){try{return g.realpathSync.native(e)}catch{return _.resolve(e)}}function Cn(e){let t=(e??``).trim().toLowerCase();return t===`http`?`http`:t===`dual`?`dual`:`socket`}function wn(e){let t=(e??``).trim().toLowerCase();return t===`auto`?`auto`:t===`socket`?`socket`:t===`http`?`http`:`auto`}function Tn(e){return(e??``).trim().toLowerCase()===`tenant`?`tenant`:`none`}function En(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}const Dn=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,On=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,kn=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`];function An(){let e=process.argv[1];return e?jn(e):`unknown`}function jn(e,t=u()){try{let n=_.resolve(t),r=[_.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=g.statSync(e);if(!t.isFile())continue;let o=_.relative(n,e)||e;a.push(`${o}:${t.size}:${Math.trunc(t.mtimeMs)}`);let s=g.readFileSync(e,`utf8`);for(let t of Mn(s)){let n=Pn(e,t);n&&r.push(n)}}let o=a.sort().join(`|`),s=h.createHash(`sha1`).update(o).digest(`hex`);return`graph:${a.length}:${s}`}catch{return`unknown`}}function Mn(e){let t=new Set;return Nn(e,Dn,t),Nn(e,On,t),[...t]}function Nn(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 Pn(e,t){let n=_.resolve(_.dirname(e),t),r=Y(n);if(r)return r;for(let e of kn){let t=Y(`${n}${e}`);if(t)return t}for(let e of kn){let t=Y(_.join(n,`index${e}`));if(t)return t}return null}function Y(e){try{return g.statSync(e).isFile()?e:null}catch{return null}}const Fn=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function In(e){let t=e.toLowerCase().replaceAll(`\\`,`/`);return t.includes(`agent-device`)?Fn.some(e=>e.test(t)):!1}function Ln(e,t){if(!le(e))return!1;if(t){let n=ue(e);if(!n||n!==t)return!1}let n=ce(e);return n?In(n):!1}function X(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 Rn(e,t){Ln(e,t.expectedStartTime)&&X(e,`SIGTERM`)&&(await m(e,t.termTimeoutMs)||X(e,`SIGKILL`)&&await m(e,t.killTimeoutMs))}const zn=/^[A-Za-z0-9_@%+=:,./-]+$/;function Bn(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function Vn(e){return zn.test(e)?e:Bn(e)}function Hn(e,t){let n=[],r=e+t.toString(),i=r.indexOf(`
4
+ `,n))if(oi(e.slice(n,r),t),n=r+1,t.nextCursor!==void 0)return``;return e.slice(n)}function oi(e,t){let n=e.endsWith(`\r`)?e.slice(0,-1):e;if(n.trim().length!==0){if(t.lineIndex>=t.cursor+t.limit){t.nextCursor=t.cursor+t.limit;return}t.lineIndex>=t.cursor&&t.lines.push(n),t.lineIndex+=1}}function si(e){if(e===void 0||e.trim()===``)return 0;let n=Number(e);if(Number.isInteger(n)&&n>=0)return n;throw new t(`INVALID_ARGS`,`events cursor must be a non-negative integer string.`)}function ci(e){if(e===void 0||typeof e==`string`&&e.trim()===``)return 100;let n=typeof e==`string`?Number(e):e;if(Number.isInteger(n)&&n>=1&&n<=500)return n;throw new t(`INVALID_ARGS`,`events limit must be between 1 and 500.`)}function li(e){try{let t=ui(JSON.parse(e));return t?di(t):void 0}catch{return}}function ui(e){if(u(e)&&e.version===1&&!(typeof e.ts!=`string`||typeof e.session!=`string`)&&fi(e.kind))return e}function di(e){let t=u(e.details)?e.details:void 0;return{version:1,ts:e.ts,session:e.session,kind:e.kind,...typeof e.requestId==`string`?{requestId:e.requestId}:{},...typeof e.command==`string`?{command:e.command}:{},...pi(e.status)?{status:e.status}:{},...typeof e.summary==`string`?{summary:e.summary}:{},...t?{details:t}:{}}}function fi(e){return e===`request.started`||e===`request.finished`||e===`action.recorded`}function pi(e){return e===`ok`||e===`error`}const mi=60*6e4;var hi=class{sessions=new Map;runtimeHints=new Map;sessionsDir;scriptWriter;constructor(e){this.sessionsDir=e,this.scriptWriter=new en(e)}get(e){return this.sessions.get(e)}set(e,t){this.sessions.set(e,t)}delete(e){return this.runtimeHints.delete(e),this.sessions.delete(e)}values(){return this.sessions.values()}toArray(){return Array.from(this.sessions.values())}getRuntimeHints(e){return this.runtimeHints.get(e)}setRuntimeHints(e,t){this.runtimeHints.set(e,t)}clearRuntimeHints(e){return this.runtimeHints.delete(e)}recordAction(e,t){let n=ft(e,t);if(n){let t=this.resolveStoredSessionName(e);$r(this.resolveEventLogPath(t),t,n)}}recordEvent(e,t){Yr(this.resolveEventLogPath(e),e,t)}readEvents(e,t={}){return ni(this.resolveEventLogPath(e),t)}async flushEvents(e){await Xr(e?this.resolveEventLogPath(e):void 0)}writeSessionLog(e,t){let n=this.scriptWriter.write(e,t);return n.written&&i({level:`info`,phase:`session_script_written`,data:{session:e.name,path:n.path}}),n}finalizeRepairTeardown(e){this.recordRepairFinalizeCloseIfCommitting(e);let t=this.writeSessionLog(e,{force:e.saveScriptForce});e.saveScriptBoundary!==void 0&&e.saveScriptCommitted!==!0&&(!t.written&&t.error?this.writeRepairTombstone(e,mi,{code:String(t.error.code),message:t.error.message}):this.writeRepairTombstone(e))}recordRepairFinalizeCloseIfCommitting(e){e.saveScriptBoundary!==void 0&&e.saveScriptComplete===!0&&e.saveScriptCommitted!==!0&&this.recordAction(e,{command:`close`,positionals:[],flags:{},result:{session:e.name,...ie(`Closed: ${e.name}`)}})}writeRepairTombstone(e,t=mi,n){try{let r=this.resolveSessionDir(e.name);m.mkdirSync(r,{recursive:!0});let i={owner:e.name,reapedAt:Date.now(),expiresAt:Date.now()+t,...e.repairSourcePath?{sourcePath:e.repairSourcePath}:{},...n?{commitFailure:n}:{}};m.writeFileSync(this.repairTombstonePath(e.name),`${JSON.stringify(i)}\n`)}catch(t){i({level:`warn`,phase:`repair_tombstone_write_failed`,data:{session:e.name,error:t instanceof Error?t.message:String(t)}})}}readRepairTombstone(e){return gi(this.repairTombstonePath(e))}clearRepairTombstone(e){try{m.rmSync(this.repairTombstonePath(e),{force:!0})}catch{}}repairTombstonePath(e){return h.join(this.resolveSessionDir(e),`repair-tombstone.json`)}defaultTracePath(e){let t=g(e.name),n=new Date().toISOString().replace(/[:.]/g,`-`);return h.join(this.sessionsDir,`${t}-${n}.trace.log`)}resolveSessionDir(e){return h.join(this.sessionsDir,g(e))}resolveDaemonStateDir(){return h.dirname(this.sessionsDir)}ensureSessionDir(e){let t=this.resolveSessionDir(e);return m.mkdirSync(t,{recursive:!0}),t}resolveAppLogPath(e){return h.join(this.resolveSessionDir(e),`app.log`)}resolveAppLogPidPath(e){return h.join(this.resolveSessionDir(e),`app-log.pid`)}resolveEventLogPath(e){return qr(this.resolveSessionDir(e))}static expandHome(e,t){return _(e,t)}resolveStoredSessionName(e){for(let[t,n]of this.sessions)if(n===e)return t;return e.name}};function gi(e){let t;try{t=m.readFileSync(e,`utf8`)}catch{return}let n;try{n=JSON.parse(t)}catch{return}if(!(typeof n?.expiresAt!=`number`||n.expiresAt<=Date.now()))return n}function _i(e){let t;try{t=m.readdirSync(e,{withFileTypes:!0})}catch{return}for(let n of t){if(!n.isDirectory())continue;let t=gi(h.join(e,n.name,`repair-tombstone.json`));if(t?.commitFailure)return{sessionName:n.name,tombstone:{...t,commitFailure:t.commitFailure}}}}function vi(e){return h.join(e,`runner.log`)}function yi(e,t){let n=g(t&&t.length>0?t:`unknown`);return h.join(e,`requests`,`${n}.ndjson`)}function bi(e,t={}){let n=xi(e,t);return{baseDir:n,infoPath:h.join(n,`daemon.json`),lockPath:h.join(n,`daemon.lock`),logPath:h.join(n,`daemon.log`),sessionsDir:h.join(n,`sessions`)}}function xi(e,t){let n=(e??``).trim();return n?fe(n,{env:t.env}):Si(t)}function Si(e={}){let t=h.join(pe(`~`,{env:e.env}),`.agent-device`),n=e.projectRoot??de();return Ci(n)?h.join(t,`dev`,wi(n)):t}function Ci(e){return m.existsSync(h.join(e,`package.json`))&&m.existsSync(h.join(e,`src`,`daemon.ts`))}function wi(e){let t=Ti(e),n=h.basename(t).replaceAll(/[^a-zA-Z0-9._-]+/g,`-`),r=Se.createHash(`sha1`).update(t).digest(`hex`).slice(0,12);return`${n||`agent-device`}-${r}`}function Ti(e){try{return m.realpathSync.native(e)}catch{return h.resolve(e)}}function Ei(e){let t=(e??``).trim().toLowerCase();return t===`http`?`http`:t===`dual`?`dual`:`socket`}function Di(e){let t=(e??``).trim().toLowerCase();return t===`auto`?`auto`:t===`socket`?`socket`:t===`http`?`http`:`auto`}function Oi(e){return(e??``).trim().toLowerCase()===`tenant`?`tenant`:`none`}function ki(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}const Ai=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,ji=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,Mi=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`];function Ni(){let e=process.argv[1];return e?Pi(e):`unknown`}function Pi(e,t=de()){try{let n=h.resolve(t),r=[h.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=m.statSync(e);if(!t.isFile())continue;let o=h.relative(n,e)||e;a.push(`${o}:${t.size}:${Math.trunc(t.mtimeMs)}`);let s=m.readFileSync(e,`utf8`);for(let t of Fi(s)){let n=Li(e,t);n&&r.push(n)}}let o=a.sort().join(`|`),s=Se.createHash(`sha1`).update(o).digest(`hex`);return`graph:${a.length}:${s}`}catch{return`unknown`}}function Fi(e){let t=new Set;return Ii(e,Ai,t),Ii(e,ji,t),[...t]}function Ii(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 Li(e,t){let n=h.resolve(h.dirname(e),t),r=X(n);if(r)return r;for(let e of Mi){let t=X(`${n}${e}`);if(t)return t}for(let e of Mi){let t=X(h.join(n,`index${e}`));if(t)return t}return null}function X(e){try{return m.statSync(e).isFile()?e:null}catch{return null}}const Ri=/^[A-Za-z0-9_@%+=:,./-]+$/;function zi(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function Bi(e){return Ri.test(e)?e:zi(e)}const Vi=[/(^|[/\s"'=])dist\/src\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])dist\/src\/internal\/daemon\.js($|[\s"'])/,/(^|[/\s"'=])src\/daemon\.ts($|[\s"'])/];function Hi(e){let t=e.toLowerCase().replaceAll(`\\`,`/`);return t.includes(`agent-device`)?Vi.some(e=>e.test(t)):!1}function Ui(e,t){if(!be(e))return!1;if(t){let n=xe(e);if(!n||n!==t)return!1}let n=ye(e);return n?Hi(n):!1}function Z(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 Wi(e,t){Ui(e,t.expectedStartTime)&&Z(e,`SIGTERM`)&&(await p(e,t.termTimeoutMs)||Z(e,`SIGKILL`)&&await p(e,t.killTimeoutMs))}function Gi(e,t){let n=[],r=e+t.toString(),i=r.indexOf(`
5
5
  `);for(;i!==-1;){let e=r.slice(0,i).trim();r=r.slice(i+1),e&&n.push(e),i=r.indexOf(`
6
- `)}return{lines:n,buffer:r}}function Un(e){return e.meta?.requestProgress===`replay-test`||e.meta?.requestProgress===`command`}function Wn(e){return!!e&&typeof e==`object`&&e.type===`progress`&&!!e.event}function Gn(e){return!!e&&typeof e==`object`&&e.type===`response`&&!!e.response}function Kn(e){return`${JSON.stringify({type:`progress`,event:e})}\n`}function qn(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function Jn(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function Yn(e,t={}){return{ok:!0,service:e,version:re(),rpcProtocolVersion:2,...t.upstream===void 0?{}:{upstream:t.upstream}}}function Z(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 Xn(e){if(p(e))return Z({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(er).flatMap(e=>{let t=Zn(e);return t?[t]:[]}):void 0})}function Zn(e){if(typeof e.ref!=`string`||e.ref.length===0)return;let t=Qn(e);if(t)return{ref:e.ref,...$n(e),...t}}function Qn(e){let t=f(e.rect);if(!t)return;let n=f(e.overlayRect);if(!n)return;let r=se(e.center);return r?{rect:t,overlayRect:n,center:r}:void 0}function $n(e){return typeof e.label==`string`&&e.label.length>0?{label:e.label}:{}}function er(e){return p(e)}const Q=1500;function tr(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function nr(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return rr(t)}function rr(e){if(e.length===0)return;let t=or(e);return{stats:t,...t.p95Ms>=Q?{warning:$(t)}:{}}}function ir(e){let t=e.flatMap(e=>mr(e?.stats));if(t.length===0)return;let n=or(t);return{stats:n,...n.p95Ms>=Q?{warning:$(n)}:{}}}function ar(e){if(!p(e))return;let t=ur(e.stats);if(!t)return;let n=typeof e.warning==`string`?e.warning:void 0;return{stats:t,...n?{warning:n}:{}}}function or(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:sr(t,50),p95Ms:sr(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:Q,...cr(e),...lr(e)}}function sr(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 cr(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function lr(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 ur(e){if(!p(e))return;let t=dr(e);if(t)return{...t,...pr(e)}}function dr(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 fr(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function pr(e){let t=typeof e.platform==`string`?e.platform:void 0,n=p(e.backends)?fr(e.backends):void 0;return{...t?{platform:t}:{},...n?{backends:n}:{}}}function mr(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{ve as $,gn as A,T as B,En as C,Tn as D,wn as E,V as F,Te as G,We as H,Ke as I,Se as J,b as K,Le as L,Zt as M,Xt as N,fn as O,Wt as P,be as Q,D as R,An as S,Cn as T,S as U,P as V,x as W,_e as X,xe as Y,ye as Z,Vn as _,rr as a,me as at,X as b,Yn as c,Kn as d,v as et,qn as f,Bn as g,Hn as h,nr as i,ge as it,hn as j,mn as k,Wn as l,Un as m,ar as n,he as nt,Z as o,Jn as p,y as q,tr as r,pe as rt,Xn as s,ir as t,fe as tt,Gn as u,Ln as v,_n as w,jn as x,Rn as y,w as z};
6
+ `)}return{lines:n,buffer:r}}function Ki(e){return e.meta?.requestProgress===`replay-test`||e.meta?.requestProgress===`command`}function qi(e){return!!e&&typeof e==`object`&&e.type===`progress`&&!!e.event}function Ji(e){return!!e&&typeof e==`object`&&e.type===`response`&&!!e.response}function Yi(e){return`${JSON.stringify({type:`progress`,event:e})}\n`}function Xi(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function Zi(e){return`${JSON.stringify({type:`response`,response:e})}\n`}function Qi(e,t={}){return{ok:!0,service:e,version:ue(),rpcProtocolVersion:2,...t.upstream===void 0?{}:{upstream:t.upstream}}}function $i(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 ea(e){if(u(e))return $i({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(ia).flatMap(e=>{let t=ta(e);return t?[t]:[]}):void 0})}function ta(e){if(typeof e.ref!=`string`||e.ref.length===0)return;let t=na(e);if(t)return{ref:e.ref,...ra(e),...t}}function na(e){let t=c(e.rect);if(!t)return;let n=c(e.overlayRect);if(!n)return;let r=l(e.center);return r?{rect:t,overlayRect:n,center:r}:void 0}function ra(e){return typeof e.label==`string`&&e.label.length>0?{label:e.label}:{}}function ia(e){return u(e)}const Q=1500;function aa(e,t){e&&(e.snapshotDiagnostics??={samples:[]}).samples.push({...t,durationMs:Math.max(0,Math.round(t.durationMs))})}function oa(e){let t=e?.snapshotDiagnostics?.samples;if(!(!t||t.length===0))return sa(t)}function sa(e){if(e.length===0)return;let t=ua(e);return{stats:t,...t.p95Ms>=Q?{warning:$(t)}:{}}}function ca(e){let t=e.flatMap(e=>va(e?.stats));if(t.length===0)return;let n=ua(t);return{stats:n,...n.p95Ms>=Q?{warning:$(n)}:{}}}function la(e){if(!u(e))return;let t=ma(e.stats);if(!t)return;let n=typeof e.warning==`string`?e.warning:void 0;return{stats:t,...n?{warning:n}:{}}}function ua(e){let t=e.map(e=>e.durationMs).sort((e,t)=>e-t);return{count:t.length,p50Ms:da(t,50),p95Ms:da(t,95),maxMs:t[t.length-1]??0,slowThresholdMs:Q,...fa(e),...pa(e)}}function da(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 fa(e){let t=e.map(e=>e.platform).filter(e=>!!e);return new Set(t).size===1?{platform:t[0]}:{}}function pa(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 ma(e){if(!u(e))return;let t=ha(e);if(t)return{...t,..._a(e)}}function ha(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 ga(e){let t=Object.entries(e).filter(e=>typeof e[1]==`number`);return t.length>0?Object.fromEntries(t):void 0}function _a(e){let t=typeof e.platform==`string`?e.platform:void 0,n=u(e.backends)?ga(e.backends):void 0;return{...t?{platform:t}:{},...n?{backends:n}:{}}}function va(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{Re as $,yi as A,O as B,ki as C,Oi as D,Di as E,Tr as F,w as G,D as H,qn as I,rt as J,dt as K,N as L,ti as M,ei as N,hi as O,Jr as P,y as Q,Ut as R,Ni as S,Ei as T,Bt as U,E as V,zt as W,Ye as X,Xe as Y,Je as Z,Wi as _,Oe as _t,sa as a,We as at,Bi as b,De as bt,Qi as c,g as ct,Yi as d,Ae as dt,Ke as et,Xi as f,Me as ft,Ui as g,Te as gt,Gi as h,we as ht,oa as i,He as it,vi as j,_i as k,qi as l,Fe as lt,Ki as m,je as mt,la as n,Be as nt,$i as o,v as ot,Zi as p,Ne as pt,gt as q,aa as r,Ve as rt,ea as s,_ as st,ca as t,ze as tt,Ji as u,Pe as ut,Z as v,Ee as vt,bi as w,Pi as x,zi as y,ke as yt,jt as z};
@@ -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){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
+ 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}const l=new Set([`empty-helper-output`,`system-window-only`,`content-poor-app-window`]);function u(e){if(!e||typeof e!=`object`)return!1;let t=e.details?.androidSnapshotHelperFailureReason;return typeof t==`string`&&l.has(t)}export{a as i,u as n,r,i as t};
@@ -1 +1 @@
1
- import{S as e,_ as t}from"./sdk-contracts.js";import{F as n,j as r}from"./sdk-android-adb.js";import{x as i}from"./sdk-batch.js";import{Gt as a,Ht as o,Jt as s,Xt as c,Zt as l,qn as u,qt as d}from"./tv-remote.js";import{G as f,i as p}from"./snapshot-diagnostics.js";import{c as m,m as h,s as g}from"./sdk-device.js";import{t as _}from"./timeouts.js";import{t as v}from"./runtime.js";import{l as y,n as b,s as x,t as S}from"./context.js";import{i as C}from"./helper.js";import{a as w}from"./runner-client.js";import{$t as T,Ft as E,Jt as D,Kt as O,Nt as k,Pt as A,Zt as j,kt as ee,nn as te,rn as ne,u as re,vn as ie}from"./internal/daemon.js";import{l as ae,n as M}from"./input-actions.js";import{C as N,S as P,b as F,i as I,o as L,x as R}from"./selector-runtime.js";import{promises as z}from"node:fs";import B from"node:os";import V from"node:path";async function H(e,t,n={}){return t===`wait`?await U(e,n.timeoutMs??1e4):t===`get`?q((await K(e))?.alert??null):await W(e,t)}async function U(e,n){let r=Date.now(),i=await G(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,...u(`Alert visible`)}}async function W(e,n){let r=await G(e,c);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=A(r.buttons,n);if(i)return await ae(e,i.x,i.y),J(n,r.alert,i.label);if(n===`dismiss`)return await M(e),J(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 G(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await K(e);if(t)return t;await _(300)}return null}async function K(e){return E((await n(`snapshot_capture`,async()=>await k(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function q(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...u(e?`Alert visible`:`No alert visible`)}}function J(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...u(`Alert ${e}ed`)}}async function oe(e){let{req:t,logPath:n,session:r,device:a}=e,o=se(t.positionals?.[0]),s=r?r.surface===`frontmost-app`?{surface:`frontmost-app`}:{bundleId:r.appBundleId,surface:r.surface}:{},c=y(`alert`,a);if(c)return c;if(r&&ie(t)===`may-invalidate`&&T(r),a.platform===`android`)return Z(e,await H(a,o,{timeoutMs:i(t.positionals?.[1])??1e4}));if(m(a))return await Y(e,o,async e=>await C(e,s));let l=re({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await Y(e,o,async(e,t)=>await w(a,{command:`alert`,action:e,appBundleId:r?.appBundleId,timeoutMs:t},l))}async function Y(e,t,n){if(t===`wait`)return await ce(e,n);let r=t===`accept`||t===`dismiss`?t:`get`;return r===`accept`||r===`dismiss`?await le(e,r,n):Z(e,await n(`get`,l))}function se(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}async function ce(e,t){let n=i(e.req.positionals?.[1])??1e4,r=Date.now(),a=!0;for(;Date.now()-r<n;){try{let i=a?n:X(r,n);return a=!1,Z(e,await t(`get`,i))}catch{}await _(300)}return x(`COMMAND_FAILED`,`alert wait timed out`)}async function le(e,t,n){let r=g(e.device)?l:c,i=Date.now(),a,o=!0;for(;Date.now()-i<c;){try{let a=o?r:X(i,c);return o=!1,Z(e,await n(t,a))}catch(e){a=e;let t=String(e?.message??``).toLowerCase();if(!t.includes(`alert not found`)&&!t.includes(`no alert`))break}await _(300)}throw ue(a)}function X(e,t){return Math.max(1,t-(Date.now()-e))}function Z(e,t){let n=t;return R(e.sessionStore,e.session,e.req,n),{ok:!0,data:n}}function ue(e){return!(e instanceof t)||!de(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 de(e){let t=String(e?.message??``).toLowerCase();return t.includes(`alert not found`)||t.includes(`no alert`)}function fe(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])?x(`INVALID_ARGS`,a):{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:i,device:a,parsed:o}=e,{setting:c,state:l,appBundleId:u,permissionTarget:f,latitude:p,longitude:h}=o,g=y(`settings`,a);if(g)return g;if(m(a)&&!s(c))return x(`INVALID_ARGS`,d(c));let _=u??i?.appBundleId;if(c===`clear-app-state`&&!_)return x(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let v=c===`clear-app-state`?[c,l,_??``]:c===`permission`?[c,l,f??``,t.positionals?.[3]??``,_??``]:c===`location`&&l===`set`?[c,l,p??``,h??``,_??``]:[c,l,_??``];i&&T(i);let C=await b(a,`settings`,v,t.flags?.out,{...S(n,t.flags,_,i?.trace?.outPath)});return R(r,i,t,C??{setting:c,state:l}),{ok:!0,data:C??{setting:c,state:l}}}async function me(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(ye(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await he(t)}}}}async function he(t){try{let e=await z.mkdtemp(V.join(B.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=V.join(e,`snapshot-timeout-overlay-refs.png`),i=_e(await b(t.device,`screenshot`,[n],void 0,{...S(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await z.access(i);let a=await ge(i,t.session);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:i,overlayRefCount:`overlayRefCount`in a?a.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in a?a.overlayRefsAnnotated:void 0}}),a}catch(t){let n=e(t);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function ge(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await ee({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 i=e(n);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:i.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:i.message}}}function _e(e,t){return ve(e)?e.path:t}function ve(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function ye(e){return e.code===`COMMAND_FAILED`?be(e)||xe(e.details?.helper):!1}function be(e){let t=`${e.message}\n${e.hint??``}`;return/Android accessibility snapshots can be blocked/i.test(t)}function xe(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)}async function Se(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 Ce(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 P(i,n,t.flags),s=y(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=ne(t.flags?.snapshotScope,a);return c.ok?we(e.command,a,o)||await N(a,o,async()=>{let s=Te({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 me({error:t,command:e.command,logPath:r,session:a,device:o});if(!n)throw t;return n}return je({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function we(e,t,n){return!g(n)||t?.appBundleId?null:x(`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 Te(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return v({backend:Ae({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...L(`snapshot`),sessions:O({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=Me(e),a=i.get(n);i.set(n,Ee({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:De(t),issuesRefsToClient:t.command===`snapshot`}))}})})}function Ee(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=Oe(t,i,a),s=F({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return s.snapshotScopeSource=$({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),s.snapshotGeneration=o?t?.snapshotGeneration:D(t?.snapshotGeneration),ke(s,o,e.issuesRefsToClient),i.appName&&(s.appName=i.appName),s}function De(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function Oe(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function ke(e,t,n){!t&&n&&j(e)}function $(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function Ae(e){let{req:t,logPath:n,session:r,device:i,snapshotScope:a}=e;return{platform:h(i),captureSnapshot:async(e,s)=>{let c=await te({device:i,session:r,flags:t.flags,outPath:s?.outPath??t.flags?.out,logPath:n,snapshotScope:a}),l=p(r);return{snapshot:c.snapshot,...o(c),...l?{snapshotDiagnostics:l}:{},appName:r?.appBundleId?r.appName??r.appBundleId:void 0,appBundleId:r?.appBundleId}}}}function je(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:Ne(e.result),interactiveObservation:f(e.req)})}function Me(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function Ne(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const Pe={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await Se({req:e,sessionName:t,logPath:n,sessionStore:r}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>e.positionals?.[0]===`snapshot`?await Ce({req:e,sessionName:t,logPath:n,sessionStore:r}):x(`INVALID_ARGS`,`diff currently supports only: diff snapshot`),wait:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await I({req:e,sessionName:t,logPath:n,sessionStore:r}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let{session:i,device:a}=await P(r,t,e.flags);return await N(i,a,async()=>await oe({req:e,logPath:n,sessionStore:r,session:i,device:a}))},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let i=fe(e);if(!i.ok)return i;let{session:a,device:o}=await P(r,t,e.flags);return await N(a,o,async()=>await pe({req:e,logPath:n,sessionStore:r,session:a,device:o,parsed:i.parsed}))}};async function Fe(e){let t=e.req.command,n=Pe[t];return n?await n(e):null}export{Fe as handleSnapshotCommands};
1
+ import{S as e,_ as t}from"./sdk-contracts.js";import{I as n,j as r}from"./sdk-android-adb.js";import{z as i}from"./sdk-batch-runner.js";import{At as a,Dt as o,Et as s,Qn as c,kt as l,wt as u,xt as d}from"./recording-export-quality.js";import{i as f,q as p}from"./snapshot-diagnostics.js";import{c as m,h,s as g}from"./sdk-device.js";import{t as _}from"./timeouts.js";import{i as v}from"./android-system-chrome.js";import{t as y}from"./runtime.js";import{l as b,n as x,s as S,t as C}from"./context.js";import{i as ee}from"./helper.js";import{a as w}from"./runner-client.js";import{Lt as T,Nt as E,Rt as D,Sn as O,Xt as k,en as A,on as te,rn as j,sn as ne,tn as re,u as ie,zt as ae}from"./internal/daemon.js";import{l as oe,n as M}from"./input-actions.js";import{C as N,S as P,b as F,i as I,o as L,x as R}from"./selector-runtime.js";import{promises as z}from"node:fs";import B from"node:os";import V from"node:path";async function H(e,t,n={}){return t===`wait`?await U(e,n.timeoutMs??1e4):t===`get`?q((await K(e))?.alert??null):await W(e,t)}async function U(e,n){let r=Date.now(),i=await G(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,...c(`Alert visible`)}}async function W(e,n){let r=await G(e,l);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=D(r.buttons,n);if(i)return await oe(e,i.x,i.y),J(n,r.alert,i.label);if(n===`dismiss`)return await M(e),J(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 G(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await K(e);if(t)return t;await _(300)}return null}async function K(e){return ae((await n(`snapshot_capture`,async()=>await T(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function q(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...c(e?`Alert visible`:`No alert visible`)}}function J(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...c(`Alert ${e}ed`)}}async function se(e){let{req:t,logPath:n,session:r,device:a}=e,o=ce(t.positionals?.[0]),s=r?r.surface===`frontmost-app`?{surface:`frontmost-app`}:{bundleId:r.appBundleId,surface:r.surface}:{},c=b(`alert`,a);if(c)return c;if(r&&O(t)===`may-invalidate`&&j(r),a.platform===`android`)return Z(e,await H(a,o,{timeoutMs:i(t.positionals?.[1])??1e4}));if(m(a))return await Y(e,o,async e=>await ee(e,s));let l=ie({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await Y(e,o,async(e,t)=>await w(a,{command:`alert`,action:e,appBundleId:r?.appBundleId,timeoutMs:t},l))}async function Y(e,t,n){if(t===`wait`)return await le(e,n);let r=t===`accept`||t===`dismiss`?t:`get`;return r===`accept`||r===`dismiss`?await ue(e,r,n):Z(e,await n(`get`,a))}function ce(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}async function le(e,t){let n=i(e.req.positionals?.[1])??1e4,r=Date.now(),a=!0;for(;Date.now()-r<n;){try{let i=a?n:X(r,n);return a=!1,Z(e,await t(`get`,i))}catch{}await _(300)}return S(`COMMAND_FAILED`,`alert wait timed out`)}async function ue(e,t,n){let r=g(e.device)?a:l,i=Date.now(),o,s=!0;for(;Date.now()-i<l;){try{let a=s?r:X(i,l);return s=!1,Z(e,await n(t,a))}catch(e){o=e;let t=String(e?.message??``).toLowerCase();if(!t.includes(`alert not found`)&&!t.includes(`no alert`))break}await _(300)}throw de(o)}function X(e,t){return Math.max(1,t-(Date.now()-e))}function Z(e,t){let n=t;return R(e.sessionStore,e.session,e.req,n),{ok:!0,data:n}}function de(e){return!(e instanceof t)||!fe(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 fe(e){let t=String(e?.message??``).toLowerCase();return t.includes(`alert not found`)||t.includes(`no alert`)}function pe(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`,u):{ok:!0,parsed:{setting:t,state:n,permissionTarget:r,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}}async function me(e){let{req:t,logPath:n,sessionStore:r,session:i,device:a,parsed:c}=e,{setting:l,state:u,appBundleId:d,permissionTarget:f,latitude:p,longitude:h}=c,g=b(`settings`,a);if(g)return g;if(m(a)&&!o(l))return S(`INVALID_ARGS`,s(l));let _=d??i?.appBundleId;if(l===`clear-app-state`&&!_)return S(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let v=l===`clear-app-state`?[l,u,_??``]:l===`permission`?[l,u,f??``,t.positionals?.[3]??``,_??``]:l===`location`&&u===`set`?[l,u,p??``,h??``,_??``]:[l,u,_??``];i&&j(i);let y=await x(a,`settings`,v,t.flags?.out,{...C(n,t.flags,_,i?.trace?.outPath)});return R(r,i,t,y??{setting:l,state:u}),{ok:!0,data:y??{setting:l,state:u}}}async function he(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 ge(t)}}}}async function ge(t){try{let e=await z.mkdtemp(V.join(B.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=V.join(e,`snapshot-timeout-overlay-refs.png`),i=ve(await x(t.device,`screenshot`,[n],void 0,{...C(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await z.access(i);let a=await _e(i,t.session);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:i,overlayRefCount:`overlayRefCount`in a?a.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in a?a.overlayRefsAnnotated:void 0}}),a}catch(t){let n=e(t);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function _e(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await E({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 i=e(n);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:i.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:i.message}}}function ve(e,t){return ye(e)?e.path:t}function ye(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function be(e){return e.code===`COMMAND_FAILED`?xe(e)||Se(e.details?.helper):!1}function xe(e){let t=`${e.message}\n${e.hint??``}`;return/Android accessibility snapshots can be blocked/i.test(t)}function Se(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)}async function Ce(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,s=v(a.nodes),c=s===a.nodes?a:{...a,nodes:s};return{data:o===void 0?c:{...c,refsGeneration:o},record:{kind:`snapshot`,nodes:a.nodes.length,truncated:a.truncated}}}})}async function we(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 P(i,n,t.flags),s=b(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=ne(t.flags?.snapshotScope,a);return c.ok?Te(e.command,a,o)||await N(a,o,async()=>{let s=Ee({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 he({error:t,command:e.command,logPath:r,session:a,device:o});if(!n)throw t;return n}return Me({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function Te(e,t,n){return!g(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 Ee(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return y({backend:je({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...L(`snapshot`),sessions:k({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=Ne(e),a=i.get(n);i.set(n,De({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:Oe(t),issuesRefsToClient:t.command===`snapshot`}))}})})}function De(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=ke(t,i,a),s=F({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return A(s,{scopeSource:$({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),keptCurrentSnapshot:o,previousGeneration:t?.snapshotGeneration}),Ae(s,o,e.issuesRefsToClient),i.appName&&(s.appName=i.appName),s}function Oe(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function ke(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function Ae(e,t,n){!t&&n&&re(e)}function $(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function je(e){let{req:t,logPath:n,session:r,device:i,snapshotScope:a}=e;return{platform:h(i),captureSnapshot:async(e,o)=>{let s=await te({device:i,session:r,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:a}),c=f(r);return{snapshot:s.snapshot,...d(s),...c?{snapshotDiagnostics:c}:{},appName:r?.appBundleId?r.appName??r.appBundleId:void 0,appBundleId:r?.appBundleId}}}}function Me(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:Pe(e.result),interactiveObservation:p(e.req)})}function Ne(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function Pe(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const Fe={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await Ce({req:e,sessionName:t,logPath:n,sessionStore:r}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>e.positionals?.[0]===`snapshot`?await we({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 I({req:e,sessionName:t,logPath:n,sessionStore:r}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let{session:i,device:a}=await P(r,t,e.flags);return await N(i,a,async()=>await se({req:e,logPath:n,sessionStore:r,session:i,device:a}))},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let i=pe(e);if(!i.ok)return i;let{session:a,device:o}=await P(r,t,e.flags);return await N(a,o,async()=>await me({req:e,logPath:n,sessionStore:r,session:a,device:o,parsed:i.parsed}))}};async function Ie(e){let t=e.req.command,n=Fe[t];return n?await n(e):null}export{Ie as handleSnapshotCommands};
@@ -0,0 +1 @@
1
+ import{t as e}from"./rolldown-runtime.js";import{v as t,w as n}from"./sdk-android-adb.js";import{t as r}from"./scoped-provider.js";import{constants as i}from"node:fs";import a from"node:os";import o from"node:path";import{access as s}from"node:fs/promises";var c=e({createLocalVegaToolProvider:()=>d,resolveVegaToolProvider:()=>f,withVegaToolProvider:()=>p});const l={run:async(e,n)=>await t(await h()??`vega`,e,n),isAvailable:async()=>!!await h()},u=r(d());function d(e=l){return{isAvailable:async()=>await e.isAvailable(),version:async t=>await e.run([`--version`],t),listDevices:async t=>await e.run([`device`,`list`],t),checkConnected:async(t,n)=>await e.run([`device`,`is-connected`,`--device`,t],n),launchApp:async(t,n,r)=>await e.run([`device`,`launch-app`,`--device`,t,`--appName`,n],r),terminateApp:async(t,n,r)=>await e.run([`device`,`terminate-app`,`--device`,t,`--appName`,n],r),pressRemote:async(t,n,r,i)=>await e.run([`device`,`run-cmd`,`--device`,t,`--command`,[`inputd-cli`,`button_press`,n,...r===void 0?[]:[`--holdDuration`,String(r)]].join(` `)],i)}}function f(e){return u.resolve(e)}async function p(e,t){return await u.run(e,t)}let m;async function h(){if(m)return m;if(await n(`vega`))return m=`vega`,m;let e=o.join(a.homedir(),`vega`,`bin`,`vega`);try{await s(e,i.X_OK),m=e}catch{return}return m}export{c as n,f as t};
@@ -0,0 +1 @@
1
+ import{_ as e}from"./sdk-contracts.js";function t(t){let n=async n=>{throw new e(`UNSUPPORTED_OPERATION`,`${n} is not supported on ${t}`)};return{open:()=>n(`open`),openDevice:()=>n(`openDevice`),close:()=>n(`close`),tap:()=>n(`tap`),doubleTap:()=>n(`doubleTap`),longPress:()=>n(`longPress`),focus:()=>n(`focus`),type:()=>n(`type`),fill:()=>n(`fill`),scroll:()=>n(`scroll`),screenshot:()=>n(`screenshot`),snapshot:()=>n(`snapshot`),back:()=>n(`back`),home:()=>n(`home`),setOrientation:()=>n(`setOrientation`),appSwitcher:()=>n(`appSwitcher`),tvRemote:()=>n(`tvRemote`),readClipboard:()=>n(`readClipboard`),writeClipboard:()=>n(`writeClipboard`),setSetting:()=>n(`setSetting`)}}export{t};
package/dist/src/web.js CHANGED
@@ -1 +1 @@
1
- import{_ as e}from"./sdk-contracts.js";import{F as t}from"./sdk-android-adb.js";import{m as n}from"./internal/daemon.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`),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),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`),setOrientation:()=>i(`orientation`),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};
1
+ import{_ as e}from"./sdk-contracts.js";import{I as t}from"./sdk-android-adb.js";import{m as n}from"./internal/daemon.js";import{t as r}from"./unsupported-interactor.js";function i(){let i=()=>n();return{...r(`web`),open:(e,t)=>i().open(t?.url??e,{url:t?.url}),openDevice:()=>i().open(`about:blank`),close:e=>i().close(e),tap:(e,t)=>i().click(e,t),focus:(e,t)=>i().click(e,t),type:(e,t)=>i().typeText(e,{delayMs:t}),fill:(e,t,n,r)=>i().fill(e,t,n,{delayMs:r}),scroll:(e,t)=>i().scroll(e,t),screenshot:(e,t)=>i().screenshot(e,t),setViewport:(e,t)=>i().setViewport(e,t),snapshot:async e=>{let n=await t(`snapshot_capture`,async()=>await i().snapshot(e),{backend:`web`});return{nodes:n.nodes,truncated:n.truncated??!1,backend:`web`}},setOrientation:async()=>{throw new e(`UNSUPPORTED_OPERATION`,`orientation is not supported on web`)}}}export{i as createWebInteractor};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.20.0",
3
+ "version": "0.20.1",
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",
@@ -109,8 +109,8 @@
109
109
  "perf:ios": "node --experimental-strip-types scripts/perf/run.ts --platform ios",
110
110
  "perf:android": "node --experimental-strip-types scripts/perf/run.ts --platform android",
111
111
  "lint": "oxlint . --deny-warnings",
112
- "format": "node ./node_modules/oxfmt/bin/oxfmt --write src test skills package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
113
- "format:check": "node ./node_modules/oxfmt/bin/oxfmt --check src test skills package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
112
+ "format": "node ./node_modules/oxfmt/bin/oxfmt --write src test skills scripts/help-conformance-bench.mjs scripts/help-conformance-case-checks.mjs scripts/help-conformance-command-validator.ts scripts/help-conformance-expectations.mjs scripts/help-conformance-plan-validator.mjs scripts/help-conformance-runner-output.mjs scripts/help-conformance-summary.mjs scripts/help-conformance-cases.mjs scripts/help-conformance-sample-outputs.mjs scripts/__tests__/help-conformance-bench.test.ts scripts/__tests__/help-conformance-sample-outputs.test.ts scripts/__tests__/help-conformance-topic-coverage.test.ts package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
113
+ "format:check": "node ./node_modules/oxfmt/bin/oxfmt --check src test skills scripts/help-conformance-bench.mjs scripts/help-conformance-case-checks.mjs scripts/help-conformance-command-validator.ts scripts/help-conformance-expectations.mjs scripts/help-conformance-plan-validator.mjs scripts/help-conformance-runner-output.mjs scripts/help-conformance-summary.mjs scripts/help-conformance-cases.mjs scripts/help-conformance-sample-outputs.mjs scripts/__tests__/help-conformance-bench.test.ts scripts/__tests__/help-conformance-sample-outputs.test.ts scripts/__tests__/help-conformance-topic-coverage.test.ts package.json tsconfig.json tsconfig.lib.json tsdown.config.ts vitest.config.ts .github/actions/setup-node-pnpm/action.yml .oxlintrc.json .oxfmtrc.json '!test/skillgym/.skillgym-results/**'",
114
114
  "fallow": "fallow audit --base origin/main",
115
115
  "fallow:all": "fallow --summary",
116
116
  "fallow:baseline": "(fallow dead-code --save-baseline fallow-baselines/dead-code.json --summary || true) && (fallow health --save-baseline fallow-baselines/health.json --summary || true)",
@@ -118,6 +118,8 @@
118
118
  "check:affected": "node --experimental-strip-types scripts/check-affected/run.ts",
119
119
  "check:affected:test": "node --experimental-strip-types --test scripts/check-affected/model.test.ts scripts/check-affected/run.test.ts",
120
120
  "check:layering": "node --experimental-strip-types --test scripts/layering/model.test.ts && node --experimental-strip-types scripts/layering/check.ts",
121
+ "depgraph": "node --experimental-strip-types scripts/depgraph/build.ts",
122
+ "depgraph:test": "node --experimental-strip-types --test scripts/depgraph/model.test.ts",
121
123
  "check:production-exports": "fallow dead-code --config fallow-production-exports.json --production --unused-exports --fail-on-issues",
122
124
  "check:bundle-owner-files": "node --experimental-strip-types scripts/check-bundle-owner-files.ts",
123
125
  "check:freerange": "fr",
@@ -125,7 +127,7 @@
125
127
  "sync:mcp-metadata": "node scripts/sync-mcp-metadata.mjs",
126
128
  "check:mcp-metadata": "node scripts/sync-mcp-metadata.mjs --check",
127
129
  "version": "node scripts/sync-mcp-metadata.mjs && git add server.json",
128
- "check:tooling": "pnpm lint && pnpm typecheck && pnpm check:layering && pnpm check:production-exports && pnpm check:mcp-metadata && pnpm build && pnpm check:bundle-owner-files",
130
+ "check:tooling": "pnpm lint && pnpm typecheck && pnpm check:layering && pnpm depgraph:test && pnpm check:production-exports && pnpm check:mcp-metadata && pnpm build && pnpm check:bundle-owner-files",
129
131
  "check:unit": "pnpm test:unit && pnpm test:smoke",
130
132
  "check": "pnpm check:tooling && pnpm check:fallow && pnpm check:unit",
131
133
  "prepack": "pnpm check:mcp-metadata && pnpm build:all && pnpm package:apple-runner:npm && pnpm package:android-snapshot-helper:npm && pnpm package:android-ime-helper:npm",
@@ -140,8 +142,8 @@
140
142
  "test-app:maestro": "node scripts/run-test-app-maestro-suite.mjs",
141
143
  "test-app:maestro:ios": "node scripts/run-test-app-maestro-suite.mjs --platform ios",
142
144
  "test-app:maestro:android": "node scripts/run-test-app-maestro-suite.mjs --platform android",
143
- "test": "vitest run --project unit-core --project android-adb",
144
- "test:unit": "vitest run --project unit-core --project android-adb",
145
+ "test": "vitest run --project unit-core --project subprocess-stub",
146
+ "test:unit": "vitest run --project unit-core --project subprocess-stub",
145
147
  "test:coverage": "vitest run --coverage",
146
148
  "test:integration:provider": "vitest run --project provider-integration",
147
149
  "test:integration:progress": "node --experimental-strip-types scripts/integration-progress.ts",
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.20.0",
10
+ "version": "0.20.1",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "agent-device",
15
- "version": "0.20.0",
15
+ "version": "0.20.1",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agent-device
3
- description: Automates Apple-platform apps (iOS, tvOS, macOS) and Android devices. Use when navigating apps, taking snapshots/screenshots, tapping, typing, scrolling, extracting UI info, collecting logs/network/perf evidence, or planning agent-device CLI commands.
3
+ description: Automates Apple-platform apps (iOS, tvOS, macOS), Android devices, and Amazon Vega OS TV apps in Vega Virtual Devices. Use when navigating apps, taking snapshots/screenshots where supported, driving TV remotes, tapping, typing, scrolling, extracting UI info, collecting evidence, or planning agent-device CLI commands.
4
4
  ---
5
5
 
6
6
  # agent-device
@@ -13,7 +13,7 @@ agent-device --version
13
13
 
14
14
  If that fails but the user may have installed `agent-device` globally, check the user's configured login/interactive shell and environment before using `npx`. Resolve the command the same way the user would from a normal terminal session, then run the absolute binary path if found. This may require inspecting shell startup behavior or package-manager/global bin locations; do not assume the Codex process `PATH` is the user's `PATH`.
15
15
 
16
- Require `agent-device >= 0.19.1`; older CLIs lack these help topics. If older, stop and tell the user to upgrade the trusted install or approve an exact-version npm command. Do not run `npm install -g agent-device@latest` or `npx -y agent-device@latest` autonomously, and do not include version/upgrade commands in final plans.
16
+ Require `agent-device >= 0.20.0`; older CLIs lack the current help topics and Vega OS routing. If older, stop and tell the user to upgrade the trusted install or approve an exact-version npm command. Do not run `npm install -g agent-device@latest` or `npx -y agent-device@latest` autonomously, and do not include version/upgrade commands in final plans.
17
17
 
18
18
  Before your first agent-device command or plan, read the smallest version-matched CLI guide that fits the task:
19
19
 
@@ -34,9 +34,11 @@ agent-device help cdp
34
34
  agent-device help remote
35
35
  agent-device help macos
36
36
  agent-device help dogfood
37
+ agent-device help tv
38
+ agent-device help ios-system-ui # iOS SpringBoard, widgets, and system-UI surfaces
37
39
  ```
38
40
 
39
- Default loop: `open -> snapshot/-i -> get/is/find or press/fill/scroll/wait -> verify -> close`.
41
+ Default loop: `open -> snapshot/-i -> get/is/find or press/fill/scroll/wait -> verify -> close`. When target-specific help says capture or selectors are unsupported, use its control-only loop and the device display as visual truth.
40
42
 
41
43
  Use this skill only to route into version-matched CLI help. Let the selected help topic provide exact command shapes, platform limits, and current workflow guidance; use `help workflow` as the full reference when a task-specific topic is too narrow.
42
44
 
@@ -1 +0,0 @@
1
- 315907205b4d573cbfe4dfa4bcb7bafd360d9f6d93427f255574d7f02ea6656e agent-device-android-ime-helper-0.20.0.apk
@@ -1 +0,0 @@
1
- d635fe2e577ece9d5924719f907232693231644d69ba08b7d21d7bea04baa652 agent-device-android-snapshot-helper-0.20.0.apk
@@ -1 +0,0 @@
1
- const e=18e4,t=6e4,n=6e4,r=2e4,i=12e4,a=1e4,o=15e3,s=2e4,c=2e4,l=1e3,u=5e3;export{c as a,l as c,o as d,i,u as l,e as n,t as o,r,a as s,n as t,s as u};
@@ -1 +0,0 @@
1
- import{i as e,p as t}from"./sdk-device.js";import{n,o as r}from"./host-process.js";import i from"node:crypto";import a from"node:fs";import o from"node:os";import s from"node:path";function c(e,t){let n=i.createHash(`sha256`).update(e).digest(),r=i.createHash(`sha256`).update(t).digest();return i.timingSafeEqual(n,r)}const l={browserStack:`browserstack`,awsDeviceFarm:`aws-device-farm`},u=new Set(Object.values(l));function d(e){return e!==void 0&&u.has(e)}function f(){return{pid:process.pid,startTime:r(process.pid)}}function p(e,t){return e.pid===t.pid&&e.startTime===t.startTime}function m(e){let{owner:t,stateDir:i}=e;if(!n(t.pid)||t.startTime&&r(t.pid)!==t.startTime)return`owner-process-dead`;if(!i)return`live`;try{return a.statSync(i),`live`}catch(e){let t=e?.code;return t===`ENOENT`||t===`ENOTDIR`?`owner-state-dir-gone`:`unknown`}}function h(){let e=process.env.AGENT_DEVICE_CLAIMS_DIR?.trim();return e?s.resolve(e):s.join(o.homedir(),`.agent-device`,`device-claims`)}function g(e){let t=i.createHash(`sha256`).update(e).digest(`hex`);return s.join(h(),`${t}.json`)}function _(e){let t=h(),n=v(t);return`claims`in n?n.claims:n.entries.filter(e=>e.isFile()&&e.name.endsWith(`.json`)).map(e=>C(s.join(t,e.name))).filter(e=>e!==null).filter(t=>y(t.claim,e))}function v(e){try{return{entries:a.readdirSync(e,{withFileTypes:!0})}}catch(t){let n=t.code;return n===`ENOENT`||n===`ENOTDIR`?{claims:[]}:{claims:[{fileName:s.basename(e),classification:`unknown`,error:String(t)}]}}}function y(e,t){return e?[b(e,t.udid??t.serial),x(e,t.device),S(e,t.platform)].every(Boolean):!0}function b(e,t){return!t||e.device.id===t}function x(e,t){return!t||e.device.name===t||e.device.id===t}function S(n,r){return t({...e(n.device.platform),appleOs:n.device.appleOs},r)}function C(e){let t=s.basename(e);try{return w(t,a.readFileSync(e,`utf8`))}catch(e){let n=e.code;return n===`ENOENT`||n===`ENOTDIR`?null:{fileName:t,classification:`unknown`,error:String(e)}}}function w(e,t){try{let n=T(JSON.parse(t));return n?{fileName:e,deviceKey:n.deviceKey,claim:n,classification:m({owner:{pid:n.ownerPid,startTime:n.ownerStartTime},stateDir:n.stateDir})}:{fileName:e,classification:`inconsistent`}}catch(t){return{fileName:e,classification:`inconsistent`,error:String(t)}}}function T(e){if(!E(e))return null;let t=e;return D(t)?t:null}function E(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function D(e){return e.schemaVersion===1&&O(e.device)&&[e.deviceKey,e.session,e.workspace,e.stateDir,e.ownerToken].every(k)&&A(e.ownerPid)&&j(e.createdAtMs)&&j(e.updatedAtMs)}function O(e){if(!E(e))return!1;let t=e;return[t.id,t.name,t.platform,t.kind].every(k)}function k(e){return typeof e==`string`&&e.length>0}function A(e){return typeof e==`number`&&Number.isInteger(e)&&e>0}function j(e){return typeof e==`number`&&Number.isFinite(e)}function M(e,t){let n={providerReleases:{released:t.released.map(I),pending:t.pending.map(I)}},r=F(e),i=`${r}.${process.pid}.${Date.now()}.tmp`;try{a.writeFileSync(i,`${JSON.stringify(n)}\n`,{mode:384}),a.renameSync(i,r),a.chmodSync(r,384)}catch{try{a.rmSync(i,{force:!0})}catch{}}}function N(e){try{let t=JSON.parse(a.readFileSync(F(e),`utf8`));return L(t)?t:null}catch{return null}}function P(e){try{a.rmSync(F(e),{force:!0})}catch{}}function F(e){return s.join(e,`daemon-shutdown.json`)}function I(e){return{leaseId:e.leaseId,...e.leaseProvider?{provider:e.leaseProvider}:{}}}function L(e){if(!e||typeof e!=`object`)return!1;let t=e.providerReleases;if(!t||typeof t!=`object`)return!1;let n=t;return Array.isArray(n.released)&&Array.isArray(n.pending)&&n.released.every(R)&&n.pending.every(R)}function R(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.leaseId==`string`&&t.leaseId.trim().length>0&&(t.provider===void 0||typeof t.provider==`string`)}export{_ as a,p as c,d,c as f,C as i,f as l,N as n,g as o,M as r,m as s,P as t,l as u};
@@ -1,2 +0,0 @@
1
- import{_ as e}from"./sdk-contracts.js";const t=new Set([`id`,`role`,`text`,`label`,`value`,`appname`,`windowtitle`]),n=new Set([`visible`,`hidden`,`editable`,`selected`,`focused`,`enabled`,`hittable`]),r=new Set([...t,...n]),i=[...r],a=new Set(`button.imagebutton.link.cell.statictext.checkedtextview.textfield.textbox.edittext.textarea.switch.slider.image.imageview.webview.framelayout.linearlayout.relativelayout.constraintlayout.viewgroup.view.listview.recyclerview.collectionview.list.searchfield.segmentedcontrol.group.window.checkbox.radio.menuitem.toolbar.scrollarea.scrollview.nestedscrollview.table.application.navigationbar.tabbar.tab.alert.dialog.header`.split(`.`));function o(e){return a.has(e.trim().toLowerCase())}const s=new Map([[`"`,`"`],[`'`,`'`],[`\\`,`\\`],[`/`,`/`],[`b`,`\b`],[`f`,`\f`],[`n`,`
2
- `],[`r`,`\r`],[`t`,` `]]);function c(t){let n=t.trim();if(!n)throw new e(`INVALID_ARGS`,`Selector expression cannot be empty`);let r=re(n);if(r.length===0)throw new e(`INVALID_ARGS`,`Selector expression cannot be empty`);return{raw:n,selectors:r.map(e=>te(e))}}function l(e){try{return c(e)}catch{return null}}function u(e){let t=e.trim();if(!t)return!1;if(t===`||`)return!0;let n=t.indexOf(`=`);if(n!==-1){let e=t.slice(0,n).trim().toLowerCase();return r.has(e)}return r.has(t.toLowerCase())}function ee(e){let t=e.trim(),n=t.indexOf(`=`);if(n===-1)return null;let i=t.slice(0,n).trim().toLowerCase();if(!i||r.has(i))return null;let a=t.slice(n+1).trim();if(!a)return null;let o=p(a).trim();return o?{key:i,value:o}:null}function d(e,t={}){if(e.length===0)return null;let n=t.preferTrailingValue??!1,r=0,i=[];for(;r<e.length;){let t=e[r];if(t===void 0||!u(t))break;r+=1;let n=e.slice(0,r).join(` `).trim();n&&l(n)&&i.push(r)}if(i.length===0)return null;let a=i.at(-1);if(a===void 0)return null;let o=a;if(n)for(let t=i.length-1;t>=0;--t){let n=i[t];if(n!==void 0&&n<e.length){o=n;break}}let s=e.slice(0,o).join(` `).trim();return s?{selectorExpression:s,rest:e.slice(o)}:null}function te(t){let n=t.trim();if(!n)throw new e(`INVALID_ARGS`,`Selector segment cannot be empty`);let r=ie(n);if(r.length===0)throw new e(`INVALID_ARGS`,`Invalid selector segment: ${t}`);return{raw:n,terms:r.map(ne)}}function ne(t){let i=t.trim();if(!i)throw new e(`INVALID_ARGS`,`Empty selector term`);let a=i.indexOf(`=`);if(a===-1){let r=i.toLowerCase();if(!n.has(r))throw new e(`INVALID_ARGS`,`Invalid selector term "${t}", expected key=value`);return{key:r,value:!0}}let o=i.slice(0,a).trim().toLowerCase(),s=i.slice(a+1).trim();if(!r.has(o))throw new e(`INVALID_ARGS`,`Unknown selector key: ${o}`);if(!s)throw new e(`INVALID_ARGS`,`Missing selector value for key: ${o}`);if(n.has(o)){let t=se(s);if(t===null)throw new e(`INVALID_ARGS`,`Invalid boolean value for ${o}: ${s}`);return{key:o,value:t}}return{key:o,value:p(s)}}function re(t){let n=[],r=``,i=null;for(let a=0;a<t.length;a+=1){let o=t[a];if((o===`"`||o===`'`)&&!m(t,a)){i=f(i,o),r+=o;continue}if(!i&&o===`|`&&t[a+1]===`|`){let i=r.trim();if(!i)throw new e(`INVALID_ARGS`,`Invalid selector fallback expression: ${t}`);n.push(i),r=``,a+=1;continue}r+=o}let a=r.trim();if(!a)throw new e(`INVALID_ARGS`,`Invalid selector fallback expression: ${t}`);return n.push(a),n}function ie(t){let n=[],r=``,i=null;for(let e=0;e<t.length;e+=1){let a=t.charAt(e);if((a===`"`||a===`'`)&&!m(t,e)){i=f(i,a),r+=a;continue}if(!i&&/\s/.test(a)){r.trim()&&n.push(r.trim()),r=``;continue}r+=a}if(i)throw new e(`INVALID_ARGS`,`Unclosed quote in selector: ${t}`);return r.trim()&&n.push(r.trim()),n}function f(e,t){return e?e===t?null:e:t}function p(e){let t=e.trim();return t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?ae(t.slice(1,-1)):t}function ae(e){let t=``,n=0;for(;n<e.length;){let r=e.charAt(n);if(r!==`\\`){t+=r,n+=1;continue}let i=e.charAt(n+1);if(!i){t+=r,n+=1;continue}let a=oe(i);if(a!==null){t+=a,n+=2;continue}if(i===`u`){let r=e.slice(n+2,n+6);if(/^[0-9a-fA-F]{4}$/.test(r)){t+=String.fromCharCode(Number.parseInt(r,16)),n+=6;continue}}t+=r,n+=1}return t}function oe(e){return s.get(e)??null}function se(e){let t=p(e).toLowerCase();return t===`true`?!0:t===`false`?!1:null}function m(e,t){let n=0;for(let r=t-1;r>=0&&e[r]===`\\`;--r)n+=1;return n%2==1}const ce=[`any`,`text`,`label`,`value`,`role`,`id`],le=[`text`,`label`,`value`,`role`,`id`];function h(e){return e===`exists`||e===`wait`||e===`get_text`||e===`get_attrs`}function ue(e,t,n,r={}){let i=_(n);if(!i)return{matches:[],score:0};let a=0,o=[];for(let n of e){if(r.requireRect&&!n.rect)continue;let e=de(n,t,i);if(!(e<=0)){if(e>a){a=e,o.length=0,o.push(n);continue}e===a&&o.push(n)}}return{matches:o,score:a}}function de(e,t,n){switch(t){case`role`:return fe(e.type,n);case`label`:return g(e.label,n);case`value`:return g(e.value,n);case`id`:return g(e.identifier,n);default:return Math.max(g(e.label,n),g(e.value,n),g(e.identifier,n))}}function g(e,t){let n=_(e??``);return n?n===t?2:+!!n.includes(t):0}function fe(e,t){let n=pe(e??``);return n?n===t?2:+!!n.includes(t):0}function _(e){return e.trim().toLowerCase().replace(/\s+/g,` `)}function pe(e){let t=e.trim();return t?(t=(t.split(`.`).pop()??t).replace(/XCUIElementType/gi,``).toLowerCase(),t):``}function v(t){let n=`any`,r=0;le.includes(t[0])&&(n=t[0],r=1);let i=t[r]??``,a=t.slice(r+1);if(a.length===0)return{locator:n,query:i,action:`click`};let o=a[0]?.toLowerCase();if(o===`get`){let t=a[1]?.toLowerCase();if(t===`text`)return{locator:n,query:i,action:`get_text`};if(t===`attrs`)return{locator:n,query:i,action:`get_attrs`};throw new e(`INVALID_ARGS`,`find get only supports text or attrs`)}if(o===`wait`){let e=he(a[1]);return{locator:n,query:i,action:`wait`,timeoutMs:e??void 0}}if(o===`exists`)return{locator:n,query:i,action:`exists`};if(o===`click`)return{locator:n,query:i,action:`click`};if(o===`focus`)return{locator:n,query:i,action:`focus`};if(o===`fill`){let e=a.slice(1).join(` `);return{locator:n,query:i,action:`fill`,value:e}}if(o===`type`){let e=a.slice(1).join(` `);return{locator:n,query:i,action:`type`,value:e}}throw new e(`INVALID_ARGS`,`Unsupported find action: ${a[0]}`)}function me(e,t){return e!==`any`||!t.includes(`=`)&&!t.includes(`||`)?null:l(t)}function he(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function y(e){if(!e)return null;let t=Number(e);return Number.isFinite(t)?t:null}function b(e){let t=e[0];if(t===void 0)return null;let n=y(t);if(n!==null)return{kind:`sleep`,durationMs:n};let r=y(e[e.length-1]);if(t===`text`)return{kind:`text`,text:(r===null?e.slice(1).join(` `):e.slice(1,-1).join(` `)).trim(),timeoutMs:r};if(t===`stable`){let t=e.slice(1),n=t.length>1?y(t[1]):null;return{kind:`stable`,quietMs:t.length>0?y(t[0]):null,timeoutMs:n}}if(t.startsWith(`@`))return{kind:`ref`,rawRef:t,timeoutMs:r};let i=d(r===null?e.slice():e.slice(0,-1));return i&&i.rest.length===0&&l(i.selectorExpression)?{kind:`selector`,selectorExpression:i.selectorExpression,timeoutMs:r}:{kind:`text`,text:(r===null?e.join(` `):e.slice(0,-1).join(` `)).trim(),timeoutMs:r}}function ge(e){let t=b(e);return t?t.kind===`sleep`?t.durationMs:t.timeoutMs:null}const x=24e4,S={budget:{source:`none`},envelopeMs:9e4,onTimeout:`reset-daemon`},_e={click:`settle-and-verify`,press:`settle-and-verify`,fill:`settle-and-verify`,longpress:`settle`};function C(e){if(e!==void 0)return _e[e]}const w={leaseAdmissionExempt:!0,sessionExecutionLockExempt:!0},T={leaseAdmissionExempt:!0,sessionExecutionLockExempt:!0,selectorValidationExempt:!0},E=()=>!0,ve=e=>(e.positionals?.[0]??``).toLowerCase()===`start`,D=e=>e.command===`test`&&(typeof e.flags?.shardAll==`number`||typeof e.flags?.shardSplit==`number`),O=new Set([`status`,`get`]),ye=e=>A(e,O,`status`),k=new Set([`get`,`wait`]),be=e=>A(e,k,`get`),xe=e=>j(e,O,`status`),Se=e=>j(e,k,`get`),Ce=e=>{try{return h(v(e.positionals??[]).action)?`observes-app`:`mutates-app`}catch{return`mutates-app`}};function A(e,t,n){return t.has((e.positionals?.[0]??n).toLowerCase())?`preserve`:`may-invalidate`}function j(e,t,n){return t.has((e.positionals?.[0]??n).toLowerCase())?`observes-app`:`mutates-app`}const M={simulator:!0,device:!0},N={emulator:!0,device:!0,unknown:!0},P={device:!0},F={},I={apple:M,android:N,linux:P},L=I,we={apple:M,android:N,linux:F},R={apple:M,android:N,linux:F},z={recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`generic`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:P},timeoutPolicy:S,batchable:!0},B={...S,onTimeout:`preserve-daemon`},V={...S,envelopeMs:18e4},H={...S,budget:{source:`flag`,envelope:`widen`,defaultBudgetMs:1e4},onTimeout:`preserve-daemon`},U={fields:{count:{defaultValue:1,omitDefault:!0},intervalMs:{defaultValue:0,omitDefault:!0},holdMs:{defaultValue:0,omitDefault:!0},jitterPx:{defaultValue:0,omitDefault:!0},doubleTap:{defaultValue:!1,omitDefault:!0}}},Te={fields:{delayMs:{defaultValue:0}}};function W(e){return C(e)===void 0?B:H}function G(e){let t=C(e);if(t===void 0)throw Error(`Missing post-action observation descriptor support for ${e}`);return t}const K=[{name:`lease_allocate`,catalog:{group:`internal`,key:`leaseAllocate`},recordsSessionAction:!1,daemon:{route:`lease`,refFrameEffect:`preserve`,...w},timeoutPolicy:S,batchable:!1},{name:`lease_heartbeat`,catalog:{group:`internal`,key:`leaseHeartbeat`},recordsSessionAction:!1,daemon:{route:`lease`,refFrameEffect:`preserve`,...w},timeoutPolicy:S,batchable:!1},{name:`lease_release`,catalog:{group:`internal`,key:`leaseRelease`},recordsSessionAction:!1,daemon:{route:`lease`,refFrameEffect:`preserve`,...w},timeoutPolicy:S,batchable:!1},{name:`artifacts`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`lease`,refFrameEffect:`preserve`,...w},timeoutPolicy:S,batchable:!1},{name:`session_list`,catalog:{group:`internal`,key:`sessionList`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`inventory`,...T},timeoutPolicy:S,batchable:!1},{name:`session_save_script`,catalog:{group:`internal`,key:`sessionSaveScript`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`publication`},timeoutPolicy:S,batchable:!1},{name:`devices`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`inventory`,lockPolicySelectorOverride:!0,...T},timeoutPolicy:S,batchable:!0},{name:`capabilities`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`inventory`,lockPolicySelectorOverride:!0,preferExplicitDeviceOverExistingSession:!0,...T},timeoutPolicy:S,batchable:!0},{name:`doctor`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`inventory`,lockPolicySelectorOverride:!0,allowSessionlessDefaultDevice:E,...T},timeoutPolicy:S,batchable:!0},{name:`apps`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`inventory`,lockPolicySelectorOverride:!0,preferExplicitDeviceOverExistingSession:!0},capability:we,timeoutPolicy:S,batchable:!0},{name:`boot`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`may-invalidate`,sessionKind:`state`},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`shutdown`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`may-invalidate`,sessionKind:`state`},capability:{apple:{simulator:!0},android:{emulator:!0},linux:F},timeoutPolicy:S,batchable:!0},{name:`appstate`,catalog:{group:`public`,key:`appState`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`state`},timeoutPolicy:S,batchable:!0},{name:`perf`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`observability`},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`logs`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`observability`},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`events`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`observability`,allowInvalidRecording:!0,...T},timeoutPolicy:S,batchable:!1},{name:`network`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`observability`},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`audio`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,sessionKind:`observability`},capability:{apple:M,android:{emulator:!0},linux:F},timeoutPolicy:S,batchable:!0},{name:`replay`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`delegated`,sessionKind:`replay`,skipSessionlessProviderDevice:D},timeoutPolicy:{...S,budget:{source:`flag`}},batchable:!1},{name:`test`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`delegated`,sessionKind:`replay`,skipSessionlessProviderDevice:D},timeoutPolicy:{...S,envelopeMs:`unbounded`},batchable:!0},{name:`runtime`,catalog:{group:`internal`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`},timeoutPolicy:S,batchable:!1},{name:`clipboard`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`session`,refFrameEffect:`preserve`},dispatch:{},capability:{apple:M,android:N,linux:P},timeoutPolicy:S,batchable:!0},{name:`keyboard`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:xe,daemon:{route:`session`,refFrameEffect:ye,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`install`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`},capability:R,timeoutPolicy:V,batchable:!0},{name:`reinstall`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`},capability:R,timeoutPolicy:V,batchable:!0},{name:`install_source`,catalog:{group:`internal`,key:`installSource`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`},timeoutPolicy:V,batchable:!1},{name:`release_materialized_paths`,catalog:{group:`internal`,key:`releaseMaterializedPaths`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`,...T},timeoutPolicy:S,batchable:!1},{name:`push`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`},dispatch:{},capability:{apple:{simulator:!0},android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`trigger-app-event`,catalog:{group:`public`,key:`triggerAppEvent`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`open`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`,allowSessionlessDefaultDevice:E},dispatch:{},capability:L,timeoutPolicy:S,batchable:!0},{name:`prepare`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`preserve`},timeoutPolicy:{budget:{source:`flag`},envelopeMs:x,onTimeout:`reset-daemon`},batchable:!1,mcpExposed:!1},{name:`batch`,catalog:{group:`public`},recordsSessionAction:!1,daemon:{route:`session`,refFrameEffect:`delegated`},timeoutPolicy:S,batchable:!1},{name:`close`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`session`,refFrameEffect:`may-invalidate`,allowInvalidRecording:!0},dispatch:{},capability:L,timeoutPolicy:S,batchable:!0},{name:`snapshot`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`snapshot`,refFrameEffect:`preserve`},dispatch:{},capability:I,timeoutPolicy:{...B,budget:{source:`flag`}},batchable:!0},{name:`diff`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`snapshot`,refFrameEffect:`preserve`},capability:I,timeoutPolicy:S,batchable:!0},{name:`wait`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`snapshot`,refFrameEffect:`preserve`},capability:I,timeoutPolicy:{...B,budget:{source:`positional-parser`,parser:ge}},batchable:!0},{name:`alert`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:Se,daemon:{route:`snapshot`,refFrameEffect:be},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`settings`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`snapshot`,refFrameEffect:`may-invalidate`},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`react-native`,catalog:{group:`public`,key:`reactNative`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`reactNative`,refFrameEffect:`may-invalidate`},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`record`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`recordTrace`,refFrameEffect:`preserve`,allowInvalidRecording:!0,allowSessionlessDefaultDevice:ve},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`trace`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`recordTrace`,refFrameEffect:`preserve`},timeoutPolicy:S,batchable:!0},{name:`find`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:Ce,daemon:{route:`find`,refFrameEffect:`may-invalidate`},capability:I,timeoutPolicy:B,batchable:!0},{name:`click`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},capability:{apple:M,android:N,linux:P},timeoutPolicy:W(`click`),postActionObservation:G(`click`),responseDataTransform:U,batchable:!0},{name:`fill`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:P},timeoutPolicy:W(`fill`),postActionObservation:G(`fill`),responseDataTransform:Te,batchable:!0},{name:`longpress`,catalog:{group:`public`,key:`longPress`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:P},timeoutPolicy:{...H,envelopeMs:21e4},postActionObservation:G(`longpress`),batchable:!0},{name:`press`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:P},timeoutPolicy:W(`press`),postActionObservation:G(`press`),responseDataTransform:U,batchable:!0},{name:`type`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:I,timeoutPolicy:W(`type`),batchable:!0},{name:`get`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`interaction`,refFrameEffect:`preserve`},capability:I,timeoutPolicy:W(`get`),batchable:!0},{name:`read`,catalog:{group:`dispatch-alias`},recordsSessionAction:!1,dispatch:{},timeoutPolicy:S,batchable:!1},{name:`is`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`interaction`,refFrameEffect:`preserve`},capability:I,timeoutPolicy:W(`is`),batchable:!0},{name:`back`,catalog:{group:`public`},...z},{name:`gesture`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},capability:I,timeoutPolicy:S,batchable:!0},{name:`home`,catalog:{group:`public`},...z},{name:`tv-remote`,catalog:{group:`public`,key:`tvRemote`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`generic`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`orientation`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`generic`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`scroll`,catalog:{group:`public`},...z},{name:`swipe`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`interaction`,refFrameEffect:`may-invalidate`,androidBlockingDialogGuard:!0},capability:{apple:M,android:N,linux:P},timeoutPolicy:S,batchable:!0},{name:`focus`,catalog:{group:`public`},...z},{name:`screenshot`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`observes-app`,daemon:{route:`generic`,refFrameEffect:`preserve`},dispatch:{},capability:I,timeoutPolicy:S,batchable:!0},{name:`viewport`,catalog:{group:`public`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`generic`,refFrameEffect:`may-invalidate`},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!1},{name:`app-switcher`,catalog:{group:`public`,key:`appSwitcher`},recordsSessionAction:!0,recordingEffect:`mutates-app`,daemon:{route:`generic`,refFrameEffect:`may-invalidate`},dispatch:{},capability:{apple:M,android:N,linux:F},timeoutPolicy:S,batchable:!0},{name:`install-from-source`,catalog:{group:`public`,key:`installFromSource`},recordsSessionAction:!0,recordingEffect:`mutates-app`,capability:R,timeoutPolicy:S,batchable:!0},{name:`debug`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1},{name:`daemon`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`device`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`metro`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1},{name:`session`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1},{name:`cdp`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`auth`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`connect`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`connection`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`disconnect`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`mcp`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`proxy`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`react-devtools`,catalog:{group:`local-cli`,key:`reactDevtools`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1},{name:`web`,catalog:{group:`local-cli`},recordsSessionAction:!1,timeoutPolicy:S,batchable:!1,mcpExposed:!1}],Ee=new Set([`public`,`local-cli`]),q=new Set(K.filter(e=>Ee.has(X(e))).map(e=>e.name)),J=K.map(e=>({...e,mcpExposed:Ae(e)}));function De(e){return J.filter(t=>X(t)===e).map(e=>[Me(e),e.name])}function Oe(){return J.filter(e=>je(e)).map(e=>e.name).sort()}const Y=new Map(J.map(e=>[e.name,e]));function ke(e){return q.has(e)}function Ae(e){return e.mcpExposed??q.has(e.name)}function je(e){return e.mcpExposed&&ke(e.name)}function X(e){return e.catalog.group}function Me(e){return e.catalog.key??e.name}const Ne=new Map(J.map(e=>[e.name,e.timeoutPolicy])),Z=new Map(Array.from(Y.values()).flatMap(e=>e.responseDataTransform?[[e.name,e.responseDataTransform]]:[]));function Q(e){if(e!==void 0)return Y.get(e)?.postActionObservation}function Pe(e){return Q(e)!==void 0}function Fe(e){return Q(e)===`settle-and-verify`}function Ie(e){return e===void 0?S:Ne.get(e)??S}function Le(e){if(e!==void 0)return Z.get(e)}function Re(e){return e===void 0?!1:Y.get(e)?.recordsSessionAction??!1}function ze(e){let t=Y.get(e.command);if(t?.recordsSessionAction)return typeof t.recordingEffect==`function`?t.recordingEffect(e):t.recordingEffect}function Be(){return[...new Set(Array.from(Z.values()).flatMap(e=>Object.keys(e.fields)))].sort()}function Ve(e){let t=[];for(let n of e)n.daemon&&t.push({command:n.name,...n.daemon,replayScopedAction:n.recordsSessionAction});return t}function He(e){let t={};for(let n of e)n.capability&&(t[n.name]=n.capability);return t}function Ue(e){return e.filter(e=>e.batchable).map(e=>e.name)}const $=Ue(J),We=new Set([`batch`,`replay`]),Ge=[`command`,`positionals`,`input`,`flags`,`runtime`],Ke=[`platform`,`target`,`device`,`udid`,`serial`,`verbose`,`out`],qe=new Set($);function Je(e){return qe.has(e)}function Ye(e){return typeof e==`string`?e.trim().toLowerCase():``}function Xe(t,n){let r=Ye(t);if(Je(r))return r;throw new e(`INVALID_ARGS`,`Batch step ${n} command is not available through command batch: ${String(t)}`)}function Ze(t,n){if(We.has(t))throw new e(`INVALID_ARGS`,`Batch step ${n} cannot run ${t}.`)}export{o as A,ue as C,me as D,v as E,c as M,d as N,i as O,l as P,ce as S,_ as T,Le as _,Ye as a,b,Ve as c,Fe as d,Be as f,Re as g,ze as h,Ze as i,u as j,ee as k,J as l,Oe as m,Ke as n,Xe as o,De as p,$ as r,He as s,Ge as t,Pe as u,Ie as v,h as w,y as x,x as y};