agent-device 0.20.1 → 0.20.3
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 +0 -2
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.1.apk → agent-device-android-ime-helper-0.20.3.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.3.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.1.manifest.json → agent-device-android-ime-helper-0.20.3.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.1.apk → agent-device-android-snapshot-helper-0.20.3.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.3.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.1.manifest.json → agent-device-android-snapshot-helper-0.20.3.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +2 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +1 -35
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +0 -208
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Keyboard.swift +184 -0
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Orientation.swift +92 -0
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android-adb.d.ts +3 -26
- package/dist/src/android-adb.js +1 -1
- package/dist/src/android.js +1 -1
- package/dist/src/app-helpers.js +1 -0
- 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/apps.js +5 -5
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +6 -6
- 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-schema.js +3 -3
- package/dist/src/context.js +1 -1
- package/dist/src/contracts.d.ts +1 -1
- package/dist/src/device-input-state.d.ts +26 -0
- 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/find.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 +1174 -1413
- 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 -1
- 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 +437 -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/metro.d.ts +71 -2
- 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 +12 -13
- package/dist/src/register-builtins.js +1 -1
- package/dist/src/registry.js +18 -18
- 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/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 -2
- package/dist/src/sdk-batch-runner.d.ts +13 -3
- package/dist/src/sdk-batch-runner.js +1 -1
- package/dist/src/sdk-contracts.d.ts +28 -2
- package/dist/src/sdk-contracts.js +2 -2
- package/dist/src/sdk-finders.d.ts +1 -1
- package/dist/src/sdk-remote-config.d.ts +119 -4
- 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/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 -1
- package/dist/src/tv-remote.d.ts +213 -0
- package/dist/src/xml.js +2 -0
- package/package.json +49 -30
- package/server.json +2 -2
- package/smithery.yaml +1 -1
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.1.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.1.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/metro-types.d.ts +0 -52
- package/dist/src/project-runtime.js +0 -1
- package/dist/src/scoped-provider.js +0 -1
- package/dist/src/simctl.js +0 -1
- package/dist/src/snapshot-quality.js +0 -1
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{M as a,R as o,et as s,g as c,h as l,m as u}from"./sdk-batch-runner.js";import{Dn as ee,Gn as te,Jn as ne,Pn as re,Qn as ie,Xn as d,bn as ae,cr as f,er as oe,kn as se,rr as ce,sr as le}from"./recording-export-quality.js";import{n as ue,t as de}from"./version.js";import{n as fe,t as pe}from"./path-resolution.js";import{h as me,n as he,r as ge,t as _e}from"./sdk-device.js";import{mt as ve}from"./sdk-selectors.js";import{a as ye,n as be,o as xe,u as p}from"./host-process.js";import Se from"node:crypto";import m from"node:fs";import h from"node:path";import{StringDecoder as Ce}from"node:string_decoder";const we=`/agent-device`,Te=`x-agent-device-tenant`;function Ee(e){return De(e,we)}function De(e,t){let n=e.endsWith(`/`)?e:`${e}/`;return new URL(t.replace(/^\/+/,``),n).toString()}function Oe(e){let t=e?.trim();return t?{authorization:`Bearer ${t}`,"x-agent-device-token":t}:{}}function ke(e){let t=e?.trim();return t?{[Te]:t}:{}}const Ae=`.webm`;function je(e){return e===`web`?Ae:`.mp4`}function Me(e,t){return h.extname(e)?e:`${e}${t}`}function Ne(e){return`./recording-${Date.now()}${je(e)}`}function Pe(e){return new Promise((t,n)=>{let r=``;e.setEncoding(`utf8`),e.on(`data`,e=>{r+=e}),e.on(`end`,()=>t(r)),e.on(`error`,n)})}async function Fe(e,n,r){let i=[],a=0;for await(let o of e){let e=Buffer.isBuffer(o)?o:Buffer.from(o);if(a+=e.length,a>n)throw new t(`INVALID_ARGS`,r);i.push(e)}return Buffer.concat(i)}function g(e){return e.replace(/[^a-zA-Z0-9._-]/g,`_`)}function _(e,t){return fe(e,{cwd:t})}function v(e){let t=e.result?.text;if(typeof t==`string`)return t;let n=e.positionals??[];return n.length===0?``:n[0]?.startsWith(`@`)?n.length>=3?n.slice(2).join(` `):n.slice(1).join(` `):n.length>=3&&!Number.isNaN(Number(n[0]))&&!Number.isNaN(Number(n[1]))?n.slice(2).join(` `):n.slice(1).join(` `)}const y=/^[A-Z_][A-Z0-9_]*$/,Ie=/(\\\$\{)|\$\{([A-Za-z_][A-Za-z0-9_.]*)(?::-((?:[^}\\]|\\.)*))?\}/g;function b(e){return e.startsWith(`AD_`)}function Le(e){return new t(`INVALID_ARGS`,`The AD_* namespace is reserved for built-in variables. Rename ${e} to avoid the AD_ prefix.`)}function Re(e){let t={};if(e.builtins)for(let[n,r]of Object.entries(e.builtins))t[n]=r;let n=[e.fileEnv,e.shellEnv,e.cliEnv];for(let e of n)if(e)for(let[n,r]of Object.entries(e)){if(b(n))throw Le(n);t[n]=r}return{values:t,expandedBuiltinNames:new Set}}function ze(e){let t={};for(let[n,r]of Object.entries(e)){if(typeof r!=`string`||!n.startsWith(`AD_VAR_`))continue;let e=n.slice(7);e.length!==0&&y.test(e)&&(b(e)||(t[e]=r))}return t}function Be(e){let n={};for(let r of e){let e=r.indexOf(`=`);if(e<=0)throw new t(`INVALID_ARGS`,`Invalid -e entry "${r}": expected KEY=VALUE.`);let i=r.slice(0,e);if(!y.test(i))throw new t(`INVALID_ARGS`,`Invalid -e key "${i}": keys must be uppercase letters, digits, and underscores (e.g. APP_ID).`);if(b(i))throw Le(i);n[i]=r.slice(e+1)}return n}function Ve(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function He(e){if(e&&typeof e==`object`&&!Array.isArray(e)){let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}return process.env}function Ue(e,n,r){return e.replace(Ie,(e,i,a,o)=>{if(i)return"${";if(!a)return e;if(Object.prototype.hasOwnProperty.call(n.values,a))return b(a)&&(n.expandedBuiltinNames??=new Set).add(a),String(n.values[a]);if(o!==void 0)return o.replace(/\\(.)/g,`$1`);throw new t(`INVALID_ARGS`,`Unresolved variable \${${a}} at ${r.file}:${r.line}.`)})}function We(e,t,n){return{...e,positionals:(e.positionals??[]).map(e=>Ue(e,t,n)),flags:Ge(e.flags,t,n)??{},runtime:Ge(e.runtime,t,n)}}function Ge(e,t,n){return e&&x(e,t,n)}function x(e,t,n){return typeof e==`string`?Ue(e,t,n):Array.isArray(e)?e.map(e=>x(e,t,n)):e&&typeof e==`object`?Object.fromEntries(Object.entries(e).map(([e,r])=>[e,x(r,t,n)])):e}function Ke(e){return Object.entries(e.values).filter(([t,n])=>n.length>0&&(!b(t)||e.expandedBuiltinNames?.has(t))).map(([e,t])=>({name:e,value:t})).sort((e,t)=>t.value.length-e.value.length)}const qe=/^\$\{([A-Z_][A-Z0-9_]*)\}$/;function Je(e){if(e!==e.trim()||!y.test(e))throw new t(`INVALID_ARGS`,`Invalid --record-as variable "${e}": use uppercase letters, digits, and underscores (for example PASSWORD).`);if(e.startsWith(`AD_`))throw new t(`INVALID_ARGS`,`Invalid --record-as variable "${e}": the AD_* namespace is reserved for built-in replay variables.`);return e}function Ye(e){return`\${${e}}`}function Xe(e){let t=qe.exec(e);if(!(!t?.[1]||t[1].startsWith(`AD_`)))return t[1]}const Ze=new Set([`text`,`label`,`value`]),Qe=new Set(`action.backend.cost.delayMs.evidence.gesture.hint.kind.maestroFallbackReason.maestroNonHittableCoordinateFallbackAllowed.maestroNonHittableCoordinateFallbackUsed.message.platform.ref.referenceHeight.referenceWidth.refLabel.resolution.selector.selectorChain.settle.targetHittable.targetKind.text.warning.x.y`.split(`.`)),$e=new Set([`action`,`backend`,`gesture`,`kind`,`platform`,`ref`,`selector`,`targetKind`]),et=new Set([`cost`,`evidence`,`resolution`,`settle`]),tt=new Map([[`cost`,new Set([`nodeCount`,`runnerRoundTrips`,`wallClockMs`])],[`evidence`,new Set([`changedFromBefore`,`digest`,`foregroundApp`,`interactiveNodeCount`,`nodeCount`])],[`resolution`,new Set([`alternatives`,`kind`,`matchCount`,`phase`,`source`,`tiebreak`,`winnerDiagnostic`])],[`resolution.alternatives`,new Set([`diagnosticRef`,`label`,`role`])],[`resolution.winnerDiagnostic`,new Set([`diagnosticRef`,`label`,`role`])],[`settle`,new Set([`captures`,`diff`,`hint`,`quietMs`,`refs`,`refsGeneration`,`settled`,`tail`,`tailTruncated`,`timeoutMs`,`waitedMs`])],[`settle.diff`,new Set([`lines`,`summary`,`truncated`])],[`settle.diff.lines`,new Set([`kind`,`ref`,`text`])],[`settle.diff.summary`,new Set([`additions`,`removals`,`unchanged`])],[`settle.refs`,new Set([`ref`])],[`settle.tail`,new Set([`label`,`ref`,`role`])]]),nt=new Set([`evidence.digest`,`evidence.foregroundApp`,`resolution.alternatives.diagnosticRef`,`resolution.alternatives.role`,`resolution.kind`,`resolution.phase`,`resolution.source`,`resolution.tiebreak`,`resolution.winnerDiagnostic.diagnosticRef`,`resolution.winnerDiagnostic.role`,`settle.diff.lines.kind`,`settle.diff.lines.ref`,`settle.refs.ref`,`settle.tail.ref`,`settle.tail.role`]);function rt(e,t,n){if(!e)return e;let r=ut(e.selectorChain);return{...ot(e,t,n),...typeof e.text==`string`?{text:n}:{},...r?{selectorChain:r.filter(e=>!at(e,t))}:{}}}function it(e,t,n){return e&&{...e,...e.label===t?{label:n}:{},ancestry:e.ancestry.map(e=>({...e,...e.label===t?{label:n}:{}})),...e.scrollRegion?{scrollRegion:{...e.scrollRegion,...e.scrollRegion.label===t?{label:n}:{}}}:{}}}function at(e,t){return s(e)?.selectors.some(e=>e.terms.some(e=>Ze.has(e.key)&&typeof e.value==`string`&&C(e.value,t,``)!==e.value))??!1}function ot(e,t,n){return Object.fromEntries(Object.entries(e).map(([e,r])=>[Qe.has(e)?e:C(e,t,n),st(r,e,t,n)]))}function st(e,t,n,r){return typeof e==`string`&&$e.has(t)?e:t===`selectorChain`&<(e)?ct(e,n):S(e,n,r,et.has(t)?t:void 0)}function S(e,t,n,r){if(typeof e==`string`)return r&&nt.has(r)?e:C(e,t,n);if(Array.isArray(e))return e.map(e=>S(e,t,n,r));if(!e||typeof e!=`object`)return e;let i=r?tt.get(r):void 0;return Object.fromEntries(Object.entries(e).map(([e,a])=>{let o=i?.has(e)===!0;return[o?e:C(e,t,n),S(a,t,n,o?`${r}.${e}`:void 0)]}))}function ct(e,t){return e.filter(e=>!at(e,t))}function C(e,t,n){if(!t)return e===t?n:e;let r=n?e.split(n):[e];return r.every(e=>!e.includes(t))?e:t.trim()?r.map(e=>e.replaceAll(t,n)).join(n):n}function lt(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function ut(e){return lt(e)?e:void 0}function dt(e,t,n){e.saveScriptPath!==void 0&&e.saveScriptPath!==t&&!n&&(e.saveScriptForce=void 0),e.saveScriptPath=t}function ft(e,t){if(t.flags?.noRecord||_t(e,t))return;t.flags?.saveScript&&(e.recordSession=!0,typeof t.flags.saveScript==`string`&&(dt(e,_(t.flags.saveScript),t.flags.force),e.saveScriptDefaultedHealedPath=!1),t.flags.force&&(e.saveScriptForce=!0));let n=pt(t),r={ts:Date.now(),command:n.command,positionals:n.positionals,runtime:n.runtime,flags:yt(n.flags),result:n.result,...n.targetEvidence?{targetEvidence:n.targetEvidence}:{}};return e.actions.push(r),i({level:`debug`,phase:`record_action`,data:{command:t.command,session:e.name}}),r}function pt(e){if(e.command!==`fill`||typeof e.flags.recordAs!=`string`)return e;let t=Ye(Je(e.flags.recordAs)),n=v({ts:0,command:e.command,positionals:e.positionals,flags:e.flags});return{...e,positionals:mt(e.positionals,t),result:rt(e.result,n,t),targetEvidence:it(e.targetEvidence,n,t)}}function mt(e,t){let n=e[0];return n?.startsWith(`@`)?e.length>=3?[n,e[1],t]:[n,t]:e.length>=3&&Number.isFinite(Number(e[0]))&&Number.isFinite(Number(e[1]))?[e[0],e[1],t]:n===void 0?[t]:[n,t]}const ht=new Set([`snapshot`,`get`,`is`,`find`]);function gt(e){return e.internal?.replayPlanStep===!0?!1:ht.has(e.command)}function _t(e,t){return!t.interactiveObservation||e.saveScriptBoundary===void 0?!1:t.flags?.record!==!0}const vt=[`platform`,`device`,`udid`,`serial`,`out`,`verbose`,`metroHost`,`metroPort`,`bundleUrl`,`launchUrl`,`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`,...oe,`relaunch`,`saveScript`,`force`,`noRecord`,`record`,`fps`,`quality`,`hideTouches`,`count`,`pointerCount`,`intervalMs`,`delayMs`,`holdMs`,`jitterPx`,`doubleTap`,`clickButton`,`pauseMs`,`pattern`];function yt(e){if(!e)return{};let t={};for(let n of vt)e[n]!==void 0&&(t[n]=e[n]);return t}function w(e){return e.startsWith(`@`)?n(e)?.base??e:e}const T=/^-?\d+(\.\d+)?$/,bt=/^[^\s"\\]+$/,xt=new Map([[`--count`,`count`],[`--interval-ms`,`intervalMs`],[`--hold-ms`,`holdMs`],[`--jitter-px`,`jitterPx`]]),St=new Map([[`--count`,`count`],[`--pause-ms`,`pauseMs`]]),Ct=new Map([[`--pointer-count`,`pointerCount`]]),wt=new Map([[`--delay-ms`,`delayMs`]]);function E(e){return e===`click`||e===`press`}function D(e){return E(e)||e===`longpress`}function Tt(e){return e===`type`||e===`fill`}function O(e){return Dt(e,Ot)}function Et(e){return JSON.stringify(e)}function k(e){return Dt(e,kt)}function Dt(e,t){return t(e)?e:Et(e)}function Ot(e){return kt(e)&&e.startsWith(`@`)||T.test(e)}function kt(e){return bt.test(e)}const At=new Set([`fill`,`type`]);function jt(e){if(!At.has(e.command)){let t=(e.positionals??[]).map(e=>O(e));return[e.command,...t].join(` `)}let t=Mt(e).map(e=>O(e)).join(` `);return[e.command,t,`<text>`].filter(e=>e.length>0).join(` `)}function Mt(e){if(e.command===`type`)return[];let t=e.positionals??[],n=t[0];return n===void 0?[]:n.startsWith(`@`)?[n]:t.length>=3&&T.test(n)&&T.test(t[1]??``)?[n,t[1]]:[n]}function A(e,t){let n=t.flags??{};if(E(t.command)){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.intervalMs==`number`&&e.push(`--interval-ms`,String(n.intervalMs)),typeof n.holdMs==`number`&&e.push(`--hold-ms`,String(n.holdMs)),typeof n.jitterPx==`number`&&e.push(`--jitter-px`,String(n.jitterPx)),n.doubleTap===!0&&e.push(`--double-tap`);let t=n.clickButton;t&&t!==`primary`&&e.push(`--button`,t);return}if(t.command===`swipe`){typeof n.count==`number`&&e.push(`--count`,String(n.count)),typeof n.pauseMs==`number`&&e.push(`--pause-ms`,String(n.pauseMs)),(n.pattern===`one-way`||n.pattern===`ping-pong`)&&e.push(`--pattern`,n.pattern);return}if(t.command===`gesture`){typeof n.pointerCount==`number`&&e.push(`--pointer-count`,String(n.pointerCount));return}Tt(t.command)&&typeof n.delayMs==`number`&&e.push(`--delay-ms`,String(n.delayMs))}function Nt(e,t){t&&((t.platform===`ios`||t.platform===`android`)&&e.push(`--platform`,t.platform),typeof t.metroHost==`string`&&t.metroHost.length>0&&e.push(`--metro-host`,k(t.metroHost)),typeof t.metroPort==`number`&&e.push(`--metro-port`,String(t.metroPort)),typeof t.bundleUrl==`string`&&t.bundleUrl.length>0&&e.push(`--bundle-url`,k(t.bundleUrl)),typeof t.launchUrl==`string`&&t.launchUrl.length>0&&e.push(`--launch-url`,k(t.launchUrl)))}function Pt(e,t){let[n,...r]=t.positionals??[];n&&e.push(k(n));for(let t of r)e.push(O(t));typeof t.flags?.fps==`number`&&e.push(`--fps`,String(t.flags.fps)),typeof t.flags?.screenshotMaxSize==`number`&&e.push(`--max-size`,String(t.flags.screenshotMaxSize)),(typeof t.flags?.quality==`number`||typeof t.flags?.quality==`string`)&&e.push(`--quality`,String(t.flags.quality)),t.flags?.hideTouches&&e.push(`--hide-touches`)}function Ft(e,t){t.flags?.snapshotInteractiveOnly&&e.push(`-i`),typeof t.flags?.snapshotDepth==`number`&&e.push(`-d`,String(t.flags.snapshotDepth)),t.flags?.snapshotScope&&e.push(`-s`,O(t.flags.snapshotScope)),t.flags?.snapshotRaw&&e.push(`--raw`)}function It(e,t){for(let n of t.positionals??[])e.push(O(n));ce(e,t.flags)}function Lt(e,t,n={}){let r=t.positionals??[],i=n.includeAllPositionals?r:r.slice(0,1);for(let t of i)e.push(k(t));Nt(e,t.flags)}function Rt(e,t){for(let n of t.positionals??[])e.push(O(t.command===`wait`?w(n):n));A(e,t)}function zt(e,t){let n=[],r={},i=E(e)?xt:e===`swipe`?St:e===`gesture`?Ct:Tt(e)?wt:void 0;for(let a=0;a<t.length;a+=1){let o=t[a];if(E(e)&&o===`--double-tap`){r.doubleTap=!0;continue}let s=t[a+1];if(E(e)&&o===`--button`&&s!==void 0){let e=s;(e===`primary`||e===`secondary`||e===`middle`)&&(r.clickButton=e),a+=1;continue}let c=i?.get(o);if(c&&s!==void 0){let e=Vt(s);if(e!==null){r[c]=e,a+=1;continue}}if(e===`swipe`&&o===`--pattern`&&s!==void 0){let e=s;(e===`one-way`||e===`ping-pong`)&&(r.pattern=e),a+=1;continue}n.push(o)}return{positionals:n,flags:r}}function Bt(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r],a=e[r+1];if(i===`--platform`&&a!==void 0){let e=a;(e===`ios`||e===`android`)&&(n.platform=e),r+=1;continue}if(i===`--metro-host`&&a!==void 0){n.metroHost=a,r+=1;continue}if(i===`--metro-port`&&a!==void 0){let e=Vt(a);e!==null&&(n.metroPort=e),r+=1;continue}if(i===`--bundle-url`&&a!==void 0){n.bundleUrl=a,r+=1;continue}if(i===`--launch-url`&&a!==void 0){n.launchUrl=a,r+=1;continue}t.push(i)}return{positionals:t,flags:n}}function Vt(e){if(!e)return null;let t=Number(e);return!Number.isFinite(t)||t<0?null:Math.floor(t)}function Ht(e,t){for(let n of t.positionals??[])e.push(O(n));t.flags?.relaunch&&e.push(`--relaunch`),Nt(e,t.runtime)}function Ut(e){let t=[],n={};for(let r of e){if(r===`--relaunch`){n.relaunch=!0;continue}t.push(r)}let r=Bt(t);return{positionals:r.positionals,flags:n,runtime:Wt(r.flags)?r.flags:void 0}}function Wt(e){return!!(e.platform||e.metroHost||e.metroPort!==void 0||e.bundleUrl||e.launchUrl)}function Gt(e,t={}){let n=[e.command];return e.command===`snapshot`?Ft(n,e):e.command===`open`?Ht(n,e):e.command===`runtime`?Lt(n,e,{includeAllPositionals:t.runtimeIncludeAllPositionals}):e.command===`record`?Pt(n,e):e.command===`screenshot`?It(n,e):Rt(n,e),n.join(` `)}function Kt(e){return e.targetEvidence?[ve(e.targetEvidence)]:[]}function qt(e){let n=e.flatMap((e,t)=>e.command===`open`?[t]:[]);if(n.length!==1||n[0]!==0)throw new t(`COMMAND_FAILED`,`Cannot publish this session: an open-to-destination script requires exactly one initial recorded open.`,{retriable:!1,hint:`Close this session and start a fresh one with open <app> --save-script[=<path>].`});if(e.some(e=>e.command===`close`))throw new t(`COMMAND_FAILED`,`Cannot publish an active-session script containing close.`,{retriable:!1,hint:`Close this session and record the journey again from a fresh open --save-script session.`});let r=-1;for(let[t,n]of e.entries())a({command:n.command,positionals:n.positionals,flags:n.flags})===`mutates-app`&&(r=t);if(!e.slice(r+1).some(Xt))throw new t(`COMMAND_FAILED`,`Cannot publish this session without a portable destination guard after the final mutating action.`,{retriable:!0,hint:`Record a selector-targeted wait on a labeled or id-bearing landmark, for example wait 'role="heading" label="Screen X"', so its recorded identity is captured, then retry session save-script.`})}function Jt(e){for(let n of e){let e=Zt(n),r=e??(n.command===`wait`?n.positionals[0]:void 0);if(r?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${r}": the session-local ref was not converted to a portable selector.`,{retriable:!1,hint:`Close this session and record the journey again using selectors or resolvable refs.`});if(n.command===`find`&&a(n)===`mutates-app`)throw new t(`COMMAND_FAILED`,`Cannot publish a recorded mutating find step because its target identity is not replay-verifiable.`,{retriable:!1,hint:`Close this session and record the journey again with an explicit selector-targeted click, press, fill, or focus action.`});let i=e;if(!(!i||!s(i)||n.targetEvidence))throw new t(`COMMAND_FAILED`,`Cannot publish recorded step "${n.command} ${i}": recording-time target identity evidence is missing.`,{retriable:!1,hint:`Close this session and record the journey again from open --save-script so target-v1 evidence is captured before each interaction.`})}}function Yt(e,n){if(e instanceof t){if(e.details?.reason===`script_target_exists`)return new t(e.code,`A file already exists at ${String(e.details.path)}.`,{...e.details,retriable:!0,hint:`Retry session save-script with another path, or pass --force to replace the existing file. The session remains armed.`});let n=e.details?.retriable===!0;return new t(e.code,e.message,{...e.details,retriable:n,hint:e.details?.hint??(n?`Fix the recorded journey or target, then retry session save-script. The session remains armed.`:`Close this session and start a fresh one with open <app> --save-script[=<path>].`)})}let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to publish the active session script${n?` to ${n}`:``}: ${r}`,{retriable:!0,hint:`Check the target path and permissions, then retry session save-script. The session remains armed.`})}function Xt(e){if(e.command!==`wait`)return!1;let t=o(e.positionals);return t?.kind!==`selector`||s(t.selectorExpression)===null?!1:e.targetEvidence?.verification===`verified`}function Zt(e){if(e.command===`get`)return e.positionals[1];if(D(e.command)||e.command===`fill`){let[t,n]=e.positionals;return t!==void 0&&n!==void 0&&Qt(t)&&Qt(n)?void 0:t}}function Qt(e){return e.trim().length>0&&Number.isFinite(Number(e))}function $t(e){return e.saveScriptBoundary===void 0?!1:e.saveScriptCommitted?!0:!e.saveScriptComplete}var en=class{sessionsDir;constructor(e){this.sessionsDir=e}write(e,t){let n=e.saveScriptBoundary!==void 0,r=t?.publication===`active`,i;try{if(!e.recordSession||$t(e))return{written:!1};let a=tn(e,{appendCompleteSentinel:n,activePublication:r});i=this.resolveScriptPath(e);let o=h.dirname(i);return m.existsSync(o)||m.mkdirSync(o,{recursive:!0}),an({scriptPath:i,script:a.script,force:t?.force}),n&&(e.saveScriptCommitted=!0),{written:!0,path:i,actionCount:a.actionCount}}catch(t){return nn({session:e,error:t,scriptPath:i,repairArmed:n,activePublication:r})}}resolveScriptPath(e){if(e.saveScriptPath)return _(e.saveScriptPath);let t=g(e.name),n=new Date(e.createdAt).toISOString().replace(/[:.]/g,`-`);return h.join(this.sessionsDir,`${t}-${n}.ad`)}};function tn(e,t){let n=on(e,{strictPortableRefs:t.activePublication});return t.activePublication&&qt(n),{script:hn(e,n,t.appendCompleteSentinel),actionCount:n.length}}function nn(e){let{session:n,error:r,scriptPath:a,repairArmed:o,activePublication:s}=e;if(i({level:`warn`,phase:`session_script_write_failed`,data:{session:n.name,path:a,error:r instanceof Error?r.message:String(r)}}),o)return{written:!1,error:rn(r,a)};if(s)return{written:!1,error:Yt(r,a)};if(r instanceof t)throw r;return{written:!1}}function rn(e,n){if(e instanceof t)return e;let r=e instanceof Error?e.message:String(e);return new t(`COMMAND_FAILED`,`Failed to write the healed script${n?` to ${n}`:``}: ${r}`,{hint:`The repair transaction completed but the healed .ad could not be published; check the target path and permissions, then retry close --save-script.`})}function an(e){let{scriptPath:n,script:r,force:i}=e,a=h.dirname(n),o=h.join(a,`.${h.basename(n)}.${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`);m.writeFileSync(o,r);try{if(i){m.renameSync(o,n);return}m.linkSync(o,n)}catch(e){throw e.code===`EEXIST`?new t(`COMMAND_FAILED`,`A file already exists at ${n}; remove it, pass replay --save-script=<other-path>, or pass --force/--overwrite to replace it.`,{reason:`script_target_exists`,path:n}):e}finally{m.rmSync(o,{force:!0})}}function on(e,t={}){let n=e.saveScriptBoundary!==void 0,r=e.actions.slice(e.saveScriptBoundary??0),i=[];for(let a of r){if(a.command===`snapshot`)continue;let r=cn(a);if(r){i.push(r);continue}(n||t.strictPortableRefs)&&sn(a);let o=mn(e,a);o&&i.push(o),i.push(a)}return t.strictPortableRefs&&Jt(i),i}function sn(e){if(!j(e.command))return;let n=e.command===`get`?e.positionals?.[1]:e.positionals?.[0];if(n?.startsWith(`@`))throw new t(`COMMAND_FAILED`,`Cannot write recorded step "${e.command} ${n}" to a script: it never resolved to a selector, so the ref would not resolve in a fresh replay session.`)}function cn(e){let t=ln(e);if(!(!t||!j(e.command)))return E(e.command)?{...e,positionals:[t]}:e.command===`longpress`?dn(e,t):e.command===`fill`?un(e,t):fn(e,t)}function ln(e){let t=Array.isArray(e.result?.selectorChain)&&e.result.selectorChain.every(e=>typeof e==`string`)?e.result.selectorChain:[];return t.length>0?t.join(` || `):void 0}function j(e){return D(e)||e===`fill`||e===`get`}function un(e,t){let n=v(e);return n.length>0?{...e,positionals:[t,n]}:void 0}function dn(e,t){let n=typeof e.result?.durationMs==`number`?String(e.result.durationMs):pn(e.positionals??[]);return{...e,positionals:n?[t,n]:[t]}}function fn(e,t){let n=e.positionals?.[0];return n===`text`||n===`attrs`?{...e,positionals:[n,t]}:void 0}function pn(e){let t=e.at(-1);if(!(e.length<=1||t===void 0||t.trim()===``))return Number.isFinite(Number(t))?t:void 0}function mn(e,t){if(!j(t.command))return;let n=t.result?.refLabel;if(typeof n!=`string`||n.trim().length===0)return;let r=n.trim();return{ts:t.ts,command:`snapshot`,positionals:[],flags:{platform:e.device.platform,snapshotInteractiveOnly:!0,snapshotScope:r},result:{scope:r}}}function hn(e,t,n){let r=[],i=e.device.kind?` kind=${e.device.kind}`:``;r.push(`context platform=${me(e.device)} device=${Et(e.device.name)}${i} theme=unknown`);for(let e of t)e.flags?.noRecord||(r.push(...Kt(e)),r.push(gn(e)));return n&&r.push(`# agent-device:heal-complete`),`${r.join(`
|
|
2
|
-
`)}\n`}function gn(e){return _n([e.command],e)||Gt(e)}function _n(e,t){if(E(t.command))return vn(e,t);if(t.command===`fill`)return yn(e,t);if(t.command===`get`)return bn(e,t)}function vn(e,t){let n=t.positionals?.[0];if(n){if(n.startsWith(`@`))return e.push(O(w(n))),M(e,t),A(e,t),e.join(` `);if(t.positionals.length===1)return e.push(O(n)),A(e,t),e.join(` `)}}function yn(e,t){let n=t.positionals?.[0];if(!n?.startsWith(`@`))return;e.push(O(w(n))),M(e,t);let r=t.positionals.slice(1).join(` `);return t.positionals.length>1&&e.push(O(r)),A(e,t),e.join(` `)}function bn(e,t){let n=t.positionals?.[0],r=t.positionals?.[1];if(!(!n||!r))return e.push(O(n)),e.push(O(w(r))),r.startsWith(`@`)&&M(e,t),e.join(` `)}function M(e,t){let n=t.result?.refLabel;typeof n==`string`&&n.trim().length>0&&e.push(O(n))}const xn=[`status`,`get`,`dismiss`,`enter`,`return`];function N(e){return xn.includes(e)}const Sn=[`id`,`deviceId`,`device_id`,`serial`,`udid`,`device_udid`,`identifier`],Cn={ios:`iOS`,ipados:`iPadOS`,tvos:`tvOS`,watchos:`watchOS`,visionos:`visionOS`,macos:`macOS`,apple:`Apple`,android:`Android`,linux:`Linux`,web:`Web`};function wn(e,t){let n=t??{};switch(e.command){case f.devices:return Tn(n.devices);case f.apps:return En(n.apps,e.flags?.appsFilter);case f.boot:return Dn(`Booted`,n,!0);case f.shutdown:return Dn(`Shut down`,n,!1);case f.install:return On(`Installed`,n);case f.reinstall:return On(`Reinstalled`,n);case f.screenshot:return kn(e,n);default:return{}}}function Tn(e){if(!Array.isArray(e))return{};let t=e.flatMap(e=>{let t=jn(e);return t?[t]:[]}),n=t.slice(0,5),r=Math.max(0,t.length-n.length),i=t.slice(0,3);return{summary:Bn(`Found ${t.length} ${Vn(`device`,t.length)}`,i.map(e=>Rn(e,!0)),Math.max(0,t.length-i.length)),details:{deviceCount:t.length,devices:n,...r>0?{omittedDeviceCount:r}:{}}}}function En(e,t){if(!Array.isArray(e))return{};let n=e.flatMap(e=>{let t=I(e);return t?[t]:[]}),r=n.slice(0,5),i=Math.max(0,n.length-r.length),a=n.slice(0,3);return{summary:Bn(`Found ${n.length} ${Vn(`app`,n.length)}`,a,Math.max(0,n.length-a.length)),details:{appCount:n.length,apps:r,...i>0?{omittedAppCount:i}:{},...t===`all`||t===`user-installed`?{filter:t}:{}}}}function Dn(e,t,n){let r=Mn(t);if(!r)return{};let i={device:r,...Ln(t),booted:n};return{summary:`${e} ${Rn(i,!1)}`,details:i}}function On(e,t){let n=I(t.appName),r=I(t.bundleId),i=P(t,[`packageName`,`package`]),a=I(t.platform),o=I(t.launchTarget),s=P(t,[`bundleId`,`packageName`,`package`,`appId`,`launchTarget`]),c=zn(n,s);if(!c)return{};let l={};return F(l,`appName`,n),F(l,`bundleId`,r),F(l,`packageName`,i),F(l,`platform`,a),o!==s&&F(l,`launchTarget`,o),{summary:`${e} ${c}`,details:l}}function kn(e,t){let n=An(e,t);return n?{details:{requestedFileName:n}}:{}}function An(e,t){let n=H(e.meta?.clientArtifactPaths?.path)??H(t.path);if(n)return V(n)}function jn(e){if(!u(e))return;let t=Mn(e);if(t)return{name:t,...Ln(e)}}function Mn(e){let t=P(e,[`name`,`deviceName`,`device`]);return!t||!Nn(e,t)?t:Fn(e)}function Nn(e,t){let n=Pn(t);return Sn.some(t=>{let r=I(e[t]);return r!==void 0&&Pn(r)===n})}function Pn(e){return e.toLowerCase()}function Fn(e){let t=I(e.appleOs),n=I(e.platform),r=I(e.kind),i=In(t,n);return i&&(r===`simulator`||r===`emulator`)?`${i} ${r}`:i?`${i} device`:r===`simulator`?`Simulator`:r===`emulator`?`Emulator`:`Unnamed device`}function In(e,t){let n=e??t;if(!(!n||!Object.hasOwn(Cn,n)))return Cn[n]}function Ln(e){let t=I(e.platform),n=I(e.appleOs),r=I(e.kind),i=I(e.target);return{...t?{platform:t}:{},...n?{appleOs:n}:{},...r?{kind:r}:{},...i?{target:i}:{},...typeof e.booted==`boolean`?{booted:e.booted}:{}}}function Rn(e,t){let n=I(e.name)??I(e.device)??`device`,r=I(e.platform),i=I(e.appleOs),a=[r,i===r?void 0:i,I(e.kind),I(e.target),t&&typeof e.booted==`boolean`?e.booted?`booted`:`stopped`:void 0].filter(e=>!!e);return a.length>0?`${n} (${a.join(`, `)})`:n}function zn(e,t){return e&&t&&e!==t?`${e} (${t})`:e??t}function P(e,t){for(let n of t){let t=I(e[n]);if(t)return t}}function F(e,t,n){n&&(e[t]=n)}function Bn(e,t,n){let r=[...t,...n>0?[`+${n} more`]:[]];return r.length>0?`${e}: ${r.join(`, `)}`:e}function Vn(e,t){return t===1?e:`${e}s`}function I(e){let t=H(e);if(!t)return;let n=t.trim(),r=Array.from(n);return r.length<=120?n:`${r.slice(0,119).join(``)}…`}function L(e){return I(e)}function R(e){return typeof e==`boolean`?e:void 0}function z(e,t){let n=L(e);return n&&t.includes(n)?n:void 0}function B(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function V(e){let t=H(e);return t?I(t.split(/[\\/]/).at(-1)):void 0}function H(e){if(typeof e==`string`)return e.trim().length>0?e:void 0}function U(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}const Hn=[`up`,`down`,`left`,`right`],Un=[`top`,`bottom`];function Wn(e){return`${e.command===f.reinstall?`Reinstalled`:`Installed`} ${Jn(e.result??{})??`app`}`}function Gn(e){let t=e.result??{};switch(e.command){case f.scroll:return Xn(t);case f.screenshot:return $n(t);case f.home:return`Went home`;case f.back:return tr(t);case f.appSwitcher:return`Opened app switcher`;case f.orientation:return nr(t);case f.viewport:return rr(t);case f.clipboard:return ir(t);case f.keyboard:return ar(t);case f.tvRemote:return sr(t);case f.gesture:return cr(t);case f.swipe:return lr(t);case f.trace:return dr(`trace`,e);case f.record:return dr(`recording`,e);default:return}}function Kn(e){let t=e.result??{};switch(e.command){case f.scroll:return B({direction:z(t.direction,Hn),edge:z(t.edge,Un),passes:U(t.passes),amount:U(t.amount),pixels:U(t.pixels),durationMs:U(t.durationMs),x1:U(t.x1),y1:U(t.y1),x2:U(t.x2),y2:U(t.y2)});case f.screenshot:return B({requestedFileName:er(t)});case f.back:return B({mode:z(t.mode,d)});case f.orientation:return B({orientation:z(t.orientation,ee)});case f.viewport:return B({width:U(t.width),height:U(t.height)});case f.clipboard:return B({action:z(t.action,[`read`,`write`])});case f.keyboard:return or(t);case f.tvRemote:return B({button:z(t.button,ae),durationMs:U(t.durationMs)});case f.gesture:case f.swipe:return ur(t);case f.trace:case f.record:return B({action:z(t.action,[`start`,`stop`]),fileName:pr(e),showTouches:R(t.showTouches)});default:return{}}}function qn(e,t){if(e.command!==f.screenshot)return t;let n=An(e,t);return n?{...t,requestedFileName:n}:t}function Jn(e){let t=L(e.appName),n=mr(e,[`bundleId`,`packageName`,`appBundleId`,`launchTarget`]);return t&&n&&t!==n?`${t} (${n})`:t??n??Yn(e)}function Yn(e){let t=L(e.app);return t&&!t.includes(`/`)&&!t.includes(`\\`)?t:void 0}function Xn(e){let t=z(e.direction,Hn),n=z(e.edge,Un),r=U(e.passes);return n?Zn(n,r):t?Qn(t,e):`Scrolled`}function Zn(e,t){return t===0?`Already at ${e}`:t===void 0?`Scrolled to ${e}`:`Scrolled to ${e} in ${t} ${t===1?`pass`:`passes`}`}function Qn(e,t){let n=U(t.pixels);if(n!==void 0)return`Scrolled ${e} by ${n}px`;let r=U(t.amount);return r===void 0?`Scrolled ${e}`:`Scrolled ${e} by ${r}`}function $n(e){let t=er(e);return t?`Captured screenshot ${t}`:`Captured screenshot`}function er(e){return V(e.requestedFileName)??V(e.path)}function tr(e){return z(e.mode,d)===`system`?`Went back using system navigation`:`Went back`}function nr(e){let t=z(e.orientation,ee);return t?`Rotated to ${t}`:`Changed orientation`}function rr(e){let t=U(e.width),n=U(e.height);return t!==void 0&&n!==void 0?`Set viewport to ${t}×${n}`:`Changed viewport`}function ir(e){let t=z(e.action,[`read`,`write`]);return t===`read`?`Read clipboard`:t===`write`?`Updated clipboard`:`Used clipboard`}function ar(e){let t=H(e.action);if(!t||!N(t))return`Used keyboard`;if(t===`dismiss`)return R(e.dismissed)===!1?`Keyboard was already hidden`:`Dismissed keyboard`;if(t===`enter`||t===`return`)return`Pressed keyboard return`;let n=R(e.visible);return n===void 0?`Inspected keyboard`:n?`Keyboard is visible`:`Keyboard is hidden`}function or(e){let t=H(e.action);return B({action:t&&N(t)?t:void 0,platform:z(e.platform,[`ios`,`android`]),visible:R(e.visible),wasVisible:R(e.wasVisible),dismissed:R(e.dismissed),attempts:U(e.attempts)})}function sr(e){let t=z(e.button,ae);return t?`Pressed TV remote ${t}`:`Used TV remote`}function cr(e){let t=z(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]);return t?`Ran ${t} gesture`:`Ran gesture`}function lr(e){let t=U(e.count);return t!==void 0&&t>1?`Swiped ${t} times`:`Swiped`}function ur(e){return B({kind:z(e.kind,[`fling`,`pan`,`pinch`,`rotate`,`transform`]),durationMs:U(e.durationMs),pointerCount:U(e.pointerCount),x1:U(e.x1),y1:U(e.y1),x2:U(e.x2),y2:U(e.y2),count:U(e.count),pauseMs:U(e.pauseMs),pattern:z(e.pattern,[`one-way`,`ping-pong`]),scale:U(e.scale)})}function dr(e,t){let n=fr(e,z(t.result?.action,[`start`,`stop`])),r=pr(t);return r?`${n} ${r}`:n}function fr(e,t){return t===`start`?e===`trace`?`Started trace`:`Started recording`:t===`stop`?e===`trace`?`Stopped trace`:`Stopped recording`:e===`trace`?`Updated trace`:`Updated recording`}function pr(e){let t=e.result??{};return V(t.requestedFileName)??V(t.outPath)??V(t.path)??V(e.positionals[1])}function mr(e,t){for(let n of t){let t=L(e[n]);if(t)return t}}function hr(e){switch(e.command){case f.open:return`Opened ${W(e)??`session`}`;case f.close:return`Closed ${L(e.result?.session)??`session`}`;case f.click:case f.press:return`Tapped ${W(e)??`target`}`;case f.longPress:return`Long pressed ${W(e)??`target`}`;case f.fill:return`Filled ${W(e)??`target`}`;case f.type:return`Typed text`;case f.install:case f.reinstall:case le.installSource:return Wn(e);default:return Gn(e)??`Ran ${e.command}`}}function gr(e){return B({command:e.command,positionals:Tr(e),flags:Ir(e),..._r(e),...vr(e),...yr(e),...Kn(e)})}function _r(e){if(!br(e.command))return{};let t=e.result??{};return B({ref:J(t),targetLabel:W(e),selectorChainLength:Nr(t.selectorChain)?.length,x:U(t.x),y:U(t.y),x2:U(t.x2),y2:U(t.y2),durationMs:U(t.durationMs)})}function vr(e){if(!xr(e.command))return{};let t=e.result??{};return B({platform:z(t.platform,ge),target:z(t.target,_e),appName:L(t.appName),appBundleId:L(t.appBundleId),bundleId:L(t.bundleId),packageName:L(t.packageName),launchTarget:L(t.launchTarget)})}function yr(e){let t=e.result??{};return e.command===f.snapshot?{...Array.isArray(t.nodes)?{nodeCount:t.nodes.length}:{}}:e.command!==f.wait&&e.command!==f.find&&e.command!==f.get&&e.command!==f.is?{}:B({waitedMs:U(t.waitedMs),found:R(t.found)})}function br(e){return e===f.click||e===f.press||e===f.longPress||e===f.focus||e===f.fill}function xr(e){return e===f.open||e===f.install||e===f.reinstall||e===le.installSource}function W(e){let t=e.result??{};return Sr(t)??Cr(t)??wr(t)??jr(e.positionals[0])}function Sr(e){let t=J(e);if(t)return t.startsWith(`@`)?t:`@${t}`}function Cr(e){let t=U(e.x),n=U(e.y);if(t!==void 0&&n!==void 0)return`(${t}, ${n})`}function wr(e){return L(e.appName)??L(e.appBundleId)??L(e.bundleId)??L(e.packageName)}function Tr(e){if(e.positionals.length!==0)return e.command===f.type?[K(`text`)]:e.command===f.fill?Er(e):e.command===f.find?Dr(e):e.command===f.clipboard?Or(e):e.command===f.push?kr(e,`app`,`payload`):e.command===f.triggerAppEvent?kr(e,`event`,`payload`):e.positionals.map(G)}function Er(e){let t=K(`text`),n=e.result??{},r=J(n);if(r)return[`@${r}`,t];if(L(n.selector))return[K(`target`),t];let i=U(n.x),a=U(n.y);return i!==void 0&&a!==void 0?[String(i),String(a),t]:[t]}function Dr(e){let t=+!!Mr(e.positionals[0]);if(e.positionals[t]===void 0)return;let n=t+1,r=[...t===1?[String(e.positionals[0])]:[],K(`query`)],i=e.positionals[n];return i?i===`fill`||i===`type`?[...r,i,K(`text`)]:[...r,...e.positionals.slice(n).map(Ar)]:r}function Or(e){let t=e.positionals[0]?.toLowerCase();return t===`read`?[`read`]:t===`write`?[`write`,K(`text`)]:e.positionals.map(G)}function kr(e,t,n){let[r,i,...a]=e.positionals;return[...r?[K(t)]:[],...i?[K(n)]:[],...a.map(G)]}function Ar(e){return e===`click`||e===`focus`||e===`exists`||e===`get`||e===`text`||e===`attrs`||e===`wait`?e:G(e)}function G(e){return jr(e)??K(`arg`)}function jr(e){if(!e)return;let t=e.trim();if(/^@[a-zA-Z0-9:_-]+$/.test(t))return t}function K(e){return`<${e}>`}function Mr(e){return e===`text`||e===`label`||e===`value`||e===`role`||e===`id`}function Nr(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)?e:void 0}const Pr={enums:[{source:`platform`,values:he},{source:`target`,values:_e}]},Fr={[f.open]:{booleans:[{source:`relaunch`},{source:`testIme`}],enums:[{source:`surface`,values:te}]},[f.click]:q(),[f.press]:q(),[f.longPress]:q(),[f.fill]:Lr(),[f.type]:Lr(),[f.scroll]:{numbers:[{source:`pixels`},{source:`durationMs`}]},[f.gesture]:Rr(),[f.swipe]:Rr(),[f.screenshot]:{booleans:[{source:`overlayRefs`},{source:`screenshotFullscreen`,output:`fullscreen`},{source:`screenshotNoStabilize`,output:`noStabilize`},{source:`screenshotNormalizeStatusBar`,output:`normalizeStatusBar`}],numbers:[{source:`screenshotPixelDensity`,output:`pixelDensity`},{source:`screenshotMaxSize`,output:`maxSize`}]},[f.snapshot]:{booleans:[{source:`snapshotInteractiveOnly`,output:`interactiveOnly`},{source:`snapshotDiff`,output:`diff`},{source:`snapshotRaw`,output:`raw`},{source:`snapshotForceFull`,output:`forceFull`}],numbers:[{source:`snapshotDepth`,output:`depth`}]},[f.back]:{enums:[{source:`backMode`,output:`mode`,values:d}]},[f.record]:{booleans:[{source:`hideTouches`}],numbers:[{source:`fps`},{source:`screenshotMaxSize`,output:`maxSize`}],enums:[{source:`recordingScope`,output:`scope`,values:ne}]},[f.apps]:{enums:[{source:`appsFilter`,output:`filter`,values:[`user-installed`,`all`]}]},[f.boot]:{booleans:[{source:`headless`}]},[f.close]:{booleans:[{source:`shutdown`}]}};function Ir(e){let t=e.flags??{},n={},r=Object.hasOwn(Fr,e.command)?Fr[e.command]:void 0;return zr(n,t,Pr),zr(n,t,r),Object.keys(n).length>0?n:void 0}function q(){return{booleans:[{source:`doubleTap`},{source:`settle`}],numbers:[{source:`count`},{source:`intervalMs`},{source:`holdMs`},{source:`jitterPx`},{source:`settleQuietMs`}],enums:[{source:`clickButton`,values:se}]}}function Lr(){return{booleans:[{source:`settle`}],numbers:[{source:`delayMs`},{source:`settleQuietMs`}]}}function Rr(){return{numbers:[{source:`pointerCount`},{source:`count`},{source:`pauseMs`}],enums:[{source:`pattern`,values:re}]}}function zr(e,t,n){n&&(Br(e,t,n.booleans??[]),Vr(e,t,n.numbers??[]),Hr(e,t,n.enums??[]))}function Br(e,t,n){for(let r of n)Ur(e,r.output??r.source,t[r.source])}function Vr(e,t,n){for(let r of n)Wr(e,r.output??r.source,t[r.source])}function Hr(e,t,n){for(let r of n)Gr(e,r.output??r.source,t[r.source],r.values)}function J(e){let t=L(e.ref);if(!t)return;let n=t.startsWith(`@`)?t.slice(1):t;return/^[a-zA-Z0-9:_-]+$/.test(n)?n:void 0}function Ur(e,t,n){typeof n==`boolean`&&(e[t]=n)}function Wr(e,t,n){let r=U(n);r!==void 0&&(e[t]=r)}function Gr(e,t,n,r){let i=z(n,r);i!==void 0&&(e[t]=i)}const Y=new Map,Kr=new Set;function qr(e){return h.join(e,`events.ndjson`)}function Jr(e){return e.command!==f.events}function Yr(t,n,r){let i=e({version:1,ts:r.ts??new Date().toISOString(),session:n,...r});Zr(t,`${JSON.stringify(i)}\n`)}async function Xr(e){await(e?Y.get(e):Promise.all(Y.values()))}function Zr(e,t){let n=(Y.get(e)??Promise.resolve()).catch(()=>void 0).then(async()=>{await Qr(e),await m.promises.appendFile(e,t,`utf8`)}).catch(t=>{i({level:`warn`,phase:`session_event_log_write_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}})}).finally(()=>{Y.get(e)===n&&Y.delete(e)});Y.set(e,n)}async function Qr(e){let t=h.dirname(e);if(!Kr.has(t))try{await m.promises.mkdir(t,{recursive:!0}),Kr.add(t)}catch(t){throw i({level:`warn`,phase:`session_event_log_dir_failed`,data:{path:e,error:t instanceof Error?t.message:String(t)}}),t}}function $r(e,t,n){Yr(e,t,{kind:`action.recorded`,requestId:r().requestId,command:n.command,summary:hr(n),details:gr(n)})}function ei(e){let{req:t}=e;return{kind:`request.started`,requestId:t.meta?.requestId??r().requestId,command:t.command,summary:`Started ${t.command}`}}function ti(e){let{req:t,response:n,durationMs:i}=e;if(n.ok){let e=wn(t,n.data);return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`ok`,summary:e.summary??`Finished ${t.command}`,details:{durationMs:i,...e.details}}}return{kind:`request.finished`,requestId:t.meta?.requestId??r().requestId,command:t.command,status:`error`,summary:`Failed ${t.command}: ${n.error.code}`,details:{durationMs:i,code:n.error.code,diagnosticId:n.error.diagnosticId}}}function ni(e,t={}){let n=si(t.cursor),r=ci(t.limit);if(!m.existsSync(e))return{path:e,cursor:String(n),limit:r,events:[]};let i=ri(e,n,r),a=i.lines.flatMap(e=>{let t=li(e);return t?[t]:[]});return{path:e,cursor:String(n),limit:r,events:a,...i.nextCursor===void 0?{}:{nextCursor:String(i.nextCursor)}}}function ri(e,t,n){let r=m.openSync(e,`r`);try{let e=new Ce(`utf8`),i=Buffer.allocUnsafe(65536),a=ii(t,n),o=``,s=0;do{s=m.readSync(r,i,0,i.length,null);let t=e.write(i.subarray(0,s));o=ai(`${o}${t}`,a)}while(s>0&&a.nextCursor===void 0);let c=`${o}${e.end()}`;return a.nextCursor===void 0&&c.length>0&&oi(c,a),{lines:a.lines,nextCursor:a.nextCursor}}finally{m.closeSync(r)}}function ii(e,t){return{cursor:e,limit:t,lineIndex:0,lines:[]}}function ai(e,t){let n=0;for(let r=e.indexOf(`
|
|
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(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,...
|
|
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 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:
|
|
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{I as n,j as r}from"./sdk-android-adb.js";import{z as i}from"./sdk-batch-runner.js";import{At as a,Dt as o,Et as s,Qn as c,kt as l,wt as u,xt as d}from"./recording-export-quality.js";import{i as f,q as p}from"./snapshot-diagnostics.js";import{c as m,h,s as g}from"./sdk-device.js";import{t as _}from"./timeouts.js";import{i as v}from"./android-system-chrome.js";import{t as y}from"./runtime.js";import{l as b,n as x,s as S,t as C}from"./context.js";import{i as ee}from"./helper.js";import{a as w}from"./runner-client.js";import{Lt as T,Nt as E,Rt as D,Sn as O,Xt as k,en as A,on as te,rn as j,sn as ne,tn as re,u as ie,zt as ae}from"./internal/daemon.js";import{l as oe,n as M}from"./input-actions.js";import{C as N,S as P,b as F,i as I,o as L,x as R}from"./selector-runtime.js";import{promises as z}from"node:fs";import B from"node:os";import V from"node:path";async function H(e,t,n={}){return t===`wait`?await U(e,n.timeoutMs??1e4):t===`get`?q((await K(e))?.alert??null):await W(e,t)}async function U(e,n){let r=Date.now(),i=await G(e,n);if(!i)throw new t(`COMMAND_FAILED`,`alert wait timed out`);return{kind:`alertWait`,platform:`android`,action:`wait`,alert:i.alert,waitedMs:Date.now()-r,...c(`Alert visible`)}}async function W(e,n){let r=await G(e,l);if(!r)throw new t(`COMMAND_FAILED`,`alert not found`,{hint:`If a sheet is visible in snapshot but alert reports no alert, it is likely app-owned UI. Use snapshot -i and press the visible label/ref.`});let i=D(r.buttons,n);if(i)return await oe(e,i.x,i.y),J(n,r.alert,i.label);if(n===`dismiss`)return await M(e),J(n,r.alert,`Back`);throw new t(`COMMAND_FAILED`,`alert accept found an alert but no accept button`,{alert:r.alert,hint:`Inspect alert get --json for visible buttons, then use press by visible label/ref if needed.`})}async function G(e,t){let n=Date.now();for(;Date.now()-n<t;){let t=await K(e);if(t)return t;await _(300)}return null}async function K(e){return ae((await n(`snapshot_capture`,async()=>await T(e,{helperWaitForIdleTimeoutMs:0,includeHiddenContentHints:!1}),{backend:`android`,purpose:`alert`})).nodes)}function q(e){return{kind:`alertStatus`,platform:`android`,action:`get`,alert:e,...c(e?`Alert visible`:`No alert visible`)}}function J(e,t,n){return{kind:`alertHandled`,platform:`android`,action:e,handled:!0,alert:t,button:n,...c(`Alert ${e}ed`)}}async function se(e){let{req:t,logPath:n,session:r,device:a}=e,o=ce(t.positionals?.[0]),s=r?r.surface===`frontmost-app`?{surface:`frontmost-app`}:{bundleId:r.appBundleId,surface:r.surface}:{},c=b(`alert`,a);if(c)return c;if(r&&O(t)===`may-invalidate`&&j(r),a.platform===`android`)return Z(e,await H(a,o,{timeoutMs:i(t.positionals?.[1])??1e4}));if(m(a))return await Y(e,o,async e=>await ee(e,s));let l=ie({req:t,logPath:n,traceLogPath:r?.trace?.outPath});return await Y(e,o,async(e,t)=>await w(a,{command:`alert`,action:e,appBundleId:r?.appBundleId,timeoutMs:t},l))}async function Y(e,t,n){if(t===`wait`)return await le(e,n);let r=t===`accept`||t===`dismiss`?t:`get`;return r===`accept`||r===`dismiss`?await ue(e,r,n):Z(e,await n(`get`,a))}function ce(e){return e===`accept`||e===`dismiss`||e===`wait`?e:`get`}async function le(e,t){let n=i(e.req.positionals?.[1])??1e4,r=Date.now(),a=!0;for(;Date.now()-r<n;){try{let i=a?n:X(r,n);return a=!1,Z(e,await t(`get`,i))}catch{}await _(300)}return S(`COMMAND_FAILED`,`alert wait timed out`)}async function ue(e,t,n){let r=g(e.device)?a:l,i=Date.now(),o,s=!0;for(;Date.now()-i<l;){try{let a=s?r:X(i,l);return s=!1,Z(e,await n(t,a))}catch(e){o=e;let t=String(e?.message??``).toLowerCase();if(!t.includes(`alert not found`)&&!t.includes(`no alert`))break}await _(300)}throw de(o)}function X(e,t){return Math.max(1,t-(Date.now()-e))}function Z(e,t){let n=t;return R(e.sessionStore,e.session,e.req,n),{ok:!0,data:n}}function de(e){return!(e instanceof t)||!fe(e)?e:new t(e.code,e.message,{...e.details??{},hint:`If the permission sheet is visible in snapshot or screenshot but alert reports no alert, take a scoped snapshot around the visible button label and use press @ref.`})}function fe(e){let t=String(e?.message??``).toLowerCase();return t.includes(`alert not found`)||t.includes(`no alert`)}function pe(e){let t=e.positionals?.[0]?.toLowerCase(),n=e.positionals?.[1]?.toLowerCase(),r=e.positionals?.[2]?.toLowerCase();return t===`clear-app-state`?{ok:!0,parsed:{setting:t,state:`clear`,appBundleId:n===`clear`?e.positionals?.[2]:e.positionals?.[1]}}:!t||!n||t===`permission`&&!r||t===`location`&&n===`set`&&(!e.positionals?.[2]||!e.positionals?.[3])?S(`INVALID_ARGS`,u):{ok:!0,parsed:{setting:t,state:n,permissionTarget:r,latitude:e.positionals?.[2],longitude:e.positionals?.[3]}}}async function me(e){let{req:t,logPath:n,sessionStore:r,session:i,device:a,parsed:c}=e,{setting:l,state:u,appBundleId:d,permissionTarget:f,latitude:p,longitude:h}=c,g=b(`settings`,a);if(g)return g;if(m(a)&&!o(l))return S(`INVALID_ARGS`,s(l));let _=d??i?.appBundleId;if(l===`clear-app-state`&&!_)return S(`INVALID_ARGS`,`settings clear-app-state requires an app id when no app is bound to the session`);let v=l===`clear-app-state`?[l,u,_??``]:l===`permission`?[l,u,f??``,t.positionals?.[3]??``,_??``]:l===`location`&&u===`set`?[l,u,p??``,h??``,_??``]:[l,u,_??``];i&&j(i);let y=await x(a,`settings`,v,t.flags?.out,{...C(n,t.flags,_,i?.trace?.outPath)});return R(r,i,t,y??{setting:l,state:u}),{ok:!0,data:y??{setting:l,state:u}}}async function he(t){if(t.command!==`snapshot`||t.device.platform!==`android`)return;let n=e(t.error);if(be(n))return{ok:!1,error:{...n,details:{...n.details??{},androidSnapshotTimeoutScreenshot:await ge(t)}}}}async function ge(t){try{let e=await z.mkdtemp(V.join(B.tmpdir(),`agent-device-android-snapshot-timeout-`)),n=V.join(e,`snapshot-timeout-overlay-refs.png`),i=ve(await x(t.device,`screenshot`,[n],void 0,{...C(t.logPath,{screenshotNoStabilize:!0},t.session?.appBundleId,t.session?.trace?.outPath),surface:t.session?.surface}),n);await z.access(i);let a=await _e(i,t.session);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_captured`,data:{path:i,overlayRefCount:`overlayRefCount`in a?a.overlayRefCount:void 0,overlayRefsAnnotated:`overlayRefsAnnotated`in a?a.overlayRefsAnnotated:void 0}}),a}catch(t){let n=e(t);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_failed`,data:{error:n.message}}),{captureFailed:!0,error:n.message}}}async function _e(t,n){if(!n?.snapshot)return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`unavailable`,overlayRefCount:0};try{let e=await E({screenshotPath:t,snapshot:n.snapshot});return{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:e.length>0,overlayRefCount:e.length,overlayRefSource:`session-snapshot`,overlayRefs:e}}catch(n){let i=e(n);return r({level:`warn`,phase:`android_snapshot_timeout_screenshot_overlay_failed`,data:{path:t,error:i.message}}),{path:t,overlayRefsRequested:!0,overlayRefsAnnotated:!1,overlayRefSource:`session-snapshot`,overlayRefCount:0,overlayAnnotationError:i.message}}}function ve(e,t){return ye(e)?e.path:t}function ye(e){return typeof e==`object`&&!!e&&`path`in e&&typeof e.path==`string`}function be(e){return e.code===`COMMAND_FAILED`?xe(e)||Se(e.details?.helper):!1}function xe(e){let t=`${e.message}\n${e.hint??``}`;return/Android accessibility snapshots can be blocked/i.test(t)}function Se(e){if(!e||typeof e!=`object`)return!1;let t=e,n=String(t.errorType??``),r=String(t.message??``);return/TimeoutException/i.test(n)||/timed out/i.test(r)}async function Ce(e){return await Q({...e,command:`snapshot`,unsupportedMessage:`snapshot is not supported on this device`,execute:async({runtime:t,sessionName:n,req:r,snapshotScope:i})=>{let a=await t.capture.snapshot({session:n,interactiveOnly:r.flags?.snapshotInteractiveOnly,depth:r.flags?.snapshotDepth,scope:i,raw:r.flags?.snapshotRaw,forceFull:r.flags?.snapshotForceFull}),o=e.sessionStore.get(n)?.snapshotGeneration,s=v(a.nodes),c=s===a.nodes?a:{...a,nodes:s};return{data:o===void 0?c:{...c,refsGeneration:o},record:{kind:`snapshot`,nodes:a.nodes.length,truncated:a.truncated}}}})}async function we(e){return await Q({...e,command:`diff`,unsupportedMessage:`diff is not supported on this device`,execute:async({runtime:e,sessionName:t,req:n,snapshotScope:r})=>{let i=await e.capture.diffSnapshot({session:t,interactiveOnly:n.flags?.snapshotInteractiveOnly,depth:n.flags?.snapshotDepth,scope:r,raw:n.flags?.snapshotRaw});return{data:i,record:{kind:`diff`,mode:`snapshot`,baselineInitialized:i.baselineInitialized,summary:i.summary}}}})}async function Q(e){let{req:t,sessionName:n,logPath:r,sessionStore:i}=e,{session:a,device:o}=await P(i,n,t.flags),s=b(e.command,o,{message:e.unsupportedMessage});if(s)return s;let c=ne(t.flags?.snapshotScope,a);return c.ok?Te(e.command,a,o)||await N(a,o,async()=>{let s=Ee({req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:c.scope}),l;try{l=await e.execute({runtime:s,sessionName:n,req:t,snapshotScope:c.scope})}catch(t){let n=await he({error:t,command:e.command,logPath:r,session:a,device:o});if(!n)throw t;return n}return Me({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function Te(e,t,n){return!g(n)||t?.appBundleId?null:S(`SESSION_NOT_FOUND`,`iOS ${e} requires an active app session on the target device. Run open first (for example: open --session ${t?.name??`sim`} --platform ios --device "<name>" <app>).`)}function Ee(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return y({backend:je({req:t,logPath:r,session:a,device:o,snapshotScope:s}),...L(`snapshot`),sessions:k({sessionName:n,getSession:()=>i.get(n),recordOptions:{includeSnapshot:!0},setRecord:e=>{let r=Ne(e),a=i.get(n);i.set(n,De({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:Oe(t),issuesRefsToClient:t.command===`snapshot`}))}})})}function De(e){let{current:t,sessionName:n,device:r,record:i,refScopedSnapshot:a}=e,o=ke(t,i,a),s=F({session:t,sessionName:n,device:r,snapshot:o?t.snapshot:i.snapshot,appBundleId:i.appBundleId});return A(s,{scopeSource:$({current:t,keepCurrentSnapshot:o,refScopedSnapshot:a}),keptCurrentSnapshot:o,previousGeneration:t?.snapshotGeneration}),Ae(s,o,e.issuesRefsToClient),i.appName&&(s.appName=i.appName),s}function Oe(e){return e.flags?.snapshotScope?.trim().startsWith(`@`)===!0}function ke(e,t,n){return n&&t.snapshot?.nodes.length===0&&e?.snapshot!==void 0}function Ae(e,t,n){!t&&n&&re(e)}function $(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function je(e){let{req:t,logPath:n,session:r,device:i,snapshotScope:a}=e;return{platform:h(i),captureSnapshot:async(e,o)=>{let s=await te({device:i,session:r,flags:t.flags,outPath:o?.outPath??t.flags?.out,logPath:n,snapshotScope:a}),c=f(r);return{snapshot:s.snapshot,...d(s),...c?{snapshotDiagnostics:c}:{},appName:r?.appBundleId?r.appName??r.appBundleId:void 0,appBundleId:r?.appBundleId}}}}function Me(e){let t=e.sessionStore.get(e.sessionName);t&&e.sessionStore.recordAction(t,{command:e.req.command,positionals:e.req.positionals??[],flags:e.req.flags??{},result:Pe(e.result),interactiveObservation:p(e.req)})}function Ne(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function Pe(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const Fe={snapshot:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await Ce({req:e,sessionName:t,logPath:n,sessionStore:r}),diff:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>e.positionals?.[0]===`snapshot`?await we({req:e,sessionName:t,logPath:n,sessionStore:r}):S(`INVALID_ARGS`,`diff currently supports only: diff snapshot`),wait:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>await I({req:e,sessionName:t,logPath:n,sessionStore:r}),alert:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let{session:i,device:a}=await P(r,t,e.flags);return await N(i,a,async()=>await se({req:e,logPath:n,sessionStore:r,session:i,device:a}))},settings:async({req:e,sessionName:t,logPath:n,sessionStore:r})=>{let i=pe(e);if(!i.ok)return i;let{session:a,device:o}=await P(r,t,e.flags);return await N(a,o,async()=>await me({req:e,logPath:n,sessionStore:r,session:a,device:o,parsed:i.parsed}))}};async function Ie(e){let t=e.req.command,n=Fe[t];return n?await n(e):null}export{Ie as handleSnapshotCommands};
|
|
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{Bt as A,Ft as j,Mt as te,Nt as ne,Ot as re,Tt as ie,en 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&&ae(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 ie({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=we(r,e.sessionStore.get(n)),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}}}})}function we(e,t){return e.internal?.observationOnly===!0?void 0:t?.snapshotGeneration}async function Te(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=A(t.flags?.snapshotScope,a);return c.ok?Ee(e.command,a,o)||await N(a,o,async()=>{let s=De({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 Ne({req:t,sessionName:n,sessionStore:i,result:l.record}),{ok:!0,data:l.data}}):c}function Ee(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 De(e){let{req:t,sessionName:n,logPath:r,sessionStore:i,session:a,device:o,snapshotScope:s}=e;return y({backend:Me({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=Pe(e),a=i.get(n);i.set(n,$({current:a,sessionName:n,device:o,record:r,refScopedSnapshot:Oe(t),issuesRefsToClient:t.command===`snapshot`&&t.internal?.observationOnly!==!0}))}})})}function $(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:je({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 je(e){let{current:t,keepCurrentSnapshot:n,refScopedSnapshot:r}=e;if(r)return n?t?.snapshotScopeSource:t?.snapshotScopeSource??t?.snapshot}function Me(e){let{req:t,logPath:n,session:r,device:i,snapshotScope:a}=e;return{platform:m(i),captureSnapshot:async(e,o)=>{let s=await M({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 Ne(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:Fe(e.result),interactiveObservation:f(e.req)})}function Pe(e){if(!e.snapshot)throw new t(`UNKNOWN`,`snapshot runtime did not produce session state`);return e}function Fe(e){return e.kind===`snapshot`?{nodes:e.nodes,truncated:e.truncated}:{mode:e.mode,baselineInitialized:e.baselineInitialized,summary:e.summary}}const Ie={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 Te({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 Le(e){let t=e.req.command,n=Ie[t];return n?await n(e):null}export{Le 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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./rolldown-runtime.js";import{v as t,w as n}from"./sdk-android-adb.js";import{
|
|
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 { h as AndroidSnapshotHelperTransport, m as AndroidSnapshotHelperInstallReason, p as AndroidSnapshotCaptureMode } 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 };
|