agent-device 0.20.7 → 0.20.8
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/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.apk → agent-device-android-ime-helper-0.20.8.apk} +0 -0
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.8.apk.sha256 +1 -0
- package/android/ime-helper/dist/{agent-device-android-ime-helper-0.20.7.manifest.json → agent-device-android-ime-helper-0.20.8.manifest.json} +4 -4
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.apk → agent-device-android-snapshot-helper-0.20.8.apk} +0 -0
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.8.apk.sha256 +1 -0
- package/android/snapshot-helper/dist/{agent-device-android-snapshot-helper-0.20.7.manifest.json → agent-device-android-snapshot-helper-0.20.8.manifest.json} +6 -6
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +5 -1
- package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+RecordingTests.swift +4 -0
- package/dist/src/agent-browser-tool.js +1 -1
- package/dist/src/agent-device-client.js +2 -2
- package/dist/src/android.js +1 -1
- package/dist/src/app-lifecycle.js +7 -7
- package/dist/src/app-lifecycle2.js +1 -1
- package/dist/src/app-log-reconnect.js +1 -1
- package/dist/src/app-log-runtime.js +3 -3
- package/dist/src/app-resolution.js +2 -2
- package/dist/src/apps.js +5 -5
- package/dist/src/auth-session.js +1 -1
- package/dist/src/boot-diagnostics.js +1 -1
- package/dist/src/cli-config.js +1 -1
- package/dist/src/cli-help.js +1 -1
- package/dist/src/cli.js +4 -4
- package/dist/src/client-metro.js +1 -1
- package/dist/src/connection-runtime.js +1 -1
- package/dist/src/debug-symbols.js +3 -3
- package/dist/src/device-claim-inspection.js +1 -1
- package/dist/src/device-input-state.js +1 -1
- package/dist/src/device-ready.js +1 -0
- package/dist/src/dispatch.js +1 -0
- package/dist/src/find.js +1 -1
- package/dist/src/finders.js +1 -1
- package/dist/src/generic-settle.js +1 -1
- package/dist/src/handler-utils.js +1 -0
- package/dist/src/harmonyos.js +1 -1
- package/dist/src/hdc.js +1 -0
- package/dist/src/helper.js +1 -1
- package/dist/src/host-process.js +3 -2
- package/dist/src/ime-lifecycle.js +5 -5
- package/dist/src/index.d.ts +21 -21
- package/dist/src/input-actions.js +4 -4
- package/dist/src/input-actions2.js +1 -1
- package/dist/src/install-artifact.js +1 -1
- package/dist/src/interaction-runtime.js +1 -1
- package/dist/src/interaction-snapshot.js +1 -1
- package/dist/src/interaction-touch-reference-frame.js +1 -1
- package/dist/src/interaction.js +1 -1
- package/dist/src/interactor.js +1 -1
- package/dist/src/interactor2.js +1 -1
- package/dist/src/internal/bin.js +1 -1
- package/dist/src/internal/daemon.js +7 -29
- package/dist/src/inventory2.js +1 -1
- package/dist/src/lease-context.js +1 -1
- package/dist/src/lease.js +1 -1
- package/dist/src/limrun-runtime-dependencies.js +1 -1
- package/dist/src/linux.js +1 -1
- package/dist/src/manifest.js +1 -1
- package/dist/src/notifications.js +1 -1
- package/dist/src/output-path.js +1 -0
- package/dist/src/owner-identity.js +1 -1
- package/dist/src/physical-device-control.js +1 -1
- package/dist/src/platform-runtime-app-log-process.js +1 -1
- package/dist/src/platform-runtime-host.js +1 -1
- package/dist/src/platform-runtime-network-web-transport.js +1 -1
- package/dist/src/platform-runtime-operation-host.js +4 -4
- package/dist/src/platform-runtime-screen-recording-android-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-runner-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-simulator-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-apple-transport.js +1 -0
- package/dist/src/platform-runtime-screen-recording-finalizer-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-harmony-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-output-host.js +1 -0
- package/dist/src/platform-runtime-screen-recording-web-host.js +1 -0
- package/dist/src/platform-runtime-toolchain-host.js +1 -1
- package/dist/src/platform-runtime.js +1 -1
- package/dist/src/prepare-kind.js +13 -13
- package/dist/src/provider-webdriver.js +1 -1
- package/dist/src/proxy.js +1 -1
- package/dist/src/react-native.js +1 -1
- package/dist/src/record-runtime.js +1 -0
- package/dist/src/record-trace.js +1 -1
- package/dist/src/recording-telemetry.js +1 -0
- package/dist/src/registry.js +4 -4
- package/dist/src/remote-config2.js +1 -1
- package/dist/src/replay.js +2 -2
- package/dist/src/runner-disposal.js +1 -1
- package/dist/src/runner-lease.js +1 -1
- package/dist/src/runtime.js +3 -3
- package/dist/src/runtime2.js +3 -3
- package/dist/src/runtime3.js +3 -3
- package/dist/src/runtime4.js +1 -1
- package/dist/src/runtime7.js +1 -1
- package/dist/src/screenshot-result.js +4 -4
- package/dist/src/sdk-android-adb.js +4 -4
- package/dist/src/sdk-batch-runner.js +2 -2
- package/dist/src/sdk-finders.js +1 -1
- package/dist/src/sdk-remote-config.js +1 -1
- package/dist/src/sdk-selectors.d.ts +5 -1
- package/dist/src/sdk-selectors.js +1 -1
- package/dist/src/selector-runtime.js +1 -1
- package/dist/src/selectors.js +1 -1
- package/dist/src/server.js +2 -2
- package/dist/src/session-target-evidence.js +1 -1
- package/dist/src/session.js +10 -10
- package/dist/src/simulator.js +1 -1
- package/dist/src/snapshot-runtime.js +1 -1
- package/dist/src/snapshot-session.js +1 -1
- package/dist/src/snapshot.js +1 -1
- package/dist/src/snapshot2.js +1 -1
- package/dist/src/src.js +1 -1
- package/dist/src/src2.js +2 -2
- package/dist/src/src3.js +1 -1
- package/dist/src/text-surface.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/update-check.js +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/video.js +23 -0
- package/dist/src/web.js +1 -1
- package/package.json +2 -4
- package/server.json +2 -2
- package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.7.apk.sha256 +0 -1
- package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.7.apk.sha256 +0 -1
- package/dist/src/context.js +0 -1
- package/dist/src/provider.js +0 -1
- package/dist/src/runner-client.js +0 -1
- package/dist/src/runner-provider.js +0 -1
- package/skills/agent-device/SKILL.md +0 -20
- package/skills/dogfood/SKILL.md +0 -27
package/dist/src/registry.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{_ as e,n as t,t as n}from"./sdk-contracts.js";import{$ as r,C as i,Dt as a,Ft as o,It as s,J as c,Lt as ee,Nt as te,O as ne,Ot as re,Pt as ie,Q as ae,S as oe,Tt as se,V as ce,W as le,X as ue,Y as de,Z as fe,et as pe,g as me,k as he,kt as ge,lt as _e,mt as ve,p as ye,pt as be,tt as xe,w as Se}from"./version.js";import{Gt as Ce,Ht as we,Kt as Te,Qt as Ee,Rn as De,Ut as Oe,Wn as l,Xt as ke,_ as Ae,d as je,f as Me,g as Ne,i as Pe,in as Fe,it as Ie,m as Le,on as Re,p as ze,qt as Be,r as Ve,st as He,tr as Ue,u as We,un as Ge,vn as Ke}from"./sdk-batch-runner.js";import{r as qe,t as Je}from"./sdk-device.js";import{$t as Ye,At as Xe,Bt as Ze,Ft as Qe,Lt as $e,Mt as et,Nt as tt,Pt as nt,Rt as rt,St as it,Ut as at,Vt as ot,Wt as st,Xt as u,Yt as ct,_t as lt,a as ut,c as dt,cn as ft,dn as pt,fn as mt,hn as ht,jt as gt,l as _t,ln as vt,mn as yt,n as bt,nn as xt,o as St,pn as Ct,qt as wt,r as Tt,t as Et,un as Dt,wn as Ot,xn as kt,xt as At,zt as jt}from"./prepare-kind.js";import{a as Mt}from"./sdk-remote-config.js";import{a as Nt,d as Pt,f as Ft,t as It}from"./device.js";const Lt=[{key:`count`,names:[`--count`],type:`int`,min:1,max:200,usageLabel:`--count <n>`,usageDescription:`Repeat count for press/swipe series`},{key:`pointerCount`,names:[`--pointer-count`],type:`int`,min:1,max:2,usageLabel:`--pointer-count <1|2>`,usageDescription:`Gesture pan: number of touch pointers (default 1)`},{key:`fps`,names:[`--fps`],type:`int`,min:1,max:120,usageLabel:`--fps <n>`,usageDescription:`Record: target frames per second (iOS physical device runner)`},{key:`quality`,names:[`--quality`],type:`string`,usageLabel:`--quality <medium|high>`,usageDescription:`Record: output quality preset; Android maps this to screenrecord bitrate, Apple targets use it for export/encoding. Legacy numeric values 5-7 map to medium; 8-10 map to high`},{key:`hideTouches`,names:[`--hide-touches`],type:`boolean`,usageLabel:`--hide-touches`,usageDescription:`Record: skip touch-overlay post-processing for faster raw benchmark videos`},{key:`recordingScope`,names:[`--scope`],type:`enum`,enumValues:Ye,usageLabel:`--scope <app|device|system>`,usageDescription:`Record: app requires an active app session; device/system records the whole screen`},{key:`intervalMs`,names:[`--interval-ms`],type:`int`,min:0,max:1e4,usageLabel:`--interval-ms <ms>`,usageDescription:`Delay between press iterations`},{key:`delayMs`,names:[`--delay-ms`],type:`int`,min:0,max:1e4,usageLabel:`--delay-ms <ms>`,usageDescription:`Delay between typed characters`},{key:`recordAs`,names:[`--record-as`],type:`string`,usageLabel:`--record-as <VAR>`,usageDescription:"Fill: send the live text but publish ${VAR} in an armed .ad recording"},{key:`durationMs`,names:[`--duration-ms`],type:`int`,min:0,max:1e4,usageLabel:`--duration-ms <ms>`,usageDescription:`Scroll: pace the gesture over this duration when supported`},{key:`holdMs`,names:[`--hold-ms`],type:`int`,min:0,max:1e4,usageLabel:`--hold-ms <ms>`,usageDescription:`Press hold duration for each iteration`},{key:`jitterPx`,names:[`--jitter-px`],type:`int`,min:0,max:100,usageLabel:`--jitter-px <n>`,usageDescription:`Deterministic coordinate jitter radius for press`},{key:`pixels`,names:[`--pixels`],type:`int`,min:1,max:1e5,usageLabel:`--pixels <n>`,usageDescription:`Scroll: explicit gesture distance in pixels`},{key:`doubleTap`,names:[`--double-tap`],type:`boolean`,usageLabel:`--double-tap`,usageDescription:`Use double-tap gesture per press iteration`},{key:`verify`,names:[`--verify`],type:`boolean`,usageLabel:`--verify`,usageDescription:`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot`},{key:`settle`,names:[`--settle`],type:`boolean`,usageLabel:`--settle`,usageDescription:`After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response (best-effort; never fails the action)`},{key:`settleQuietMs`,names:[`--settle-quiet`],type:`int`,min:0,usageLabel:`--settle-quiet <ms>`,usageDescription:`Settle: quiet window the UI must hold to count as settled (default 500ms)`},{key:`clickButton`,names:[`--button`],type:`enum`,enumValues:[`primary`,`secondary`,`middle`],usageLabel:`--button primary|secondary|middle`,usageDescription:`Click: choose mouse button (middle reserved for future macOS support)`},{key:`backMode`,names:[`--in-app`],type:`enum`,enumValues:[`in-app`,`system`],setValue:`in-app`,usageLabel:`--in-app`,usageDescription:`Back: use app-provided back UI when available`},{key:`backMode`,names:[`--system`],type:`enum`,enumValues:[`in-app`,`system`],setValue:`system`,usageLabel:`--system`,usageDescription:`Back: use system back input or gesture when available`},{key:`pauseMs`,names:[`--pause-ms`],type:`int`,min:0,max:1e4,usageLabel:`--pause-ms <ms>`,usageDescription:`Delay between swipe iterations`},{key:`pattern`,names:[`--pattern`],type:`enum`,enumValues:[`one-way`,`ping-pong`],usageLabel:`--pattern one-way|ping-pong`,usageDescription:`Swipe repeat pattern`},{key:`verbose`,names:[`--debug`,`--verbose`,`-v`],type:`boolean`,usageLabel:`--debug, --verbose, -v`,usageDescription:`Enable debug diagnostics; test --verbose prints per-test step timings without debug logs`},{key:`cost`,names:[`--cost`],type:`boolean`,usageLabel:`--cost`,usageDescription:`Include per-command wall-clock latency (cost.wallClockMs) in the response`},{key:`responseLevel`,names:[`--level`],type:`enum`,enumValues:t,usageLabel:`--level digest|default|full`,usageDescription:`Response detail level: digest (token-cheap), default (today), or full. Default keeps the wire shape unchanged.`},{key:`json`,names:[`--json`],type:`boolean`,usageLabel:`--json`,usageDescription:`JSON output`},{key:`help`,names:[`--help`,`-h`],type:`boolean`,usageLabel:`--help, -h`,usageDescription:`Print help and exit`},{key:`version`,names:[`--version`,`-V`],type:`boolean`,usageLabel:`--version, -V`,usageDescription:`Print version and exit`},{key:`snapshotDiff`,names:[`--diff`],type:`boolean`,usageLabel:`--diff`,usageDescription:`Snapshot: show structural diff against the previous session baseline`},{key:`saveScript`,names:[`--save-script`],type:`booleanOrString`,usageLabel:`--save-script [path]`,usageDescription:`Arm evidence capture on open, publish the armed recording on close; close --save-script alone (without an armed open) is rejected — start with open --save-script, or use session save-script mid-session. Optional custom output path.`},{key:`networkInclude`,names:[`--include`],type:`enum`,enumValues:[`summary`,`headers`,`body`,`all`],usageLabel:`--include summary|headers|body|all`,usageDescription:`Network: include headers, bodies, or both in output`},{key:`shutdown`,names:[`--shutdown`],type:`boolean`,usageLabel:`--shutdown`,usageDescription:`close: shutdown associated simulator/emulator after ending session`},{key:`relaunch`,names:[`--relaunch`],type:`boolean`,usageLabel:`--relaunch`,usageDescription:`open: terminate app process before launching it`},{key:`foreground`,names:[`--foreground`],type:`boolean`,usageLabel:`--foreground`,usageDescription:`open: keep normal app/device selection and return an initial snapshot; without an app, resolve the sole running app on the sole booted iOS simulator`},{key:`restart`,names:[`--restart`],type:`boolean`,usageLabel:`--restart`,usageDescription:`logs clear: stop active stream, clear logs, then start streaming again`},{key:`retainPaths`,names:[`--retain-paths`],type:`boolean`,usageLabel:`--retain-paths`,usageDescription:`install-from-source: keep materialized artifact paths after install`},{key:`retentionMs`,names:[`--retention-ms`],type:`int`,min:1,usageLabel:`--retention-ms <ms>`,usageDescription:`install-from-source: retention TTL for materialized artifact paths`},{key:`noRecord`,names:[`--no-record`],type:`boolean`,usageLabel:`--no-record`,usageDescription:`Do not record this action`},{key:`record`,names:[`--record`],type:`boolean`,usageLabel:`--record`,usageDescription:`Force-record this action even though its command is observation-only and would otherwise be excluded from a repair-armed heal by default (mutually exclusive with --no-record)`}],Rt=[{key:`config`,names:[`--config`],type:`string`,usageLabel:`--config <path>`,usageDescription:`Load CLI defaults from a specific config file (required for connection/provider defaults outside user config)`},{key:`remoteConfig`,names:[`--remote-config`],type:`string`,usageLabel:`--remote-config <path>`,usageDescription:`Load remote host + Metro workflow settings from a specific profile file`},{key:`stateDir`,names:[`--state-dir`],type:`string`,usageLabel:`--state-dir <path>`,usageDescription:`Daemon state directory (defaults to ~/.agent-device for packages, or a worktree-scoped dev dir from source)`},{key:`daemonBaseUrl`,names:[`--daemon-base-url`],type:`string`,usageLabel:`--daemon-base-url <url>`,usageDescription:`Explicit remote HTTP daemon base URL (skip local daemon discovery/startup)`},{key:`daemonAuthToken`,names:[`--daemon-auth-token`],type:`string`,usageLabel:`--daemon-auth-token <token>`,usageDescription:`Remote HTTP daemon or proxy auth token (sent as request token and bearer header)`},{key:`daemonTransport`,names:[`--daemon-transport`],type:`enum`,enumValues:[`auto`,`socket`,`http`],usageLabel:`--daemon-transport auto|socket|http`,usageDescription:`Daemon client transport preference`},{key:`daemonServerMode`,names:[`--daemon-server-mode`],type:`enum`,enumValues:[`socket`,`http`,`dual`],usageLabel:`--daemon-server-mode socket|http|dual`,usageDescription:`Daemon server mode used when spawning daemon`},{key:`proxyHost`,names:[`--host`],type:`string`,usageLabel:`--host <host>`,usageDescription:`Proxy: host interface to bind (default: 127.0.0.1)`},{key:`proxyPort`,names:[`--port`],type:`int`,min:1,max:65535,usageLabel:`--port <port>`,usageDescription:`Proxy: TCP port to bind (default: 0, choose a free port)`},{key:`tenant`,names:[`--tenant`],type:`string`,usageLabel:`--tenant <id>`,usageDescription:`Tenant scope identifier for isolated daemon sessions`},{key:`sessionIsolation`,names:[`--session-isolation`],type:`enum`,enumValues:[`none`,`tenant`],usageLabel:`--session-isolation none|tenant`,usageDescription:`Session isolation strategy (tenant prefixes session namespace)`},{key:`runId`,names:[`--run-id`],type:`string`,usageLabel:`--run-id <id>`,usageDescription:`Run identifier used for tenant lease admission checks`},{key:`leaseId`,names:[`--lease-id`],type:`string`,usageLabel:`--lease-id <id>`,usageDescription:`Lease identifier bound to tenant/run admission scope`},{key:`leaseBackend`,names:[`--lease-backend`],type:`enum`,enumValues:[`ios-simulator`,`ios-instance`,`android-instance`],usageLabel:`--lease-backend ios-simulator|ios-instance|android-instance`,usageDescription:`Lease backend for remote tenant connection admission`},{key:`provider`,names:[`--provider`],type:`string`,usageLabel:`--provider <name>`,usageDescription:`Cloud provider name for provider-scoped commands`},{key:`providerSessionId`,names:[`--provider-session`],type:`string`,usageLabel:`--provider-session <id>`,usageDescription:`Cloud provider session id or ARN`},{key:`providerApp`,names:[`--provider-app`],type:`string`,usageLabel:`--provider-app <ref-or-path>`,usageDescription:`Cloud provider app reference or local app path used when creating hosted WebDriver sessions`},{key:`providerOsVersion`,names:[`--provider-os-version`,`--os-version`],type:`string`,usageLabel:`--provider-os-version <version>`,usageDescription:`Hosted cloud provider OS version, for example 17 or 14.0`},{key:`providerProject`,names:[`--provider-project`],type:`string`,usageLabel:`--provider-project <name>`,usageDescription:`Hosted cloud provider project label`},{key:`providerBuild`,names:[`--provider-build`],type:`string`,usageLabel:`--provider-build <name>`,usageDescription:`Hosted cloud provider build label`},{key:`providerSessionName`,names:[`--provider-session-name`],type:`string`,usageLabel:`--provider-session-name <name>`,usageDescription:`Hosted cloud provider session label`},{key:`providerDeviceOrientation`,names:[`--provider-device-orientation`,`--device-orientation`],type:`enum`,enumValues:Mt,usageLabel:`--provider-device-orientation portrait|landscape`,usageDescription:`Screen orientation a hosted cloud provider session starts in. Set this rather than rotating after launch: a session that boots landscape renders login webviews landscape`},{key:`providerGeoLocation`,names:[`--provider-geo-location`,`--geo-location`],type:`string`,usageLabel:`--provider-geo-location <country>`,usageDescription:`Hosted cloud provider IP geolocation country code, for example US`},{key:`providerTimezone`,names:[`--provider-timezone`,`--timezone`],type:`string`,usageLabel:`--provider-timezone <zone>`,usageDescription:`Hosted cloud provider device time zone, for example New_York`},{key:`providerLanguage`,names:[`--provider-language`,`--language`],type:`string`,usageLabel:`--provider-language <language>`,usageDescription:`Hosted cloud provider app language, for example Fr`},{key:`providerLocale`,names:[`--provider-locale`,`--locale`],type:`string`,usageLabel:`--provider-locale <locale>`,usageDescription:`Hosted cloud provider device locale, for example Fr`},{key:`providerNetworkProfile`,names:[`--provider-network-profile`,`--network-profile`],type:`string`,usageLabel:`--provider-network-profile <profile>`,usageDescription:`Hosted cloud provider named network condition profile, for example 4g-lte-advanced-good. Mutually exclusive with --provider-custom-network`},{key:`providerCustomNetwork`,names:[`--provider-custom-network`,`--custom-network`],type:`string`,usageLabel:`--provider-custom-network <shape>`,usageDescription:`Hosted cloud provider custom network shape. Mutually exclusive with --provider-network-profile`},{key:`providerNoResignApp`,names:[`--provider-no-resign-app`],type:`boolean`,usageLabel:`--provider-no-resign-app`,usageDescription:`iOS only: keep an Enterprise-signed app as uploaded instead of letting the provider re-sign it, which strips entitlements such as push notifications`},{key:`awsProjectArn`,names:[`--aws-project-arn`],type:`string`,usageLabel:`--aws-project-arn <arn>`,usageDescription:`AWS Device Farm project ARN for hosted WebDriver sessions`},{key:`awsDeviceArn`,names:[`--aws-device-arn`],type:`string`,usageLabel:`--aws-device-arn <arn>`,usageDescription:`AWS Device Farm device ARN for hosted WebDriver sessions`},{key:`awsAppArn`,names:[`--aws-app-arn`],type:`string`,usageLabel:`--aws-app-arn <arn>`,usageDescription:`AWS Device Farm app ARN attached to hosted remote access sessions`},{key:`awsRegion`,names:[`--aws-region`],type:`string`,usageLabel:`--aws-region <region>`,usageDescription:`AWS region for Device Farm API calls`},{key:`awsInteractionMode`,names:[`--aws-interaction-mode`],type:`enum`,enumValues:[`INTERACTIVE`,`NO_VIDEO`,`VIDEO_ONLY`],usageLabel:`--aws-interaction-mode INTERACTIVE|NO_VIDEO|VIDEO_ONLY`,usageDescription:`AWS Device Farm remote access interaction mode`},{key:`force`,names:[`--force`,`--overwrite`],type:`boolean`,usageLabel:`--force, --overwrite`,usageDescription:`Force replacement of existing state (connect: replace an active connection; --save-script: overwrite an existing target instead of refusing)`},{key:`clean`,names:[`--clean`],type:`boolean`,usageLabel:`--clean`,usageDescription:`Daemon stop: remove retained runner processes and leases after stopping`},{key:`noLogin`,names:[`--no-login`],type:`boolean`,usageLabel:`--no-login`,usageDescription:`Connect: fail instead of starting implicit cloud login`},{key:`sessionLock`,names:[`--session-lock`],type:`enum`,enumValues:[`reject`,`strip`],usageLabel:`--session-lock reject|strip`,usageDescription:`Lock bound-session device routing for this CLI invocation and nested batch steps`}],zt=[{key:`platform`,names:[`--platform`],type:`enum`,enumValues:qe,usageLabel:`--platform ${qe.join(`|`)}`,usageDescription:"Platform to target (`apple` aliases the Apple automation backend)"},{key:`target`,names:[`--target`],type:`enum`,enumValues:[`mobile`,`tv`,`desktop`],usageLabel:`--target mobile|tv|desktop`,usageDescription:`Device target class to match`},{key:`device`,names:[`--device`],type:`string`,usageLabel:`--device <name>`,usageDescription:`Device name to target`},{key:`udid`,names:[`--udid`],type:`string`,usageLabel:`--udid <udid>`,usageDescription:`iOS device UDID`},{key:`serial`,names:[`--serial`],type:`string`,usageLabel:`--serial <serial>`,usageDescription:`Android device or Vega VVD serial`},{key:`stale`,names:[`--stale`],type:`boolean`,usageLabel:`--stale`,usageDescription:`Device status: show only claims with a provably stale owner`},{key:`surface`,names:[`--surface`],type:`enum`,enumValues:wt,usageLabel:`--surface app|frontmost-app|desktop|menubar`,usageDescription:`macOS session surface for open (defaults to app)`},{key:`headless`,names:[`--headless`],type:`boolean`,usageLabel:`--headless`,usageDescription:`Boot: launch Android emulator without a GUI window`},{key:`targetApp`,names:[`--app`,`--target-app`],type:`string`,usageLabel:`--app <id-or-name>`,usageDescription:`Doctor: verify an installed target app without opening a session`},{key:`metroHost`,names:[`--metro-host`],type:`string`,usageLabel:`--metro-host <host>`,usageDescription:`Session-scoped Metro/debug host hint`},{key:`metroPort`,names:[`--metro-port`],type:`int`,min:1,max:65535,usageLabel:`--metro-port <port>`,usageDescription:`Session-scoped Metro/debug port hint; on an emulator/simulator the host defaults to the loopback alias, physical devices still need --metro-host`},{key:`metroProjectRoot`,names:[`--project-root`],type:`string`,usageLabel:`--project-root <path>`,usageDescription:`metro prepare: React Native project root (default: cwd)`},{key:`kind`,names:[`--kind`],type:`enum`,enumValues:[`auto`,`react-native`,`expo`,`repack`,...Qe],usageLabel:`--kind <kind>`,usageDescription:`Kind selector for commands that support it, such as metro prepare or perf artifact collectors`},{key:`perfTemplate`,names:[`--template`],type:`string`,usageLabel:`--template <name>`,usageDescription:`Perf xctrace template name, for example Time Profiler`},{key:`metroKind`,names:[`--metro-kind`],type:`enum`,enumValues:[`auto`,`react-native`,`expo`,`repack`],usageLabel:`--metro-kind auto|react-native|expo|repack`,usageDescription:`metro prepare: detect or force the React Native dev-server launcher kind`},{key:`metroPublicBaseUrl`,names:[`--public-base-url`],type:`string`,usageLabel:`--public-base-url <url>`,usageDescription:`metro prepare: public base URL used for direct dev-server bundle hints`},{key:`metroProxyBaseUrl`,names:[`--proxy-base-url`],type:`string`,usageLabel:`--proxy-base-url <url>`,usageDescription:`metro prepare: optional bridge origin for remote dev-server access`},{key:`metroBearerToken`,names:[`--bearer-token`],type:`string`,usageLabel:`--bearer-token <token>`,usageDescription:`metro prepare: host bridge bearer token (or AGENT_DEVICE_METRO_BEARER_TOKEN; falls back to AGENT_DEVICE_DAEMON_AUTH_TOKEN)`},{key:`metroPreparePort`,names:[`--port`],type:`int`,min:1,max:65535,usageLabel:`--port <port>`,usageDescription:`metro prepare: local dev-server port (default: 8081)`},{key:`metroListenHost`,names:[`--listen-host`],type:`string`,usageLabel:`--listen-host <host>`,usageDescription:`metro prepare: host dev server listens on (default: 0.0.0.0)`},{key:`metroStatusHost`,names:[`--status-host`],type:`string`,usageLabel:`--status-host <host>`,usageDescription:`metro prepare: host used for local dev-server /status polling (default: 127.0.0.1)`},{key:`metroStartupTimeoutMs`,names:[`--startup-timeout-ms`],type:`int`,min:1,usageLabel:`--startup-timeout-ms <ms>`,usageDescription:`metro prepare: timeout while waiting for the dev server to become ready`},{key:`metroProbeTimeoutMs`,names:[`--probe-timeout-ms`],type:`int`,min:1,usageLabel:`--probe-timeout-ms <ms>`,usageDescription:`metro prepare: timeout for /status and proxy bridge calls`},{key:`metroRuntimeFile`,names:[`--runtime-file`],type:`string`,usageLabel:`--runtime-file <path>`,usageDescription:`metro prepare: optional file path to persist the JSON result`},{key:`metroNoReuseExisting`,names:[`--no-reuse-existing`],type:`boolean`,usageLabel:`--no-reuse-existing`,usageDescription:`metro prepare: always start a fresh Metro process`},{key:`metroNoInstallDeps`,names:[`--no-install-deps`],type:`boolean`,usageLabel:`--no-install-deps`,usageDescription:`metro prepare: skip package-manager install when node_modules is missing`},{key:`bundleUrl`,names:[`--bundle-url`],type:`string`,usageLabel:`--bundle-url <url>`,usageDescription:`Session-scoped bundle URL hint`},{key:`launchUrl`,names:[`--launch-url`],type:`string`,usageLabel:`--launch-url <url>`,usageDescription:`Session-scoped deep link / launch URL hint`},{key:`iosSimulatorDeviceSet`,names:[`--ios-simulator-device-set`],type:`string`,usageLabel:`--ios-simulator-device-set <path>`,usageDescription:`Scope iOS simulator discovery/commands to this simulator device set`},{key:`iosXctestrunFile`,names:[`--ios-xctestrun-file`],type:`string`,usageLabel:`--ios-xctestrun-file <path>`,usageDescription:`Use an externally built iOS XCTest runner .xctestrun artifact`},{key:`iosXctestDerivedDataPath`,names:[`--ios-xctest-derived-data-path`],type:`string`,usageLabel:`--ios-xctest-derived-data-path <path>`,usageDescription:`Derived data path for external iOS XCTest runner execution`},{key:`iosXctestEnvDir`,names:[`--ios-xctest-env-dir`],type:`string`,usageLabel:`--ios-xctest-env-dir <path>`,usageDescription:`Writable directory for per-session iOS XCTest runner env overlays`},{key:`deviceHub`,names:[`--device-hub`],type:`boolean`,usageLabel:`--device-hub`,usageDescription:`open: use Xcode Device Hub when surfacing Apple simulators`},{key:`testIme`,names:[`--test-ime`],type:`boolean`,usageLabel:`--test-ime`,usageDescription:`open: activate the headless Android test IME for deterministic Unicode text entry (default on for emulators; opt-in on real devices)`},{key:`testIme`,names:[`--no-test-ime`],type:`boolean`,setValue:!1,usageLabel:`--no-test-ime`,usageDescription:`open: keep the real Android keyboard even on emulators (opt out of the headless test IME)`},{key:`androidDeviceAllowlist`,names:[`--android-device-allowlist`],type:`string`,usageLabel:`--android-device-allowlist <serials>`,usageDescription:`Comma/space separated Android serial allowlist for discovery/selection`},{key:`remote`,names:[`--remote`],type:`boolean`,usageLabel:`--remote`,usageDescription:`Doctor: check remote connection setup instead of local device inventory`},{key:`activity`,names:[`--activity`],type:`string`,usageLabel:`--activity <component>`,usageDescription:`Android app launch activity (package/Activity); not for URL opens`},{key:`launchConsole`,names:[`--launch-console`],type:`string`,usageLabel:`--launch-console <path>`,usageDescription:`open: capture the initial iOS simulator launch console window to a file`},{key:`launchArgs`,names:[`--launch-args`],type:`string`,multiple:!0,usageLabel:`--launch-args <arg>`,usageDescription:`open: repeatable launch argument forwarded verbatim to the platform launch command (iOS app process args; Android adb shell am start args). Linux and macOS reject the flag.`},{key:`header`,names:[`--header`],type:`string`,multiple:!0,usageLabel:`--header <name:value>`,usageDescription:`install-from-source: repeatable HTTP header for URL downloads`},{key:`githubActionsArtifact`,names:[`--github-actions-artifact`],type:`string`,usageLabel:`--github-actions-artifact <owner/repo:artifact>`,usageDescription:`install-from-source: GitHub Actions artifact resolved by a remote daemon`},{key:`installSource`,names:[],type:`string`},{key:`session`,names:[`--session`],type:`string`,usageLabel:`--session <name>`,usageDescription:`Named session`}],Bt=[{key:`replayUpdate`,names:[`--update`,`-u`],type:`boolean`,usageLabel:`--update, -u`,usageDescription:`Replay: retired as a rewrite (ADR 0012) — never edits the .ad file; every divergence already carries ranked selector suggestions, --update or not`},{key:`replayFrom`,names:[`--from`],type:`int`,min:1,usageLabel:`--from <n>`,usageDescription:`Replay: resume at 1-based plan step n, skipping 1..n-1 without executing them (requires --plan-digest; see a divergence report's resume field). replay only, not test`},{key:`replayPlanDigest`,names:[`--plan-digest`],type:`string`,usageLabel:`--plan-digest <sha256>`,usageDescription:`Replay: the plan digest a --from resume must match (from a prior divergence report); mismatch, edits, or include/platform-expansion changes fail INVALID_ARGS before any action`},{key:`replayKeepSession`,names:[`--keep-session`],type:`boolean`,usageLabel:`--keep-session`,usageDescription:`Replay: leave the session active by suppressing exactly an authored terminal close in a native .ad script; replay only, not test or Maestro YAML`},{key:`replayMaestro`,names:[`--maestro`],type:`boolean`,usageLabel:`--maestro`,usageDescription:`Replay: treat input as a supported Maestro YAML subset; unsupported syntax fails loudly. See agent-device help maestro for commands and boundaries`},{key:`replayEnv`,names:[`-e`,`--env`],type:`string`,multiple:!0,usageLabel:`-e KEY=VALUE, --env KEY=VALUE`,usageDescription:"Replay/Test: inject or override a ${KEY} variable for the script (repeatable)"},{key:`failFast`,names:[`--fail-fast`],type:`boolean`,usageLabel:`--fail-fast`,usageDescription:`Test: stop the suite after the first failing script; with sharding, each shard stops independently`},{key:`timeoutMs`,names:[`--timeout`],type:`int`,min:1,usageLabel:`--timeout <ms>`,usageDescription:`Prepare/Replay/Snapshot/Test: maximum wall-clock time for the command or attempt. With --settle: the settle-wait deadline (default 10s)`},{key:`retries`,names:[`--retries`],type:`int`,min:0,max:3,usageLabel:`--retries <n>`,usageDescription:`Test: retry each failed script up to n additional times`},{key:`recordVideo`,names:[`--record-video`],type:`boolean`,usageLabel:`--record-video`,usageDescription:`Test: record each replay attempt to recording.mp4 in its attempt artifacts`},{key:`artifactsDir`,names:[`--artifacts-dir`],type:`string`,usageLabel:`--artifacts-dir <path>`,usageDescription:`Test: root directory for suite artifacts`},{key:`reporter`,names:[`--reporter`],type:`string`,multiple:!0,usageLabel:`--reporter <name-or-path>`,usageDescription:`Test: add a replay suite reporter; use default, junit:<path>, or a custom reporter path (repeatable)`},{key:`reportJunit`,names:[`--report-junit`],type:`string`,usageLabel:`--report-junit <path>`,usageDescription:`Test: compatibility alias for --reporter junit:<path>`},{key:`shardAll`,names:[`--shard-all`],type:`int`,min:1,usageLabel:`--shard-all <n>`,usageDescription:`Test: run the full suite on each of n devices; combine with --device id1,id2 for explicit connected devices; AD_SHARD_INDEX is zero-based`},{key:`shardSplit`,names:[`--shard-split`],type:`int`,min:1,usageLabel:`--shard-split <n>`,usageDescription:`Test: split runnable suite entries across n devices; AD_SHARD_INDEX is zero-based`},{key:`steps`,names:[`--steps`],type:`string`,usageLabel:`--steps <json>`,usageDescription:`Batch: JSON array of steps`},{key:`stepsFile`,names:[`--steps-file`],type:`string`,usageLabel:`--steps-file <path>`,usageDescription:`Batch: read steps JSON from file`},{key:`batchOnError`,names:[`--on-error`],type:`enum`,enumValues:[`stop`],usageLabel:`--on-error stop`,usageDescription:`Batch: stop when a step fails`},{key:`batchMaxSteps`,names:[`--max-steps`],type:`int`,min:1,max:1e3,usageLabel:`--max-steps <n>`,usageDescription:`Batch: maximum number of allowed steps`},{key:`appsFilter`,names:[`--all`],type:`enum`,enumValues:[`user-installed`,`all`],setValue:`all`,usageLabel:`--all`,usageDescription:`Apps: include system/OEM apps`},{key:`snapshotInteractiveOnly`,names:[`-i`],type:`boolean`,usageLabel:`-i`,usageDescription:`Snapshot: interactive elements only`},{key:`snapshotDepth`,names:[`--depth`,`-d`],type:`int`,min:0,usageLabel:`--depth, -d <depth>`,usageDescription:`Snapshot: limit snapshot depth`},{key:`snapshotScope`,names:[`--scope`,`-s`],type:`string`,usageLabel:`--scope, -s <scope>`,usageDescription:`Snapshot: scope snapshot to label/identifier`},{key:`snapshotRaw`,names:[`--raw`],type:`boolean`,usageLabel:`--raw`,usageDescription:`Snapshot: raw node output`},{key:`snapshotCustomActions`,names:[`--actions`],type:`boolean`,usageLabel:`--actions`,usageDescription:`Snapshot: name the affordances merged inside an element (iOS sim); not directly invokable — reach them via the detail screen, labeled children, or coordinates`},{key:`snapshotForceFull`,names:[`--force-full`],type:`boolean`,usageLabel:`--force-full`,usageDescription:`Snapshot: re-emit the full tree even when unchanged`},{key:`findFirst`,names:[`--first`],type:`boolean`,usageLabel:`--first`,usageDescription:`Find: pick the first match when ambiguous`},{key:`findLast`,names:[`--last`],type:`boolean`,usageLabel:`--last`,usageDescription:`Find: pick the last match when ambiguous`},{key:`out`,names:[`--out`],type:`string`,usageLabel:`--out <path>`,usageDescription:`Output path`},{key:`artifact`,names:[`--artifact`],type:`string`,usageLabel:`--artifact <path>`,usageDescription:`Debug symbols: Apple crash artifact path (.ips, .crash, or .log)`},{key:`dsym`,names:[`--dsym`],type:`string`,usageLabel:`--dsym <path>`,usageDescription:`Debug symbols: matching .dSYM bundle path`},{key:`searchPath`,names:[`--search-path`],type:`string`,usageLabel:`--search-path <dir>`,usageDescription:`Debug symbols: directory to scan for matching .dSYM bundles`},{key:`overlayRefs`,names:[`--overlay-refs`],type:`boolean`,usageLabel:`--overlay-refs`,usageDescription:`Screenshot: draw current snapshot refs and target rectangles onto the saved PNG; diff screenshot: also write a separate current-screen overlay guide`},...ge,{key:`baseline`,names:[`--baseline`,`-b`],type:`string`,usageLabel:`--baseline, -b <path>`,usageDescription:`Diff screenshot: path to baseline image file`},{key:`threshold`,names:[`--threshold`],type:`string`,usageLabel:`--threshold <0-1>`,usageDescription:`Diff screenshot: color distance threshold (default 0.1)`}],Vt=[...Rt,...zt,...Lt,...Bt],Ht=new Map;for(let e of Vt)for(let t of e.names)Ht.set(t,e);function Ut(e){return Ht.get(e)}function Wt(){return Vt}const Gt=new Set(Wt().map(e=>e.key));function Kt(e){let t=kt(e);return Ue({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...Ot(t),provider:e.provider,providerSessionId:e.providerSessionId,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,sessionIsolation:e.sessionIsolation,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,surface:e.surface,activity:e.activity,launchConsole:e.launchConsole,launchArgs:e.launchArgs,relaunch:e.relaunch,shutdown:e.shutdown,saveScript:e.saveScript,deviceHub:e.deviceHub,testIme:e.testIme,noRecord:e.noRecord,recordAs:e.recordAs,record:e.record,backMode:e.backMode,metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,launchUrl:e.launchUrl,snapshotInteractiveOnly:e.interactiveOnly,snapshotDepth:e.depth,snapshotScope:e.scope,snapshotRaw:e.raw,snapshotCustomActions:e.customActions,snapshotForceFull:e.forceFull,...te(e),appsFilter:e.appsFilter,kind:e.kind,out:e.out,count:e.count,fps:e.fps,quality:e.quality,hideTouches:e.hideTouches,recordingScope:e.recordingScope,intervalMs:e.intervalMs,delayMs:e.delayMs,durationMs:e.durationMs,holdMs:e.holdMs,jitterPx:e.jitterPx,pixels:e.pixels,doubleTap:e.doubleTap,verify:e.verify,settle:e.settle,settleQuietMs:e.settleQuietMs,clickButton:e.clickButton,pauseMs:e.pauseMs,pattern:e.pattern,headless:e.headless,restart:e.restart,replayUpdate:e.replayUpdate,replayBackend:e.replayBackend,replayEnv:e.replayEnv,replayShellEnv:e.replayShellEnv,replayFrom:e.replayFrom,replayPlanDigest:e.replayPlanDigest,replayKeepSession:e.replayKeepSession,failFast:e.failFast,timeoutMs:e.timeoutMs,retries:e.retries,recordVideo:e.recordVideo,artifactsDir:e.artifactsDir,shardAll:e.shardAll,shardSplit:e.shardSplit,findFirst:e.findFirst,findLast:e.findLast,networkInclude:e.networkInclude,batchOnError:e.batchOnError,batchMaxSteps:e.batchMaxSteps,batchSteps:e.batchSteps,verbose:e.debug})}function qt(e,t){return{...Kt(e),...t}}function Jt(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!Gt.has(e))continue;let t=i[e];Yt(t)&&(r[e]=t)}return r}function Yt(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}const Xt=[`ref`,`selector`,`point`];function Zt(e,t=[]){return{type:`object`,properties:{...Rn(),...e},...t.length>0?{required:t}:{},additionalProperties:!1}}function Qt(e){return{type:`object`,description:e,properties:{x:{type:`number`},y:{type:`number`}},required:[`x`,`y`],additionalProperties:!1}}function $t(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function d(e){return{type:`string`,...e?{description:e}:{}}}function en(e,t={}){return{type:`number`,...e?{description:e}:{},...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function tn(e){return{type:`integer`,...e?{description:e}:{}}}function nn(e){return{type:`boolean`,...e?{description:e}:{}}}function rn(e){return{type:`array`,items:{type:`string`},...e?{description:e}:{}}}function an(e){return{type:`object`,additionalProperties:!0,...e?{description:e}:{}}}function f(e){return{...e,required:!0}}function p(e){return S(d(e),y)}function on(t){return{schema:{type:`null`},required:!1,retired:!0,read:(n,r)=>{if(Object.hasOwn(n,r))throw new e(`INVALID_ARGS`,t)}}}function m(e,t={}){return S(en(e,t),(e,n)=>Oe(e,n,t))}function h(e,t={}){return S(Nn(e,t),(e,n)=>we(e,n,t))}function g(e){return S(nn(e),Tn)}function _(e,t){return S($t(e,t),(t,n)=>Dn(t,n,e))}function sn(e){return S(an(e),In)}function cn(e){return S(rn(e),Ln)}function v(e){return S(e,(e,t)=>e[t])}function ln(e,t){return S(e,t)}function un(){return S(zn(),(e,t)=>e[t]===void 0?void 0:bn(e,t))}function dn(){return S(Bn(),(e,t)=>e[t]===void 0?void 0:xn(e,t))}function fn(e){return S(Qt(e),(e,t)=>e[t]===void 0?void 0:Sn(e,t))}function pn(){return{depth:h(`Snapshot traversal depth.`,{min:0}),scope:p(`Snapshot scope selector used before resolution.`),raw:g(`Use raw snapshot data during selector resolution.`)}}function mn(){return{count:h(`Number of press/click repetitions.`,{min:1}),intervalMs:h(`Delay between repeated press/click actions.`,{min:0}),holdMs:h(`Hold duration for each action.`,{min:0}),jitterPx:h(`Randomization radius in pixels.`,{min:0}),doubleTap:g(`Request a double-tap action.`)}}function hn(e){return Zt(Pn(e),Fn(e))}function gn(t,n){let r=_n(t),i=Object.fromEntries(Object.entries(n).flatMap(([t,n])=>{let i=n.read(r,t);if(n.required&&i===void 0)throw new e(`INVALID_ARGS`,`Expected ${t} to be set.`);return i===void 0?[]:[[t,i]]})),a=vn(r,{readTargetAlias:!Object.hasOwn(n,`target`)});return x({...a,...b(a),...i})}function _n(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function vn(e,t={}){return{session:y(e,`session`),platform:Dn(e,`platform`,qe),deviceTarget:yn(e,t),device:y(e,`device`),udid:y(e,`udid`),serial:y(e,`serial`),iosSimulatorDeviceSet:y(e,`iosSimulatorDeviceSet`),iosXctestrunFile:y(e,`iosXctestrunFile`),iosXctestDerivedDataPath:y(e,`iosXctestDerivedDataPath`),iosXctestEnvDir:y(e,`iosXctestEnvDir`),androidDeviceAllowlist:y(e,`androidDeviceAllowlist`),noRecord:Tn(e,`noRecord`),daemonBaseUrl:y(e,`daemonBaseUrl`),daemonAuthToken:y(e,`daemonAuthToken`),tenant:y(e,`tenant`),runId:y(e,`runId`),leaseId:y(e,`leaseId`),cwd:y(e,`cwd`),debug:Tn(e,`debug`)}}function yn(t,n){let r=Dn(t,`deviceTarget`,Je);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=Dn(t,`target`,Je);if(r!==void 0&&i!==r)throw new e(`INVALID_ARGS`,`Expected target alias to match deviceTarget when both are set.`);return r??i}function bn(e,t){let n=Hn(e,t),r=En(n,`kind`,Xt);switch(r){case`ref`:return{kind:r,ref:Cn(n,`ref`),label:y(n,`label`)};case`selector`:return{kind:r,selector:Cn(n,`selector`)};case`point`:return{kind:r,x:wn(n,`x`),y:wn(n,`y`)}}}function xn(e,t){let n=Hn(e,t),r=En(n,`kind`,[`ref`,`selector`]);return r===`ref`?{kind:r,ref:Cn(n,`ref`),label:y(n,`label`)}:{kind:r,selector:Cn(n,`selector`)}}function Sn(e,t){let n=Hn(e,t);return{x:wn(n,`x`),y:wn(n,`y`)}}function Cn(t,n){let r=t[n];if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}function y(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}}function wn(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function Tn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`boolean`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a boolean.`);return r}}function En(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}function Dn(t,n,r){let i=t[n];if(i!==void 0){if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}}function b(e){return x({noRecord:e.noRecord,session:e.session,platform:e.platform,target:e.deviceTarget,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,cwd:e.cwd,debug:e.debug})}function On(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector};case`point`:return{x:e.x,y:e.y}}}function kn(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector}}}function An(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function jn(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function Mn(t,n,r){let i=new Set(n),a=Object.keys(t).filter(e=>!i.has(e));if(a.length>0)throw new e(`INVALID_ARGS`,`${r} has unknown field(s): ${a.join(`, `)}.`)}function x(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function S(e,t){return{schema:e,required:!1,read:t}}function Nn(e,t){return{...tn(e),...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function Pn(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>!e.retired).map(([e,t])=>[e,t.schema]))}function Fn(e){return Object.entries(e).flatMap(([e,t])=>t.required?[e]:[])}function In(t,n){let r=t[n];if(r!==void 0){if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}}function Ln(t,n){let r=t[n];if(r!==void 0){if(!Array.isArray(r)||r.some(e=>typeof e!=`string`))throw new e(`INVALID_ARGS`,`Expected ${n} to be an array of strings.`);return r}}function Rn(){return{session:{type:`string`,description:`Agent-device session name.`},platform:{type:`string`,enum:qe,description:`Platform selector used to resolve a device.`},deviceTarget:{type:`string`,enum:Je,description:`Device target form. Maps to the CLI --target flag.`},target:{type:`string`,enum:Je,description:`Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element.`},device:{type:`string`,description:`Device name selector.`},udid:{type:`string`,description:`iOS device UDID selector.`},serial:{type:`string`,description:`Android device or Vega VVD serial selector.`},iosSimulatorDeviceSet:{type:`string`,description:`iOS simulator device-set path used for device resolution.`},iosXctestrunFile:{type:`string`,description:`Externally built iOS XCTest runner .xctestrun artifact path.`},iosXctestDerivedDataPath:{type:`string`,description:`Derived data path for external iOS XCTest runner execution.`},iosXctestEnvDir:{type:`string`,description:`Writable directory for iOS XCTest runner env overlays.`},androidDeviceAllowlist:{type:`string`,description:`Android serial allowlist used for device resolution.`},daemonBaseUrl:{type:`string`,description:`Remote daemon base URL.`},daemonAuthToken:{type:`string`,description:`Remote daemon auth token.`},tenant:{type:`string`,description:`Remote tenant identifier.`},runId:{type:`string`,description:`Lease run identifier.`},leaseId:{type:`string`,description:`Existing lease identifier.`},cwd:{type:`string`,description:`Working directory for command execution.`},debug:{type:`boolean`,description:`Enable debug diagnostics.`}}}function zn(){return{oneOf:[...Vn(),{type:`object`,properties:{kind:{type:`string`,const:`point`},x:{type:`number`},y:{type:`number`}},required:[`kind`,`x`,`y`],additionalProperties:!1}],description:`UI target. This is separate from deviceTarget, which selects the device form.`}}function Bn(){return{oneOf:Vn(),description:`UI element target by snapshot ref or selector expression.`}}function Vn(){return[{type:`object`,properties:{kind:{type:`string`,const:`ref`},ref:{type:`string`,description:`Snapshot element ref such as @e12.`},label:{type:`string`,description:`Optional human label for the ref.`}},required:[`kind`,`ref`],additionalProperties:!1},{type:`object`,properties:{kind:{type:`string`,const:`selector`},selector:{type:`string`,description:`Agent-device selector expression.`}},required:[`kind`,`selector`],additionalProperties:!1}]}function Hn(t,n){let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}function C(e,t){return n=>w(e,t?t(n):[],n)}function w(e,t,n,r){return{command:e,positionals:t,...r?{input:r}:{},options:Un(n)}}function Un(e){let t=Wn(e.deviceTarget??e.target);if(t===void 0&&e.target===void 0)return e;let{target:n,...r}=e;return t===void 0?r:{...r,target:t}}function Wn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function T(e){return x({noRecord:e.noRecord,session:e.session,platform:e.platform,deviceTarget:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist})}function Gn(e){return x({record:e.record})}function Kn(e){return{noRecord:e.noRecord,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,androidDeviceAllowlist:e.androidDeviceAllowlist}}function qn(e){return x({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function Jn(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function E(e){return x({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function Yn(e){return x({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function Xn(e){if(`ref`in e&&e.ref!==void 0)return x({kind:`ref`,ref:e.ref,label:e.label});if(`selector`in e&&e.selector!==void 0)return{kind:`selector`,selector:e.selector};let t=e;return{kind:`point`,x:t.x,y:t.y}}function Zn(t){let n=$n(t);if(typeof n.ref==`string`)return[n.ref,...tr(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(er(n.x,`x`)),String(er(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function Qn(t){let n=$n(t);if(typeof n.ref==`string`)return[n.ref,...tr(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function $n(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected target object.`);let n=t,r=n.target;return r&&typeof r==`object`&&!Array.isArray(r)?r:n}function er(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function tr(e){return typeof e==`string`&&e.length>0?[e]:[]}function nr(t){let n=Te(t);if(!n.ok)throw new e(n.code,n.message);return`ref`in n?{ref:n.ref,label:or(t.slice(1))}:{selector:n.selector}}function rr(t){let n=Be(t);if(!n.ok)throw new e(n.code,n.message);return n.format}function ir(t,n={}){let r=Ke(t,n);if(!r)throw new e(`INVALID_ARGS`,Ce);return r}function ar(t,n){try{let e=JSON.parse(t);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}throw new e(`INVALID_ARGS`,`${n} must be a JSON object`)}function or(e){return e.join(` `).trim()||void 0}function D(...e){return new Set(e)}function O(e,t){return e!==void 0&&t.has(e)}function sr(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function cr(t,n){if(t===void 0)return;let r=Number(t);if(Number.isFinite(r))return r;throw new e(`INVALID_ARGS`,`${n} must be a finite number.`)}function k(e){return e===void 0?void 0:Number(e)}function A(e){return e===void 0?[]:[e]}function j(e){return e===void 0?[]:[String(e)]}function M(t,n){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,n);return t}function N(t,n){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,n);return t}function lr(e){return fr(e.description,e.cliDetail)}function ur(e){return fr(e.description,e.mcpDetail)}function dr(e,t){return{...e,description:t}}function fr(e,t){return t?`${e} ${t}`:e}function P(e){let t=dr(e.text,e.metadata.description),n=t.mcpDetail?{mcpDetail:t.mcpDetail}:{};return{...e,metadata:{...e.metadata,...n},definition:{...e.definition,...n},cliSchema:{...e.cliSchema,text:t}}}function F(e){let t={},n={},r={},i={},a={};for(let o of e.commands){I(t,`CLI schema`,o.name,o.cliSchema);let e=o.definition.projection?.clientMethod??o.clientMethod;e&&I(n,`client command method`,e,o.name),I(r,`CLI reader`,o.name,o.cliReader),o.daemonWriter&&I(i,`daemon writer`,o.name,o.daemonWriter),o.cliOutputFormatter&&I(a,`CLI output formatter`,o.name,o.cliOutputFormatter)}return{name:e.name,clientSurface:e.clientSurface,metadata:e.commands.map(e=>e.metadata),definitions:e.commands.map(e=>e.definition),clientCommandMethods:n,cliSchemas:t,cliReaders:r,daemonWriters:i,cliOutputFormatters:a}}function pr(e){let t={};for(let n of e)n.projection&&I(t,`command output schema`,n.name,n.projection.outputSchema);return t}function I(e,t,n,r){if(Object.hasOwn(e,n))throw Error(`Duplicate command family ${t}: ${n}`);e[n]=r}function L(e){return e}function R(e,t,n){return{...e,run:t,invoke:async(n,r)=>await t(n,e.readInput(r)),...n?{projection:n}:{}}}function z(e){return({result:t})=>e(t)}const B=z(V);function V(e){return{data:e,text:ht(e)}}function mr(e,t){if(!(typeof e!=`string`||e.length===0)&&typeof t==`number`)return`@${e.startsWith(`@`)?e.slice(1):e}~s${t}`}function hr(e){let t=[`Batch completed: ${e.executed}/${e.total} steps in ${e.totalDurationMs}ms`];for(let n of e.results)t.push(_r(n));return{data:e,text:t.join(`
|
|
2
|
-
`)}}const gr={batch:z(hr)};function _r(e){let t=ht(e.data)??e.command;return`${e.step}. OK ${t} (${e.durationMs}ms)`}function vr(e=Ve){let t=yr(e);return L({name:`batch`,description:`Execute multiple commands in one daemon request`,inputSchema:hn(t),readInput:e=>xr(e,t)})}function yr(e){return{steps:f(ln({type:`array`,description:`Structured batch steps. Each step uses a command name and the same input object as that command tool.`,items:br(e)},(t,n)=>Sr(t[n],e))),onError:_([`stop`],`Batch failure policy.`),maxSteps:h(`Maximum number of steps accepted for this batch.`,{min:1,max:1e3}),out:p(`Optional output path for command artifacts.`)}}function br(e){return{type:`object`,properties:{command:{type:`string`,enum:e,description:`Command name to run with structured input.`},input:{type:`object`,additionalProperties:!0,description:`Structured command input for the nested command. Use the matching MCP tool schema for this object.`},runtime:{type:`object`,additionalProperties:!0,description:`Optional per-step runtime payload.`}},required:[`command`,`input`],additionalProperties:!1}}function xr(t,n){let r=gn(t,n),i=r.maxSteps??100;if(!je(i))throw new e(`INVALID_ARGS`,`Invalid batch maxSteps: ${String(r.maxSteps)}`);return We(r.steps.length,i),{...r}}function Sr(t,n){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected steps to be an array.`);return t.map((e,t)=>Cr(e,t+1,n))}function Cr(e,t,n){let r=Le(e,t);return Mn(r,[`command`,`input`,`runtime`],`Batch step ${t}`),{command:wr(r,t,n),input:ze(r,t),...Tr(r,t)}}function wr(t,n,r){if(r===Ve)return Pe(t.command,n);let i=t.command;if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected command to be one of: ${r.join(`, `)}.`);return i}function Tr(e,t){let n=Me(e.runtime,t);return n===void 0?{}:{runtime:n}}function Er(e){return t=>w(u.batch,[],{...t,batchSteps:Dr(t.steps,e),batchOnError:t.onError,batchMaxSteps:t.maxSteps})}function Dr(t,n){if(!Array.isArray(t)||t.length===0)throw new e(`INVALID_ARGS`,`batch requires a non-empty steps array.`);return t.map((e,t)=>Or(e,t+1,n))}function Or(e,t,n){let r=Le(e,t),i=kr(r,t),a=ze(r,t),o=Me(r.runtime,t),s=n(i,a,t);return{command:s.command,positionals:s.positionals,...s.input?{input:s.input}:{},flags:qt(s.options,s.metadataFlags),runtime:o??s.options.runtime}}function kr(e,t){return Pe(e.command,t)}const Ar=vr(),jr=F({name:`batch`,clientSurface:!1,commands:[P({name:`batch`,text:{summary:`Run multiple commands`},metadata:Ar,definition:R(Ar,(e,t)=>e.batch.run(Mr(t))),cliSchema:{usageOverride:`batch [--steps <json> | --steps-file <path>]`,listUsageOverride:`batch --steps <json> | --steps-file <path>`,allowedFlags:[`steps`,`stepsFile`,`batchOnError`,`batchMaxSteps`,`out`]},cliReader:(e,t)=>({...T(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out}),cliOutputFormatter:gr.batch})]});function Mr(e){return{...b(e),steps:e.steps,onError:e.onError,maxSteps:e.maxSteps,out:e.out}}function H(e,t,n){return L({name:e,description:t,inputSchema:hn(n),readInput:e=>gn(e,n)})}const Nr=`alert`,Pr=H(Nr,`Inspect, wait for, accept, or dismiss a platform alert. Use get before acting when the alert content matters; accept and dismiss change the active alert state.`,{action:_(ve),timeoutMs:h()}),Fr=P({name:Nr,text:{summary:`Inspect, accept, or dismiss a platform alert`},metadata:Pr,definition:R(Pr,(e,t)=>e.command.alert(t)),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...T(t),...Lr(e)}),daemonWriter:C(u.alert,e=>Ir(e)),cliOutputFormatter:B});function Ir(e){return[e.action??`get`,...j(e.timeoutMs)]}function Lr(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return x({action:Rr(t[0]),timeoutMs:cr(t[1],`alert timeout`)})}function Rr(t){let n=t?.toLowerCase();if(n===void 0||n===`get`||n===`accept`||n===`dismiss`||n===`wait`)return n;throw new e(`INVALID_ARGS`,`alert action must be get, accept, dismiss, or wait.`)}function U(...e){return e}const zr=U(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),W=U(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),Br=U(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),Vr=U(`metroHost`,`metroPort`,`bundleUrl`),Hr=U(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),Ur=U(`settle`,`settleQuietMs`,`timeoutMs`),Wr=U(`replayUpdate`,`replayEnv`),Gr=U(`remoteConfig`,`stateDir`,`daemonBaseUrl`,`daemonAuthToken`,`daemonTransport`,`daemonServerMode`,`tenant`,`sessionIsolation`,`runId`,`leaseId`,`leaseBackend`,`sessionLock`,`platform`,`target`,`device`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`providerDeviceOrientation`,`providerGeoLocation`,`providerTimezone`,`providerLanguage`,`providerLocale`,`providerNetworkProfile`,`providerCustomNetwork`,`providerNoResignApp`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`udid`,`serial`,`iosSimulatorDeviceSet`,`iosXctestrunFile`,`iosXctestDerivedDataPath`,`iosXctestEnvDir`,`androidDeviceAllowlist`,`session`,`noRecord`),Kr=new Set([`json`,`config`,`help`,`version`,`verbose`,`cost`,`responseLevel`]),qr=`diff`,Jr=H(qr,`Compare accessibility snapshots or screenshots to identify UI changes. Use snapshot comparisons for semantic tree changes and screenshot comparisons for pixel differences.`,{kind:f(v({type:`string`,const:`snapshot`})),out:p(),interactiveOnly:g(),depth:h(),scope:p(),raw:g()}),Yr=P({name:qr,text:{summary:`Diff snapshot or screenshot`,cliDetail:`Live iOS simulator screenshot diffs normalize status-bar chrome by default; use screenshot --normalize-status-bar when capturing reusable baselines.`},metadata:Jr,definition:R(Jr,(e,t)=>e.capture.diff(t)),cliSchema:{usageOverride:`diff snapshot | diff screenshot --baseline <path> [current.png] [--out <diff.png>] [--threshold <0-1>] [--overlay-refs]`,positionalArgs:[`kind`,`current?`],allowedFlags:[...zr,`baseline`,`threshold`,`out`,`overlayRefs`]},cliReader:(t,n)=>{if(t[0]!==`snapshot`)throw new e(`INVALID_ARGS`,`Only diff snapshot is available through this parser.`);return{...T(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:C(u.diff,e=>[N(e.kind,`diff requires kind`)])}),Xr=`screenshot`,Zr=H(Xr,`Capture a screenshot of the active app or web session. Choose the capture scope, density, size, or annotations through the corresponding input fields when needed.`,{path:p(`Output path.`),overlayRefs:g(),pixelDensity:h(`Output screenshot pixel density in pixels per logical point.`,{min:1}),fullscreen:g(),scale:m(`Screenshot scale factor.`,re),maxSize:on(se.migration.screenshot),stabilize:g(),normalizeStatusBar:g(),surface:_(wt)}),Qr=P({name:Xr,text:{summary:`Capture a screenshot`,cliDetail:`Web defaults to the viewport; use --fullscreen, --full, or -f for the entire page. iOS simulators default to 1x logical-point output; use --pixel-density to request a different screenshot density. macOS app sessions default to the app window; use --fullscreen for full desktop, --scale to downscale, --overlay-refs to annotate current refs, --normalize-status-bar for deterministic iOS simulator chrome, or --no-stabilize for low-latency Android capture loops.`},metadata:Zr,definition:R(Zr,(e,t)=>e.capture.screenshot(t)),cliSchema:{positionalArgs:[`path?`],allowedFlags:a},cliReader:(e,t)=>({...T(t),path:e[0]??t.out,...o(t)}),daemonWriter:e=>(s(`screenshot`,e),ee(e),w(u.screenshot,A(e.path),{...e,...ie(e)}))}),$r=`settings`,ei=H($r,`Change supported operating-system settings, animation scales, appearance, or app permissions on the selected target. Platform support varies by setting and action.`,{setting:f(p()),state:f(p()),app:p(),latitude:m(),longitude:m(),permission:p(),mode:_([`full`,`limited`])}),ti=P({name:$r,text:{summary:`Change OS settings and app permissions`,cliDetail:`macOS supports only settings appearance <light|dark|toggle> and settings permission <grant|reset> <accessibility|screen-recording|input-monitoring>; wifi|airplane|location|animations remain unsupported on macOS. Mobile permission actions use the active session app.`},metadata:ei,definition:R(ei,(e,t)=>e.settings.update(t)),cliSchema:{usageOverride:me,listUsageOverride:`settings [area] [options]`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>ni(e,t),daemonWriter:C(u.settings,e=>ri(e))});function ni(t,n){let r=Kn(n),i=t[0],a=t[1];if(O(i,oi)&&O(a,si))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:ye(t[2],`latitude`),longitude:ye(t[3],`longitude`)};if(i===`appearance`&&O(a,ci)||O(i,li)&&O(a,ui)||i===`fingerprint`&&O(a,di))return{...r,setting:i,state:a};if(i===`permission`&&O(a,fi))return{...r,setting:i,state:a,permission:ii(t[2]),mode:ai(t[3])};if(i===`clear-app-state`){let e=a===`clear`?t[2]:a;return{...r,setting:i,state:`clear`,app:e}}throw new e(`INVALID_ARGS`,`Invalid settings arguments.`)}function ri(e){return e.setting===`clear-app-state`?[e.setting,...A(e.app)]:e.setting===`location`&&e.state===`set`?[e.setting,e.state,String(e.latitude),String(e.longitude)]:e.setting===`permission`?[e.setting,e.state,e.permission,...A(e.mode)]:[e.setting,e.state]}function ii(t){if(O(t,pi))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function ai(t){if(t===void 0||t===`full`||t===`limited`)return t;throw new e(`INVALID_ARGS`,`settings permission mode must be full or limited.`)}const oi=D(`wifi`,`airplane`,`location`,`animations`),si=D(`on`,`off`),ci=D(`light`,`dark`,`toggle`),li=D(`faceid`,`touchid`),ui=D(`match`,`nonmatch`,`enroll`,`unenroll`),di=D(`match`,`nonmatch`),fi=D(`grant`,`deny`,`reset`),pi=D(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function mi(e){if(!Array.isArray(e)||e.length===0)return e;let t=De(e);return e.map(e=>{let n=hi(e,t,e=>e.label),r=hi(e,t,e=>e.identifier),i=typeof e.label==`string`&&e.label.length>=24&&e.label===n,a=typeof e.identifier==`string`&&e.identifier.length>=24&&e.identifier===r;if(!i&&!a)return e;let o={...e};return i&&(delete o.label,o.inheritsLabel=!0),a&&(delete o.identifier,o.inheritsIdentifier=!0),o})}function hi(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0;for(;r;){let e=n(r);if(typeof e==`string`&&e.length>0)return e;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}}function gi(e){let t=yt(e.raw||!Array.isArray(e.result.nodes)?e.result:{...e.result,nodes:mi(e.result.nodes)});return{data:t,jsonData:vi(t),stderr:e.result.snapshotDiagnostics?.warning?`${e.result.snapshotDiagnostics.warning}\n`:void 0,text:lt(t,{raw:e.raw,flatten:e.interactiveOnly,scoped:typeof e.scope==`string`&&e.scope.trim().length>0,depthLimited:typeof e.depth==`number`})}}const _i={snapshot:({input:e,result:t})=>gi({result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}),wait:B,alert:B};function vi(e){let{unchanged:t,...n}=e;return n}const yi=`snapshot`,bi=H(yi,`Capture the accessibility tree or compare it with the previous session baseline. Use the returned refs for subsequent semantic interactions and the diff option to verify UI changes.`,{interactiveOnly:g(),depth:h(),scope:p(),raw:g(),customActions:g(`Name the affordances an element merged away (iOS UIAccessibilityCustomAction, React Native accessibilityActions) — a card whose reply/options controls are not separate elements still lists them here. The names are for PLANNING, not invocation: there is no API to trigger them, so reach the affordance through the element detail screen, through the same control exposed as a labeled element elsewhere, or by coordinates from its rect. iOS simulator only; costs one accessibility round trip per merged element.`),forceFull:g(),timeoutMs:h(`Maximum wall-clock time for the snapshot command.`),noRecord:g(`Do not record this action.`),record:g(`Force-record this out-of-band observation into a repair-armed heal (mutually exclusive with noRecord). Authored replay steps are recorded automatically and never need this.`)}),xi=P({name:yi,text:{summary:`Capture or diff the accessibility tree`,cliDetail:`For iOS raw-coordinate fallback after a no-op ref press, inspect rects with snapshot -i --json, press the rect center, then verify with diff snapshot -i or snapshot --diff.`},metadata:bi,definition:R(bi,(e,t)=>e.capture.snapshot(t)),cliSchema:{usageOverride:`snapshot [--diff] [-i] [-d <depth>] [-s <scope>] [--raw] [--actions] [--force-full] [--timeout <ms>]`,allowedFlags:[`snapshotDiff`,...zr,`snapshotCustomActions`,`snapshotForceFull`,`timeoutMs`,`record`]},cliReader:(e,t)=>({...T(t),...Gn(t),interactiveOnly:t.snapshotInteractiveOnly,depth:t.snapshotDepth,scope:t.snapshotScope,raw:t.snapshotRaw,customActions:t.snapshotCustomActions,forceFull:t.snapshotForceFull,timeoutMs:t.timeoutMs}),daemonWriter:C(u.snapshot),cliOutputFormatter:_i.snapshot}),Si=[`duration`,`text`,`ref`,`selector`,`stable`],Ci=`wait`,wi=H(Ci,`Wait for a duration, text, snapshot ref, selector, or stable UI. Use text, ref, or selector for a specific readiness condition; stable waits until the UI stays quiet for the requested window.`,{kind:_(Si),durationMs:h(),text:p(),ref:p(),selector:p(),stable:g(),quietMs:h(),timeoutMs:h(),depth:h(),scope:p(),raw:g()}),Ti=P({name:Ci,text:{summary:`Wait for a duration, text, selector, or stable UI`},metadata:wi,definition:R(wi,(e,t)=>e.command.wait(Ei(t))),cliSchema:{usageOverride:`wait <ms>|text <text>|@ref|<selector>|stable [quietMs] [timeoutMs]`,positionalArgs:[`durationOrSelector`,`timeoutMs?`],allowsExtraPositionals:!0,allowedFlags:[...W]},cliReader:(e,t)=>Di(e,t),daemonWriter:C(u.wait,e=>Oi(e)),cliOutputFormatter:B});function Ei(e){Dn(e,`kind`,Si);let t={...e};return delete t.kind,t}function Di(t,n){let r=Ie(t);if(!r)throw new e(`INVALID_ARGS`,`wait requires <ms>, text <text>, @ref, <selector> [timeoutMs], or stable [quietMs] [timeoutMs].`);let i={...Kn(n),...Jn(n)};if(r.kind===`sleep`)return{...i,durationMs:r.durationMs};if(r.kind===`text`){if(!r.text)throw new e(`INVALID_ARGS`,`wait requires text.`);return{...i,text:r.text,...ki(r.timeoutMs)}}return r.kind===`ref`?{...i,ref:r.rawRef,...ki(r.timeoutMs)}:r.kind===`stable`?{...i,stable:!0,...Ai(r.quietMs),...ki(r.timeoutMs)}:{...i,selector:r.selectorExpression,...ki(r.timeoutMs)}}function Oi(t){if([t.durationMs===void 0?void 0:`durationMs`,t.text===void 0?void 0:`text`,t.ref===void 0?void 0:`ref`,t.selector===void 0?void 0:`selector`,t.stable===void 0?void 0:`stable`].filter(Boolean).length!==1)throw new e(`INVALID_ARGS`,`wait command requires exactly one of durationMs, text, ref, selector, or stable.`);if(t.durationMs!==void 0)return[String(t.durationMs)];let n=j(t.timeoutMs);if(t.text!==void 0)return[`text`,t.text,...n];if(t.ref!==void 0)return[t.ref,...n];if(t.stable!==void 0){let r=j(t.quietMs);if(r.length===0&&n.length>0)throw new e(`INVALID_ARGS`,`wait stable requires quietMs before timeoutMs.`);return[`stable`,...r,...n]}let r=t.selector;if(!He(r))throw new e(`INVALID_ARGS`,`Invalid wait selector: ${r}`);return[r,...n]}function ki(e){return e===null?{}:{timeoutMs:e}}function Ai(e){return e===null?{}:{quietMs:e}}const ji=F({name:`capture`,commands:[xi,Qr,Yr,Ti,Fr,ti]});function Mi(e){let t=[e.outPath,e.message];t.push(...Pi(e));for(let n of e.matchedImages)t.push(`Matched: ${n.name} ${n.uuid}${n.arch?` ${n.arch}`:``}`);for(let n of e.warnings??[])t.push(`Warning: ${n}`);return{data:e,text:t.join(`
|
|
3
|
-
`)}}const Ni={debug:z(Mi)};function Pi(e){let t=e.crash,n=[`Crash: ${t.appName??`unknown app`}${t.crashedThread===void 0?``:` thread ${t.crashedThread}`}`];t.bundleId&&n.push(`Bundle: ${t.bundleId}`),t.exceptionType&&n.push(`Exception: ${t.exceptionType}`),t.terminationReason&&n.push(`Termination: ${t.terminationReason}`);for(let e of t.topFrames)n.push(`Frame ${e.index}: ${e.image} ${e.symbol??e.address}`);for(let e of t.findings)n.push(`Finding: ${e}`);return n}const Fi=`debug`,Ii=H(Fi,`Symbolicate Apple crash artifacts with matching dSYM UUIDs. This debug namespace is intentionally narrow: use logs for app logs, network for HTTP evidence, perf for performance samples, record/trace for media and traces, and react-devtools for React Native profiles.`,{action:f(_([`symbols`])),artifact:f(p(`Apple crash artifact path (.ips, .crash, or .log).`)),dsym:p(`Path to a matching .dSYM bundle.`),searchPath:p(`Directory to scan for matching .dSYM bundles.`),out:p(`Output path for the symbolicated artifact.`)}),Li=F({name:`debugging`,commands:[P({name:Fi,text:{summary:`Symbolicate Apple crash artifacts`},metadata:Ii,definition:R(Ii,(e,t)=>e.debug.symbols(t)),cliSchema:{usageOverride:`debug symbols --artifact <crash.ips|crash.log> (--dsym <App.dSYM> | --search-path <dir>) [--out <symbolicated>]`,listUsageOverride:`debug`,positionalArgs:[`symbols`],allowedFlags:[`artifact`,`dsym`,`searchPath`,`out`]},cliReader:(e,t)=>({...T(t),action:Ri(e[0]),artifact:t.artifact,dsym:t.dsym,searchPath:t.searchPath,out:t.out}),cliOutputFormatter:Ni.debug})]});function Ri(t){if(t===`symbols`)return t;throw new e(`INVALID_ARGS`,`debug supports only symbols; use logs, network, perf, record, trace, or react-devtools for other diagnostics`)}const zi=()=>g(`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot.`),Bi=()=>({settle:g(`After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response. Best-effort; never fails the action.`),settleQuietMs:h(`Settle: quiet window in milliseconds (default 500).`,{min:0}),timeoutMs:h(`Settle: wait deadline in milliseconds (default 10000).`,{min:1})});function Vi(e){return{...
|
|
1
|
+
import{_ as e,n as t,t as n}from"./sdk-contracts.js";import{$ as r,C as i,Dt as a,Ft as o,It as s,J as c,Lt as ee,Nt as te,O as ne,Ot as re,Pt as ie,Q as ae,S as oe,Tt as se,V as ce,W as le,X as ue,Y as de,Z as fe,et as pe,g as me,k as he,kt as ge,lt as _e,mt as ve,p as ye,pt as be,tt as xe,w as Se}from"./version.js";import{Gn as l,Gt as Ce,Ht as we,Kt as Te,Qt as Ee,Ut as De,Xt as Oe,_ as ke,an as Ae,ct as je,d as Me,dn as Ne,f as Pe,g as Fe,i as Ie,m as Le,nr as Re,p as ze,qt as Be,r as Ve,sn as He,u as Ue,ut as We,yn as Ge,zn as Ke}from"./sdk-batch-runner.js";import{r as qe,t as Je}from"./sdk-device.js";import{$t as Ye,At as Xe,Bt as Ze,Ft as Qe,Lt as $e,Mt as et,Nt as tt,Pt as nt,Rt as rt,St as it,Ut as at,Vt as ot,Wt as st,Xt as u,Yt as ct,_t as lt,a as ut,c as dt,cn as ft,dn as pt,fn as mt,hn as ht,jt as gt,l as _t,ln as vt,mn as yt,n as bt,nn as xt,o as St,pn as Ct,qt as wt,r as Tt,t as Et,un as Dt,wn as Ot,xn as kt,xt as At,zt as jt}from"./prepare-kind.js";import{a as Mt}from"./sdk-remote-config.js";import{a as Nt,d as Pt,f as Ft,t as It}from"./device.js";const Lt=[{key:`count`,names:[`--count`],type:`int`,min:1,max:200,usageLabel:`--count <n>`,usageDescription:`Repeat count for press/swipe series`},{key:`pointerCount`,names:[`--pointer-count`],type:`int`,min:1,max:2,usageLabel:`--pointer-count <1|2>`,usageDescription:`Gesture pan: number of touch pointers (default 1)`},{key:`fps`,names:[`--fps`],type:`int`,min:1,max:120,usageLabel:`--fps <n>`,usageDescription:`Record: target frames per second (iOS physical device runner)`},{key:`quality`,names:[`--quality`],type:`string`,usageLabel:`--quality <medium|high>`,usageDescription:`Record: output quality preset; Android maps this to screenrecord bitrate, Apple targets use it for export/encoding. Legacy numeric values 5-7 map to medium; 8-10 map to high`},{key:`hideTouches`,names:[`--hide-touches`],type:`boolean`,usageLabel:`--hide-touches`,usageDescription:`Record: skip touch-overlay post-processing for faster raw benchmark videos`},{key:`recordingScope`,names:[`--scope`],type:`enum`,enumValues:Ye,usageLabel:`--scope <app|device|system>`,usageDescription:`Record: app requires an active app session; device/system records the whole screen`},{key:`intervalMs`,names:[`--interval-ms`],type:`int`,min:0,max:1e4,usageLabel:`--interval-ms <ms>`,usageDescription:`Delay between press iterations`},{key:`delayMs`,names:[`--delay-ms`],type:`int`,min:0,max:1e4,usageLabel:`--delay-ms <ms>`,usageDescription:`Delay between typed characters`},{key:`recordAs`,names:[`--record-as`],type:`string`,usageLabel:`--record-as <VAR>`,usageDescription:"Fill: send the live text but publish ${VAR} in an armed .ad recording"},{key:`durationMs`,names:[`--duration-ms`],type:`int`,min:0,max:1e4,usageLabel:`--duration-ms <ms>`,usageDescription:`Scroll: pace the gesture over this duration when supported`},{key:`holdMs`,names:[`--hold-ms`],type:`int`,min:0,max:1e4,usageLabel:`--hold-ms <ms>`,usageDescription:`Press hold duration for each iteration`},{key:`jitterPx`,names:[`--jitter-px`],type:`int`,min:0,max:100,usageLabel:`--jitter-px <n>`,usageDescription:`Deterministic coordinate jitter radius for press`},{key:`pixels`,names:[`--pixels`],type:`int`,min:1,max:1e5,usageLabel:`--pixels <n>`,usageDescription:`Scroll: explicit gesture distance in pixels`},{key:`doubleTap`,names:[`--double-tap`],type:`boolean`,usageLabel:`--double-tap`,usageDescription:`Use double-tap gesture per press iteration`},{key:`verify`,names:[`--verify`],type:`boolean`,usageLabel:`--verify`,usageDescription:`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot`},{key:`settle`,names:[`--settle`],type:`boolean`,usageLabel:`--settle`,usageDescription:`After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response (best-effort; never fails the action)`},{key:`settleQuietMs`,names:[`--settle-quiet`],type:`int`,min:0,usageLabel:`--settle-quiet <ms>`,usageDescription:`Settle: quiet window the UI must hold to count as settled (default 500ms)`},{key:`clickButton`,names:[`--button`],type:`enum`,enumValues:[`primary`,`secondary`,`middle`],usageLabel:`--button primary|secondary|middle`,usageDescription:`Click: choose mouse button (middle reserved for future macOS support)`},{key:`backMode`,names:[`--in-app`],type:`enum`,enumValues:[`in-app`,`system`],setValue:`in-app`,usageLabel:`--in-app`,usageDescription:`Back: use app-provided back UI when available`},{key:`backMode`,names:[`--system`],type:`enum`,enumValues:[`in-app`,`system`],setValue:`system`,usageLabel:`--system`,usageDescription:`Back: use system back input or gesture when available`},{key:`pauseMs`,names:[`--pause-ms`],type:`int`,min:0,max:1e4,usageLabel:`--pause-ms <ms>`,usageDescription:`Delay between swipe iterations`},{key:`pattern`,names:[`--pattern`],type:`enum`,enumValues:[`one-way`,`ping-pong`],usageLabel:`--pattern one-way|ping-pong`,usageDescription:`Swipe repeat pattern`},{key:`verbose`,names:[`--debug`,`--verbose`,`-v`],type:`boolean`,usageLabel:`--debug, --verbose, -v`,usageDescription:`Enable debug diagnostics; test --verbose prints per-test step timings without debug logs`},{key:`cost`,names:[`--cost`],type:`boolean`,usageLabel:`--cost`,usageDescription:`Include per-command wall-clock latency (cost.wallClockMs) in the response`},{key:`responseLevel`,names:[`--level`],type:`enum`,enumValues:t,usageLabel:`--level digest|default|full`,usageDescription:`Response detail level: digest (token-cheap), default (today), or full. Default keeps the wire shape unchanged.`},{key:`json`,names:[`--json`],type:`boolean`,usageLabel:`--json`,usageDescription:`JSON output`},{key:`help`,names:[`--help`,`-h`],type:`boolean`,usageLabel:`--help, -h`,usageDescription:`Print help and exit`},{key:`version`,names:[`--version`,`-V`],type:`boolean`,usageLabel:`--version, -V`,usageDescription:`Print version and exit`},{key:`snapshotDiff`,names:[`--diff`],type:`boolean`,usageLabel:`--diff`,usageDescription:`Snapshot: show structural diff against the previous session baseline`},{key:`saveScript`,names:[`--save-script`],type:`booleanOrString`,usageLabel:`--save-script [path]`,usageDescription:`Arm evidence capture on open, publish the armed recording on close; close --save-script alone (without an armed open) is rejected — start with open --save-script, or use session save-script mid-session. Optional custom output path.`},{key:`networkInclude`,names:[`--include`],type:`enum`,enumValues:[`summary`,`headers`,`body`,`all`],usageLabel:`--include summary|headers|body|all`,usageDescription:`Network: include headers, bodies, or both in output`},{key:`shutdown`,names:[`--shutdown`],type:`boolean`,usageLabel:`--shutdown`,usageDescription:`close: shutdown associated simulator/emulator after ending session`},{key:`relaunch`,names:[`--relaunch`],type:`boolean`,usageLabel:`--relaunch`,usageDescription:`open: terminate app process before launching it`},{key:`foreground`,names:[`--foreground`],type:`boolean`,usageLabel:`--foreground`,usageDescription:`open: keep normal app/device selection and return an initial snapshot; without an app, resolve the sole running app on the sole booted iOS simulator`},{key:`restart`,names:[`--restart`],type:`boolean`,usageLabel:`--restart`,usageDescription:`logs clear: stop active stream, clear logs, then start streaming again`},{key:`retainPaths`,names:[`--retain-paths`],type:`boolean`,usageLabel:`--retain-paths`,usageDescription:`install-from-source: keep materialized artifact paths after install`},{key:`retentionMs`,names:[`--retention-ms`],type:`int`,min:1,usageLabel:`--retention-ms <ms>`,usageDescription:`install-from-source: retention TTL for materialized artifact paths`},{key:`noRecord`,names:[`--no-record`],type:`boolean`,usageLabel:`--no-record`,usageDescription:`Do not record this action`},{key:`record`,names:[`--record`],type:`boolean`,usageLabel:`--record`,usageDescription:`Force-record this action even though its command is observation-only and would otherwise be excluded from a repair-armed heal by default (mutually exclusive with --no-record)`}],Rt=[{key:`config`,names:[`--config`],type:`string`,usageLabel:`--config <path>`,usageDescription:`Load CLI defaults from a specific config file (required for connection/provider defaults outside user config)`},{key:`remoteConfig`,names:[`--remote-config`],type:`string`,usageLabel:`--remote-config <path>`,usageDescription:`Load remote host + Metro workflow settings from a specific profile file`},{key:`stateDir`,names:[`--state-dir`],type:`string`,usageLabel:`--state-dir <path>`,usageDescription:`Daemon state directory (defaults to ~/.agent-device for packages, or a worktree-scoped dev dir from source)`},{key:`daemonBaseUrl`,names:[`--daemon-base-url`],type:`string`,usageLabel:`--daemon-base-url <url>`,usageDescription:`Explicit remote HTTP daemon base URL (skip local daemon discovery/startup)`},{key:`daemonAuthToken`,names:[`--daemon-auth-token`],type:`string`,usageLabel:`--daemon-auth-token <token>`,usageDescription:`Remote HTTP daemon or proxy auth token (sent as request token and bearer header)`},{key:`daemonTransport`,names:[`--daemon-transport`],type:`enum`,enumValues:[`auto`,`socket`,`http`],usageLabel:`--daemon-transport auto|socket|http`,usageDescription:`Daemon client transport preference`},{key:`daemonServerMode`,names:[`--daemon-server-mode`],type:`enum`,enumValues:[`socket`,`http`,`dual`],usageLabel:`--daemon-server-mode socket|http|dual`,usageDescription:`Daemon server mode used when spawning daemon`},{key:`proxyHost`,names:[`--host`],type:`string`,usageLabel:`--host <host>`,usageDescription:`Proxy: host interface to bind (default: 127.0.0.1)`},{key:`proxyPort`,names:[`--port`],type:`int`,min:1,max:65535,usageLabel:`--port <port>`,usageDescription:`Proxy: TCP port to bind (default: 0, choose a free port)`},{key:`tenant`,names:[`--tenant`],type:`string`,usageLabel:`--tenant <id>`,usageDescription:`Tenant scope identifier for isolated daemon sessions`},{key:`sessionIsolation`,names:[`--session-isolation`],type:`enum`,enumValues:[`none`,`tenant`],usageLabel:`--session-isolation none|tenant`,usageDescription:`Session isolation strategy (tenant prefixes session namespace)`},{key:`runId`,names:[`--run-id`],type:`string`,usageLabel:`--run-id <id>`,usageDescription:`Run identifier used for tenant lease admission checks`},{key:`leaseId`,names:[`--lease-id`],type:`string`,usageLabel:`--lease-id <id>`,usageDescription:`Lease identifier bound to tenant/run admission scope`},{key:`leaseBackend`,names:[`--lease-backend`],type:`enum`,enumValues:[`ios-simulator`,`ios-instance`,`android-instance`],usageLabel:`--lease-backend ios-simulator|ios-instance|android-instance`,usageDescription:`Lease backend for remote tenant connection admission`},{key:`provider`,names:[`--provider`],type:`string`,usageLabel:`--provider <name>`,usageDescription:`Cloud provider name for provider-scoped commands`},{key:`providerSessionId`,names:[`--provider-session`],type:`string`,usageLabel:`--provider-session <id>`,usageDescription:`Cloud provider session id or ARN`},{key:`providerApp`,names:[`--provider-app`],type:`string`,usageLabel:`--provider-app <ref-or-path>`,usageDescription:`Cloud provider app reference or local app path used when creating hosted WebDriver sessions`},{key:`providerOsVersion`,names:[`--provider-os-version`,`--os-version`],type:`string`,usageLabel:`--provider-os-version <version>`,usageDescription:`Hosted cloud provider OS version, for example 17 or 14.0`},{key:`providerProject`,names:[`--provider-project`],type:`string`,usageLabel:`--provider-project <name>`,usageDescription:`Hosted cloud provider project label`},{key:`providerBuild`,names:[`--provider-build`],type:`string`,usageLabel:`--provider-build <name>`,usageDescription:`Hosted cloud provider build label`},{key:`providerSessionName`,names:[`--provider-session-name`],type:`string`,usageLabel:`--provider-session-name <name>`,usageDescription:`Hosted cloud provider session label`},{key:`providerDeviceOrientation`,names:[`--provider-device-orientation`,`--device-orientation`],type:`enum`,enumValues:Mt,usageLabel:`--provider-device-orientation portrait|landscape`,usageDescription:`Screen orientation a hosted cloud provider session starts in. Set this rather than rotating after launch: a session that boots landscape renders login webviews landscape`},{key:`providerGeoLocation`,names:[`--provider-geo-location`,`--geo-location`],type:`string`,usageLabel:`--provider-geo-location <country>`,usageDescription:`Hosted cloud provider IP geolocation country code, for example US`},{key:`providerTimezone`,names:[`--provider-timezone`,`--timezone`],type:`string`,usageLabel:`--provider-timezone <zone>`,usageDescription:`Hosted cloud provider device time zone, for example New_York`},{key:`providerLanguage`,names:[`--provider-language`,`--language`],type:`string`,usageLabel:`--provider-language <language>`,usageDescription:`Hosted cloud provider app language, for example Fr`},{key:`providerLocale`,names:[`--provider-locale`,`--locale`],type:`string`,usageLabel:`--provider-locale <locale>`,usageDescription:`Hosted cloud provider device locale, for example Fr`},{key:`providerNetworkProfile`,names:[`--provider-network-profile`,`--network-profile`],type:`string`,usageLabel:`--provider-network-profile <profile>`,usageDescription:`Hosted cloud provider named network condition profile, for example 4g-lte-advanced-good. Mutually exclusive with --provider-custom-network`},{key:`providerCustomNetwork`,names:[`--provider-custom-network`,`--custom-network`],type:`string`,usageLabel:`--provider-custom-network <shape>`,usageDescription:`Hosted cloud provider custom network shape. Mutually exclusive with --provider-network-profile`},{key:`providerNoResignApp`,names:[`--provider-no-resign-app`],type:`boolean`,usageLabel:`--provider-no-resign-app`,usageDescription:`iOS only: keep an Enterprise-signed app as uploaded instead of letting the provider re-sign it, which strips entitlements such as push notifications`},{key:`awsProjectArn`,names:[`--aws-project-arn`],type:`string`,usageLabel:`--aws-project-arn <arn>`,usageDescription:`AWS Device Farm project ARN for hosted WebDriver sessions`},{key:`awsDeviceArn`,names:[`--aws-device-arn`],type:`string`,usageLabel:`--aws-device-arn <arn>`,usageDescription:`AWS Device Farm device ARN for hosted WebDriver sessions`},{key:`awsAppArn`,names:[`--aws-app-arn`],type:`string`,usageLabel:`--aws-app-arn <arn>`,usageDescription:`AWS Device Farm app ARN attached to hosted remote access sessions`},{key:`awsRegion`,names:[`--aws-region`],type:`string`,usageLabel:`--aws-region <region>`,usageDescription:`AWS region for Device Farm API calls`},{key:`awsInteractionMode`,names:[`--aws-interaction-mode`],type:`enum`,enumValues:[`INTERACTIVE`,`NO_VIDEO`,`VIDEO_ONLY`],usageLabel:`--aws-interaction-mode INTERACTIVE|NO_VIDEO|VIDEO_ONLY`,usageDescription:`AWS Device Farm remote access interaction mode`},{key:`force`,names:[`--force`,`--overwrite`],type:`boolean`,usageLabel:`--force, --overwrite`,usageDescription:`Force replacement of existing state (connect: replace an active connection; --save-script: overwrite an existing target instead of refusing)`},{key:`clean`,names:[`--clean`],type:`boolean`,usageLabel:`--clean`,usageDescription:`Daemon stop: remove retained runner processes and leases after stopping`},{key:`noLogin`,names:[`--no-login`],type:`boolean`,usageLabel:`--no-login`,usageDescription:`Connect: fail instead of starting implicit cloud login`},{key:`sessionLock`,names:[`--session-lock`],type:`enum`,enumValues:[`reject`,`strip`],usageLabel:`--session-lock reject|strip`,usageDescription:`Lock bound-session device routing for this CLI invocation and nested batch steps`}],zt=[{key:`platform`,names:[`--platform`],type:`enum`,enumValues:qe,usageLabel:`--platform ${qe.join(`|`)}`,usageDescription:"Platform to target (`apple` aliases the Apple automation backend)"},{key:`target`,names:[`--target`],type:`enum`,enumValues:[`mobile`,`tv`,`desktop`],usageLabel:`--target mobile|tv|desktop`,usageDescription:`Device target class to match`},{key:`device`,names:[`--device`],type:`string`,usageLabel:`--device <name>`,usageDescription:`Device name to target`},{key:`udid`,names:[`--udid`],type:`string`,usageLabel:`--udid <udid>`,usageDescription:`iOS device UDID`},{key:`serial`,names:[`--serial`],type:`string`,usageLabel:`--serial <serial>`,usageDescription:`Android device or Vega VVD serial`},{key:`stale`,names:[`--stale`],type:`boolean`,usageLabel:`--stale`,usageDescription:`Device status: show only claims with a provably stale owner`},{key:`surface`,names:[`--surface`],type:`enum`,enumValues:wt,usageLabel:`--surface app|frontmost-app|desktop|menubar`,usageDescription:`macOS session surface for open (defaults to app)`},{key:`headless`,names:[`--headless`],type:`boolean`,usageLabel:`--headless`,usageDescription:`Boot: launch Android emulator without a GUI window`},{key:`targetApp`,names:[`--app`,`--target-app`],type:`string`,usageLabel:`--app <id-or-name>`,usageDescription:`Doctor: verify an installed target app without opening a session`},{key:`metroHost`,names:[`--metro-host`],type:`string`,usageLabel:`--metro-host <host>`,usageDescription:`Session-scoped Metro/debug host hint`},{key:`metroPort`,names:[`--metro-port`],type:`int`,min:1,max:65535,usageLabel:`--metro-port <port>`,usageDescription:`Session-scoped Metro/debug port hint; on an emulator/simulator the host defaults to the loopback alias, physical devices still need --metro-host`},{key:`metroProjectRoot`,names:[`--project-root`],type:`string`,usageLabel:`--project-root <path>`,usageDescription:`metro prepare: React Native project root (default: cwd)`},{key:`kind`,names:[`--kind`],type:`enum`,enumValues:[`auto`,`react-native`,`expo`,`repack`,...Qe],usageLabel:`--kind <kind>`,usageDescription:`Kind selector for commands that support it, such as metro prepare or perf artifact collectors`},{key:`perfTemplate`,names:[`--template`],type:`string`,usageLabel:`--template <name>`,usageDescription:`Perf xctrace template name, for example Time Profiler`},{key:`metroKind`,names:[`--metro-kind`],type:`enum`,enumValues:[`auto`,`react-native`,`expo`,`repack`],usageLabel:`--metro-kind auto|react-native|expo|repack`,usageDescription:`metro prepare: detect or force the React Native dev-server launcher kind`},{key:`metroPublicBaseUrl`,names:[`--public-base-url`],type:`string`,usageLabel:`--public-base-url <url>`,usageDescription:`metro prepare: public base URL used for direct dev-server bundle hints`},{key:`metroProxyBaseUrl`,names:[`--proxy-base-url`],type:`string`,usageLabel:`--proxy-base-url <url>`,usageDescription:`metro prepare: optional bridge origin for remote dev-server access`},{key:`metroBearerToken`,names:[`--bearer-token`],type:`string`,usageLabel:`--bearer-token <token>`,usageDescription:`metro prepare: host bridge bearer token (or AGENT_DEVICE_METRO_BEARER_TOKEN; falls back to AGENT_DEVICE_DAEMON_AUTH_TOKEN)`},{key:`metroPreparePort`,names:[`--port`],type:`int`,min:1,max:65535,usageLabel:`--port <port>`,usageDescription:`metro prepare: local dev-server port (default: 8081)`},{key:`metroListenHost`,names:[`--listen-host`],type:`string`,usageLabel:`--listen-host <host>`,usageDescription:`metro prepare: host dev server listens on (default: 0.0.0.0)`},{key:`metroStatusHost`,names:[`--status-host`],type:`string`,usageLabel:`--status-host <host>`,usageDescription:`metro prepare: host used for local dev-server /status polling (default: 127.0.0.1)`},{key:`metroStartupTimeoutMs`,names:[`--startup-timeout-ms`],type:`int`,min:1,usageLabel:`--startup-timeout-ms <ms>`,usageDescription:`metro prepare: timeout while waiting for the dev server to become ready`},{key:`metroProbeTimeoutMs`,names:[`--probe-timeout-ms`],type:`int`,min:1,usageLabel:`--probe-timeout-ms <ms>`,usageDescription:`metro prepare: timeout for /status and proxy bridge calls`},{key:`metroRuntimeFile`,names:[`--runtime-file`],type:`string`,usageLabel:`--runtime-file <path>`,usageDescription:`metro prepare: optional file path to persist the JSON result`},{key:`metroNoReuseExisting`,names:[`--no-reuse-existing`],type:`boolean`,usageLabel:`--no-reuse-existing`,usageDescription:`metro prepare: always start a fresh Metro process`},{key:`metroNoInstallDeps`,names:[`--no-install-deps`],type:`boolean`,usageLabel:`--no-install-deps`,usageDescription:`metro prepare: skip package-manager install when node_modules is missing`},{key:`bundleUrl`,names:[`--bundle-url`],type:`string`,usageLabel:`--bundle-url <url>`,usageDescription:`Session-scoped bundle URL hint`},{key:`launchUrl`,names:[`--launch-url`],type:`string`,usageLabel:`--launch-url <url>`,usageDescription:`Session-scoped deep link / launch URL hint`},{key:`iosSimulatorDeviceSet`,names:[`--ios-simulator-device-set`],type:`string`,usageLabel:`--ios-simulator-device-set <path>`,usageDescription:`Scope iOS simulator discovery/commands to this simulator device set`},{key:`iosXctestrunFile`,names:[`--ios-xctestrun-file`],type:`string`,usageLabel:`--ios-xctestrun-file <path>`,usageDescription:`Use an externally built iOS XCTest runner .xctestrun artifact`},{key:`iosXctestDerivedDataPath`,names:[`--ios-xctest-derived-data-path`],type:`string`,usageLabel:`--ios-xctest-derived-data-path <path>`,usageDescription:`Derived data path for external iOS XCTest runner execution`},{key:`iosXctestEnvDir`,names:[`--ios-xctest-env-dir`],type:`string`,usageLabel:`--ios-xctest-env-dir <path>`,usageDescription:`Writable directory for per-session iOS XCTest runner env overlays`},{key:`deviceHub`,names:[`--device-hub`],type:`boolean`,usageLabel:`--device-hub`,usageDescription:`open: use Xcode Device Hub when surfacing Apple simulators`},{key:`testIme`,names:[`--test-ime`],type:`boolean`,usageLabel:`--test-ime`,usageDescription:`open: activate the headless Android test IME for deterministic Unicode text entry (default on for emulators; opt-in on real devices)`},{key:`testIme`,names:[`--no-test-ime`],type:`boolean`,setValue:!1,usageLabel:`--no-test-ime`,usageDescription:`open: keep the real Android keyboard even on emulators (opt out of the headless test IME)`},{key:`androidDeviceAllowlist`,names:[`--android-device-allowlist`],type:`string`,usageLabel:`--android-device-allowlist <serials>`,usageDescription:`Comma/space separated Android serial allowlist for discovery/selection`},{key:`remote`,names:[`--remote`],type:`boolean`,usageLabel:`--remote`,usageDescription:`Doctor: check remote connection setup instead of local device inventory`},{key:`activity`,names:[`--activity`],type:`string`,usageLabel:`--activity <component>`,usageDescription:`Android app launch activity (package/Activity); not for URL opens`},{key:`launchConsole`,names:[`--launch-console`],type:`string`,usageLabel:`--launch-console <path>`,usageDescription:`open: capture the initial iOS simulator launch console window to a file`},{key:`launchArgs`,names:[`--launch-args`],type:`string`,multiple:!0,usageLabel:`--launch-args <arg>`,usageDescription:`open: repeatable launch argument forwarded verbatim to the platform launch command (iOS app process args; Android adb shell am start args). Linux and macOS reject the flag.`},{key:`header`,names:[`--header`],type:`string`,multiple:!0,usageLabel:`--header <name:value>`,usageDescription:`install-from-source: repeatable HTTP header for URL downloads`},{key:`githubActionsArtifact`,names:[`--github-actions-artifact`],type:`string`,usageLabel:`--github-actions-artifact <owner/repo:artifact>`,usageDescription:`install-from-source: GitHub Actions artifact resolved by a remote daemon`},{key:`installSource`,names:[],type:`string`},{key:`session`,names:[`--session`],type:`string`,usageLabel:`--session <name>`,usageDescription:`Named session`}],Bt=[{key:`replayUpdate`,names:[`--update`,`-u`],type:`boolean`,usageLabel:`--update, -u`,usageDescription:`Replay: retired as a rewrite (ADR 0012) — never edits the .ad file; every divergence already carries ranked selector suggestions, --update or not`},{key:`replayFrom`,names:[`--from`],type:`int`,min:1,usageLabel:`--from <n>`,usageDescription:`Replay: resume at 1-based plan step n, skipping 1..n-1 without executing them (requires --plan-digest; see a divergence report's resume field). replay only, not test`},{key:`replayPlanDigest`,names:[`--plan-digest`],type:`string`,usageLabel:`--plan-digest <sha256>`,usageDescription:`Replay: the plan digest a --from resume must match (from a prior divergence report); mismatch, edits, or include/platform-expansion changes fail INVALID_ARGS before any action`},{key:`replayKeepSession`,names:[`--keep-session`],type:`boolean`,usageLabel:`--keep-session`,usageDescription:`Replay: leave the session active by suppressing exactly an authored terminal close in a native .ad script; replay only, not test or Maestro YAML`},{key:`replayMaestro`,names:[`--maestro`],type:`boolean`,usageLabel:`--maestro`,usageDescription:`Replay: treat input as a supported Maestro YAML subset; unsupported syntax fails loudly. See agent-device help maestro for commands and boundaries`},{key:`replayEnv`,names:[`-e`,`--env`],type:`string`,multiple:!0,usageLabel:`-e KEY=VALUE, --env KEY=VALUE`,usageDescription:"Replay/Test: inject or override a ${KEY} variable for the script (repeatable)"},{key:`failFast`,names:[`--fail-fast`],type:`boolean`,usageLabel:`--fail-fast`,usageDescription:`Test: stop the suite after the first failing script; with sharding, each shard stops independently`},{key:`timeoutMs`,names:[`--timeout`],type:`int`,min:1,usageLabel:`--timeout <ms>`,usageDescription:`Prepare/Replay/Snapshot/Test: maximum wall-clock time for the command or attempt. With --settle: the settle-wait deadline (default 10s)`},{key:`retries`,names:[`--retries`],type:`int`,min:0,max:3,usageLabel:`--retries <n>`,usageDescription:`Test: retry each failed script up to n additional times`},{key:`recordVideo`,names:[`--record-video`],type:`boolean`,usageLabel:`--record-video`,usageDescription:`Test: record each replay attempt to recording.mp4 in its attempt artifacts`},{key:`artifactsDir`,names:[`--artifacts-dir`],type:`string`,usageLabel:`--artifacts-dir <path>`,usageDescription:`Test: root directory for suite artifacts`},{key:`reporter`,names:[`--reporter`],type:`string`,multiple:!0,usageLabel:`--reporter <name-or-path>`,usageDescription:`Test: add a replay suite reporter; use default, junit:<path>, or a custom reporter path (repeatable)`},{key:`reportJunit`,names:[`--report-junit`],type:`string`,usageLabel:`--report-junit <path>`,usageDescription:`Test: compatibility alias for --reporter junit:<path>`},{key:`shardAll`,names:[`--shard-all`],type:`int`,min:1,usageLabel:`--shard-all <n>`,usageDescription:`Test: run the full suite on each of n devices; combine with --device id1,id2 for explicit connected devices; AD_SHARD_INDEX is zero-based`},{key:`shardSplit`,names:[`--shard-split`],type:`int`,min:1,usageLabel:`--shard-split <n>`,usageDescription:`Test: split runnable suite entries across n devices; AD_SHARD_INDEX is zero-based`},{key:`steps`,names:[`--steps`],type:`string`,usageLabel:`--steps <json>`,usageDescription:`Batch: JSON array of steps`},{key:`stepsFile`,names:[`--steps-file`],type:`string`,usageLabel:`--steps-file <path>`,usageDescription:`Batch: read steps JSON from file`},{key:`batchOnError`,names:[`--on-error`],type:`enum`,enumValues:[`stop`],usageLabel:`--on-error stop`,usageDescription:`Batch: stop when a step fails`},{key:`batchMaxSteps`,names:[`--max-steps`],type:`int`,min:1,max:1e3,usageLabel:`--max-steps <n>`,usageDescription:`Batch: maximum number of allowed steps`},{key:`appsFilter`,names:[`--all`],type:`enum`,enumValues:[`user-installed`,`all`],setValue:`all`,usageLabel:`--all`,usageDescription:`Apps: include system/OEM apps`},{key:`snapshotInteractiveOnly`,names:[`-i`],type:`boolean`,usageLabel:`-i`,usageDescription:`Snapshot: interactive elements only`},{key:`snapshotDepth`,names:[`--depth`,`-d`],type:`int`,min:0,usageLabel:`--depth, -d <depth>`,usageDescription:`Snapshot: limit snapshot depth`},{key:`snapshotScope`,names:[`--scope`,`-s`],type:`string`,usageLabel:`--scope, -s <scope>`,usageDescription:`Snapshot: scope snapshot to label/identifier`},{key:`snapshotRaw`,names:[`--raw`],type:`boolean`,usageLabel:`--raw`,usageDescription:`Snapshot: raw node output`},{key:`snapshotCustomActions`,names:[`--actions`],type:`boolean`,usageLabel:`--actions`,usageDescription:`Snapshot: name the affordances merged inside an element (iOS sim); not directly invokable — reach them via the detail screen, labeled children, or coordinates`},{key:`snapshotForceFull`,names:[`--force-full`],type:`boolean`,usageLabel:`--force-full`,usageDescription:`Snapshot: re-emit the full tree even when unchanged`},{key:`findFirst`,names:[`--first`],type:`boolean`,usageLabel:`--first`,usageDescription:`Find: pick the first match when ambiguous`},{key:`findLast`,names:[`--last`],type:`boolean`,usageLabel:`--last`,usageDescription:`Find: pick the last match when ambiguous`},{key:`out`,names:[`--out`],type:`string`,usageLabel:`--out <path>`,usageDescription:`Output path`},{key:`artifact`,names:[`--artifact`],type:`string`,usageLabel:`--artifact <path>`,usageDescription:`Debug symbols: Apple crash artifact path (.ips, .crash, or .log)`},{key:`dsym`,names:[`--dsym`],type:`string`,usageLabel:`--dsym <path>`,usageDescription:`Debug symbols: matching .dSYM bundle path`},{key:`searchPath`,names:[`--search-path`],type:`string`,usageLabel:`--search-path <dir>`,usageDescription:`Debug symbols: directory to scan for matching .dSYM bundles`},{key:`overlayRefs`,names:[`--overlay-refs`],type:`boolean`,usageLabel:`--overlay-refs`,usageDescription:`Screenshot: draw current snapshot refs and target rectangles onto the saved PNG; diff screenshot: also write a separate current-screen overlay guide`},...ge,{key:`baseline`,names:[`--baseline`,`-b`],type:`string`,usageLabel:`--baseline, -b <path>`,usageDescription:`Diff screenshot: path to baseline image file`},{key:`threshold`,names:[`--threshold`],type:`string`,usageLabel:`--threshold <0-1>`,usageDescription:`Diff screenshot: color distance threshold (default 0.1)`}],Vt=[...Rt,...zt,...Lt,...Bt],Ht=new Map;for(let e of Vt)for(let t of e.names)Ht.set(t,e);function Ut(e){return Ht.get(e)}function Wt(){return Vt}const Gt=new Set(Wt().map(e=>e.key));function Kt(e){let t=kt(e);return Re({stateDir:e.stateDir,daemonBaseUrl:e.daemonBaseUrl,daemonTransport:e.daemonTransport,daemonServerMode:e.daemonServerMode,...Ot(t),provider:e.provider,providerSessionId:e.providerSessionId,providerApp:e.providerApp,providerOsVersion:e.providerOsVersion,providerProject:e.providerProject,providerBuild:e.providerBuild,providerSessionName:e.providerSessionName,providerDeviceOrientation:e.providerDeviceOrientation,providerGeoLocation:e.providerGeoLocation,providerTimezone:e.providerTimezone,providerLanguage:e.providerLanguage,providerLocale:e.providerLocale,providerNetworkProfile:e.providerNetworkProfile,providerCustomNetwork:e.providerCustomNetwork,providerNoResignApp:e.providerNoResignApp,awsProjectArn:e.awsProjectArn,awsDeviceArn:e.awsDeviceArn,awsAppArn:e.awsAppArn,awsRegion:e.awsRegion,awsInteractionMode:e.awsInteractionMode,sessionIsolation:e.sessionIsolation,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,surface:e.surface,activity:e.activity,launchConsole:e.launchConsole,launchArgs:e.launchArgs,relaunch:e.relaunch,shutdown:e.shutdown,saveScript:e.saveScript,deviceHub:e.deviceHub,testIme:e.testIme,noRecord:e.noRecord,recordAs:e.recordAs,record:e.record,backMode:e.backMode,metroHost:e.metroHost,metroPort:e.metroPort,bundleUrl:e.bundleUrl,launchUrl:e.launchUrl,snapshotInteractiveOnly:e.interactiveOnly,snapshotDepth:e.depth,snapshotScope:e.scope,snapshotRaw:e.raw,snapshotCustomActions:e.customActions,snapshotForceFull:e.forceFull,...te(e),appsFilter:e.appsFilter,kind:e.kind,out:e.out,count:e.count,fps:e.fps,quality:e.quality,hideTouches:e.hideTouches,recordingScope:e.recordingScope,intervalMs:e.intervalMs,delayMs:e.delayMs,durationMs:e.durationMs,holdMs:e.holdMs,jitterPx:e.jitterPx,pixels:e.pixels,doubleTap:e.doubleTap,verify:e.verify,settle:e.settle,settleQuietMs:e.settleQuietMs,clickButton:e.clickButton,pauseMs:e.pauseMs,pattern:e.pattern,headless:e.headless,restart:e.restart,replayUpdate:e.replayUpdate,replayBackend:e.replayBackend,replayEnv:e.replayEnv,replayShellEnv:e.replayShellEnv,replayFrom:e.replayFrom,replayPlanDigest:e.replayPlanDigest,replayKeepSession:e.replayKeepSession,failFast:e.failFast,timeoutMs:e.timeoutMs,retries:e.retries,recordVideo:e.recordVideo,artifactsDir:e.artifactsDir,shardAll:e.shardAll,shardSplit:e.shardSplit,findFirst:e.findFirst,findLast:e.findLast,networkInclude:e.networkInclude,batchOnError:e.batchOnError,batchMaxSteps:e.batchMaxSteps,batchSteps:e.batchSteps,verbose:e.debug})}function qt(e,t){return{...Kt(e),...t}}function Jt(e,t){let n=e.inputSchema.properties;if(!n)return{};let r={},i=t;for(let e of Object.keys(n)){if(!Gt.has(e))continue;let t=i[e];Yt(t)&&(r[e]=t)}return r}function Yt(e){return typeof e==`boolean`||typeof e==`number`||typeof e==`string`}const Xt=[`ref`,`selector`,`point`];function Zt(e,t=[]){return{type:`object`,properties:{...Rn(),...e},...t.length>0?{required:t}:{},additionalProperties:!1}}function Qt(e){return{type:`object`,description:e,properties:{x:{type:`number`},y:{type:`number`}},required:[`x`,`y`],additionalProperties:!1}}function $t(e,t){return{type:`string`,enum:e,...t?{description:t}:{}}}function d(e){return{type:`string`,...e?{description:e}:{}}}function en(e,t={}){return{type:`number`,...e?{description:e}:{},...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function tn(e){return{type:`integer`,...e?{description:e}:{}}}function nn(e){return{type:`boolean`,...e?{description:e}:{}}}function rn(e){return{type:`array`,items:{type:`string`},...e?{description:e}:{}}}function an(e){return{type:`object`,additionalProperties:!0,...e?{description:e}:{}}}function f(e){return{...e,required:!0}}function p(e){return S(d(e),y)}function on(t){return{schema:{type:`null`},required:!1,retired:!0,read:(n,r)=>{if(Object.hasOwn(n,r))throw new e(`INVALID_ARGS`,t)}}}function m(e,t={}){return S(en(e,t),(e,n)=>De(e,n,t))}function h(e,t={}){return S(Nn(e,t),(e,n)=>we(e,n,t))}function g(e){return S(nn(e),Tn)}function _(e,t){return S($t(e,t),(t,n)=>Dn(t,n,e))}function sn(e){return S(an(e),In)}function cn(e){return S(rn(e),Ln)}function v(e){return S(e,(e,t)=>e[t])}function ln(e,t){return S(e,t)}function un(){return S(zn(),(e,t)=>e[t]===void 0?void 0:bn(e,t))}function dn(){return S(Bn(),(e,t)=>e[t]===void 0?void 0:xn(e,t))}function fn(e){return S(Qt(e),(e,t)=>e[t]===void 0?void 0:Sn(e,t))}function pn(){return{depth:h(`Snapshot traversal depth.`,{min:0}),scope:p(`Snapshot scope selector used before resolution.`),raw:g(`Use raw snapshot data during selector resolution.`)}}function mn(){return{count:h(`Number of press/click repetitions.`,{min:1}),intervalMs:h(`Delay between repeated press/click actions.`,{min:0}),holdMs:h(`Hold duration for each action.`,{min:0}),jitterPx:h(`Randomization radius in pixels.`,{min:0}),doubleTap:g(`Request a double-tap action.`)}}function hn(e){return Zt(Pn(e),Fn(e))}function gn(t,n){let r=_n(t),i=Object.fromEntries(Object.entries(n).flatMap(([t,n])=>{let i=n.read(r,t);if(n.required&&i===void 0)throw new e(`INVALID_ARGS`,`Expected ${t} to be set.`);return i===void 0?[]:[[t,i]]})),a=vn(r,{readTargetAlias:!Object.hasOwn(n,`target`)});return x({...a,...b(a),...i})}function _n(t){if(t==null)return{};if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected object arguments.`);return t}function vn(e,t={}){return{session:y(e,`session`),platform:Dn(e,`platform`,qe),deviceTarget:yn(e,t),device:y(e,`device`),udid:y(e,`udid`),serial:y(e,`serial`),iosSimulatorDeviceSet:y(e,`iosSimulatorDeviceSet`),iosXctestrunFile:y(e,`iosXctestrunFile`),iosXctestDerivedDataPath:y(e,`iosXctestDerivedDataPath`),iosXctestEnvDir:y(e,`iosXctestEnvDir`),androidDeviceAllowlist:y(e,`androidDeviceAllowlist`),noRecord:Tn(e,`noRecord`),daemonBaseUrl:y(e,`daemonBaseUrl`),daemonAuthToken:y(e,`daemonAuthToken`),tenant:y(e,`tenant`),runId:y(e,`runId`),leaseId:y(e,`leaseId`),cwd:y(e,`cwd`),debug:Tn(e,`debug`)}}function yn(t,n){let r=Dn(t,`deviceTarget`,Je);if(n.readTargetAlias===!1||t.target===void 0)return r;let i=Dn(t,`target`,Je);if(r!==void 0&&i!==r)throw new e(`INVALID_ARGS`,`Expected target alias to match deviceTarget when both are set.`);return r??i}function bn(e,t){let n=Hn(e,t),r=En(n,`kind`,Xt);switch(r){case`ref`:return{kind:r,ref:Cn(n,`ref`),label:y(n,`label`)};case`selector`:return{kind:r,selector:Cn(n,`selector`)};case`point`:return{kind:r,x:wn(n,`x`),y:wn(n,`y`)}}}function xn(e,t){let n=Hn(e,t),r=En(n,`kind`,[`ref`,`selector`]);return r===`ref`?{kind:r,ref:Cn(n,`ref`),label:y(n,`label`)}:{kind:r,selector:Cn(n,`selector`)}}function Sn(e,t){let n=Hn(e,t);return{x:wn(n,`x`),y:wn(n,`y`)}}function Cn(t,n){let r=t[n];if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}function y(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`string`||r.length===0)throw new e(`INVALID_ARGS`,`Expected ${n} to be a non-empty string.`);return r}}function wn(t,n){let r=t[n];if(typeof r!=`number`||!Number.isFinite(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be a finite number.`);return r}function Tn(t,n){let r=t[n];if(r!==void 0){if(typeof r!=`boolean`)throw new e(`INVALID_ARGS`,`Expected ${n} to be a boolean.`);return r}}function En(t,n,r){let i=t[n];if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}function Dn(t,n,r){let i=t[n];if(i!==void 0){if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected ${n} to be one of: ${r.join(`, `)}.`);return i}}function b(e){return x({noRecord:e.noRecord,session:e.session,platform:e.platform,target:e.deviceTarget,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist,daemonBaseUrl:e.daemonBaseUrl,daemonAuthToken:e.daemonAuthToken,tenant:e.tenant,runId:e.runId,leaseId:e.leaseId,cwd:e.cwd,debug:e.debug})}function On(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector};case`point`:return{x:e.x,y:e.y}}}function kn(e){switch(e.kind){case`ref`:return{ref:e.ref,label:e.label};case`selector`:return{selector:e.selector}}}function An(e){return{count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap}}function jn(e){return{depth:e.depth,scope:e.scope,raw:e.raw}}function Mn(t,n,r){let i=new Set(n),a=Object.keys(t).filter(e=>!i.has(e));if(a.length>0)throw new e(`INVALID_ARGS`,`${r} has unknown field(s): ${a.join(`, `)}.`)}function x(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}function S(e,t){return{schema:e,required:!1,read:t}}function Nn(e,t){return{...tn(e),...t.min===void 0?{}:{minimum:t.min},...t.max===void 0?{}:{maximum:t.max}}}function Pn(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>!e.retired).map(([e,t])=>[e,t.schema]))}function Fn(e){return Object.entries(e).flatMap(([e,t])=>t.required?[e]:[])}function In(t,n){let r=t[n];if(r!==void 0){if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}}function Ln(t,n){let r=t[n];if(r!==void 0){if(!Array.isArray(r)||r.some(e=>typeof e!=`string`))throw new e(`INVALID_ARGS`,`Expected ${n} to be an array of strings.`);return r}}function Rn(){return{session:{type:`string`,description:`Agent-device session name.`},platform:{type:`string`,enum:qe,description:`Platform selector used to resolve a device.`},deviceTarget:{type:`string`,enum:Je,description:`Device target form. Maps to the CLI --target flag.`},target:{type:`string`,enum:Je,description:`Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element.`},device:{type:`string`,description:`Device name selector.`},udid:{type:`string`,description:`iOS device UDID selector.`},serial:{type:`string`,description:`Android device or Vega VVD serial selector.`},iosSimulatorDeviceSet:{type:`string`,description:`iOS simulator device-set path used for device resolution.`},iosXctestrunFile:{type:`string`,description:`Externally built iOS XCTest runner .xctestrun artifact path.`},iosXctestDerivedDataPath:{type:`string`,description:`Derived data path for external iOS XCTest runner execution.`},iosXctestEnvDir:{type:`string`,description:`Writable directory for iOS XCTest runner env overlays.`},androidDeviceAllowlist:{type:`string`,description:`Android serial allowlist used for device resolution.`},daemonBaseUrl:{type:`string`,description:`Remote daemon base URL.`},daemonAuthToken:{type:`string`,description:`Remote daemon auth token.`},tenant:{type:`string`,description:`Remote tenant identifier.`},runId:{type:`string`,description:`Lease run identifier.`},leaseId:{type:`string`,description:`Existing lease identifier.`},cwd:{type:`string`,description:`Working directory for command execution.`},debug:{type:`boolean`,description:`Enable debug diagnostics.`}}}function zn(){return{oneOf:[...Vn(),{type:`object`,properties:{kind:{type:`string`,const:`point`},x:{type:`number`},y:{type:`number`}},required:[`kind`,`x`,`y`],additionalProperties:!1}],description:`UI target. This is separate from deviceTarget, which selects the device form.`}}function Bn(){return{oneOf:Vn(),description:`UI element target by snapshot ref or selector expression.`}}function Vn(){return[{type:`object`,properties:{kind:{type:`string`,const:`ref`},ref:{type:`string`,description:`Snapshot element ref such as @e12.`},label:{type:`string`,description:`Optional human label for the ref.`}},required:[`kind`,`ref`],additionalProperties:!1},{type:`object`,properties:{kind:{type:`string`,const:`selector`},selector:{type:`string`,description:`Agent-device selector expression.`}},required:[`kind`,`selector`],additionalProperties:!1}]}function Hn(t,n){let r=t[n];if(!r||typeof r!=`object`||Array.isArray(r))throw new e(`INVALID_ARGS`,`Expected ${n} to be an object.`);return r}function C(e,t){return n=>w(e,t?t(n):[],n)}function w(e,t,n,r){return{command:e,positionals:t,...r?{input:r}:{},options:Un(n)}}function Un(e){let t=Wn(e.deviceTarget??e.target);if(t===void 0&&e.target===void 0)return e;let{target:n,...r}=e;return t===void 0?r:{...r,target:t}}function Wn(e){return e===`mobile`||e===`tv`||e===`desktop`?e:void 0}function T(e){return x({noRecord:e.noRecord,session:e.session,platform:e.platform,deviceTarget:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,iosXctestrunFile:e.iosXctestrunFile,iosXctestDerivedDataPath:e.iosXctestDerivedDataPath,iosXctestEnvDir:e.iosXctestEnvDir,androidDeviceAllowlist:e.androidDeviceAllowlist})}function Gn(e){return x({record:e.record})}function Kn(e){return{noRecord:e.noRecord,platform:e.platform,target:e.target,device:e.device,udid:e.udid,serial:e.serial,iosSimulatorDeviceSet:e.iosSimulatorDeviceSet,androidDeviceAllowlist:e.androidDeviceAllowlist}}function qn(e){return x({depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw})}function Jn(e){return{depth:e.snapshotDepth,scope:e.snapshotScope,raw:e.snapshotRaw}}function E(e){return x({settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs})}function Yn(e){return x({count:e.count,intervalMs:e.intervalMs,holdMs:e.holdMs,jitterPx:e.jitterPx,doubleTap:e.doubleTap})}function Xn(e){if(`ref`in e&&e.ref!==void 0)return x({kind:`ref`,ref:e.ref,label:e.label});if(`selector`in e&&e.selector!==void 0)return{kind:`selector`,selector:e.selector};let t=e;return{kind:`point`,x:t.x,y:t.y}}function Zn(t){let n=$n(t);if(typeof n.ref==`string`)return[n.ref,...tr(n.label)];if(typeof n.selector==`string`)return[n.selector];if(n.kind===`point`||n.x!==void 0||n.y!==void 0)return[String(er(n.x,`x`)),String(er(n.y,`y`))];throw new e(`INVALID_ARGS`,`interaction requires @ref, selector, or point target`)}function Qn(t){let n=$n(t);if(typeof n.ref==`string`)return[n.ref,...tr(n.label)];if(typeof n.selector==`string`)return[n.selector];throw new e(`INVALID_ARGS`,`element command requires @ref or selector target`)}function $n(t){if(!t||typeof t!=`object`||Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected target object.`);let n=t,r=n.target;return r&&typeof r==`object`&&!Array.isArray(r)?r:n}function er(t,n){if(typeof t!=`number`||!Number.isFinite(t))throw new e(`INVALID_ARGS`,`point target requires numeric ${n}.`);return t}function tr(e){return typeof e==`string`&&e.length>0?[e]:[]}function nr(t){let n=Te(t);if(!n.ok)throw new e(n.code,n.message);return`ref`in n?{ref:n.ref,label:or(t.slice(1))}:{selector:n.selector}}function rr(t){let n=Be(t);if(!n.ok)throw new e(n.code,n.message);return n.format}function ir(t,n={}){let r=Ge(t,n);if(!r)throw new e(`INVALID_ARGS`,Ce);return r}function ar(t,n){try{let e=JSON.parse(t);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}throw new e(`INVALID_ARGS`,`${n} must be a JSON object`)}function or(e){return e.join(` `).trim()||void 0}function D(...e){return new Set(e)}function O(e,t){return e!==void 0&&t.has(e)}function sr(e){return e===void 0||e.trim()===``?!1:Number.isFinite(Number(e))}function cr(t,n){if(t===void 0)return;let r=Number(t);if(Number.isFinite(r))return r;throw new e(`INVALID_ARGS`,`${n} must be a finite number.`)}function k(e){return e===void 0?void 0:Number(e)}function A(e){return e===void 0?[]:[e]}function j(e){return e===void 0?[]:[String(e)]}function M(t,n){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,n);return t}function N(t,n){if(typeof t!=`string`||t.length===0)throw new e(`INVALID_ARGS`,n);return t}function lr(e){return fr(e.description,e.cliDetail)}function ur(e){return fr(e.description,e.mcpDetail)}function dr(e,t){return{...e,description:t}}function fr(e,t){return t?`${e} ${t}`:e}function P(e){let t=dr(e.text,e.metadata.description),n=t.mcpDetail?{mcpDetail:t.mcpDetail}:{};return{...e,metadata:{...e.metadata,...n},definition:{...e.definition,...n},cliSchema:{...e.cliSchema,text:t}}}function F(e){let t={},n={},r={},i={},a={};for(let o of e.commands){I(t,`CLI schema`,o.name,o.cliSchema);let e=o.definition.projection?.clientMethod??o.clientMethod;e&&I(n,`client command method`,e,o.name),I(r,`CLI reader`,o.name,o.cliReader),o.daemonWriter&&I(i,`daemon writer`,o.name,o.daemonWriter),o.cliOutputFormatter&&I(a,`CLI output formatter`,o.name,o.cliOutputFormatter)}return{name:e.name,clientSurface:e.clientSurface,metadata:e.commands.map(e=>e.metadata),definitions:e.commands.map(e=>e.definition),clientCommandMethods:n,cliSchemas:t,cliReaders:r,daemonWriters:i,cliOutputFormatters:a}}function pr(e){let t={};for(let n of e)n.projection&&I(t,`command output schema`,n.name,n.projection.outputSchema);return t}function I(e,t,n,r){if(Object.hasOwn(e,n))throw Error(`Duplicate command family ${t}: ${n}`);e[n]=r}function L(e){return e}function R(e,t,n){return{...e,run:t,invoke:async(n,r)=>await t(n,e.readInput(r)),...n?{projection:n}:{}}}function z(e){return({result:t})=>e(t)}const B=z(V);function V(e){return{data:e,text:ht(e)}}function mr(e,t){if(!(typeof e!=`string`||e.length===0)&&typeof t==`number`)return`@${e.startsWith(`@`)?e.slice(1):e}~s${t}`}function hr(e){let t=[`Batch completed: ${e.executed}/${e.total} steps in ${e.totalDurationMs}ms`];for(let n of e.results)t.push(_r(n));return{data:e,text:t.join(`
|
|
2
|
+
`)}}const gr={batch:z(hr)};function _r(e){let t=ht(e.data)??e.command;return`${e.step}. OK ${t} (${e.durationMs}ms)`}function vr(e=Ve){let t=yr(e);return L({name:`batch`,description:`Execute multiple commands in one daemon request`,inputSchema:hn(t),readInput:e=>xr(e,t)})}function yr(e){return{steps:f(ln({type:`array`,description:`Structured batch steps. Each step uses a command name and the same input object as that command tool.`,items:br(e)},(t,n)=>Sr(t[n],e))),onError:_([`stop`],`Batch failure policy.`),maxSteps:h(`Maximum number of steps accepted for this batch.`,{min:1,max:1e3}),out:p(`Optional output path for command artifacts.`)}}function br(e){return{type:`object`,properties:{command:{type:`string`,enum:e,description:`Command name to run with structured input.`},input:{type:`object`,additionalProperties:!0,description:`Structured command input for the nested command. Use the matching MCP tool schema for this object.`},runtime:{type:`object`,additionalProperties:!0,description:`Optional per-step runtime payload.`}},required:[`command`,`input`],additionalProperties:!1}}function xr(t,n){let r=gn(t,n),i=r.maxSteps??100;if(!Me(i))throw new e(`INVALID_ARGS`,`Invalid batch maxSteps: ${String(r.maxSteps)}`);return Ue(r.steps.length,i),{...r}}function Sr(t,n){if(!Array.isArray(t))throw new e(`INVALID_ARGS`,`Expected steps to be an array.`);return t.map((e,t)=>Cr(e,t+1,n))}function Cr(e,t,n){let r=Le(e,t);return Mn(r,[`command`,`input`,`runtime`],`Batch step ${t}`),{command:wr(r,t,n),input:ze(r,t),...Tr(r,t)}}function wr(t,n,r){if(r===Ve)return Ie(t.command,n);let i=t.command;if(typeof i!=`string`||!r.includes(i))throw new e(`INVALID_ARGS`,`Expected command to be one of: ${r.join(`, `)}.`);return i}function Tr(e,t){let n=Pe(e.runtime,t);return n===void 0?{}:{runtime:n}}function Er(e){return t=>w(u.batch,[],{...t,batchSteps:Dr(t.steps,e),batchOnError:t.onError,batchMaxSteps:t.maxSteps})}function Dr(t,n){if(!Array.isArray(t)||t.length===0)throw new e(`INVALID_ARGS`,`batch requires a non-empty steps array.`);return t.map((e,t)=>Or(e,t+1,n))}function Or(e,t,n){let r=Le(e,t),i=kr(r,t),a=ze(r,t),o=Pe(r.runtime,t),s=n(i,a,t);return{command:s.command,positionals:s.positionals,...s.input?{input:s.input}:{},flags:qt(s.options,s.metadataFlags),runtime:o??s.options.runtime}}function kr(e,t){return Ie(e.command,t)}const Ar=vr(),jr=F({name:`batch`,clientSurface:!1,commands:[P({name:`batch`,text:{summary:`Run multiple commands`},metadata:Ar,definition:R(Ar,(e,t)=>e.batch.run(Mr(t))),cliSchema:{usageOverride:`batch [--steps <json> | --steps-file <path>]`,listUsageOverride:`batch --steps <json> | --steps-file <path>`,allowedFlags:[`steps`,`stepsFile`,`batchOnError`,`batchMaxSteps`,`out`]},cliReader:(e,t)=>({...T(t),steps:t.batchSteps??[],onError:t.batchOnError,maxSteps:t.batchMaxSteps,out:t.out}),cliOutputFormatter:gr.batch})]});function Mr(e){return{...b(e),steps:e.steps,onError:e.onError,maxSteps:e.maxSteps,out:e.out}}function H(e,t,n){return L({name:e,description:t,inputSchema:hn(n),readInput:e=>gn(e,n)})}const Nr=`alert`,Pr=H(Nr,`Inspect, wait for, accept, or dismiss a platform alert. Use get before acting when the alert content matters; accept and dismiss change the active alert state.`,{action:_(ve),timeoutMs:h()}),Fr=P({name:Nr,text:{summary:`Inspect, accept, or dismiss a platform alert`},metadata:Pr,definition:R(Pr,(e,t)=>e.command.alert(t)),cliSchema:{usageOverride:`alert [get|accept|dismiss|wait] [timeout]`,positionalArgs:[`action?`,`timeout?`]},cliReader:(e,t)=>({...T(t),...Lr(e)}),daemonWriter:C(u.alert,e=>Ir(e)),cliOutputFormatter:B});function Ir(e){return[e.action??`get`,...j(e.timeoutMs)]}function Lr(t){if(t.length>2)throw new e(`INVALID_ARGS`,`alert accepts at most action and timeout arguments.`);return x({action:Rr(t[0]),timeoutMs:cr(t[1],`alert timeout`)})}function Rr(t){let n=t?.toLowerCase();if(n===void 0||n===`get`||n===`accept`||n===`dismiss`||n===`wait`)return n;throw new e(`INVALID_ARGS`,`alert action must be get, accept, dismiss, or wait.`)}function U(...e){return e}const zr=U(`snapshotInteractiveOnly`,`snapshotDepth`,`snapshotScope`,`snapshotRaw`),W=U(`snapshotDepth`,`snapshotScope`,`snapshotRaw`),Br=U(`metroProjectRoot`,`kind`,`metroKind`,`metroPublicBaseUrl`,`metroProxyBaseUrl`,`metroBearerToken`,`metroPreparePort`,`metroListenHost`,`metroStatusHost`,`metroStartupTimeoutMs`,`metroProbeTimeoutMs`,`metroRuntimeFile`,`metroNoReuseExisting`,`metroNoInstallDeps`),Vr=U(`metroHost`,`metroPort`,`bundleUrl`),Hr=U(`count`,`intervalMs`,`holdMs`,`jitterPx`,`doubleTap`),Ur=U(`settle`,`settleQuietMs`,`timeoutMs`),Wr=U(`replayUpdate`,`replayEnv`),Gr=U(`remoteConfig`,`stateDir`,`daemonBaseUrl`,`daemonAuthToken`,`daemonTransport`,`daemonServerMode`,`tenant`,`sessionIsolation`,`runId`,`leaseId`,`leaseBackend`,`sessionLock`,`platform`,`target`,`device`,`providerApp`,`providerOsVersion`,`providerProject`,`providerBuild`,`providerSessionName`,`providerDeviceOrientation`,`providerGeoLocation`,`providerTimezone`,`providerLanguage`,`providerLocale`,`providerNetworkProfile`,`providerCustomNetwork`,`providerNoResignApp`,`awsProjectArn`,`awsDeviceArn`,`awsAppArn`,`awsRegion`,`awsInteractionMode`,`udid`,`serial`,`iosSimulatorDeviceSet`,`iosXctestrunFile`,`iosXctestDerivedDataPath`,`iosXctestEnvDir`,`androidDeviceAllowlist`,`session`,`noRecord`),Kr=new Set([`json`,`config`,`help`,`version`,`verbose`,`cost`,`responseLevel`]),qr=`diff`,Jr=H(qr,`Compare accessibility snapshots or screenshots to identify UI changes. Use snapshot comparisons for semantic tree changes and screenshot comparisons for pixel differences.`,{kind:f(v({type:`string`,const:`snapshot`})),out:p(),interactiveOnly:g(),depth:h(),scope:p(),raw:g()}),Yr=P({name:qr,text:{summary:`Diff snapshot or screenshot`,cliDetail:`Live iOS simulator screenshot diffs normalize status-bar chrome by default; use screenshot --normalize-status-bar when capturing reusable baselines.`},metadata:Jr,definition:R(Jr,(e,t)=>e.capture.diff(t)),cliSchema:{usageOverride:`diff snapshot | diff screenshot --baseline <path> [current.png] [--out <diff.png>] [--threshold <0-1>] [--overlay-refs]`,positionalArgs:[`kind`,`current?`],allowedFlags:[...zr,`baseline`,`threshold`,`out`,`overlayRefs`]},cliReader:(t,n)=>{if(t[0]!==`snapshot`)throw new e(`INVALID_ARGS`,`Only diff snapshot is available through this parser.`);return{...T(n),kind:`snapshot`,out:n.out,interactiveOnly:n.snapshotInteractiveOnly,depth:n.snapshotDepth,scope:n.snapshotScope,raw:n.snapshotRaw}},daemonWriter:C(u.diff,e=>[N(e.kind,`diff requires kind`)])}),Xr=`screenshot`,Zr=H(Xr,`Capture a screenshot of the active app or web session. Choose the capture scope, density, size, or annotations through the corresponding input fields when needed.`,{path:p(`Output path.`),overlayRefs:g(),pixelDensity:h(`Output screenshot pixel density in pixels per logical point.`,{min:1}),fullscreen:g(),scale:m(`Screenshot scale factor.`,re),maxSize:on(se.migration.screenshot),stabilize:g(),normalizeStatusBar:g(),surface:_(wt)}),Qr=P({name:Xr,text:{summary:`Capture a screenshot`,cliDetail:`Web defaults to the viewport; use --fullscreen, --full, or -f for the entire page. iOS simulators default to 1x logical-point output; use --pixel-density to request a different screenshot density. macOS app sessions default to the app window; use --fullscreen for full desktop, --scale to downscale, --overlay-refs to annotate current refs, --normalize-status-bar for deterministic iOS simulator chrome, or --no-stabilize for low-latency Android capture loops.`},metadata:Zr,definition:R(Zr,(e,t)=>e.capture.screenshot(t)),cliSchema:{positionalArgs:[`path?`],allowedFlags:a},cliReader:(e,t)=>({...T(t),path:e[0]??t.out,...o(t)}),daemonWriter:e=>(s(`screenshot`,e),ee(e),w(u.screenshot,A(e.path),{...e,...ie(e)}))}),$r=`settings`,ei=H($r,`Change supported operating-system settings, animation scales, appearance, or app permissions on the selected target. Platform support varies by setting and action.`,{setting:f(p()),state:f(p()),app:p(),latitude:m(),longitude:m(),permission:p(),mode:_([`full`,`limited`])}),ti=P({name:$r,text:{summary:`Change OS settings and app permissions`,cliDetail:`macOS supports only settings appearance <light|dark|toggle> and settings permission <grant|reset> <accessibility|screen-recording|input-monitoring>; wifi|airplane|location|animations remain unsupported on macOS. Mobile permission actions use the active session app.`},metadata:ei,definition:R(ei,(e,t)=>e.settings.update(t)),cliSchema:{usageOverride:me,listUsageOverride:`settings [area] [options]`,positionalArgs:[`setting`,`state`,`target?`,`mode?`]},cliReader:(e,t)=>ni(e,t),daemonWriter:C(u.settings,e=>ri(e))});function ni(t,n){let r=Kn(n),i=t[0],a=t[1];if(O(i,oi)&&O(a,si))return{...r,setting:i,state:a};if(i===`location`&&a===`set`)return{...r,setting:i,state:a,latitude:ye(t[2],`latitude`),longitude:ye(t[3],`longitude`)};if(i===`appearance`&&O(a,ci)||O(i,li)&&O(a,ui)||i===`fingerprint`&&O(a,di))return{...r,setting:i,state:a};if(i===`permission`&&O(a,fi))return{...r,setting:i,state:a,permission:ii(t[2]),mode:ai(t[3])};if(i===`clear-app-state`){let e=a===`clear`?t[2]:a;return{...r,setting:i,state:`clear`,app:e}}throw new e(`INVALID_ARGS`,`Invalid settings arguments.`)}function ri(e){return e.setting===`clear-app-state`?[e.setting,...A(e.app)]:e.setting===`location`&&e.state===`set`?[e.setting,e.state,String(e.latitude),String(e.longitude)]:e.setting===`permission`?[e.setting,e.state,e.permission,...A(e.mode)]:[e.setting,e.state]}function ii(t){if(O(t,pi))return t;throw new e(`INVALID_ARGS`,`settings permission requires a permission target.`)}function ai(t){if(t===void 0||t===`full`||t===`limited`)return t;throw new e(`INVALID_ARGS`,`settings permission mode must be full or limited.`)}const oi=D(`wifi`,`airplane`,`location`,`animations`),si=D(`on`,`off`),ci=D(`light`,`dark`,`toggle`),li=D(`faceid`,`touchid`),ui=D(`match`,`nonmatch`,`enroll`,`unenroll`),di=D(`match`,`nonmatch`),fi=D(`grant`,`deny`,`reset`),pi=D(`camera`,`microphone`,`photos`,`contacts`,`contacts-limited`,`notifications`,`calendar`,`location`,`location-always`,`media-library`,`motion`,`reminders`,`siri`,`accessibility`,`screen-recording`,`input-monitoring`);function mi(e){if(!Array.isArray(e)||e.length===0)return e;let t=Ke(e);return e.map(e=>{let n=hi(e,t,e=>e.label),r=hi(e,t,e=>e.identifier),i=typeof e.label==`string`&&e.label.length>=24&&e.label===n,a=typeof e.identifier==`string`&&e.identifier.length>=24&&e.identifier===r;if(!i&&!a)return e;let o={...e};return i&&(delete o.label,o.inheritsLabel=!0),a&&(delete o.identifier,o.inheritsIdentifier=!0),o})}function hi(e,t,n){let r=typeof e.parentIndex==`number`?t.get(e.parentIndex):void 0;for(;r;){let e=n(r);if(typeof e==`string`&&e.length>0)return e;r=typeof r.parentIndex==`number`?t.get(r.parentIndex):void 0}}function gi(e){let t=yt(e.raw||!Array.isArray(e.result.nodes)?e.result:{...e.result,nodes:mi(e.result.nodes)});return{data:t,jsonData:vi(t),stderr:e.result.snapshotDiagnostics?.warning?`${e.result.snapshotDiagnostics.warning}\n`:void 0,text:lt(t,{raw:e.raw,flatten:e.interactiveOnly,scoped:typeof e.scope==`string`&&e.scope.trim().length>0,depthLimited:typeof e.depth==`number`})}}const _i={snapshot:({input:e,result:t})=>gi({result:t,raw:e.raw,interactiveOnly:e.interactiveOnly,scope:e.scope,depth:e.depth}),wait:B,alert:B};function vi(e){let{unchanged:t,...n}=e;return n}const yi=`snapshot`,bi=H(yi,`Capture the accessibility tree or compare it with the previous session baseline. Use the returned refs for subsequent semantic interactions and the diff option to verify UI changes.`,{interactiveOnly:g(),depth:h(),scope:p(),raw:g(),customActions:g(`Name the affordances an element merged away (iOS UIAccessibilityCustomAction, React Native accessibilityActions) — a card whose reply/options controls are not separate elements still lists them here. The names are for PLANNING, not invocation: there is no API to trigger them, so reach the affordance through the element detail screen, through the same control exposed as a labeled element elsewhere, or by coordinates from its rect. iOS simulator only; costs one accessibility round trip per merged element.`),forceFull:g(),timeoutMs:h(`Maximum wall-clock time for the snapshot command.`),noRecord:g(`Do not record this action.`),record:g(`Force-record this out-of-band observation into a repair-armed heal (mutually exclusive with noRecord). Authored replay steps are recorded automatically and never need this.`)}),xi=P({name:yi,text:{summary:`Capture or diff the accessibility tree`,cliDetail:`For iOS raw-coordinate fallback after a no-op ref press, inspect rects with snapshot -i --json, press the rect center, then verify with diff snapshot -i or snapshot --diff.`},metadata:bi,definition:R(bi,(e,t)=>e.capture.snapshot(t)),cliSchema:{usageOverride:`snapshot [--diff] [-i] [-d <depth>] [-s <scope>] [--raw] [--actions] [--force-full] [--timeout <ms>]`,allowedFlags:[`snapshotDiff`,...zr,`snapshotCustomActions`,`snapshotForceFull`,`timeoutMs`,`record`]},cliReader:(e,t)=>({...T(t),...Gn(t),interactiveOnly:t.snapshotInteractiveOnly,depth:t.snapshotDepth,scope:t.snapshotScope,raw:t.snapshotRaw,customActions:t.snapshotCustomActions,forceFull:t.snapshotForceFull,timeoutMs:t.timeoutMs}),daemonWriter:C(u.snapshot),cliOutputFormatter:_i.snapshot}),Si=[`duration`,`text`,`ref`,`selector`,`stable`],Ci=`wait`,wi=H(Ci,`Wait for a duration, text, snapshot ref, selector, or stable UI. Use text, ref, or selector for a specific readiness condition; stable waits until the UI stays quiet for the requested window.`,{kind:_(Si),durationMs:h(),text:p(),ref:p(),selector:p(),stable:g(),quietMs:h(),timeoutMs:h(),depth:h(),scope:p(),raw:g()}),Ti=P({name:Ci,text:{summary:`Wait for a duration, text, selector, or stable UI`},metadata:wi,definition:R(wi,(e,t)=>e.command.wait(Ei(t))),cliSchema:{usageOverride:`wait <ms>|text <text>|@ref|<selector>|stable [quietMs] [timeoutMs]`,positionalArgs:[`durationOrSelector`,`timeoutMs?`],allowsExtraPositionals:!0,allowedFlags:[...W]},cliReader:(e,t)=>Di(e,t),daemonWriter:C(u.wait,e=>Oi(e)),cliOutputFormatter:B});function Ei(e){Dn(e,`kind`,Si);let t={...e};return delete t.kind,t}function Di(t,n){let r=je(t);if(!r)throw new e(`INVALID_ARGS`,`wait requires <ms>, text <text>, @ref, <selector> [timeoutMs], or stable [quietMs] [timeoutMs].`);let i={...Kn(n),...Jn(n)};if(r.kind===`sleep`)return{...i,durationMs:r.durationMs};if(r.kind===`text`){if(!r.text)throw new e(`INVALID_ARGS`,`wait requires text.`);return{...i,text:r.text,...ki(r.timeoutMs)}}return r.kind===`ref`?{...i,ref:r.rawRef,...ki(r.timeoutMs)}:r.kind===`stable`?{...i,stable:!0,...Ai(r.quietMs),...ki(r.timeoutMs)}:{...i,selector:r.selectorExpression,...ki(r.timeoutMs)}}function Oi(t){if([t.durationMs===void 0?void 0:`durationMs`,t.text===void 0?void 0:`text`,t.ref===void 0?void 0:`ref`,t.selector===void 0?void 0:`selector`,t.stable===void 0?void 0:`stable`].filter(Boolean).length!==1)throw new e(`INVALID_ARGS`,`wait command requires exactly one of durationMs, text, ref, selector, or stable.`);if(t.durationMs!==void 0)return[String(t.durationMs)];let n=j(t.timeoutMs);if(t.text!==void 0)return[`text`,t.text,...n];if(t.ref!==void 0)return[t.ref,...n];if(t.stable!==void 0){let r=j(t.quietMs);if(r.length===0&&n.length>0)throw new e(`INVALID_ARGS`,`wait stable requires quietMs before timeoutMs.`);return[`stable`,...r,...n]}let r=t.selector;if(!We(r))throw new e(`INVALID_ARGS`,`Invalid wait selector: ${r}`);return[r,...n]}function ki(e){return e===null?{}:{timeoutMs:e}}function Ai(e){return e===null?{}:{quietMs:e}}const ji=F({name:`capture`,commands:[xi,Qr,Yr,Ti,Fr,ti]});function Mi(e){let t=[e.outPath,e.message];t.push(...Pi(e));for(let n of e.matchedImages)t.push(`Matched: ${n.name} ${n.uuid}${n.arch?` ${n.arch}`:``}`);for(let n of e.warnings??[])t.push(`Warning: ${n}`);return{data:e,text:t.join(`
|
|
3
|
+
`)}}const Ni={debug:z(Mi)};function Pi(e){let t=e.crash,n=[`Crash: ${t.appName??`unknown app`}${t.crashedThread===void 0?``:` thread ${t.crashedThread}`}`];t.bundleId&&n.push(`Bundle: ${t.bundleId}`),t.exceptionType&&n.push(`Exception: ${t.exceptionType}`),t.terminationReason&&n.push(`Termination: ${t.terminationReason}`);for(let e of t.topFrames)n.push(`Frame ${e.index}: ${e.image} ${e.symbol??e.address}`);for(let e of t.findings)n.push(`Finding: ${e}`);return n}const Fi=`debug`,Ii=H(Fi,`Symbolicate Apple crash artifacts with matching dSYM UUIDs. This debug namespace is intentionally narrow: use logs for app logs, network for HTTP evidence, perf for performance samples, record/trace for media and traces, and react-devtools for React Native profiles.`,{action:f(_([`symbols`])),artifact:f(p(`Apple crash artifact path (.ips, .crash, or .log).`)),dsym:p(`Path to a matching .dSYM bundle.`),searchPath:p(`Directory to scan for matching .dSYM bundles.`),out:p(`Output path for the symbolicated artifact.`)}),Li=F({name:`debugging`,commands:[P({name:Fi,text:{summary:`Symbolicate Apple crash artifacts`},metadata:Ii,definition:R(Ii,(e,t)=>e.debug.symbols(t)),cliSchema:{usageOverride:`debug symbols --artifact <crash.ips|crash.log> (--dsym <App.dSYM> | --search-path <dir>) [--out <symbolicated>]`,listUsageOverride:`debug`,positionalArgs:[`symbols`],allowedFlags:[`artifact`,`dsym`,`searchPath`,`out`]},cliReader:(e,t)=>({...T(t),action:Ri(e[0]),artifact:t.artifact,dsym:t.dsym,searchPath:t.searchPath,out:t.out}),cliOutputFormatter:Ni.debug})]});function Ri(t){if(t===`symbols`)return t;throw new e(`INVALID_ARGS`,`debug supports only symbols; use logs, network, perf, record, trace, or react-devtools for other diagnostics`)}const zi=()=>g(`Capture cheap post-action evidence (AX digest, node counts, changedFromBefore) instead of a follow-up snapshot.`),Bi=()=>({settle:g(`After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response. Best-effort; never fails the action.`),settleQuietMs:h(`Settle: quiet window in milliseconds (default 500).`,{min:0}),timeoutMs:h(`Settle: wait deadline in milliseconds (default 10000).`,{min:1})});function Vi(e){return{...ke(e)?{verify:zi()}:{},...Fe(e)?Bi():{}}}function Hi(e){let t=[];return ke(e)&&t.push(`verify`),Fe(e)&&t.push(...Ur),t}const Ui=[`click`,`focus`,`exists`,`list`,`getText`,`getAttrs`,`wait`,`fill`,`type`],Wi={click:`Activate a UI target by snapshot ref, selector, or coordinates. Prefer a ref or selector after a snapshot; use coordinates only when semantic targeting is unavailable. This can change app state; use settle or verify to confirm the result without a follow-up snapshot.`,press:`Short-press a UI target by snapshot ref, selector, or coordinates. Use longpress instead when the target requires a context-menu or hold gesture.`,fill:`Replace text in a UI input selected by snapshot ref, selector, or coordinates. Prefer refs or selectors after snapshot; use recordAs to keep sensitive text out of a recorded replay while sending it to the live app.`,longpress:`Hold a UI target by snapshot ref, selector, or coordinates to open a context menu or perform another hold gesture. Set durationMs when the default hold duration is unsuitable.`,swipe:`Quick coordinate fling with optional repeat pattern.`,focus:`Move input focus to explicit screen coordinates without entering text. Prefer semantic interactions when a snapshot ref or selector is available; use type or fill after focus.`,type:`Append text to the currently focused input. Use fill when the existing field value should be replaced, and focus first when no input is active.`,scroll:`Scroll in a direction, or toward the top/bottom edge of scrollable content.`,get:`Read text or accessibility attributes from a snapshot ref or selector without changing the app. Use format text for visible content or attrs for the element attribute map.`,is:`Check whether a selector satisfies a UI predicate such as visible, hidden, editable, selected, focused, or text. Use wait when the condition may appear asynchronously.`,find:`Find by text/label/value/role/id and run action`,gesture:`Perform a structured pan, fling, swipe, pinch, rotate, transform, or drag gesture. Select the gesture kind, then provide only the inputs that apply to that kind.`},Gi={target:f(un()),button:_(_e,`Pointer button for platforms that support mouse buttons.`),...pn(),...mn(),...Vi(`click`)},Ki={target:f(un()),...pn(),...mn(),...Vi(`press`)},qi={target:f(un()),text:f(p(`Text to enter into the target.`)),delayMs:h(`Delay between typed characters.`,{min:0}),recordAs:p("When script recording is armed, send text to the live app but publish it as ${VAR}. Use an uppercase replay variable name such as PASSWORD."),...pn(),...Vi(`fill`)},Ji={target:f(un()),durationMs:h(`Long press duration in milliseconds.`,{min:0}),...pn(),...Vi(`longpress`)},Yi={from:f(fn(`Swipe start point.`)),to:f(fn(`Swipe end point.`)),count:h(`Number of swipe repetitions.`,{min:1,max:200}),pauseMs:h(`Pause between repeated swipes.`,{min:0,max:pe}),pattern:_(r)},Xi={x:f(m(`X coordinate.`)),y:f(m(`Y coordinate.`))},Zi={text:f(p(`Text to type.`)),delayMs:h(`Delay between typed characters.`,{min:0})},Qi={direction:f(_(ae)),amount:m(`Platform scroll amount.`),pixels:h(`Pixel scroll amount.`,{min:0}),durationMs:h(`Scroll duration in milliseconds when the backend supports pacing.`,{min:0,max:he}),...Vi(`scroll`)},$i=()=>({noRecord:g(`Do not record this action.`),record:g(`Force-record this out-of-band observation into a repair-armed heal (mutually exclusive with noRecord). Authored replay steps are recorded automatically and never need this. On find, valid only for a read-only action.`)}),ea={format:f(_([`text`,`attrs`])),target:f(dn()),...pn(),...$i()},ta={predicate:f(_([`visible`,`hidden`,`exists`,`editable`,`selected`,`focused`,`text`])),selector:f(p()),value:p(),...pn(),...$i()},na={locator:_(Ae),query:f(p()),action:_(Ui),value:p(),timeoutMs:h(),first:g(),last:g(),depth:h(),raw:g(),...$i()},ra={kind:f(_(de,`Gesture variant.`)),direction:_(fe,`Fling direction.`),preset:_(xe,`Swipe preset.`),origin:fn(`Gesture origin point.`),delta:fn(`Movement delta for pan or transform gestures.`),distance:h(`Fling distance.`,{min:0}),scale:m(`Pinch or transform scale.`),degrees:m(`Rotation in degrees.`),durationMs:h(`Pan/transform duration.`,{min:16,max:1e4}),pointerCount:h(`Pan touch pointer count (1 or 2).`,{min:1,max:2}),source:p(`Drag source @ref or selector.`),destination:p(`Drag destination @ref or selector.`),sourceHoldMs:h(`Drag activation hold duration.`,{min:1,max:1e4}),moveMs:h(`Drag movement duration.`,{min:16,max:1e4}),destinationHoldMs:h(`Hold before releasing at the destination.`,{min:0,max:1e4})},ia=[L({name:`click`,description:Wi.click,inputSchema:hn(Gi),readInput:e=>gn(e,Gi)}),L({name:`press`,description:Wi.press,inputSchema:hn(Ki),readInput:e=>gn(e,Ki)}),L({name:`fill`,description:Wi.fill,inputSchema:hn(qi),readInput:e=>gn(e,qi)}),G(`longpress`,Ji),G(`swipe`,Yi),G(`focus`,Xi),G(`type`,Zi),G(`scroll`,Qi),G(`get`,ea),G(`is`,ta),G(`find`,na),L({name:`gesture`,description:Wi.gesture,inputSchema:hn(ra),readInput:aa})];function aa(e){let t=_n(e);return{...vn(t),...ue(t)}}function G(e,t){return H(e,Wi[e],t)}const oa={gesture:ca},sa={gesture:e=>{let t=aa(e);return w(u.gesture,[],e,x(t))}};function ca(e,t){return{...T(t),...le(e,t.pointerCount)}}const K={click:(e,t)=>({...T(t),...qn(t),...Yn(t),...E(t),target:Xn(_t(e)),button:t.clickButton,verify:t.verify}),press:(e,t)=>({...T(t),...qn(t),...Yn(t),...E(t),target:Xn(_t(e)),verify:t.verify}),longpress:(e,t)=>{let n=la(e);return{...T(t),...qn(t),...E(t),target:Xn(n),durationMs:n.durationMs}},swipe:(e,t)=>({...T(t),...c(e,{count:t.count,pauseMs:t.pauseMs,pattern:t.pattern})}),focus:(e,t)=>({...T(t),x:Number(e[0]),y:Number(e[1])}),type:(e,t)=>({...T(t),text:e.join(` `),delayMs:t.delayMs}),fill:(e,t)=>{let n=dt(e);return{...T(t),...qn(t),...E(t),target:Xn(n.target),text:n.text,delayMs:t.delayMs,recordAs:t.recordAs,verify:t.verify}},scroll:(e,t)=>({...T(t),...E(t),direction:pa(e[0]),amount:k(e[1]),pixels:t.pixels,durationMs:t.durationMs}),get:(e,t)=>({...T(t),...Gn(t),...qn(t),format:rr(e[0]),target:Xn(nr(e.slice(1)))})},q={click:e=>w(u.click,Zn(e),{...e,clickButton:e.button}),press:C(u.press,e=>Zn(e)),longpress:C(u.longPress,e=>ua(e)),swipe:e=>(ce(e),w(u.swipe,[],e,{from:e.from,to:e.to,count:e.count,pauseMs:e.pauseMs,pattern:e.pattern})),focus:C(u.focus,e=>[String(e.x),String(e.y)]),type:C(u.type,e=>da(e)),fill:C(u.fill,e=>fa(e)),scroll:C(u.scroll,e=>[N(e.direction,`scroll requires direction`),...j(e.amount)]),get:C(u.get,e=>[N(e.format,`get requires format`),...Qn(e)])};function la(e){let t=ma(e);return{..._t(t.target),...t.durationMs===void 0?{}:{durationMs:t.durationMs}}}function ua(e){return[...Zn(e),...j(e.durationMs)]}function da(e){return[e.text]}function fa(e){return[...Zn(e),e.text]}function pa(t){if(t===`up`||t===`down`||t===`left`||t===`right`||t===`top`||t===`bottom`)return t;throw new e(`INVALID_ARGS`,`Unknown direction: ${String(t)}`,{hint:`scroll takes a direction first, then an optional amount: scroll <up|down|left|right|top|bottom> [amount]. It takes no @ref or selector — scroll the whole viewport, then retry the target with a selector.`})}function ma(e){if(sr(e[0])&&sr(e[1]))return{target:e.slice(0,2),...e[2]===void 0?{}:{durationMs:Number(e[2])}};let t=e.at(-1);return e.length>1&&sr(t)?{target:e.slice(0,-1),durationMs:Number(t)}:{target:e}}const ha=z(e=>{let t=V(e);return{data:t.data,text:ga(t.text,e)}});function ga(e,t){let n=typeof t.warning==`string`?`\nWarning: ${t.warning}`:``;return`${e??``}${n}${_a(t.settle)}`}function _a(e){if(!e||typeof e!=`object`)return``;let t=e,n=[xa(t),...va(t),...ba(t)];return t.hint&&n.push(`hint: ${t.hint}`),`\n${n.join(`
|
|
4
4
|
`)}`}function va(e){let t=e.diff,n=(t?.lines??[]).map(t=>`${t.kind===`removed`?`-`:`+`} ${ya(t,e.refsGeneration)}`);return t?.truncated&&n.push(`… changed lines truncated`),n}function ya(e,t){let n=e.text??``,r=mr(e.ref,t);if(!r||!e.ref)return n;let i=`@${e.ref}`;return n.startsWith(`${i} `)?`${r}${n.slice(i.length)}`:n}function ba(e){let t=e.tail??[];if(t.length===0)return[];let n=[`unchanged interactive (${t.length}):`];for(let r of t){let t=r.label?` "${r.label}"`:``,i=mr(r.ref,e.refsGeneration)??`@${r.ref??``}`;n.push(`= ${i} [${r.role??``}]${t}`)}return e.tailTruncated&&n.push(`… more interactive elements not shown, use snapshot -i`),n}function xa(e){let t=e.settled===!0?`settled`:`not settled`,n=e.diff?.summary;return n?`${t} after ${e.waitedMs??0}ms: +${n.additions??0} -${n.removals??0} (~${n.unchanged??0} unchanged)`:`${t} after ${e.waitedMs??0}ms`}function Sa(e){let t=e.result;return e.format===`text`?{data:t,text:typeof t.text==`string`?t.text:``}:e.format===`attrs`?{data:t,text:JSON.stringify(t.node??{},null,2)}:Oa(t)}function Ca(e){let t=e,n=ht(t);if(n)return{data:t,text:n};if(typeof t.text==`string`)return{data:t,text:t.text};if(Array.isArray(t.matches))return{data:t,text:wa(t.matches,t.refsGeneration)};let r=mr(t.ref,t.refsGeneration);return r?{data:t,text:`Found: ${r}`}:typeof t.found==`boolean`?{data:t,text:`Found: ${t.found}`}:t.node?{data:t,text:JSON.stringify(t.node,null,2)}:Oa(t)}function wa(e,t){return[`${e.length} match${e.length===1?``:`es`}:`,...e.map(e=>Ta(e,t))].join(`
|
|
5
|
-
`)}function Ta(e,t){let n=e.ref??``,r=n.startsWith(`@`)?n.slice(1):n,i=mr(n,t)??`@${r}`,a=it(e.node?.type??`Element`),o=e.node?At(e.node,a):``;return`= ${i} [${a}]${o?` "${o}"`:``}`}function Ea(e){let t=e;return{data:t,text:`Passed: is ${t.predicate??`assertion`}`}}function Da(e){let t=e,n=t.ref??``,r=t.x,i=t.y;if(!n||typeof r!=`number`||typeof i!=`number`){let e=Oa(t);return{data:e.data,text:ga(e.text,t)}}return{data:t,text:ga(`Tapped @${n} (${r}, ${i})`,t)}}const J={click:z(Da),press:z(Da),fill:ha,longpress:ha,scroll:ha,get:({input:e,result:t})=>Sa({result:t,format:e.format}),is:z(Ea),find:z(Ca)};function Oa(e){return V(e)}const ka={find:(e,t)=>Na(e,t),is:(e,t)=>Pa(e,t)},Aa={is:C(u.is,e=>ja(e)),find:e=>w(u.find,Ma(e),{...e,findFirst:e.first,findLast:e.last})};function ja(e){return[e.predicate,e.selector,...e.predicate===`text`?[e.value]:[]]}function Ma(e){let t=e.locator&&e.locator!==`any`?[e.locator,e.query]:[e.query];switch(e.action){case void 0:case`click`:case`focus`:case`exists`:case`list`:return e.action?[...t,e.action]:t;case`getText`:return[...t,`get`,`text`];case`getAttrs`:return[...t,`get`,`attrs`];case`wait`:return[...t,`wait`,...j(e.timeoutMs)];case`fill`:case`type`:return[...t,e.action,e.value]}}function Na(t,n){let r={...Ia(n),...Kn(n),...Gn(n),first:n.findFirst,last:n.findLast},i=Fa(t[0]),a=i!==void 0,o=a?t[1]:t[0],s=a?2:1,c=
|
|
5
|
+
`)}function Ta(e,t){let n=e.ref??``,r=n.startsWith(`@`)?n.slice(1):n,i=mr(n,t)??`@${r}`,a=it(e.node?.type??`Element`),o=e.node?At(e.node,a):``;return`= ${i} [${a}]${o?` "${o}"`:``}`}function Ea(e){let t=e;return{data:t,text:`Passed: is ${t.predicate??`assertion`}`}}function Da(e){let t=e,n=t.ref??``,r=t.x,i=t.y;if(!n||typeof r!=`number`||typeof i!=`number`){let e=Oa(t);return{data:e.data,text:ga(e.text,t)}}return{data:t,text:ga(`Tapped @${n} (${r}, ${i})`,t)}}const J={click:z(Da),press:z(Da),fill:ha,longpress:ha,scroll:ha,get:({input:e,result:t})=>Sa({result:t,format:e.format}),is:z(Ea),find:z(Ca)};function Oa(e){return V(e)}const ka={find:(e,t)=>Na(e,t),is:(e,t)=>Pa(e,t)},Aa={is:C(u.is,e=>ja(e)),find:e=>w(u.find,Ma(e),{...e,findFirst:e.first,findLast:e.last})};function ja(e){return[e.predicate,e.selector,...e.predicate===`text`?[e.value]:[]]}function Ma(e){let t=e.locator&&e.locator!==`any`?[e.locator,e.query]:[e.query];switch(e.action){case void 0:case`click`:case`focus`:case`exists`:case`list`:return e.action?[...t,e.action]:t;case`getText`:return[...t,`get`,`text`];case`getAttrs`:return[...t,`get`,`attrs`];case`wait`:return[...t,`wait`,...j(e.timeoutMs)];case`fill`:case`type`:return[...t,e.action,e.value]}}function Na(t,n){let r={...Ia(n),...Kn(n),...Gn(n),first:n.findFirst,last:n.findLast},i=Fa(t[0]),a=i!==void 0,o=a?t[1]:t[0],s=a?2:1,c=Ne(t[s]);if(c===void 0)return{...r,locator:i,query:La(o)};if(c===`get`){let n=t[s+1];if(n===`text`)return{...r,locator:i,query:La(o),action:`getText`};if(n===`attrs`)return{...r,locator:i,query:La(o),action:`getAttrs`};throw new e(`INVALID_ARGS`,`find get only supports text or attrs`)}if(c===`wait`)return{...r,locator:i,query:La(o),action:`wait`,timeoutMs:k(t[s+1])};if(c===`fill`||c===`type`)return{...r,locator:i,query:La(o),action:c,value:t.slice(s+1).join(` `)};if(c===`click`||c===`focus`||c===`exists`||c===`list`)return{...r,locator:i,query:La(o),action:c};throw new e(`INVALID_ARGS`,`Unsupported find action: ${t[s]}`,{hint:He})}function Pa(t,n){let r={...Jn(n),...Kn(n),...Gn(n)},i=Ee(t),a=Oe(i[0]??``);if(!a.ok)throw new e(a.code,a.message,{hint:a.hint});let o=a.predicate,s=ir(i.slice(1),{preferTrailingValue:o===`text`});return o===`text`?{...r,predicate:o,selector:s.selectorExpression,value:s.rest.join(` `)}:{...r,predicate:o,selector:s.selectorExpression}}function Fa(e){if(e===`text`||e===`label`||e===`value`||e===`role`||e===`id`)return e}function Ia(e){return{depth:e.snapshotDepth,raw:e.snapshotRaw}}function La(t){if(t===void 0||t===``)throw new e(`INVALID_ARGS`,`find requires query`);return t}const Y={get:{usageOverride:`get text|attrs <@ref|selector>`,positionalArgs:[`subcommand`,`target`],allowsExtraPositionals:!0,allowedFlags:[...W,`record`]},find:{usageOverride:`find <locator|text> <action> [value] [--first|--last]`,positionalArgs:[`query`,`action`,`value?`],allowsExtraPositionals:!0,allowedFlags:[`snapshotDepth`,`snapshotRaw`,`findFirst`,`findLast`,`record`]},is:{positionalArgs:[`predicate`,`selector`,`value?`],allowsExtraPositionals:!0,allowedFlags:[...W,`record`]},click:{usageOverride:`click <x y|@ref|selector>`,positionalArgs:[`target`],allowsExtraPositionals:!0,allowedFlags:[...Hr,`clickButton`,...Hi(`click`),...W]},press:{usageOverride:`press <x y|@ref|selector>`,positionalArgs:[`targetOrX`,`y?`],allowsExtraPositionals:!0,allowedFlags:[...Hr,...Hi(`press`),...W]},longpress:{usageOverride:`longpress <x y|@ref|selector> [durationMs]`,positionalArgs:[`targetOrX`,`yOrDurationMs?`,`durationMs?`],allowsExtraPositionals:!0,allowedFlags:[...Hi(`longpress`),...W]},swipe:{positionalArgs:[`x1`,`y1`,`x2`,`y2`],allowsExtraPositionals:!0,allowedFlags:[`count`,`pauseMs`,`pattern`]},gesture:{usageOverride:`gesture <pan|fling|swipe|pinch|rotate|transform|drag> ...`,listUsageOverride:`gesture <pan|fling|swipe|pinch|rotate|transform|drag> ...`,positionalArgs:[`pan|fling|swipe|pinch|rotate|transform|drag`,`args?`],allowsExtraPositionals:!0,allowedFlags:[`pointerCount`]},focus:{positionalArgs:[`x`,`y`]},type:{positionalArgs:[`text`],allowsExtraPositionals:!0,allowedFlags:[`delayMs`]},fill:{usageOverride:`fill <x> <y> <text> | fill <@ref|selector> <text>`,positionalArgs:[`targetOrX`,`yOrText`,`text?`],allowsExtraPositionals:!0,allowedFlags:[...W,`delayMs`,`recordAs`,...Hi(`fill`)]},scroll:{usageOverride:`scroll <direction|top|bottom> [amount] [--pixels <n>] [--duration-ms <ms>] [--settle]`,positionalArgs:[`directionOrEdge`,`amount?`],allowedFlags:[`pixels`,`durationMs`,...Hi(`scroll`)]}},Ra=R(X(`click`),(e,t)=>e.interactions.click(Za(t))),za=R(X(`press`),(e,t)=>e.interactions.press(Qa(t))),Ba=R(X(`fill`),(e,t)=>e.interactions.fill($a(t))),Va=R(X(`longpress`),(e,t)=>e.interactions.longPress(eo(t))),Ha=R(X(`swipe`),(e,t)=>e.interactions.swipe(t)),Ua=R(X(`focus`),(e,t)=>e.interactions.focus(t)),Wa=R(X(`type`),(e,t)=>e.interactions.type(t)),Ga=R(X(`scroll`),(e,t)=>e.interactions.scroll(t)),Ka=R(X(`get`),(e,t)=>e.interactions.get(no(t))),qa=R(X(`is`),(e,t)=>e.interactions.is(t)),Ja=R(X(`find`),(e,t)=>e.interactions.find(t)),Ya=R(X(`gesture`),async(e,t)=>{switch(t.kind){case`pan`:return await e.interactions.pan(ro(t));case`fling`:return await e.interactions.fling(ao(t));case`swipe`:return await e.interactions.swipeGesture(oo(t));case`pinch`:return await e.interactions.pinch(so(t));case`rotate`:return await e.interactions.rotateGesture(co(t));case`transform`:return await e.interactions.transformGesture(lo(t));case`drag`:return await e.interactions.drag(io(t))}}),Xa=F({name:`interaction`,clientSurface:!1,commands:[P({name:`click`,text:{summary:`Click or tap a UI target`},metadata:X(`click`),definition:Ra,cliSchema:Y.click,cliReader:K.click,daemonWriter:q.click,cliOutputFormatter:J.click}),P({name:`press`,text:{summary:`Short-press a UI target`,cliDetail:`The hold duration is positional on longpress, not press --hold-ms.`},metadata:X(`press`),definition:za,cliSchema:Y.press,cliReader:K.press,daemonWriter:q.press,cliOutputFormatter:J.press}),P({name:`fill`,text:{summary:`Replace text in a UI input`},metadata:X(`fill`),definition:Ba,cliSchema:Y.fill,cliReader:K.fill,daemonWriter:q.fill,cliOutputFormatter:J.fill}),P({name:`longpress`,text:{summary:`Hold a UI target to open a context menu`,cliDetail:`Duration is positional, for example longpress @e12 800 or longpress 300 500 800.`},metadata:X(`longpress`),definition:Va,cliSchema:Y.longpress,cliReader:K.longpress,daemonWriter:q.longpress,cliOutputFormatter:J.longpress}),P({name:`swipe`,text:{summary:`Fling between coordinates`},metadata:X(`swipe`),definition:Ha,cliSchema:Y.swipe,cliReader:K.swipe,daemonWriter:q.swipe}),P({name:`focus`,text:{summary:`Focus input at screen coordinates`},metadata:X(`focus`),definition:Ua,cliSchema:Y.focus,cliReader:K.focus,daemonWriter:q.focus}),P({name:`type`,text:{summary:`Append text to the focused input`},metadata:X(`type`),definition:Wa,cliSchema:Y.type,cliReader:K.type,daemonWriter:q.type}),P({name:`scroll`,text:{summary:`Scroll in a direction or to an edge`},metadata:X(`scroll`),definition:Ga,cliSchema:Y.scroll,cliReader:K.scroll,daemonWriter:q.scroll,cliOutputFormatter:J.scroll}),P({name:`get`,text:{summary:`Read element text or attributes`},metadata:X(`get`),definition:Ka,cliSchema:Y.get,cliReader:K.get,daemonWriter:q.get,cliOutputFormatter:J.get}),P({name:`is`,text:{summary:`Check a UI predicate on a selector`},metadata:X(`is`),definition:qa,cliSchema:Y.is,cliReader:ka.is,daemonWriter:Aa.is,cliOutputFormatter:J.is}),P({name:`find`,text:{summary:`Find an element and act`},metadata:X(`find`),definition:Ja,cliSchema:Y.find,cliReader:ka.find,daemonWriter:Aa.find,cliOutputFormatter:J.find}),P({name:`gesture`,text:{summary:`Run pan, fling, swipe, pinch, rotate, transform, or drag gestures`,cliDetail:`Argument shapes: pan <x> <y> <dx> <dy> [durationMs], fling <up|down|left|right> <x> <y> [distance], swipe <left|right|left-edge|right-edge>, pinch <scale> [x] [y], rotate <degrees> [x] [y], transform <x> <y> <dx> <dy> <scale> <degrees> [durationMs], or drag <source-selector|pinned-ref> <destination-selector|pinned-ref> [sourceHoldMs] [moveMs] [destinationHoldMs]. For command plans, output only command lines. Android transform verification should use all app-observable effects, for example wait text "pan changed yes", wait text "pinch changed yes", and wait text "rotate changed yes", not exact transform values.`},metadata:X(`gesture`),definition:Ya,cliSchema:Y.gesture,cliReader:oa.gesture,daemonWriter:sa.gesture})]});function X(e){let t=ia.find(t=>t.name===e);if(!t)throw Error(`Missing interaction command metadata for ${e}`);return t}function Za(e){return{...b(e),...On(e.target),...jn(e),...An(e),button:e.button,verify:e.verify,...to(e)}}function Qa(e){return{...b(e),...On(e.target),...jn(e),...An(e),verify:e.verify,...to(e)}}function $a(e){return{...b(e),...On(e.target),...jn(e),text:e.text,delayMs:e.delayMs,recordAs:e.recordAs,verify:e.verify,...to(e)}}function eo(e){return{...b(e),...On(e.target),...jn(e),durationMs:e.durationMs,...to(e)}}function to(e){return{settle:e.settle,settleQuietMs:e.settleQuietMs,timeoutMs:e.timeoutMs}}function no(e){return{...b(e),...kn(e.target),...jn(e),format:e.format,record:e.record}}function ro(e){return{...b(e),x:e.origin.x,y:e.origin.y,dx:e.delta.x,dy:e.delta.y,pointerCount:e.pointerCount,durationMs:e.durationMs}}function io(e){return{...b(e),source:e.source,destination:e.destination,sourceHoldMs:e.sourceHoldMs,moveMs:e.moveMs,destinationHoldMs:e.destinationHoldMs}}function ao(e){return{...b(e),direction:e.direction,x:e.origin.x,y:e.origin.y,distance:e.distance}}function oo(e){return{...b(e),preset:e.preset}}function so(e){return{...b(e),scale:e.scale,x:e.origin?.x,y:e.origin?.y}}function co(e){return{...b(e),degrees:e.degrees,x:e.origin?.x,y:e.origin?.y}}function lo(e){return{...b(e),x:e.origin.x,y:e.origin.y,dx:e.delta.x,dy:e.delta.y,scale:e.scale,degrees:e.degrees,durationMs:e.durationMs}}function uo(e){return{data:{devices:e.map(Dt)},text:e.map(To).join(`
|
|
6
6
|
`)}}function fo(e){return{data:{device:Dt(e.device),availableCommands:e.availableCommands},text:[`${To(e.device)} supports ${e.availableCommands.length} commands:`,e.availableCommands.join(` `)].join(`
|
|
7
7
|
`)}}function po(e){return{data:{apps:e.result},stderr:e.appsFilter===`all`?`Showing all apps, including system apps.
|
|
8
8
|
`:`Showing user-installed apps. Use --all to include system apps.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import{i as t,n,r}from"./sdk-remote-config.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import{i as t,n,r}from"./sdk-remote-config.js";import{O as i}from"./sdk-android-adb.js";import{n as a}from"./path-resolution.js";import o from"node:path";import s from"node:fs";function c(n){let r=n.env??process.env,c=d(n);if(!s.existsSync(c))throw new e(`INVALID_ARGS`,`Remote config file not found: ${c}`);let l;try{l=s.readFileSync(c,`utf8`)}catch(t){throw new e(`INVALID_ARGS`,`Failed to read remote config file: ${c}`,{cause:t instanceof Error?t.message:String(t)})}let u;try{u=JSON.parse(l)}catch(t){throw new e(`INVALID_ARGS`,`Invalid JSON in remote config file: ${c}`,{cause:t instanceof Error?t.message:String(t)})}if(!u||typeof u!=`object`||Array.isArray(u))throw new e(`INVALID_ARGS`,`Remote config file must contain a JSON object: ${c}`);let f={},p=u,m=o.dirname(c);for(let[n,o]of Object.entries(p)){let s=t(n);if(!s)throw new e(`INVALID_ARGS`,`Unsupported remote config key "${n}" in remote config file ${c}.`);let l=i(s,o,`remote config file ${c}`,n);f[s.key]=typeof l==`string`&&`path`in s&&s.path?a(l,{cwd:m,env:r}):l}return{resolvedPath:c,profile:f}}function l(e=process.env){let t={};for(let a of n){let n=r(a.key).map(t=>({name:t,value:e[t]})).find(e=>typeof e.value==`string`&&e.value.trim().length>0);n&&(t[a.key]=i(a,n.value,`environment variable ${n.name}`,n.name))}return t}function u(...e){let t={};for(let r of e)if(r)for(let e of n){let n=r[e.key];n!==void 0&&(t[e.key]=n)}return t}function d(e){let t=e.env??process.env;return a(e.configPath,{cwd:e.cwd,env:t})}function f(e){let t=c(e);return{resolvedPath:t.resolvedPath,profile:u(l(e.env),t.profile)}}export{d as n,f as r,c as t};
|
package/dist/src/replay.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{_ as e}from"./sdk-contracts.js";import"./version.js";import{
|
|
1
|
+
import{_ as e}from"./sdk-contracts.js";import"./version.js";import{ft as t}from"./sdk-batch-runner.js";import{_t as n,gt as r}from"./screenshot-result.js";import{n as i}from"./path-resolution.js";import{i as a,n as o}from"./selector-vocabulary.js";import{t as s}from"./shared.js";import c from"node:path";import l from"node:fs";import{stringify as u}from"yaml";function d(e,t){return`${e},${t}`}function f(e){return`${e.map(e=>u(e).trimEnd()).join(`
|
|
2
2
|
---
|
|
3
|
-
`)}\n`}function p(t,n){let r={config:m(n.metadata),warnings:[],unsupported:[]},i=[];for(let[e,a]of t.entries()){let t=n.actionLines?.[e]??e+1,o=g(a,n.resolveSelector);switch(o.kind){case`commands`:i.push(...o.commands),U(r,o.warnings,a,t);break;case`config`:V(r,o.appId,a,t),i.push(...o.commands),U(r,o.warnings,a,t);break;case`unsupported`:r.unsupported.push({line:t,action:q(a),message:o.message});break}}if(r.unsupported.length>0)throw new e(`INVALID_ARGS`,`Cannot export replay to Maestro YAML: unsupported .ad action ${K(r.unsupported)}.`,{unsupported:r.unsupported});return{yaml:G(r.config,i),warnings:r.warnings}}function m(e){return e?.env&&Object.keys(e.env).length>0?{env:e.env}:{}}const h={open:_,click:b,press:b,longpress:x,fill:T,type:E,keyboard:D,back:()=>({kind:`commands`,commands:[`back`]}),wait:O,find:k,screenshot:A,scroll:j,swipe:M};function g(e,t){return h[e.command]?.(e,t)??{kind:`unsupported`,message:`${e.command} has no Maestro equivalent`}}function _(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`open requires an app id or URL`};if(J(t))return{kind:`commands`,commands:[{openLink:t}]};let r=v(e,t);return n&&J(n)?{kind:`config`,appId:t,commands:[r,{openLink:n}]}:n?{kind:`unsupported`,message:`open with a non-URL second argument is unsupported`}:{kind:`config`,appId:t,commands:[r]}}function v(e,t){let n=y(e);return n?{launchApp:{appId:t,...n}}:`launchApp`}function y(e){let t=e.flags?.launchArgs,n={};return e.flags?.relaunch===!0&&(n.stopApp=!0),e.flags?.clearAppState===!0&&(n.clearState=!0),Array.isArray(t)&&t.length>0&&(n.launchArguments=t),Object.keys(n).length>0?n:void 0}function b(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`${e.command} requires a target`};let i=I(n,r,t);if(!i)return{kind:`unsupported`,message:`tap target is not Maestro-compatible`};let a=L(e);return a.ok?e.flags?.doubleTap===!0?{kind:`commands`,commands:[{doubleTapOn:i}],warnings:w(e,`doubleTapOn`)}:typeof e.flags?.holdMs==`number`?{kind:`commands`,commands:[{longPressOn:i}],warnings:[C(e.flags.holdMs),...w(e,`longPressOn`)]}:{kind:`commands`,commands:[B(i,a.options)]}:{kind:`unsupported`,message:a.message}}function x(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`longpress requires a target`};let i=I(n,r,t);return i?{kind:`commands`,commands:[{longPressOn:i}],warnings:S(e).map(C)}:{kind:`unsupported`,message:`longpress target is not Maestro-compatible`}}function S(e){let[t,n,r]=e.positionals,i=Y(t)&&Y(n)?r:n;return i&&Y(i)?[Number(i)]:[]}function C(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function w(e,t){let n=[];return typeof e.flags?.count==`number`&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function T(e,t){let[n,r]=e.positionals;if(!n||r===void 0)return{kind:`unsupported`,message:`fill requires a target and text`};let i=I(n,void 0,t);return i?{kind:`commands`,commands:[{tapOn:i},{inputText:r}],warnings:[`fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents`]}:{kind:`unsupported`,message:`fill target is not Maestro-compatible`}}function E(e){let[t]=e.positionals;if(t===void 0)return{kind:`unsupported`,message:`type requires text`};let n=H(t);return n===null?{kind:`commands`,commands:[{inputText:t}]}:{kind:`commands`,commands:[{eraseText:n}]}}function D(e){let[t]=e.positionals;return t===`dismiss`?{kind:`commands`,commands:[`hideKeyboard`]}:t===`enter`||t===`return`?{kind:`commands`,commands:[{pressKey:`Enter`}]}:{kind:`unsupported`,message:`keyboard ${t??``}`.trim()}}function O(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`wait requires a target or duration`};if(Y(n))return{kind:`commands`,commands:[{waitForAnimationToEnd:{timeout:Number(n)}}],warnings:[`wait <ms> exports as waitForAnimationToEnd and may return before the full duration`]};if(n===`text`&&r)return{kind:`commands`,commands:[{extendedWaitUntil:{visible:r,timeout:W(e,a.extendedWaitUntilTimeoutMs)}}]};let i=t(n);return i?{kind:`commands`,commands:[{extendedWaitUntil:{visible:i,timeout:W(e,a.extendedWaitUntilTimeoutMs)}}]}:{kind:`unsupported`,message:`wait selector is not Maestro-compatible`}}function k(e){let[t,n,r]=e.positionals;return t!==`text`||!n||!r?{kind:`unsupported`,message:`only find text <query> exists|missing exports to Maestro`}:r===`exists`?{kind:`commands`,commands:[{assertVisible:n}]}:r===`missing`||r===`not-exists`?{kind:`commands`,commands:[{assertNotVisible:n}]}:{kind:`unsupported`,message:`find text assertion "${r}" is unsupported`}}function A(e){let[t]=e.positionals;return t?{kind:`commands`,commands:[{takeScreenshot:t}]}:{kind:`unsupported`,message:`screenshot requires an output path`}}function j(e){let[t]=e.positionals;return!t||t===`down`?{kind:`commands`,commands:[`scroll`]}:{kind:`unsupported`,message:`scroll ${t} is not exported yet`}}function M(e){let t=N(e);if(!t)return{kind:`unsupported`,message:`only coordinate swipe exports to Maestro`};let n=P(e);if(n===null)return{kind:`unsupported`,message:`swipe count must be a positive integer`};let r=F(e);return r?{kind:`unsupported`,message:r}:{kind:`commands`,commands:Array.from({length:n},()=>({swipe:t}))}}function N(e){let[t,n,r,i]=e.positionals;if(!(!Y(t)||!Y(n)||!Y(r)||!Y(i)))return{start:d(t,n),end:d(r,i),duration:100}}function P(e){let t=e.flags?.count??1;return Number.isInteger(t)&&t>=1?t:null}function F(e){if(e.flags?.pauseMs!==void 0)return`swipe --pause-ms has no Maestro equivalent`;if(e.flags?.pattern&&e.flags.pattern!==`one-way`)return`swipe ping-pong pattern has no Maestro equivalent`}function I(e,t,n){return Y(e)&&Y(t)?{point:d(e,t)}:e.startsWith(`@`)?null:n(e)}function L(e){let t=z(e);return t?{ok:!1,message:t}:{ok:!0,options:R(e)}}function R(e){let t={};return typeof e.flags?.count==`number`&&e.flags.count>1&&(t.repeat=e.flags.count),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&(t.delay=e.flags.intervalMs),t}function z(e){if(e.flags?.jitterPx!==void 0)return`tap --jitter-px has no Maestro equivalent`;if(e.flags?.clickButton&&e.flags.clickButton!==`primary`)return`tap --button ${e.flags.clickButton} has no Maestro equivalent`}function B(e,t){return Object.keys(t).length===0?{tapOn:e}:typeof e==`string`?{tapOn:{text:e,...t}}:e&&typeof e==`object`&&!Array.isArray(e)?{tapOn:{...e,...t}}:{tapOn:e}}function V(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:q(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})}function H(e){return e.length===0||![...e].every(e=>e===`\b`)?null:e.length}function U(e,t,n,r){for(let i of t??[])e.warnings.push({line:r,action:q(n),message:i})}function W(e,t){let n=e.positionals.at(-1);return n&&Y(n)?Number(n):t}function G(e,t){return f(Object.keys(e).length>0?[e,t]:[t])}function K(e){return e.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join(`; `)}function q(e){return[e.command,...e.positionals??[]].join(` `).trim()}function J(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function Y(e){return e!==void 0&&Number.isFinite(Number(e))}const X=async e=>{let{positionals:t}=e;return t[0]===`export`?await Q(e):Z(e)};function Z({positionals:t,flags:n}){if(t.length>1)throw new e(`INVALID_ARGS`,`replay accepts exactly one input path: replay <path>`);if(n.out!==void 0)throw new e(`INVALID_ARGS`,`replay --out is only supported with replay export.`);return!1}async function Q({positionals:a,flags:u}){$(a,u);let d=a[1];if(!d)throw new e(`INVALID_ARGS`,`replay export requires an input path.`);let f=i(d),m=l.readFileSync(f,`utf8`),h=
|
|
3
|
+
`)}\n`}function p(t,n){let r={config:m(n.metadata),warnings:[],unsupported:[]},i=[];for(let[e,a]of t.entries()){let t=n.actionLines?.[e]??e+1,o=g(a,n.resolveSelector);switch(o.kind){case`commands`:i.push(...o.commands),U(r,o.warnings,a,t);break;case`config`:V(r,o.appId,a,t),i.push(...o.commands),U(r,o.warnings,a,t);break;case`unsupported`:r.unsupported.push({line:t,action:q(a),message:o.message});break}}if(r.unsupported.length>0)throw new e(`INVALID_ARGS`,`Cannot export replay to Maestro YAML: unsupported .ad action ${K(r.unsupported)}.`,{unsupported:r.unsupported});return{yaml:G(r.config,i),warnings:r.warnings}}function m(e){return e?.env&&Object.keys(e.env).length>0?{env:e.env}:{}}const h={open:_,click:b,press:b,longpress:x,fill:T,type:E,keyboard:D,back:()=>({kind:`commands`,commands:[`back`]}),wait:O,find:k,screenshot:A,scroll:j,swipe:M};function g(e,t){return h[e.command]?.(e,t)??{kind:`unsupported`,message:`${e.command} has no Maestro equivalent`}}function _(e){let[t,n]=e.positionals;if(!t)return{kind:`unsupported`,message:`open requires an app id or URL`};if(J(t))return{kind:`commands`,commands:[{openLink:t}]};let r=v(e,t);return n&&J(n)?{kind:`config`,appId:t,commands:[r,{openLink:n}]}:n?{kind:`unsupported`,message:`open with a non-URL second argument is unsupported`}:{kind:`config`,appId:t,commands:[r]}}function v(e,t){let n=y(e);return n?{launchApp:{appId:t,...n}}:`launchApp`}function y(e){let t=e.flags?.launchArgs,n={};return e.flags?.relaunch===!0&&(n.stopApp=!0),e.flags?.clearAppState===!0&&(n.clearState=!0),Array.isArray(t)&&t.length>0&&(n.launchArguments=t),Object.keys(n).length>0?n:void 0}function b(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`${e.command} requires a target`};let i=I(n,r,t);if(!i)return{kind:`unsupported`,message:`tap target is not Maestro-compatible`};let a=L(e);return a.ok?e.flags?.doubleTap===!0?{kind:`commands`,commands:[{doubleTapOn:i}],warnings:w(e,`doubleTapOn`)}:typeof e.flags?.holdMs==`number`?{kind:`commands`,commands:[{longPressOn:i}],warnings:[C(e.flags.holdMs),...w(e,`longPressOn`)]}:{kind:`commands`,commands:[B(i,a.options)]}:{kind:`unsupported`,message:a.message}}function x(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`longpress requires a target`};let i=I(n,r,t);return i?{kind:`commands`,commands:[{longPressOn:i}],warnings:S(e).map(C)}:{kind:`unsupported`,message:`longpress target is not Maestro-compatible`}}function S(e){let[t,n,r]=e.positionals,i=Y(t)&&Y(n)?r:n;return i&&Y(i)?[Number(i)]:[]}function C(e){return`long-press duration exports as Maestro longPressOn; Maestro uses its default long-press duration instead of ${e}ms`}function w(e,t){let n=[];return typeof e.flags?.count==`number`&&e.flags.count>1&&n.push(`tap --count ${e.flags.count} is not represented by Maestro ${t}`),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&n.push(`tap --interval-ms ${e.flags.intervalMs} is not represented by Maestro ${t}`),n}function T(e,t){let[n,r]=e.positionals;if(!n||r===void 0)return{kind:`unsupported`,message:`fill requires a target and text`};let i=I(n,void 0,t);return i?{kind:`commands`,commands:[{tapOn:i},{inputText:r}],warnings:[`fill exports as tapOn + inputText; Maestro may append text instead of replacing existing field contents`]}:{kind:`unsupported`,message:`fill target is not Maestro-compatible`}}function E(e){let[t]=e.positionals;if(t===void 0)return{kind:`unsupported`,message:`type requires text`};let n=H(t);return n===null?{kind:`commands`,commands:[{inputText:t}]}:{kind:`commands`,commands:[{eraseText:n}]}}function D(e){let[t]=e.positionals;return t===`dismiss`?{kind:`commands`,commands:[`hideKeyboard`]}:t===`enter`||t===`return`?{kind:`commands`,commands:[{pressKey:`Enter`}]}:{kind:`unsupported`,message:`keyboard ${t??``}`.trim()}}function O(e,t){let[n,r]=e.positionals;if(!n)return{kind:`unsupported`,message:`wait requires a target or duration`};if(Y(n))return{kind:`commands`,commands:[{waitForAnimationToEnd:{timeout:Number(n)}}],warnings:[`wait <ms> exports as waitForAnimationToEnd and may return before the full duration`]};if(n===`text`&&r)return{kind:`commands`,commands:[{extendedWaitUntil:{visible:r,timeout:W(e,a.extendedWaitUntilTimeoutMs)}}]};let i=t(n);return i?{kind:`commands`,commands:[{extendedWaitUntil:{visible:i,timeout:W(e,a.extendedWaitUntilTimeoutMs)}}]}:{kind:`unsupported`,message:`wait selector is not Maestro-compatible`}}function k(e){let[t,n,r]=e.positionals;return t!==`text`||!n||!r?{kind:`unsupported`,message:`only find text <query> exists|missing exports to Maestro`}:r===`exists`?{kind:`commands`,commands:[{assertVisible:n}]}:r===`missing`||r===`not-exists`?{kind:`commands`,commands:[{assertNotVisible:n}]}:{kind:`unsupported`,message:`find text assertion "${r}" is unsupported`}}function A(e){let[t]=e.positionals;return t?{kind:`commands`,commands:[{takeScreenshot:t}]}:{kind:`unsupported`,message:`screenshot requires an output path`}}function j(e){let[t]=e.positionals;return!t||t===`down`?{kind:`commands`,commands:[`scroll`]}:{kind:`unsupported`,message:`scroll ${t} is not exported yet`}}function M(e){let t=N(e);if(!t)return{kind:`unsupported`,message:`only coordinate swipe exports to Maestro`};let n=P(e);if(n===null)return{kind:`unsupported`,message:`swipe count must be a positive integer`};let r=F(e);return r?{kind:`unsupported`,message:r}:{kind:`commands`,commands:Array.from({length:n},()=>({swipe:t}))}}function N(e){let[t,n,r,i]=e.positionals;if(!(!Y(t)||!Y(n)||!Y(r)||!Y(i)))return{start:d(t,n),end:d(r,i),duration:100}}function P(e){let t=e.flags?.count??1;return Number.isInteger(t)&&t>=1?t:null}function F(e){if(e.flags?.pauseMs!==void 0)return`swipe --pause-ms has no Maestro equivalent`;if(e.flags?.pattern&&e.flags.pattern!==`one-way`)return`swipe ping-pong pattern has no Maestro equivalent`}function I(e,t,n){return Y(e)&&Y(t)?{point:d(e,t)}:e.startsWith(`@`)?null:n(e)}function L(e){let t=z(e);return t?{ok:!1,message:t}:{ok:!0,options:R(e)}}function R(e){let t={};return typeof e.flags?.count==`number`&&e.flags.count>1&&(t.repeat=e.flags.count),typeof e.flags?.intervalMs==`number`&&e.flags.intervalMs>0&&(t.delay=e.flags.intervalMs),t}function z(e){if(e.flags?.jitterPx!==void 0)return`tap --jitter-px has no Maestro equivalent`;if(e.flags?.clickButton&&e.flags.clickButton!==`primary`)return`tap --button ${e.flags.clickButton} has no Maestro equivalent`}function B(e,t){return Object.keys(t).length===0?{tapOn:e}:typeof e==`string`?{tapOn:{text:e,...t}}:e&&typeof e==`object`&&!Array.isArray(e)?{tapOn:{...e,...t}}:{tapOn:e}}function V(e,t,n,r){if(!e.config.appId){e.config.appId=t;return}e.config.appId!==t&&e.unsupported.push({line:r,action:q(n),message:`multiple app ids cannot be represented in one Maestro config (${e.config.appId} vs ${t})`})}function H(e){return e.length===0||![...e].every(e=>e===`\b`)?null:e.length}function U(e,t,n,r){for(let i of t??[])e.warnings.push({line:r,action:q(n),message:i})}function W(e,t){let n=e.positionals.at(-1);return n&&Y(n)?Number(n):t}function G(e,t){return f(Object.keys(e).length>0?[e,t]:[t])}function K(e){return e.map(e=>`line ${e.line} (${e.action}): ${e.message}`).join(`; `)}function q(e){return[e.command,...e.positionals??[]].join(` `).trim()}function J(e){return/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(e)}function Y(e){return e!==void 0&&Number.isFinite(Number(e))}const X=async e=>{let{positionals:t}=e;return t[0]===`export`?await Q(e):Z(e)};function Z({positionals:t,flags:n}){if(t.length>1)throw new e(`INVALID_ARGS`,`replay accepts exactly one input path: replay <path>`);if(n.out!==void 0)throw new e(`INVALID_ARGS`,`replay --out is only supported with replay export.`);return!1}async function Q({positionals:a,flags:u}){$(a,u);let d=a[1];if(!d)throw new e(`INVALID_ARGS`,`replay export requires an input path.`);let f=i(d),m=l.readFileSync(f,`utf8`),h=r(m),g=p(h.actions,{actionLines:h.actionLines,metadata:n(m),resolveSelector:e=>t(e,o)}),_=typeof u.out==`string`?i(u.out):void 0;_&&(l.mkdirSync(c.dirname(_),{recursive:!0}),l.writeFileSync(_,g.yaml));for(let e of g.warnings)process.stderr.write(`Warning: line ${e.line}: ${e.message}\n`);return s(u,{format:`maestro`,sourcePath:f,..._?{path:_}:{yaml:g.yaml},warnings:g.warnings},()=>_??g.yaml),!0}function $(t,n){if(t.length>2)throw new e(`INVALID_ARGS`,`replay export accepts exactly one input path: replay export <file.ad>`);if(n.replayUpdate)throw new e(`INVALID_ARGS`,`replay export does not support --update.`);if(n.replayMaestro)throw new e(`INVALID_ARGS`,`replay export reads .ad files; omit --maestro.`);if(n.replayEnv?.length)throw new e(`INVALID_ARGS`,`replay export does not evaluate --env substitutions.`)}export{X as replayCommand};
|