agent-device 0.20.0 → 0.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.apk → agent-device-android-ime-helper-0.20.2.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.2.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.0.manifest.json → agent-device-android-ime-helper-0.20.2.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.apk → agent-device-android-snapshot-helper-0.20.2.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.2.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.0.manifest.json → agent-device-android-snapshot-helper-0.20.2.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +2 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +30 -16
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -21
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +8 -3
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Orientation.swift +92 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +4 -2
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +1 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-input-method-overlays.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +5 -5
- package/dist/src/app-log-request-scope.js +1 -1
- package/dist/src/app-resolution.js +1 -1
- package/dist/src/apple-multitouch-support.js +1 -1
- package/dist/src/apps.js +5 -5
- package/dist/src/boot-diagnostics.js +2 -2
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +81 -24
- package/dist/src/cli-runner.js +1 -1
- package/dist/src/cli.js +14 -14
- package/dist/src/click-button.d.ts +5 -0
- package/dist/src/client-metro.js +1 -0
- package/dist/src/command-metadata.js +1 -1
- package/dist/src/command-schema.js +3 -3
- package/dist/src/compatibility-policy.js +1 -0
- package/dist/src/context.js +1 -1
- package/dist/src/contracts.d.ts +2 -2
- package/dist/src/debug-symbols.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device.js +9 -0
- package/dist/src/devices2.js +1 -1
- package/dist/src/devices4.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic.js +1 -1
- package/dist/src/gesture-plan-types.js +1 -0
- package/dist/src/gesture-plan.js +1 -0
- package/dist/src/index.d.ts +1205 -1309
- package/dist/src/input-actions.js +4 -4
- package/dist/src/install-artifact.js +5 -1
- package/dist/src/install-artifact2.js +1 -0
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction.d.ts +3 -6
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +2 -2
- package/dist/src/interactor2.js +1 -0
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +14 -22
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun.d.ts +361 -0
- package/dist/src/limrun.js +1 -0
- package/dist/src/linux.js +1 -1
- package/dist/src/logcat.js +1 -5
- package/dist/src/method-scope.js +1 -0
- package/dist/src/metro.d.ts +72 -3
- package/dist/src/metro.js +1 -1
- package/dist/src/metro2.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/physical-device-control.js +1 -0
- package/dist/src/plist.js +1 -0
- package/dist/src/react-native.js +1 -1
- package/dist/src/recording-export-quality.js +15 -0
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +24 -24
- package/dist/src/remote-config.d.ts +5 -2
- package/dist/src/remote-config.js +1 -1
- package/dist/src/remote-config2.js +1 -0
- package/dist/src/reporting.js +8 -8
- package/dist/src/runner-client.js +1 -1
- package/dist/src/runner-disposal.js +1 -2
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runner-provider.js +1 -1
- package/dist/src/runtime-transport.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +1 -1
- package/dist/src/sdk-android-adb.d.ts +4 -24
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-batch-runner.d.ts +13 -3
- package/dist/src/sdk-batch-runner.js +3 -2
- package/dist/src/sdk-contracts.d.ts +31 -91
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-device.js +1 -1
- package/dist/src/sdk-finders.d.ts +3 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.d.ts +83 -53
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selector-vocabulary.js +1 -1
- package/dist/src/selectors.d.ts +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +8 -8
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-diagnostics.js +4 -4
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/tool-provider.js +3 -3
- package/dist/src/tool-provider2.js +1 -1
- package/dist/src/tool-provider3.js +1 -0
- package/dist/src/tv-remote.d.ts +213 -0
- package/dist/src/unsupported-interactor.js +1 -0
- package/dist/src/web.js +1 -1
- package/dist/src/xml.js +2 -0
- package/package.json +41 -19
- package/server.json +2 -2
- package/skills/agent-device/SKILL.md +5 -3
- package/smithery.yaml +1 -1
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +0 -1
- package/dist/src/android-system-chrome.js +0 -1
- package/dist/src/client-metro-companion.js +0 -1
- package/dist/src/config.js +0 -1
- package/dist/src/daemon-shutdown-report.js +0 -1
- package/dist/src/project-runtime.js +0 -1
- package/dist/src/scoped-provider.js +0 -1
- package/dist/src/sdk-batch.js +0 -2
- package/dist/src/snapshot-quality.js +0 -1
- package/dist/src/tv-remote.js +0 -15
package/dist/src/simulator.js
CHANGED
|
@@ -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{
|
|
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{a as c,i as l}from"./tool-provider.js";import{I as u,L as d,M as f,f as p,u as m}from"./physical-device-control.js";var h=e({SIMULATOR_BOOTED_MEMO_TTL_MS:()=>v,ensureBootedSimulator:()=>E,getSimulatorState:()=>O,markSimulatorBooted:()=>S,openIosSimulatorApp:()=>T,requireSimulatorDevice:()=>w,shutdownSimulator:()=>D});const g=[`Simulator`],_=[`Device Hub`,`Simulator`],v=5e3,y=f({ttlMs:v});function b(e){return`${e.id}|${e.simulatorSetPath??``}`}function x(e){return y.get(b(e))===!0}function S(e){y.set(b(e),!0)}function C(e){y.delete(b(e))}function w(e,n){if(e.kind!==`simulator`)throw new t(`UNSUPPORTED_OPERATION`,`${n} is only supported on iOS simulators`)}async function T(e={}){let t=e.deviceHub?_:g,n=e.background?[`-g`,`-a`]:[`-a`];for(let e of t)if((await l(`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(m),f,p;try{await i(async({deadline:i})=>{if(i?.isExpired())throw new t(`COMMAND_FAILED`,`iOS simulator boot deadline exceeded`,{timeoutMs:m});let a=Math.max(1e3,i?.remainingMs()??18e4);f=await c(d(e,[`boot`,e.id]),{allowFailure:!0,timeoutMs:a});let o=`${f.stdout}\n${f.stderr}`.toLowerCase(),s=o.includes(`already booted`)||o.includes(`current state: booted`);if(f.exitCode!==0&&!s)throw new t(`COMMAND_FAILED`,`simctl boot failed`,r(f));p=await c(d(e,[`bootstatus`,e.id,`-b`]),{allowFailure:!0,timeoutMs:a}),n(p,`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:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});return t!==`IOS_BOOT_TIMEOUT`&&t!==`CI_RESOURCE_STARVATION_SUSPECTED`}},{deadline:u,phase:`boot`,classifyReason:e=>a({error:e,stdout:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}})})}catch(n){let r=a({error:n,stdout:p?.stdout??f?.stdout,stderr:p?.stderr??f?.stderr,context:{platform:`ios`,phase:`boot`}});throw new t(`COMMAND_FAILED`,`iOS simulator failed to boot`,{platform:`ios`,deviceId:e.id,timeoutMs:m,elapsedMs:u.elapsedMs(),reason:r,hint:s(r),boot:f,bootstatus:p})}S(e),await T({deviceHub:l.deviceHub})}async function D(e){C(e);let t=await c(d(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 c(typeof e==`string`?u([`list`,`devices`,`-j`]):d(e,[`list`,`devices`,`-j`]),{allowFailure:!0,timeoutMs:p});if(n.exitCode!==0)return null;try{let e=JSON.parse(n.stdout);for(let n of Object.values(e.devices??{})){let e=n.find(e=>e.udid===t);if(e)return e.state}return null}catch{return null}}export{D as a,w as i,O as n,h as o,S as r,E as t};
|
|
@@ -1,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{Cn as ee,Dn as te,On as d,bn as ne,cn as re,fn as ie,gn as f,mn as ae,on as oe,vn as se}from"./recording-export-quality.js";import{n as ce,t as le}from"./version.js";import{n as ue,t as de}from"./path-resolution.js";import{h as fe,n as pe,r as me,t as he}from"./sdk-device.js";import{mt as ge}from"./sdk-selectors.js";import{C as _e,M as ve}from"./gesture-plan-types.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 ue(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`&<(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`,...ne,`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));ee(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?[ge(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=${fe(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 d.devices:return Tn(n.devices);case d.apps:return En(n.apps,e.flags?.appsFilter);case d.boot:return Dn(`Booted`,n,!0);case d.shutdown:return Dn(`Shut down`,n,!1);case d.install:return On(`Installed`,n);case d.reinstall:return On(`Reinstalled`,n);case d.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===d.reinstall?`Reinstalled`:`Installed`} ${Jn(e.result??{})??`app`}`}function Gn(e){let t=e.result??{};switch(e.command){case d.scroll:return Xn(t);case d.screenshot:return $n(t);case d.home:return`Went home`;case d.back:return tr(t);case d.appSwitcher:return`Opened app switcher`;case d.orientation:return nr(t);case d.viewport:return rr(t);case d.clipboard:return ir(t);case d.keyboard:return ar(t);case d.tvRemote:return sr(t);case d.gesture:return cr(t);case d.swipe:return lr(t);case d.trace:return dr(`trace`,e);case d.record:return dr(`recording`,e);default:return}}function Kn(e){let t=e.result??{};switch(e.command){case d.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 d.screenshot:return B({requestedFileName:er(t)});case d.back:return B({mode:z(t.mode,f)});case d.orientation:return B({orientation:z(t.orientation,oe)});case d.viewport:return B({width:U(t.width),height:U(t.height)});case d.clipboard:return B({action:z(t.action,[`read`,`write`])});case d.keyboard:return or(t);case d.tvRemote:return B({button:z(t.button,_e),durationMs:U(t.durationMs)});case d.gesture:case d.swipe:return ur(t);case d.trace:case d.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!==d.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,f)===`system`?`Went back using system navigation`:`Went back`}function nr(e){let t=z(e.orientation,oe);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,_e);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 d.open:return`Opened ${W(e)??`session`}`;case d.close:return`Closed ${L(e.result?.session)??`session`}`;case d.click:case d.press:return`Tapped ${W(e)??`target`}`;case d.longPress:return`Long pressed ${W(e)??`target`}`;case d.fill:return`Filled ${W(e)??`target`}`;case d.type:return`Typed text`;case d.install:case d.reinstall:case te.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,me),target:z(t.target,he),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===d.snapshot?{...Array.isArray(t.nodes)?{nodeCount:t.nodes.length}:{}}:e.command!==d.wait&&e.command!==d.find&&e.command!==d.get&&e.command!==d.is?{}:B({waitedMs:U(t.waitedMs),found:R(t.found)})}function br(e){return e===d.click||e===d.press||e===d.longPress||e===d.focus||e===d.fill}function xr(e){return e===d.open||e===d.install||e===d.reinstall||e===te.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===d.type?[K(`text`)]:e.command===d.fill?Er(e):e.command===d.find?Dr(e):e.command===d.clipboard?Or(e):e.command===d.push?kr(e,`app`,`payload`):e.command===d.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:pe},{source:`target`,values:he}]},Fr={[d.open]:{booleans:[{source:`relaunch`},{source:`testIme`}],enums:[{source:`surface`,values:ie}]},[d.click]:q(),[d.press]:q(),[d.longPress]:q(),[d.fill]:Lr(),[d.type]:Lr(),[d.scroll]:{numbers:[{source:`pixels`},{source:`durationMs`}]},[d.gesture]:Rr(),[d.swipe]:Rr(),[d.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`}]},[d.snapshot]:{booleans:[{source:`snapshotInteractiveOnly`,output:`interactiveOnly`},{source:`snapshotDiff`,output:`diff`},{source:`snapshotRaw`,output:`raw`},{source:`snapshotForceFull`,output:`forceFull`}],numbers:[{source:`snapshotDepth`,output:`depth`}]},[d.back]:{enums:[{source:`backMode`,output:`mode`,values:f}]},[d.record]:{booleans:[{source:`hideTouches`}],numbers:[{source:`fps`},{source:`screenshotMaxSize`,output:`maxSize`}],enums:[{source:`recordingScope`,output:`scope`,values:ae}]},[d.apps]:{enums:[{source:`appsFilter`,output:`filter`,values:[`user-installed`,`all`]}]},[d.boot]:{booleans:[{source:`headless`}]},[d.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:re}]}}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:ve}]}}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!==d.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(
|
|
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,...se(`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?ue(n,{env:t.env}):Si(t)}function Si(e={}){let t=h.join(de(`~`,{env:e.env}),`.agent-device`),n=e.projectRoot??le();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=le()){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
|
|
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:ce(),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};
|
package/dist/src/snapshot2.js
CHANGED
|
@@ -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{ft as a,gt as o,ht as s,pt as c,ut as l,vn as u}from"./recording-export-quality.js";import{i as d,q as f}from"./snapshot-diagnostics.js";import{c as p,h as m,s as h}from"./sdk-device.js";import{a as g,g as _}from"./gesture-plan-types.js";import{t as v}from"./timeouts.js";import{t as y}from"./runtime.js";import{l as b,n as x}from"./input-actions.js";import{_ as S,g as C,v as ee}from"./device.js";import{l as w,n as T,s as E,t as D}from"./context.js";import{i as O}from"./helper.js";import{a as k}from"./runner-client.js";import{$t as A,Ft as j,Mt as te,Nt as ne,Ot as re,Rt as ie,Tt as ae,u as oe,zt as M}from"./internal/daemon.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,s);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=S(r.buttons,n);if(i)return await b(e,i.x,i.y),J(n,r.alert,i.label);if(n===`dismiss`)return await x(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 v(300)}return null}async function K(e){return ee((await n(`snapshot_capture`,async()=>await C(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 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=w(`alert`,a);if(c)return c;if(r&&A(t)===`may-invalidate`&&j(r),a.platform===`android`)return Z(e,await H(a,o,{timeoutMs:i(t.positionals?.[1])??1e4}));if(p(a))return await Y(e,o,async e=>await O(e,s));let l=oe({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await Y(e,o,async(e,t)=>await k(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`,o))}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 v(300)}return E(`COMMAND_FAILED`,`alert wait timed out`)}async function ue(e,t,n){let r=h(e.device)?o:s,i=Date.now(),a,c=!0;for(;Date.now()-i<s;){try{let a=c?r:X(i,s);return c=!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 v(300)}throw de(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 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])?E(`INVALID_ARGS`,l):{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:o,parsed:s}=e,{setting:l,state:u,appBundleId:d,permissionTarget:f,latitude:m,longitude:h}=s,g=w(`settings`,o);if(g)return g;if(p(o)&&!c(l))return E(`INVALID_ARGS`,a(l));let _=d??i?.appBundleId;if(l===`clear-app-state`&&!_)return E(`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,m??``,h??``,_??``]:[l,u,_??``];i&&j(i);let y=await T(o,`settings`,v,t.flags?.out,{...D(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 T(t.device,`screenshot`,[n],void 0,{...D(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 ae({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=g(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=w(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=M(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!h(n)||t?.appBundleId?null:E(`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:re({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 te(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&&ne(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:m(i),captureSnapshot:async(e,o)=>{let s=await ie({device:i,session:r,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:a}),c=d(r);return{snapshot:s.snapshot,..._(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:f(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}):E(`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};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{f as n,h as r,v as i,w as a}from"./sdk-android-adb.js";import{
|
|
2
|
-
`).replace(/\n$/,``),writeClipboard:async t=>{r(await e(`pbcopy`,[],{allowFailure:!0,stdin:t}),`Failed to write macOS clipboard`)},readDarkMode:async()=>{let n=r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to get dark mode`],{allowFailure:!0}),`Failed to read macOS appearance`),i=n.stdout.trim().toLowerCase();if(i===`true`)return!0;if(i===`false`)return!1;throw new t(`COMMAND_FAILED`,`Unable to determine current macOS appearance from osascript output: ${n.stdout.trim()}`)},setDarkMode:async t=>{r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to set dark mode to ${t?`true`:`false`}`],{allowFailure:!0}),`Failed to set macOS appearance`)},listApps:async t=>await
|
|
3
|
-
`)){let t=e.trim();t&&i.add(t)}}return
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{f as n,h as r,v as i,w as a}from"./sdk-android-adb.js";import{AsyncLocalStorage as o}from"node:async_hooks";import{promises as s}from"node:fs";import c from"node:os";import l from"node:path";function u(e,t=e=>e){let n=new o;return{resolve(r){return r?t(r):n.getStore()??e},async run(e,r){return e?await n.run(t(e),r):await r()},hasScope(){return!!n.getStore()}}}function d(e,t){return t===`user-installed`?e.filter(e=>!e.bundleId.startsWith(`com.apple.`)):e}function f(e,n){return{openBundle:async(t,n)=>{await e(`open`,p(t,n))},openTarget:async t=>{await e(`open`,[t])},readClipboard:async()=>r(await e(`pbpaste`,[],{allowFailure:!0}),`Failed to read macOS clipboard`).stdout.replace(/\r\n/g,`
|
|
2
|
+
`).replace(/\n$/,``),writeClipboard:async t=>{r(await e(`pbcopy`,[],{allowFailure:!0,stdin:t}),`Failed to write macOS clipboard`)},readDarkMode:async()=>{let n=r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to get dark mode`],{allowFailure:!0}),`Failed to read macOS appearance`),i=n.stdout.trim().toLowerCase();if(i===`true`)return!0;if(i===`false`)return!1;throw new t(`COMMAND_FAILED`,`Unable to determine current macOS appearance from osascript output: ${n.stdout.trim()}`)},setDarkMode:async t=>{r(await e(`osascript`,[`-e`,`tell application "System Events" to tell appearance preferences to set dark mode to ${t?`true`:`false`}`],{allowFailure:!0}),`Failed to set macOS appearance`)},listApps:async t=>await m(e,n,t)}}function p(e,t){let n=[`-b`,e];return t&&n.push(t),n}async function m(e,t,n){let r=[`/Applications`,`/System/Applications`,l.join(c.homedir(),`Applications`)],i=new Set;for(let t of r){if(!(await s.stat(t).catch(()=>null))?.isDirectory())continue;let n=await e(`find`,[t,`-maxdepth`,`4`,`-type`,`d`,`-name`,`*.app`],{allowFailure:!0});if(n.exitCode===0)for(let e of n.stdout.split(`
|
|
3
|
+
`)){let t=e.trim();t&&i.add(t)}}return d((await Promise.all(Array.from(i).map(async e=>{let n=await h(e,t).catch(()=>({})),r=n.bundleId;return r?{bundleId:r,name:n.appName??l.basename(e,`.app`)}:null}))).filter(e=>e!==null).sort((e,t)=>e.name.localeCompare(t.name)),n)}async function h(e,t){for(let n of[l.join(e,`Contents`,`Info.plist`),l.join(e,`Info.plist`)]){let e=await t(n),r=g(e,`CFBundleIdentifier`),i=g(e,`CFBundleDisplayName`),a=g(e,`CFBundleName`);if(r||i||a)return{bundleId:r,appName:i??a}}return{}}function g(e,t){let n=e?.[t];return typeof n==`string`&&n.trim()?n.trim():void 0}var _=e({createLocalAppleToolProvider:()=>b,hasScopedAppleToolProvider:()=>C,readApplePlistJson:()=>E,resolveAppleToolProvider:()=>x,runAppleToolCommand:()=>w,runXcrun:()=>T,withAppleToolProvider:()=>S});const v={runCommand:i,simctl:{run:async(e,t)=>await i(`xcrun`,[`simctl`,...e],t)},devicectl:{run:async(e,t)=>await i(`xcrun`,[`devicectl`,...e],t)},plist:{readJson:async e=>await A(i,e)},macosHost:f(i,async e=>await A(i,e)),whichCommand:a},y=u(v,D);function b(e={}){let t={...v,...e},n=e.plist??{readJson:async e=>await A(t.runCommand,e)};return{...t,simctl:e.simctl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`simctl`,...e],n)},devicectl:e.devicectl??{run:async(e,n)=>await t.runCommand(`xcrun`,[`devicectl`,...e],n)},plist:n,macosHost:e.macosHost??f(t.runCommand,async e=>await n.readJson(e))}}function x(e){return y.resolve(e)}async function S(e,t){return await y.run(e,t)}function C(){return y.hasScope()}async function w(e,t,n){return await x().runCommand(e,t,n)}async function T(e,t){let n=x(),[r,...i]=e;return r===`simctl`?await(n.simctl?.run(i,t)??n.runCommand(`xcrun`,e,t)):r===`devicectl`?await(n.devicectl?.run(i,t)??n.runCommand(`xcrun`,e,t)):await w(`xcrun`,e,t)}async function E(e){return await x().plist?.readJson(e)??null}function D(e){return b(typeof e==`function`?{runCommand:O(e)}:{...e,runCommand:O(e.runCommand),...e.simctl?{simctl:{run:k(e.simctl.run)}}:{},...e.devicectl?{devicectl:{run:k(e.devicectl.run)}}:{},...e.macosHelper?{macosHelper:{run:k(e.macosHelper.run)}}:{}})}function O(e){return async(t,r,i)=>n(await e(t,r,i))}function k(e){return async(t,r)=>n(await e(t,r))}async function A(e,t){try{let n=await e(`plutil`,[`-convert`,`json`,`-o`,`-`,t],{allowFailure:!0});return n.exitCode!==0||!n.stdout.trim()?null:JSON.parse(n.stdout)}catch{return null}}export{T as a,u as c,w as i,E as n,_ as o,x as r,d as s,C as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,v as r,w as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{_ as t}from"./sdk-contracts.js";import{j as n,v as r,w as i}from"./sdk-android-adb.js";import{t as a}from"./timeouts.js";import{c as o}from"./tool-provider.js";var s=e({createLocalLinuxToolProvider:()=>u,resolveLinuxToolProvider:()=>d,runLinuxToolCommand:()=>p,withLinuxToolProvider:()=>f});const c={runCommand:r,whichCommand:i,desktop:m(r,i),clipboard:h(r,i),screenshot:g(r,i)},l=o(c,u);function u(e={}){let t={...c,...e};return{...t,desktop:e.desktop??m(t.runCommand,t.whichCommand),clipboard:e.clipboard??h(t.runCommand,t.whichCommand),screenshot:e.screenshot??g(t.runCommand,t.whichCommand)}}function d(e){return l.resolve(e)}async function f(e,t){return await l.run(e,t)}async function p(e,t,n){return await d().runCommand(e,t,n)}function m(e,t){return{async openTarget(r){if(r.includes(`://`)||r.startsWith(`/`)){await e(`xdg-open`,[r]);return}if(await t(r)){e(r,[],{allowFailure:!0}).catch(e=>{n({level:`warn`,phase:`linux_app_launch`,data:{app:r,error:String(e)}})}),await a(500);return}await e(`xdg-open`,[r],{allowFailure:!0})},async closeApp(n){if(await t(`wmctrl`)){await e(`wmctrl`,[`-c`,n],{allowFailure:!0});return}await e(`pkill`,[`-x`,n],{allowFailure:!0})}}}function h(e,t){return{async readText(){let n=await C(t,v),r=b[n];return(await e(r.cmd,r.args,r.options)).stdout},async writeText(n){let r=await C(t,v),i=x[r](n);await e(i.cmd,i.args,i.options)}}}function g(e,t){return{async capture(n){let r=await C(t,y),i=S[r](n);await e(i.cmd,i.args,i.options)}}}const _=5e3,v={wayland:[{tool:`wl-clipboard`,command:`wl-paste`}],x11:[{tool:`xclip`,command:`xclip`},{tool:`xsel`,command:`xsel`}],waylandError:`wl-paste (wl-clipboard) is required for clipboard access on Wayland. Install via your package manager.`,x11Error:`xclip or xsel is required for clipboard access on X11. Install via your package manager.`},y={wayland:[{tool:`grim`,command:`grim`},{tool:`gnome-screenshot`,command:`gnome-screenshot`}],x11:[{tool:`scrot`,command:`scrot`},{tool:`import`,command:`import`},{tool:`gnome-screenshot`,command:`gnome-screenshot`}],waylandError:`grim or gnome-screenshot is required for screenshots on Wayland. Install via your package manager.`,x11Error:`scrot, import (ImageMagick), or gnome-screenshot is required for screenshots on X11. Install via your package manager.`},b={"wl-clipboard":{cmd:`wl-paste`,args:[`--no-newline`],options:{allowFailure:!0,timeoutMs:_}},xclip:{cmd:`xclip`,args:[`-selection`,`clipboard`,`-o`],options:{allowFailure:!0,timeoutMs:_}},xsel:{cmd:`xsel`,args:[`--clipboard`,`--output`],options:{allowFailure:!0,timeoutMs:_}}},x={"wl-clipboard":e=>({cmd:`wl-copy`,args:[`--`,e],options:{allowFailure:!1,timeoutMs:_}}),xclip:e=>({cmd:`xclip`,args:[`-selection`,`clipboard`],options:{allowFailure:!1,timeoutMs:_,stdin:e}}),xsel:e=>({cmd:`xsel`,args:[`--clipboard`,`--input`],options:{allowFailure:!1,timeoutMs:_,stdin:e}})},S={grim:e=>({cmd:`grim`,args:[e]}),scrot:e=>({cmd:`scrot`,args:[e]}),import:e=>({cmd:`import`,args:[`-window`,`root`,e]}),"gnome-screenshot":e=>({cmd:`gnome-screenshot`,args:[`-f`,e]})};async function C(e,n){let r=w()?`wayland`:`x11`;for(let t of n[r])if(await e(t.command))return t.tool;throw new t(`TOOL_MISSING`,r===`wayland`?n.waylandError:n.x11Error)}function w(){return!!process.env.WAYLAND_DISPLAY||process.env.XDG_SESSION_TYPE===`wayland`}export{p as n,s as r,d as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./rolldown-runtime.js";import{v as t,w as n}from"./sdk-android-adb.js";import{c as r}from"./tool-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,213 @@
|
|
|
1
|
+
import { M as SnapshotQualityVerdict, O as ScreenshotOverlayRef, U as PublicPlatform, n as DaemonArtifactType } from "./sdk-contracts.js";
|
|
2
|
+
import { f as AndroidSnapshotCaptureMode, m as AndroidSnapshotHelperTransport, p as AndroidSnapshotHelperInstallReason } from "./sdk-android-adb.js";
|
|
3
|
+
//#region src/contracts/json.d.ts
|
|
4
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
5
|
+
type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
|
|
6
|
+
type JsonObject = {
|
|
7
|
+
[key: string]: JsonValue;
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/contracts/session-surface.d.ts
|
|
11
|
+
declare const SESSION_SURFACES: readonly ['app', 'frontmost-app', 'desktop', 'menubar'];
|
|
12
|
+
type SessionSurface = (typeof SESSION_SURFACES)[number];
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/platforms/android/snapshot-types.d.ts
|
|
15
|
+
type AndroidSnapshotBackendMetadata = {
|
|
16
|
+
backend: 'android-helper';
|
|
17
|
+
helperVersion?: string;
|
|
18
|
+
helperApiVersion?: string;
|
|
19
|
+
helperTransport?: AndroidSnapshotHelperTransport;
|
|
20
|
+
helperSessionReused?: boolean;
|
|
21
|
+
installReason?: AndroidSnapshotHelperInstallReason;
|
|
22
|
+
waitForIdleTimeoutMs?: number;
|
|
23
|
+
waitForIdleQuietMs?: number;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
maxDepth?: number;
|
|
26
|
+
maxNodes?: number;
|
|
27
|
+
rootPresent?: boolean;
|
|
28
|
+
captureMode?: AndroidSnapshotCaptureMode;
|
|
29
|
+
systemSurfaceOnly?: boolean;
|
|
30
|
+
windowCount?: number;
|
|
31
|
+
nodeCount?: number;
|
|
32
|
+
helperTruncated?: boolean;
|
|
33
|
+
elapsedMs?: number;
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/contracts/snapshot-capture-annotations.d.ts
|
|
37
|
+
type SnapshotCaptureAnalysis = {
|
|
38
|
+
rawNodeCount: number;
|
|
39
|
+
maxDepth: number;
|
|
40
|
+
};
|
|
41
|
+
type SnapshotCaptureFreshness = {
|
|
42
|
+
action: string;
|
|
43
|
+
retryCount: number;
|
|
44
|
+
staleAfterRetries: boolean;
|
|
45
|
+
reason?: 'empty-interactive' | 'sharp-drop' | 'stuck-route';
|
|
46
|
+
};
|
|
47
|
+
type SnapshotCaptureAnnotations = {
|
|
48
|
+
analysis?: SnapshotCaptureAnalysis;
|
|
49
|
+
androidSnapshot?: AndroidSnapshotBackendMetadata;
|
|
50
|
+
freshness?: SnapshotCaptureFreshness;
|
|
51
|
+
quality?: SnapshotQualityVerdict;
|
|
52
|
+
warnings?: string[];
|
|
53
|
+
};
|
|
54
|
+
type PublicSnapshotCaptureAnnotations = Pick<SnapshotCaptureAnnotations, 'androidSnapshot' | 'warnings'> & {
|
|
55
|
+
snapshotQuality?: SnapshotQualityVerdict;
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/contracts/snapshot-diagnostics.d.ts
|
|
59
|
+
type SnapshotTimingStats = {
|
|
60
|
+
count: number;
|
|
61
|
+
p50Ms: number;
|
|
62
|
+
p95Ms: number;
|
|
63
|
+
maxMs: number;
|
|
64
|
+
slowThresholdMs: number;
|
|
65
|
+
platform?: PublicPlatform;
|
|
66
|
+
backends?: Record<string, number>;
|
|
67
|
+
};
|
|
68
|
+
type SnapshotDiagnosticsSummary = {
|
|
69
|
+
stats: SnapshotTimingStats;
|
|
70
|
+
warning?: string;
|
|
71
|
+
};
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/utils/screenshot-result.d.ts
|
|
74
|
+
type ScreenshotResultData = {
|
|
75
|
+
path?: string;
|
|
76
|
+
width?: number;
|
|
77
|
+
height?: number;
|
|
78
|
+
logicalWidth?: number;
|
|
79
|
+
logicalHeight?: number;
|
|
80
|
+
pixelDensity?: number;
|
|
81
|
+
overlayRefs?: ScreenshotOverlayRef[];
|
|
82
|
+
};
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/contracts/recording-export-quality.d.ts
|
|
85
|
+
declare const RECORDING_EXPORT_QUALITIES: readonly ['medium', 'high'];
|
|
86
|
+
type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number];
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/contracts/back-mode.d.ts
|
|
89
|
+
declare const BACK_MODES: readonly ['in-app', 'system'];
|
|
90
|
+
type BackMode = (typeof BACK_MODES)[number];
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/contracts/cloud-artifacts.d.ts
|
|
93
|
+
declare const CLOUD_ARTIFACT_KINDS: readonly ['video', 'appium-log', 'device-log', 'automation-log', 'provider-session', 'raw'];
|
|
94
|
+
type CloudArtifactKind = (typeof CLOUD_ARTIFACT_KINDS)[number];
|
|
95
|
+
type CloudArtifactAvailability = 'ready' | 'pending' | 'unavailable' | 'expired';
|
|
96
|
+
type CloudArtifact = {
|
|
97
|
+
provider: string;
|
|
98
|
+
kind: CloudArtifactKind;
|
|
99
|
+
name: string;
|
|
100
|
+
url?: string;
|
|
101
|
+
providerSessionId?: string;
|
|
102
|
+
providerArtifactId?: string;
|
|
103
|
+
contentType?: string;
|
|
104
|
+
extension?: string;
|
|
105
|
+
availability?: CloudArtifactAvailability;
|
|
106
|
+
metadata?: Record<string, unknown>;
|
|
107
|
+
};
|
|
108
|
+
type CloudArtifactsStatus = 'ready' | 'pending' | 'unavailable';
|
|
109
|
+
type CloudArtifactsResult = {
|
|
110
|
+
provider: string;
|
|
111
|
+
status: CloudArtifactsStatus;
|
|
112
|
+
cloudArtifacts: CloudArtifact[];
|
|
113
|
+
providerSessionId?: string;
|
|
114
|
+
message?: string;
|
|
115
|
+
};
|
|
116
|
+
type DaemonArtifactInventoryEntry = {
|
|
117
|
+
id: string;
|
|
118
|
+
artifactType?: DaemonArtifactType;
|
|
119
|
+
filename: string;
|
|
120
|
+
mimeType: string;
|
|
121
|
+
sizeBytes: number;
|
|
122
|
+
createdAt: string;
|
|
123
|
+
expiresAt: string;
|
|
124
|
+
};
|
|
125
|
+
type DaemonArtifactsResult = {
|
|
126
|
+
source: 'daemon';
|
|
127
|
+
status: 'ready';
|
|
128
|
+
artifacts: DaemonArtifactInventoryEntry[];
|
|
129
|
+
message?: string;
|
|
130
|
+
};
|
|
131
|
+
type AgentArtifactsResult = CloudArtifactsResult | DaemonArtifactsResult;
|
|
132
|
+
type CloudArtifactsQuery = {
|
|
133
|
+
provider?: string;
|
|
134
|
+
leaseId?: string;
|
|
135
|
+
providerSessionId?: string;
|
|
136
|
+
};
|
|
137
|
+
type CloudProviderSessionResult = {
|
|
138
|
+
provider?: string;
|
|
139
|
+
providerSessionId?: string;
|
|
140
|
+
cloudArtifacts?: CloudArtifactsResult;
|
|
141
|
+
} & Record<string, unknown>;
|
|
142
|
+
/**
|
|
143
|
+
* Return undefined only when this provider implementation does not handle the query.
|
|
144
|
+
* Return a CloudArtifactsResult with status "unavailable" when the provider handled the
|
|
145
|
+
* query but artifact retrieval failed, and "pending" when artifacts are not finalized yet.
|
|
146
|
+
*/
|
|
147
|
+
type CloudArtifactProvider = {
|
|
148
|
+
listCloudArtifacts?: (query: CloudArtifactsQuery) => Promise<CloudArtifactsResult | undefined>;
|
|
149
|
+
};
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/contracts/alert-contract.d.ts
|
|
152
|
+
declare const ALERT_ACTIONS: readonly ['get', 'accept', 'dismiss', 'wait'];
|
|
153
|
+
type AlertAction = (typeof ALERT_ACTIONS)[number];
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/contracts/device-rotation.d.ts
|
|
156
|
+
declare const DEVICE_ROTATIONS: readonly ['portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right'];
|
|
157
|
+
type DeviceRotation = (typeof DEVICE_ROTATIONS)[number];
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region src/contracts/tv-remote.d.ts
|
|
160
|
+
declare const TV_REMOTE_BUTTON_DEFINITIONS: {
|
|
161
|
+
readonly up: {
|
|
162
|
+
readonly aliases: readonly [];
|
|
163
|
+
readonly androidKeyevent: 'KEYCODE_DPAD_UP';
|
|
164
|
+
readonly appleRemoteButton: 'up';
|
|
165
|
+
readonly vegaKey: 'KEY_UP';
|
|
166
|
+
};
|
|
167
|
+
readonly down: {
|
|
168
|
+
readonly aliases: readonly [];
|
|
169
|
+
readonly androidKeyevent: 'KEYCODE_DPAD_DOWN';
|
|
170
|
+
readonly appleRemoteButton: 'down';
|
|
171
|
+
readonly vegaKey: 'KEY_DOWN';
|
|
172
|
+
};
|
|
173
|
+
readonly left: {
|
|
174
|
+
readonly aliases: readonly [];
|
|
175
|
+
readonly androidKeyevent: 'KEYCODE_DPAD_LEFT';
|
|
176
|
+
readonly appleRemoteButton: 'left';
|
|
177
|
+
readonly vegaKey: 'KEY_LEFT';
|
|
178
|
+
};
|
|
179
|
+
readonly right: {
|
|
180
|
+
readonly aliases: readonly [];
|
|
181
|
+
readonly androidKeyevent: 'KEYCODE_DPAD_RIGHT';
|
|
182
|
+
readonly appleRemoteButton: 'right';
|
|
183
|
+
readonly vegaKey: 'KEY_RIGHT';
|
|
184
|
+
};
|
|
185
|
+
readonly select: {
|
|
186
|
+
readonly aliases: readonly ["ok", "center", "enter"];
|
|
187
|
+
readonly androidKeyevent: 'KEYCODE_DPAD_CENTER';
|
|
188
|
+
readonly appleRemoteButton: 'select';
|
|
189
|
+
readonly vegaKey: 'KEY_ENTER';
|
|
190
|
+
};
|
|
191
|
+
readonly menu: {
|
|
192
|
+
readonly aliases: readonly [];
|
|
193
|
+
readonly androidKeyevent: 'KEYCODE_MENU';
|
|
194
|
+
readonly appleRemoteButton: 'menu';
|
|
195
|
+
readonly vegaKey: 'KEY_MENU';
|
|
196
|
+
};
|
|
197
|
+
readonly home: {
|
|
198
|
+
readonly aliases: readonly [];
|
|
199
|
+
readonly androidKeyevent: 'KEYCODE_HOME';
|
|
200
|
+
readonly appleRemoteButton: 'home';
|
|
201
|
+
readonly vegaKey: 'KEY_HOMEPAGE';
|
|
202
|
+
};
|
|
203
|
+
readonly back: {
|
|
204
|
+
readonly aliases: readonly [];
|
|
205
|
+
readonly androidKeyevent: 'KEYCODE_BACK';
|
|
206
|
+
readonly appleRemoteButton: 'menu';
|
|
207
|
+
readonly vegaKey: 'KEY_BACK';
|
|
208
|
+
};
|
|
209
|
+
};
|
|
210
|
+
declare const TV_REMOTE_BUTTONS: (keyof typeof TV_REMOTE_BUTTON_DEFINITIONS)[];
|
|
211
|
+
type TvRemoteButton = (typeof TV_REMOTE_BUTTONS)[number];
|
|
212
|
+
//#endregion
|
|
213
|
+
export { CloudArtifactProvider as a, RecordingExportQuality as c, PublicSnapshotCaptureAnnotations as d, SnapshotCaptureAnnotations as f, AgentArtifactsResult as i, ScreenshotResultData as l, JsonObject as m, DeviceRotation as n, CloudProviderSessionResult as o, SessionSurface as p, AlertAction as r, BackMode as s, TvRemoteButton as t, SnapshotDiagnosticsSummary as u };
|
|
@@ -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{
|
|
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/dist/src/xml.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=new Set(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.:-`),t=new Set([` `,` `,`
|
|
2
|
+
`,`\r`]),n=new Set([`__defineGetter__`,`__defineSetter__`,`__proto__`,`constructor`,`prototype`]);function r(e,t={}){let n=t.maxDocumentChars??134217728;if(e.length>n)throw Error(`XML document exceeds maximum supported size of ${n} characters.`);return new a(e).parse()}function i(e,t){for(let n of e){if(n.name===`dict`)for(let e=0;e<n.children.length-1;e+=1){let r=n.children[e],i=n.children[e+1];r?.name===`key`&&r.text&&i&&t(r.text,i)}i(n.children,t)}}var a=class{roots=[];stack=[];index=0;xml;constructor(e){this.xml=e}parse(){for(this.skipByteOrderMark();this.index<this.xml.length;)this.readNextToken();return this.assertFullyClosed(),this.roots}readNextToken(){if(this.xml[this.index]!==`<`){this.readText();return}this.resolveMarkupReader()()}resolveMarkupReader(){return this.startsWith(`<!--`)?()=>this.skipUntil(`-->`,`Comment is not closed.`):this.startsWith(`<?`)?()=>this.skipUntil(`?>`,`Processing instruction is not closed.`):this.startsWith(`<![CDATA[`)?()=>this.readCdata():this.startsWith(`<!`)?()=>this.skipDeclaration():this.startsWith(`</`)?()=>this.readClosingTag():()=>this.readOpeningTag()}assertFullyClosed(){if(this.stack.length>0){let e=this.stack[this.stack.length-1];throw Error(`Unclosed XML tag <${e?.name??`unknown`}>.`)}}skipByteOrderMark(){this.xml.charCodeAt(0)===65279&&(this.index=1)}readOpeningTag(){this.index+=1,this.skipWhitespace();let e=this.readRequiredName(`Missing XML tag name at offset ${this.index}.`),{attributes:t,selfClosing:n}=this.readOpeningTagBody(),r={name:e,attributes:t,text:null,children:[]};this.addNode(r),n||this.pushOpenNode(r)}readOpeningTagBody(){let e={};for(;;){this.skipWhitespace();let t=this.readOpeningTagEnd();if(t)return{attributes:e,selfClosing:t===`self-closing`};let n=this.readAttribute();e[n.name]=n.value}}readOpeningTagEnd(){if(this.index>=this.xml.length)throw Error(`Opening XML tag is not closed.`);return this.xml[this.index]===`>`?(this.index+=1,`open`):this.xml[this.index]===`/`&&this.xml[this.index+1]===`>`?(this.index+=2,`self-closing`):null}readAttribute(){let e=this.readRequiredName(`Invalid XML attribute at offset ${this.index}.`);if(f(e),this.skipWhitespace(),this.xml[this.index]!==`=`)throw Error(`Missing value for XML attribute "${e}".`);return this.index+=1,this.skipWhitespace(),{name:e,value:this.readAttributeValue(e)}}pushOpenNode(e){if(this.stack.length>=256)throw Error(`Maximum XML nesting depth of 256 exceeded.`);this.stack.push(e)}readClosingTag(){this.index+=2,this.skipWhitespace();let e=this.readName();if(this.skipWhitespace(),this.xml[this.index]!==`>`)throw Error(`Closing XML tag </${e}> is not closed.`);this.index+=1;let t=this.stack.pop();if(!t)throw Error(`Unexpected closing XML tag </${e}>.`);if(t.name!==e)throw Error(`Expected </${t.name}> before </${e}>.`)}readText(){let e=this.xml.indexOf(`<`,this.index),t=e===-1?this.xml.length:e;this.appendText(this.xml.slice(this.index,t),!0),this.index=t}readCdata(){let e=this.index+9,t=this.xml.indexOf(`]]>`,e);if(t===-1)throw Error(`CDATA section is not closed.`);this.appendText(this.xml.slice(e,t),!1),this.index=t+3}appendText(e,t){let n=e.trim();if(!n)return;let r=this.stack[this.stack.length-1];r&&(r.text=`${r.text??``}${t?p(n):n}`)}addNode(e){let t=this.stack[this.stack.length-1];t?t.children.push(e):this.roots.push(e)}readName(){let e=this.index;for(;this.index<this.xml.length&&o(this.xml[this.index]);)this.index+=1;return this.xml.slice(e,this.index)}readRequiredName(e){let t=this.readName();if(!t)throw Error(e);return t}readAttributeValue(e){let t=this.xml[this.index];if(t!==`"`&&t!==`'`)throw Error(`XML attribute "${e}" must use a quoted value.`);this.index+=1;let n=this.index,r=this.xml.indexOf(t,n);if(r===-1)throw Error(`XML attribute "${e}" is not closed.`);return this.index=r+1,p(this.xml.slice(n,r).trim())}skipDeclaration(){let e={quote:null,bracketDepth:0};for(let t=this.index+2;t<this.xml.length;t+=1)if(c(e,this.xml[t])){this.index=t+1;return}throw Error(`XML declaration is not closed.`)}skipUntil(e,t){let n=this.xml.indexOf(e,this.index+e.length);if(n===-1)throw Error(t);this.index=n+e.length}skipWhitespace(){for(;this.index<this.xml.length&&s(this.xml[this.index]);)this.index+=1}startsWith(e){return this.xml.startsWith(e,this.index)}};function o(t){return t!==void 0&&e.has(t)}function s(e){return e!==void 0&&t.has(e)}function c(e,t){return t===void 0||l(e,t)?!1:(u(e,t),d(e,t))}function l(e,t){return e.quote?(t===e.quote&&(e.quote=null),!0):t===`"`||t===`'`?(e.quote=t,!0):!1}function u(e,t){if(t===`[`){e.bracketDepth+=1;return}t===`]`&&e.bracketDepth>0&&--e.bracketDepth}function d(e,t){return t===`>`&&e.bracketDepth===0}function f(e){if(n.has(e))throw Error(`Unsupported XML attribute name "${e}".`)}function p(e){return e.replace(/&(#x[0-9a-fA-F]+|#[0-9]+|amp|lt|gt|quot|apos);/g,(e,t)=>{switch(t){case`amp`:return`&`;case`lt`:return`<`;case`gt`:return`>`;case`quot`:return`"`;case`apos`:return`'`;default:return m(e,t)}})}function m(e,t){let n=t.startsWith(`#x`)?Number.parseInt(t.slice(2),16):Number(t.slice(1));if(!Number.isInteger(n)||n<0||n>1114111)return e;try{return String.fromCodePoint(n)}catch{return e}}export{i as n,r as t};
|